Commit a052997e authored by Merav Sicron's avatar Merav Sicron Committed by David S. Miller

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: default avatarMerav Sicron <meravs@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d317c6a
...@@ -978,8 +978,8 @@ union cdu_context { ...@@ -978,8 +978,8 @@ union cdu_context {
}; };
/* CDU host DB constants */ /* CDU host DB constants */
#define CDU_ILT_PAGE_SZ_HW 3 #define CDU_ILT_PAGE_SZ_HW 2
#define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 64K */ #define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */
#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context))
#ifdef BCM_CNIC #ifdef BCM_CNIC
...@@ -1420,7 +1420,11 @@ struct bnx2x { ...@@ -1420,7 +1420,11 @@ struct bnx2x {
dma_addr_t fw_stats_data_mapping; dma_addr_t fw_stats_data_mapping;
int fw_stats_data_sz; int fw_stats_data_sz;
struct hw_context context; /* For max 196 cids (64*3 + non-eth), 32KB ILT page size and 1KB
* context size we need 8 ILT entries.
*/
#define ILT_MAX_L2_LINES 8
struct hw_context context[ILT_MAX_L2_LINES];
struct bnx2x_ilt *ilt; struct bnx2x_ilt *ilt;
#define BP_ILT(bp) ((bp)->ilt) #define BP_ILT(bp) ((bp)->ilt)
......
...@@ -7068,12 +7068,10 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) ...@@ -7068,12 +7068,10 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start;
for (i = 0; i < L2_ILT_LINES(bp); i++) { for (i = 0; i < L2_ILT_LINES(bp); i++) {
ilt->lines[cdu_ilt_start + i].page = ilt->lines[cdu_ilt_start + i].page = bp->context[i].vcxt;
bp->context.vcxt + (ILT_PAGE_CIDS * i);
ilt->lines[cdu_ilt_start + i].page_mapping = ilt->lines[cdu_ilt_start + i].page_mapping =
bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); bp->context[i].cxt_mapping;
/* cdu ilt pages are allocated manually so there's no need to ilt->lines[cdu_ilt_start + i].size = bp->context[i].size;
set the size */
} }
bnx2x_ilt_init_op(bp, INITOP_SET); bnx2x_ilt_init_op(bp, INITOP_SET);
...@@ -7340,6 +7338,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) ...@@ -7340,6 +7338,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
void bnx2x_free_mem(struct bnx2x *bp) void bnx2x_free_mem(struct bnx2x *bp)
{ {
int i;
/* fastpath */ /* fastpath */
bnx2x_free_fp_mem(bp); bnx2x_free_fp_mem(bp);
/* end of fastpath */ /* end of fastpath */
...@@ -7353,9 +7353,9 @@ void bnx2x_free_mem(struct bnx2x *bp) ...@@ -7353,9 +7353,9 @@ void bnx2x_free_mem(struct bnx2x *bp)
BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
sizeof(struct bnx2x_slowpath)); sizeof(struct bnx2x_slowpath));
BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, for (i = 0; i < L2_ILT_LINES(bp); i++)
bp->context.size); BNX2X_PCI_FREE(bp->context[i].vcxt, bp->context[i].cxt_mapping,
bp->context[i].size);
bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE);
BNX2X_FREE(bp->ilt->lines); BNX2X_FREE(bp->ilt->lines);
...@@ -7441,6 +7441,8 @@ static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp) ...@@ -7441,6 +7441,8 @@ static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
int bnx2x_alloc_mem(struct bnx2x *bp) int bnx2x_alloc_mem(struct bnx2x *bp)
{ {
int i, allocated, context_size;
#ifdef BCM_CNIC #ifdef BCM_CNIC
if (!CHIP_IS_E1x(bp)) if (!CHIP_IS_E1x(bp))
/* size = the status block + ramrod buffers */ /* size = the status block + ramrod buffers */
...@@ -7470,11 +7472,29 @@ int bnx2x_alloc_mem(struct bnx2x *bp) ...@@ -7470,11 +7472,29 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
if (bnx2x_alloc_fw_stats_mem(bp)) if (bnx2x_alloc_fw_stats_mem(bp))
goto alloc_mem_err; goto alloc_mem_err;
bp->context.size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); /* Allocate memory for CDU context:
* This memory is allocated separately and not in the generic ILT
BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, * functions because CDU differs in few aspects:
bp->context.size); * 1. There are multiple entities allocating memory for context -
* 'regular' driver, CNIC and SRIOV driver. Each separately controls
* its own ILT lines.
* 2. Since CDU page-size is not a single 4KB page (which is the case
* for the other ILT clients), to be efficient we want to support
* allocation of sub-page-size in the last entry.
* 3. Context pointers are used by the driver to pass to FW / update
* the context (for the other ILT clients the pointers are used just to
* free the memory during unload).
*/
context_size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp);
for (i = 0, allocated = 0; allocated < context_size; i++) {
bp->context[i].size = min(CDU_ILT_PAGE_SZ,
(context_size - allocated));
BNX2X_PCI_ALLOC(bp->context[i].vcxt,
&bp->context[i].cxt_mapping,
bp->context[i].size);
allocated += bp->context[i].size;
}
BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES);
if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC))
...@@ -7748,6 +7768,8 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, ...@@ -7748,6 +7768,8 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp,
{ {
u8 cos; u8 cos;
int cxt_index, cxt_offset;
/* FCoE Queue uses Default SB, thus has no HC capabilities */ /* FCoE Queue uses Default SB, thus has no HC capabilities */
if (!IS_FCOE_FP(fp)) { if (!IS_FCOE_FP(fp)) {
__set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); __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,9 +7806,13 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp,
fp->index, init_params->max_cos); fp->index, init_params->max_cos);
/* set the context pointers queue object */ /* set the context pointers queue object */
for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) {
cxt_index = fp->txdata[cos].cid / ILT_PAGE_CIDS;
cxt_offset = fp->txdata[cos].cid - (cxt_index *
ILT_PAGE_CIDS);
init_params->cxts[cos] = init_params->cxts[cos] =
&bp->context.vcxt[fp->txdata[cos].cid].eth; &bp->context[cxt_index].vcxt[cxt_offset].eth;
}
} }
int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp, 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,6 +12228,7 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp)
static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
{ {
struct eth_spe *spe; struct eth_spe *spe;
int cxt_index, cxt_offset;
#ifdef BNX2X_STOP_ON_ERROR #ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic)) if (unlikely(bp->panic))
...@@ -12224,10 +12251,16 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) ...@@ -12224,10 +12251,16 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
* ramrod * ramrod
*/ */
if (type == ETH_CONNECTION_TYPE) { if (type == ETH_CONNECTION_TYPE) {
if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) {
bnx2x_set_ctx_validation(bp, &bp->context. cxt_index = BNX2X_ISCSI_ETH_CID /
vcxt[BNX2X_ISCSI_ETH_CID].eth, ILT_PAGE_CIDS;
cxt_offset = BNX2X_ISCSI_ETH_CID -
(cxt_index * ILT_PAGE_CIDS);
bnx2x_set_ctx_validation(bp,
&bp->context[cxt_index].
vcxt[cxt_offset].eth,
BNX2X_ISCSI_ETH_CID); BNX2X_ISCSI_ETH_CID);
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment