diff options
author | Merav Sicron <meravs@broadcom.com> | 2012-06-19 03:48:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-19 17:34:34 -0400 |
commit | a052997ea32164b2466daff8db5f783131184dae (patch) | |
tree | e6bc18edeb5d7e74d2552f738dbdadbbc57158a8 | |
parent | 5d317c6a9597267643b6ce6593c4d1785eb1b8df (diff) |
bnx2x: Allow more than 64 L2 CIDs
With increased number of RSS queues, each multiplied by the number of traffic-
classes, we may have up to 64*3=192 CIDs. The current driver scheme with regard
to context allocation supports only 64 CIDs. The new scheme enables scatter-
gatehr list of pages for the context.
Signed-off-by: Merav Sicron <meravs@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 67 |
2 files changed, 57 insertions, 20 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8ee4bfc1b0bb..c0c539fd2490 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -978,8 +978,8 @@ union cdu_context { | |||
978 | }; | 978 | }; |
979 | 979 | ||
980 | /* CDU host DB constants */ | 980 | /* CDU host DB constants */ |
981 | #define CDU_ILT_PAGE_SZ_HW 3 | 981 | #define CDU_ILT_PAGE_SZ_HW 2 |
982 | #define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 64K */ | 982 | #define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */ |
983 | #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) | 983 | #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) |
984 | 984 | ||
985 | #ifdef BCM_CNIC | 985 | #ifdef BCM_CNIC |
@@ -1420,7 +1420,11 @@ struct bnx2x { | |||
1420 | dma_addr_t fw_stats_data_mapping; | 1420 | dma_addr_t fw_stats_data_mapping; |
1421 | int fw_stats_data_sz; | 1421 | int fw_stats_data_sz; |
1422 | 1422 | ||
1423 | struct hw_context context; | 1423 | /* For max 196 cids (64*3 + non-eth), 32KB ILT page size and 1KB |
1424 | * context size we need 8 ILT entries. | ||
1425 | */ | ||
1426 | #define ILT_MAX_L2_LINES 8 | ||
1427 | struct hw_context context[ILT_MAX_L2_LINES]; | ||
1424 | 1428 | ||
1425 | struct bnx2x_ilt *ilt; | 1429 | struct bnx2x_ilt *ilt; |
1426 | #define BP_ILT(bp) ((bp)->ilt) | 1430 | #define BP_ILT(bp) ((bp)->ilt) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index cebc557f0b37..9b216e64c4fc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -7068,12 +7068,10 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) | |||
7068 | cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; | 7068 | cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; |
7069 | 7069 | ||
7070 | for (i = 0; i < L2_ILT_LINES(bp); i++) { | 7070 | for (i = 0; i < L2_ILT_LINES(bp); i++) { |
7071 | ilt->lines[cdu_ilt_start + i].page = | 7071 | ilt->lines[cdu_ilt_start + i].page = bp->context[i].vcxt; |
7072 | bp->context.vcxt + (ILT_PAGE_CIDS * i); | ||
7073 | ilt->lines[cdu_ilt_start + i].page_mapping = | 7072 | ilt->lines[cdu_ilt_start + i].page_mapping = |
7074 | bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); | 7073 | bp->context[i].cxt_mapping; |
7075 | /* cdu ilt pages are allocated manually so there's no need to | 7074 | ilt->lines[cdu_ilt_start + i].size = bp->context[i].size; |
7076 | set the size */ | ||
7077 | } | 7075 | } |
7078 | bnx2x_ilt_init_op(bp, INITOP_SET); | 7076 | bnx2x_ilt_init_op(bp, INITOP_SET); |
7079 | 7077 | ||
@@ -7340,6 +7338,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) | |||
7340 | 7338 | ||
7341 | void bnx2x_free_mem(struct bnx2x *bp) | 7339 | void bnx2x_free_mem(struct bnx2x *bp) |
7342 | { | 7340 | { |
7341 | int i; | ||
7342 | |||
7343 | /* fastpath */ | 7343 | /* fastpath */ |
7344 | bnx2x_free_fp_mem(bp); | 7344 | bnx2x_free_fp_mem(bp); |
7345 | /* end of fastpath */ | 7345 | /* end of fastpath */ |
@@ -7353,9 +7353,9 @@ void bnx2x_free_mem(struct bnx2x *bp) | |||
7353 | BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, | 7353 | BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, |
7354 | sizeof(struct bnx2x_slowpath)); | 7354 | sizeof(struct bnx2x_slowpath)); |
7355 | 7355 | ||
7356 | BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, | 7356 | for (i = 0; i < L2_ILT_LINES(bp); i++) |
7357 | bp->context.size); | 7357 | BNX2X_PCI_FREE(bp->context[i].vcxt, bp->context[i].cxt_mapping, |
7358 | 7358 | bp->context[i].size); | |
7359 | bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); | 7359 | bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); |
7360 | 7360 | ||
7361 | BNX2X_FREE(bp->ilt->lines); | 7361 | BNX2X_FREE(bp->ilt->lines); |
@@ -7441,6 +7441,8 @@ alloc_mem_err: | |||
7441 | 7441 | ||
7442 | int bnx2x_alloc_mem(struct bnx2x *bp) | 7442 | int bnx2x_alloc_mem(struct bnx2x *bp) |
7443 | { | 7443 | { |
7444 | int i, allocated, context_size; | ||
7445 | |||
7444 | #ifdef BCM_CNIC | 7446 | #ifdef BCM_CNIC |
7445 | if (!CHIP_IS_E1x(bp)) | 7447 | if (!CHIP_IS_E1x(bp)) |
7446 | /* size = the status block + ramrod buffers */ | 7448 | /* size = the status block + ramrod buffers */ |
@@ -7470,11 +7472,29 @@ int bnx2x_alloc_mem(struct bnx2x *bp) | |||
7470 | if (bnx2x_alloc_fw_stats_mem(bp)) | 7472 | if (bnx2x_alloc_fw_stats_mem(bp)) |
7471 | goto alloc_mem_err; | 7473 | goto alloc_mem_err; |
7472 | 7474 | ||
7473 | bp->context.size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); | 7475 | /* Allocate memory for CDU context: |
7474 | 7476 | * This memory is allocated separately and not in the generic ILT | |
7475 | BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, | 7477 | * functions because CDU differs in few aspects: |
7476 | bp->context.size); | 7478 | * 1. There are multiple entities allocating memory for context - |
7479 | * 'regular' driver, CNIC and SRIOV driver. Each separately controls | ||
7480 | * its own ILT lines. | ||
7481 | * 2. Since CDU page-size is not a single 4KB page (which is the case | ||
7482 | * for the other ILT clients), to be efficient we want to support | ||
7483 | * allocation of sub-page-size in the last entry. | ||
7484 | * 3. Context pointers are used by the driver to pass to FW / update | ||
7485 | * the context (for the other ILT clients the pointers are used just to | ||
7486 | * free the memory during unload). | ||
7487 | */ | ||
7488 | context_size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); | ||
7477 | 7489 | ||
7490 | for (i = 0, allocated = 0; allocated < context_size; i++) { | ||
7491 | bp->context[i].size = min(CDU_ILT_PAGE_SZ, | ||
7492 | (context_size - allocated)); | ||
7493 | BNX2X_PCI_ALLOC(bp->context[i].vcxt, | ||
7494 | &bp->context[i].cxt_mapping, | ||
7495 | bp->context[i].size); | ||
7496 | allocated += bp->context[i].size; | ||
7497 | } | ||
7478 | BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); | 7498 | BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); |
7479 | 7499 | ||
7480 | if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) | 7500 | if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) |
@@ -7748,6 +7768,8 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, | |||
7748 | { | 7768 | { |
7749 | 7769 | ||
7750 | u8 cos; | 7770 | u8 cos; |
7771 | int cxt_index, cxt_offset; | ||
7772 | |||
7751 | /* FCoE Queue uses Default SB, thus has no HC capabilities */ | 7773 | /* FCoE Queue uses Default SB, thus has no HC capabilities */ |
7752 | if (!IS_FCOE_FP(fp)) { | 7774 | if (!IS_FCOE_FP(fp)) { |
7753 | __set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); | 7775 | __set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); |
@@ -7784,9 +7806,13 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, | |||
7784 | fp->index, init_params->max_cos); | 7806 | fp->index, init_params->max_cos); |
7785 | 7807 | ||
7786 | /* set the context pointers queue object */ | 7808 | /* set the context pointers queue object */ |
7787 | for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) | 7809 | for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) { |
7810 | cxt_index = fp->txdata[cos].cid / ILT_PAGE_CIDS; | ||
7811 | cxt_offset = fp->txdata[cos].cid - (cxt_index * | ||
7812 | ILT_PAGE_CIDS); | ||
7788 | init_params->cxts[cos] = | 7813 | init_params->cxts[cos] = |
7789 | &bp->context.vcxt[fp->txdata[cos].cid].eth; | 7814 | &bp->context[cxt_index].vcxt[cxt_offset].eth; |
7815 | } | ||
7790 | } | 7816 | } |
7791 | 7817 | ||
7792 | int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp, | 7818 | int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp, |
@@ -12202,6 +12228,7 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp) | |||
12202 | static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) | 12228 | static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) |
12203 | { | 12229 | { |
12204 | struct eth_spe *spe; | 12230 | struct eth_spe *spe; |
12231 | int cxt_index, cxt_offset; | ||
12205 | 12232 | ||
12206 | #ifdef BNX2X_STOP_ON_ERROR | 12233 | #ifdef BNX2X_STOP_ON_ERROR |
12207 | if (unlikely(bp->panic)) | 12234 | if (unlikely(bp->panic)) |
@@ -12224,10 +12251,16 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) | |||
12224 | * ramrod | 12251 | * ramrod |
12225 | */ | 12252 | */ |
12226 | if (type == ETH_CONNECTION_TYPE) { | 12253 | if (type == ETH_CONNECTION_TYPE) { |
12227 | if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) | 12254 | if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) { |
12228 | bnx2x_set_ctx_validation(bp, &bp->context. | 12255 | cxt_index = BNX2X_ISCSI_ETH_CID / |
12229 | vcxt[BNX2X_ISCSI_ETH_CID].eth, | 12256 | ILT_PAGE_CIDS; |
12257 | cxt_offset = BNX2X_ISCSI_ETH_CID - | ||
12258 | (cxt_index * ILT_PAGE_CIDS); | ||
12259 | bnx2x_set_ctx_validation(bp, | ||
12260 | &bp->context[cxt_index]. | ||
12261 | vcxt[cxt_offset].eth, | ||
12230 | BNX2X_ISCSI_ETH_CID); | 12262 | BNX2X_ISCSI_ETH_CID); |
12263 | } | ||
12231 | } | 12264 | } |
12232 | 12265 | ||
12233 | /* | 12266 | /* |