aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_init_ops.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_init_ops.h')
-rw-r--r--drivers/net/bnx2x/bnx2x_init_ops.h338
1 files changed, 338 insertions, 0 deletions
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index 2b1363a6fe7..aae7fea0062 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -151,6 +151,15 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
151 bnx2x_init_ind_wr(bp, addr, data, len); 151 bnx2x_init_ind_wr(bp, addr, data, len);
152} 152}
153 153
154static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi)
155{
156 u32 wb_write[2];
157
158 wb_write[0] = val_lo;
159 wb_write[1] = val_hi;
160 REG_WR_DMAE_LEN(bp, reg, wb_write, 2);
161}
162
154static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) 163static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off)
155{ 164{
156 const u8 *data = NULL; 165 const u8 *data = NULL;
@@ -503,4 +512,333 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
503 } 512 }
504} 513}
505 514
515/****************************************************************************
516* ILT management
517****************************************************************************/
518/*
519 * This codes hides the low level HW interaction for ILT management and
520 * configuration. The API consists of a shadow ILT table which is set by the
521 * driver and a set of routines to use it to configure the HW.
522 *
523 */
524
525/* ILT HW init operations */
526
527/* ILT memory management operations */
528#define ILT_MEMOP_ALLOC 0
529#define ILT_MEMOP_FREE 1
530
531/* the phys address is shifted right 12 bits and has an added
532 * 1=valid bit added to the 53rd bit
533 * then since this is a wide register(TM)
534 * we split it into two 32 bit writes
535 */
536#define ILT_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
537#define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
538#define ILT_RANGE(f, l) (((l) << 10) | f)
539
540static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line,
541 u32 size, u8 memop)
542{
543 if (memop == ILT_MEMOP_FREE) {
544 BNX2X_ILT_FREE(line->page, line->page_mapping, line->size);
545 return 0;
546 }
547 BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size);
548 if (!line->page)
549 return -1;
550 line->size = size;
551 return 0;
552}
553
554
555static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop)
556{
557 int i, rc;
558 struct bnx2x_ilt *ilt = BP_ILT(bp);
559 struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
560
561 if (!ilt || !ilt->lines)
562 return -1;
563
564 if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM))
565 return 0;
566
567 for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) {
568 rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i],
569 ilt_cli->page_size, memop);
570 }
571 return rc;
572}
573
574int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop)
575{
576 int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop);
577 if (!rc)
578 rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop);
579 if (!rc)
580 rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop);
581 if (!rc)
582 rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop);
583
584 return rc;
585}
586
587static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx,
588 dma_addr_t page_mapping)
589{
590 u32 reg;
591
592 if (CHIP_IS_E1(bp))
593 reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8;
594 else
595 reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8;
596
597 bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping));
598}
599
600static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt,
601 int idx, u8 initop)
602{
603 dma_addr_t null_mapping;
604 int abs_idx = ilt->start_line + idx;
605
606
607 switch (initop) {
608 case INITOP_INIT:
609 /* set in the init-value array */
610 case INITOP_SET:
611 bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping);
612 break;
613 case INITOP_CLEAR:
614 null_mapping = 0;
615 bnx2x_ilt_line_wr(bp, abs_idx, null_mapping);
616 break;
617 }
618}
619
620void bnx2x_ilt_boundry_init_op(struct bnx2x *bp,
621 struct ilt_client_info *ilt_cli,
622 u32 ilt_start, u8 initop)
623{
624 u32 start_reg = 0;
625 u32 end_reg = 0;
626
627 /* The boundary is either SET or INIT,
628 CLEAR => SET and for now SET ~~ INIT */
629
630 /* find the appropriate regs */
631 if (CHIP_IS_E1(bp)) {
632 switch (ilt_cli->client_num) {
633 case ILT_CLIENT_CDU:
634 start_reg = PXP2_REG_PSWRQ_CDU0_L2P;
635 break;
636 case ILT_CLIENT_QM:
637 start_reg = PXP2_REG_PSWRQ_QM0_L2P;
638 break;
639 case ILT_CLIENT_SRC:
640 start_reg = PXP2_REG_PSWRQ_SRC0_L2P;
641 break;
642 case ILT_CLIENT_TM:
643 start_reg = PXP2_REG_PSWRQ_TM0_L2P;
644 break;
645 }
646 REG_WR(bp, start_reg + BP_FUNC(bp)*4,
647 ILT_RANGE((ilt_start + ilt_cli->start),
648 (ilt_start + ilt_cli->end)));
649 } else {
650 switch (ilt_cli->client_num) {
651 case ILT_CLIENT_CDU:
652 start_reg = PXP2_REG_RQ_CDU_FIRST_ILT;
653 end_reg = PXP2_REG_RQ_CDU_LAST_ILT;
654 break;
655 case ILT_CLIENT_QM:
656 start_reg = PXP2_REG_RQ_QM_FIRST_ILT;
657 end_reg = PXP2_REG_RQ_QM_LAST_ILT;
658 break;
659 case ILT_CLIENT_SRC:
660 start_reg = PXP2_REG_RQ_SRC_FIRST_ILT;
661 end_reg = PXP2_REG_RQ_SRC_LAST_ILT;
662 break;
663 case ILT_CLIENT_TM:
664 start_reg = PXP2_REG_RQ_TM_FIRST_ILT;
665 end_reg = PXP2_REG_RQ_TM_LAST_ILT;
666 break;
667 }
668 REG_WR(bp, start_reg, (ilt_start + ilt_cli->start));
669 REG_WR(bp, end_reg, (ilt_start + ilt_cli->end));
670 }
671}
672
673void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp, struct bnx2x_ilt *ilt,
674 struct ilt_client_info *ilt_cli, u8 initop)
675{
676 int i;
677
678 if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
679 return;
680
681 for (i = ilt_cli->start; i <= ilt_cli->end; i++)
682 bnx2x_ilt_line_init_op(bp, ilt, i, initop);
683
684 /* init/clear the ILT boundries */
685 bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop);
686}
687
688void bnx2x_ilt_client_init_op(struct bnx2x *bp,
689 struct ilt_client_info *ilt_cli, u8 initop)
690{
691 struct bnx2x_ilt *ilt = BP_ILT(bp);
692
693 bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop);
694}
695
696static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp,
697 int cli_num, u8 initop)
698{
699 struct bnx2x_ilt *ilt = BP_ILT(bp);
700 struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
701
702 bnx2x_ilt_client_init_op(bp, ilt_cli, initop);
703}
704
705void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop)
706{
707 bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop);
708 bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop);
709 bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop);
710 bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop);
711}
712
713static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num,
714 u32 psz_reg, u8 initop)
715{
716 struct bnx2x_ilt *ilt = BP_ILT(bp);
717 struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
718
719 if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
720 return;
721
722 switch (initop) {
723 case INITOP_INIT:
724 /* set in the init-value array */
725 case INITOP_SET:
726 REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12));
727 break;
728 case INITOP_CLEAR:
729 break;
730 }
731}
732
733/*
734 * called during init common stage, ilt clients should be initialized
735 * prioir to calling this function
736 */
737void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop)
738{
739 bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU,
740 PXP2_REG_RQ_CDU_P_SIZE, initop);
741 bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM,
742 PXP2_REG_RQ_QM_P_SIZE, initop);
743 bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC,
744 PXP2_REG_RQ_SRC_P_SIZE, initop);
745 bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM,
746 PXP2_REG_RQ_TM_P_SIZE, initop);
747}
748
749/****************************************************************************
750* QM initializations
751****************************************************************************/
752#define QM_QUEUES_PER_FUNC 16 /* E1 has 32, but only 16 are used */
753#define QM_INIT_MIN_CID_COUNT 31
754#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT)
755
756/* called during init port stage */
757void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count,
758 u8 initop)
759{
760 int port = BP_PORT(bp);
761
762 if (QM_INIT(qm_cid_count)) {
763 switch (initop) {
764 case INITOP_INIT:
765 /* set in the init-value array */
766 case INITOP_SET:
767 REG_WR(bp, QM_REG_CONNNUM_0 + port*4,
768 qm_cid_count/16 - 1);
769 break;
770 case INITOP_CLEAR:
771 break;
772 }
773 }
774}
775
776static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count)
777{
778 int i;
779 u32 wb_data[2];
780
781 wb_data[0] = wb_data[1] = 0;
782
783 for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
784 REG_WR(bp, QM_REG_BASEADDR + i*4,
785 qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
786 bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8,
787 wb_data, 2);
788
789 if (CHIP_IS_E1H(bp)) {
790 REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4,
791 qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
792 bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
793 wb_data, 2);
794 }
795 }
796}
797
798/* called during init common stage */
799void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
800 u8 initop)
801{
802 if (!QM_INIT(qm_cid_count))
803 return;
804
805 switch (initop) {
806 case INITOP_INIT:
807 /* set in the init-value array */
808 case INITOP_SET:
809 bnx2x_qm_set_ptr_table(bp, qm_cid_count);
810 break;
811 case INITOP_CLEAR:
812 break;
813 }
814}
815
816/****************************************************************************
817* SRC initializations
818****************************************************************************/
819
820/* called during init func stage */
821void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
822 dma_addr_t t2_mapping, int src_cid_count)
823{
824 int i;
825 int port = BP_PORT(bp);
826
827 /* Initialize T2 */
828 for (i = 0; i < src_cid_count-1; i++)
829 t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent));
830
831 /* tell the searcher where the T2 table is */
832 REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count);
833
834 bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16,
835 U64_LO(t2_mapping), U64_HI(t2_mapping));
836
837 bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16,
838 U64_LO((u64)t2_mapping +
839 (src_cid_count-1) * sizeof(struct src_ent)),
840 U64_HI((u64)t2_mapping +
841 (src_cid_count-1) * sizeof(struct src_ent)));
842}
843
506#endif /* BNX2X_INIT_OPS_H */ 844#endif /* BNX2X_INIT_OPS_H */