aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2010-10-05 23:33:18 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-06 17:10:40 -0400
commitc2bff63fad94eeecf59e4ba8e4cb51688ccae1ec (patch)
tree677c59a6a9c3a37a569c14cf55c305d63c20b8c4 /drivers/net
parentd6214d7aaa9a82b206dac9e3b0665c49c522a271 (diff)
bnx2x, cnic: Fix SPQ return credit
Return proper L2 and L5 SPQ (slow path queue) credits. Previously, all SPQ events were counted as L5 types. Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c13
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c86
-rw-r--r--drivers/net/cnic.c18
-rw-r--r--drivers/net/cnic_if.h21
4 files changed, 91 insertions, 47 deletions
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 2998969beacc..68181cdd2096 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1369,19 +1369,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
1369 1369
1370 bnx2x_set_eth_mac(bp, 1); 1370 bnx2x_set_eth_mac(bp, 1);
1371 1371
1372#ifdef BCM_CNIC
1373 /* Set iSCSI L2 MAC */
1374 mutex_lock(&bp->cnic_mutex);
1375 if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) {
1376 bnx2x_set_iscsi_eth_mac_addr(bp, 1);
1377 bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
1378 bnx2x_init_sb(bp, bp->cnic_sb_mapping,
1379 BNX2X_VF_ID_INVALID, false,
1380 CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp));
1381 }
1382 mutex_unlock(&bp->cnic_mutex);
1383#endif
1384
1385 if (bp->port.pmf) 1372 if (bp->port.pmf)
1386 bnx2x_initial_phy_init(bp, load_mode); 1373 bnx2x_initial_phy_init(bp, load_mode);
1387 1374
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 2572eb40c0ed..a686a4c15710 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -6462,6 +6462,12 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
6462 return rc; 6462 return rc;
6463} 6463}
6464 6464
6465/* must be called prioir to any HW initializations */
6466static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp)
6467{
6468 return L2_ILT_LINES(bp);
6469}
6470
6465void bnx2x_ilt_set_info(struct bnx2x *bp) 6471void bnx2x_ilt_set_info(struct bnx2x *bp)
6466{ 6472{
6467 struct ilt_client_info *ilt_client; 6473 struct ilt_client_info *ilt_client;
@@ -9347,19 +9353,53 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
9347#endif 9353#endif
9348 9354
9349 spin_lock_bh(&bp->spq_lock); 9355 spin_lock_bh(&bp->spq_lock);
9356 BUG_ON(bp->cnic_spq_pending < count);
9350 bp->cnic_spq_pending -= count; 9357 bp->cnic_spq_pending -= count;
9351 9358
9352 for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending;
9353 bp->cnic_spq_pending++) {
9354 9359
9355 if (!bp->cnic_kwq_pending) 9360 for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) {
9361 u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type)
9362 & SPE_HDR_CONN_TYPE) >>
9363 SPE_HDR_CONN_TYPE_SHIFT;
9364
9365 /* Set validation for iSCSI L2 client before sending SETUP
9366 * ramrod
9367 */
9368 if (type == ETH_CONNECTION_TYPE) {
9369 u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons->
9370 hdr.conn_and_cmd_data) >>
9371 SPE_HDR_CMD_ID_SHIFT) & 0xff;
9372
9373 if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP)
9374 bnx2x_set_ctx_validation(&bp->context.
9375 vcxt[BNX2X_ISCSI_ETH_CID].eth,
9376 HW_CID(bp, BNX2X_ISCSI_ETH_CID));
9377 }
9378
9379 /* There may be not more than 8 L2 and COMMON SPEs and not more
9380 * than 8 L5 SPEs in the air.
9381 */
9382 if ((type == NONE_CONNECTION_TYPE) ||
9383 (type == ETH_CONNECTION_TYPE)) {
9384 if (!atomic_read(&bp->spq_left))
9385 break;
9386 else
9387 atomic_dec(&bp->spq_left);
9388 } else if (type == ISCSI_CONNECTION_TYPE) {
9389 if (bp->cnic_spq_pending >=
9390 bp->cnic_eth_dev.max_kwqe_pending)
9391 break;
9392 else
9393 bp->cnic_spq_pending++;
9394 } else {
9395 BNX2X_ERR("Unknown SPE type: %d\n", type);
9396 bnx2x_panic();
9356 break; 9397 break;
9398 }
9357 9399
9358 spe = bnx2x_sp_get_next(bp); 9400 spe = bnx2x_sp_get_next(bp);
9359 *spe = *bp->cnic_kwq_cons; 9401 *spe = *bp->cnic_kwq_cons;
9360 9402
9361 bp->cnic_kwq_pending--;
9362
9363 DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n", 9403 DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n",
9364 bp->cnic_spq_pending, bp->cnic_kwq_pending, count); 9404 bp->cnic_spq_pending, bp->cnic_kwq_pending, count);
9365 9405
@@ -9464,7 +9504,7 @@ static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid)
9464 ctl.data.comp.cid = cid; 9504 ctl.data.comp.cid = cid;
9465 9505
9466 bnx2x_cnic_ctl_send_bh(bp, &ctl); 9506 bnx2x_cnic_ctl_send_bh(bp, &ctl);
9467 bnx2x_cnic_sp_post(bp, 1); 9507 bnx2x_cnic_sp_post(bp, 0);
9468} 9508}
9469 9509
9470static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) 9510static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
@@ -9481,8 +9521,8 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
9481 break; 9521 break;
9482 } 9522 }
9483 9523
9484 case DRV_CTL_COMPLETION_CMD: { 9524 case DRV_CTL_RET_L5_SPQ_CREDIT_CMD: {
9485 int count = ctl->data.comp.comp_count; 9525 int count = ctl->data.credit.credit_count;
9486 9526
9487 bnx2x_cnic_sp_post(bp, count); 9527 bnx2x_cnic_sp_post(bp, count);
9488 break; 9528 break;
@@ -9528,6 +9568,14 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
9528 bnx2x_set_iscsi_eth_mac_addr(bp, 0); 9568 bnx2x_set_iscsi_eth_mac_addr(bp, 0);
9529 break; 9569 break;
9530 } 9570 }
9571 case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: {
9572 int count = ctl->data.credit.credit_count;
9573
9574 smp_mb__before_atomic_inc();
9575 atomic_add(count, &bp->spq_left);
9576 smp_mb__after_atomic_inc();
9577 break;
9578 }
9531 9579
9532 default: 9580 default:
9533 BNX2X_ERR("unknown command %x\n", ctl->cmd); 9581 BNX2X_ERR("unknown command %x\n", ctl->cmd);
@@ -9592,13 +9640,8 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops,
9592 cp->drv_state = CNIC_DRV_STATE_REGD; 9640 cp->drv_state = CNIC_DRV_STATE_REGD;
9593 cp->iro_arr = bp->iro_arr; 9641 cp->iro_arr = bp->iro_arr;
9594 9642
9595 bnx2x_init_sb(bp, bp->cnic_sb_mapping,
9596 BNX2X_VF_ID_INVALID, false,
9597 CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp));
9598
9599 bnx2x_setup_cnic_irq_info(bp); 9643 bnx2x_setup_cnic_irq_info(bp);
9600 bnx2x_set_iscsi_eth_mac_addr(bp, 1); 9644
9601 bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
9602 rcu_assign_pointer(bp->cnic_ops, ops); 9645 rcu_assign_pointer(bp->cnic_ops, ops);
9603 9646
9604 return 0; 9647 return 0;
@@ -9636,14 +9679,23 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
9636 cp->io_base2 = bp->doorbells; 9679 cp->io_base2 = bp->doorbells;
9637 cp->max_kwqe_pending = 8; 9680 cp->max_kwqe_pending = 8;
9638 cp->ctx_blk_size = CDU_ILT_PAGE_SZ; 9681 cp->ctx_blk_size = CDU_ILT_PAGE_SZ;
9639 cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; 9682 cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) +
9683 bnx2x_cid_ilt_lines(bp);
9640 cp->ctx_tbl_len = CNIC_ILT_LINES; 9684 cp->ctx_tbl_len = CNIC_ILT_LINES;
9641 cp->starting_cid = BCM_CNIC_CID_START; 9685 cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS;
9642 cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue; 9686 cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
9643 cp->drv_ctl = bnx2x_drv_ctl; 9687 cp->drv_ctl = bnx2x_drv_ctl;
9644 cp->drv_register_cnic = bnx2x_register_cnic; 9688 cp->drv_register_cnic = bnx2x_register_cnic;
9645 cp->drv_unregister_cnic = bnx2x_unregister_cnic; 9689 cp->drv_unregister_cnic = bnx2x_unregister_cnic;
9646 9690 cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID;
9691 cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID;
9692
9693 DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, "
9694 "starting cid %d\n",
9695 cp->ctx_blk_size,
9696 cp->ctx_tbl_offset,
9697 cp->ctx_tbl_len,
9698 cp->starting_cid);
9647 return cp; 9699 return cp;
9648} 9700}
9649EXPORT_SYMBOL(bnx2x_cnic_probe); 9701EXPORT_SYMBOL(bnx2x_cnic_probe);
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 80259815af06..27449bf775e3 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -242,14 +242,14 @@ static int cnic_in_use(struct cnic_sock *csk)
242 return test_bit(SK_F_INUSE, &csk->flags); 242 return test_bit(SK_F_INUSE, &csk->flags);
243} 243}
244 244
245static void cnic_kwq_completion(struct cnic_dev *dev, u32 count) 245static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count)
246{ 246{
247 struct cnic_local *cp = dev->cnic_priv; 247 struct cnic_local *cp = dev->cnic_priv;
248 struct cnic_eth_dev *ethdev = cp->ethdev; 248 struct cnic_eth_dev *ethdev = cp->ethdev;
249 struct drv_ctl_info info; 249 struct drv_ctl_info info;
250 250
251 info.cmd = DRV_CTL_COMPLETION_CMD; 251 info.cmd = cmd;
252 info.data.comp.comp_count = count; 252 info.data.credit.credit_count = count;
253 ethdev->drv_ctl(dev->netdev, &info); 253 ethdev->drv_ctl(dev->netdev, &info);
254} 254}
255 255
@@ -2069,7 +2069,7 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
2069static void service_kcqes(struct cnic_dev *dev, int num_cqes) 2069static void service_kcqes(struct cnic_dev *dev, int num_cqes)
2070{ 2070{
2071 struct cnic_local *cp = dev->cnic_priv; 2071 struct cnic_local *cp = dev->cnic_priv;
2072 int i, j; 2072 int i, j, comp = 0;
2073 2073
2074 i = 0; 2074 i = 0;
2075 j = 1; 2075 j = 1;
@@ -2080,7 +2080,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
2080 u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK; 2080 u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK;
2081 2081
2082 if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION)) 2082 if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION))
2083 cnic_kwq_completion(dev, 1); 2083 comp++;
2084 2084
2085 while (j < num_cqes) { 2085 while (j < num_cqes) {
2086 u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag; 2086 u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag;
@@ -2089,7 +2089,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
2089 break; 2089 break;
2090 2090
2091 if (unlikely(next_op & KCQE_RAMROD_COMPLETION)) 2091 if (unlikely(next_op & KCQE_RAMROD_COMPLETION))
2092 cnic_kwq_completion(dev, 1); 2092 comp++;
2093 j++; 2093 j++;
2094 } 2094 }
2095 2095
@@ -2119,6 +2119,8 @@ end:
2119 i += j; 2119 i += j;
2120 j = 1; 2120 j = 1;
2121 } 2121 }
2122 if (unlikely(comp))
2123 cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp);
2122} 2124}
2123 2125
2124static u16 cnic_bnx2_next_idx(u16 idx) 2126static u16 cnic_bnx2_next_idx(u16 idx)
@@ -4246,7 +4248,7 @@ static void cnic_init_rings(struct cnic_dev *dev)
4246 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) 4248 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
4247 netdev_err(dev->netdev, 4249 netdev_err(dev->netdev,
4248 "iSCSI CLIENT_SETUP did not complete\n"); 4250 "iSCSI CLIENT_SETUP did not complete\n");
4249 cnic_kwq_completion(dev, 1); 4251 cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1);
4250 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); 4252 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1);
4251 } 4253 }
4252} 4254}
@@ -4283,7 +4285,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
4283 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) 4285 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
4284 netdev_err(dev->netdev, 4286 netdev_err(dev->netdev,
4285 "iSCSI CLIENT_HALT did not complete\n"); 4287 "iSCSI CLIENT_HALT did not complete\n");
4286 cnic_kwq_completion(dev, 1); 4288 cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1);
4287 4289
4288 memset(&l5_data, 0, sizeof(l5_data)); 4290 memset(&l5_data, 0, sizeof(l5_data));
4289 type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) 4291 type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index 4018de12f819..98ebac52013e 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
12#ifndef CNIC_IF_H 12#ifndef CNIC_IF_H
13#define CNIC_IF_H 13#define CNIC_IF_H
14 14
15#define CNIC_MODULE_VERSION "2.1.3" 15#define CNIC_MODULE_VERSION "2.2.5"
16#define CNIC_MODULE_RELDATE "June 24, 2010" 16#define CNIC_MODULE_RELDATE "September 29, 2010"
17 17
18#define CNIC_ULP_RDMA 0 18#define CNIC_ULP_RDMA 0
19#define CNIC_ULP_ISCSI 1 19#define CNIC_ULP_ISCSI 1
@@ -80,18 +80,15 @@ struct kcqe {
80#define DRV_CTL_IO_RD_CMD 0x102 80#define DRV_CTL_IO_RD_CMD 0x102
81#define DRV_CTL_CTX_WR_CMD 0x103 81#define DRV_CTL_CTX_WR_CMD 0x103
82#define DRV_CTL_CTXTBL_WR_CMD 0x104 82#define DRV_CTL_CTXTBL_WR_CMD 0x104
83#define DRV_CTL_COMPLETION_CMD 0x105 83#define DRV_CTL_RET_L5_SPQ_CREDIT_CMD 0x105
84#define DRV_CTL_START_L2_CMD 0x106 84#define DRV_CTL_START_L2_CMD 0x106
85#define DRV_CTL_STOP_L2_CMD 0x107 85#define DRV_CTL_STOP_L2_CMD 0x107
86#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c
86 87
87struct cnic_ctl_completion { 88struct cnic_ctl_completion {
88 u32 cid; 89 u32 cid;
89}; 90};
90 91
91struct drv_ctl_completion {
92 u32 comp_count;
93};
94
95struct cnic_ctl_info { 92struct cnic_ctl_info {
96 int cmd; 93 int cmd;
97 union { 94 union {
@@ -100,6 +97,10 @@ struct cnic_ctl_info {
100 } data; 97 } data;
101}; 98};
102 99
100struct drv_ctl_spq_credit {
101 u32 credit_count;
102};
103
103struct drv_ctl_io { 104struct drv_ctl_io {
104 u32 cid_addr; 105 u32 cid_addr;
105 u32 offset; 106 u32 offset;
@@ -115,7 +116,7 @@ struct drv_ctl_l2_ring {
115struct drv_ctl_info { 116struct drv_ctl_info {
116 int cmd; 117 int cmd;
117 union { 118 union {
118 struct drv_ctl_completion comp; 119 struct drv_ctl_spq_credit credit;
119 struct drv_ctl_io io; 120 struct drv_ctl_io io;
120 struct drv_ctl_l2_ring ring; 121 struct drv_ctl_l2_ring ring;
121 char bytes[MAX_DRV_CTL_DATA]; 122 char bytes[MAX_DRV_CTL_DATA];
@@ -162,7 +163,9 @@ struct cnic_eth_dev {
162 u32 max_iscsi_conn; 163 u32 max_iscsi_conn;
163 u32 max_fcoe_conn; 164 u32 max_fcoe_conn;
164 u32 max_rdma_conn; 165 u32 max_rdma_conn;
165 u32 reserved0[2]; 166 u32 fcoe_init_cid;
167 u16 iscsi_l2_client_id;
168 u16 iscsi_l2_cid;
166 169
167 int num_irq; 170 int num_irq;
168 struct cnic_irq irq_arr[MAX_CNIC_VEC]; 171 struct cnic_irq irq_arr[MAX_CNIC_VEC];