aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c80
1 files changed, 73 insertions, 7 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 4b451a7c03e..be90d3598bc 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -1143,12 +1143,12 @@ static int cnic_submit_bnx2_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
1143 1143
1144 spin_lock_bh(&cp->cnic_ulp_lock); 1144 spin_lock_bh(&cp->cnic_ulp_lock);
1145 if (num_wqes > cnic_kwq_avail(cp) && 1145 if (num_wqes > cnic_kwq_avail(cp) &&
1146 !(cp->cnic_local_flags & CNIC_LCL_FL_KWQ_INIT)) { 1146 !test_bit(CNIC_LCL_FL_KWQ_INIT, &cp->cnic_local_flags)) {
1147 spin_unlock_bh(&cp->cnic_ulp_lock); 1147 spin_unlock_bh(&cp->cnic_ulp_lock);
1148 return -EAGAIN; 1148 return -EAGAIN;
1149 } 1149 }
1150 1150
1151 cp->cnic_local_flags &= ~CNIC_LCL_FL_KWQ_INIT; 1151 clear_bit(CNIC_LCL_FL_KWQ_INIT, &cp->cnic_local_flags);
1152 1152
1153 prod = cp->kwq_prod_idx; 1153 prod = cp->kwq_prod_idx;
1154 sw_prod = prod & MAX_KWQ_IDX; 1154 sw_prod = prod & MAX_KWQ_IDX;
@@ -2092,7 +2092,6 @@ end:
2092 i += j; 2092 i += j;
2093 j = 1; 2093 j = 1;
2094 } 2094 }
2095 return;
2096} 2095}
2097 2096
2098static u16 cnic_bnx2_next_idx(u16 idx) 2097static u16 cnic_bnx2_next_idx(u16 idx)
@@ -2146,17 +2145,56 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
2146 return last_cnt; 2145 return last_cnt;
2147} 2146}
2148 2147
2148static int cnic_l2_completion(struct cnic_local *cp)
2149{
2150 u16 hw_cons, sw_cons;
2151 union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *)
2152 (cp->l2_ring + (2 * BCM_PAGE_SIZE));
2153 u32 cmd;
2154 int comp = 0;
2155
2156 if (!test_bit(CNIC_F_BNX2X_CLASS, &cp->dev->flags))
2157 return 0;
2158
2159 hw_cons = *cp->rx_cons_ptr;
2160 if ((hw_cons & BNX2X_MAX_RCQ_DESC_CNT) == BNX2X_MAX_RCQ_DESC_CNT)
2161 hw_cons++;
2162
2163 sw_cons = cp->rx_cons;
2164 while (sw_cons != hw_cons) {
2165 u8 cqe_fp_flags;
2166
2167 cqe = &cqe_ring[sw_cons & BNX2X_MAX_RCQ_DESC_CNT];
2168 cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
2169 if (cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE) {
2170 cmd = le32_to_cpu(cqe->ramrod_cqe.conn_and_cmd_data);
2171 cmd >>= COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT;
2172 if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP ||
2173 cmd == RAMROD_CMD_ID_ETH_HALT)
2174 comp++;
2175 }
2176 sw_cons = BNX2X_NEXT_RCQE(sw_cons);
2177 }
2178 return comp;
2179}
2180
2149static void cnic_chk_pkt_rings(struct cnic_local *cp) 2181static void cnic_chk_pkt_rings(struct cnic_local *cp)
2150{ 2182{
2151 u16 rx_cons = *cp->rx_cons_ptr; 2183 u16 rx_cons = *cp->rx_cons_ptr;
2152 u16 tx_cons = *cp->tx_cons_ptr; 2184 u16 tx_cons = *cp->tx_cons_ptr;
2185 int comp = 0;
2153 2186
2154 if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) { 2187 if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) {
2188 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
2189 comp = cnic_l2_completion(cp);
2190
2155 cp->tx_cons = tx_cons; 2191 cp->tx_cons = tx_cons;
2156 cp->rx_cons = rx_cons; 2192 cp->rx_cons = rx_cons;
2157 2193
2158 uio_event_notify(cp->cnic_uinfo); 2194 uio_event_notify(cp->cnic_uinfo);
2159 } 2195 }
2196 if (comp)
2197 clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
2160} 2198}
2161 2199
2162static int cnic_service_bnx2(void *data, void *status_blk) 2200static int cnic_service_bnx2(void *data, void *status_blk)
@@ -2325,7 +2363,6 @@ done:
2325 status_idx, IGU_INT_ENABLE, 1); 2363 status_idx, IGU_INT_ENABLE, 1);
2326 2364
2327 cp->kcq_prod_idx = sw_prod; 2365 cp->kcq_prod_idx = sw_prod;
2328 return;
2329} 2366}
2330 2367
2331static int cnic_service_bnx2x(void *data, void *status_blk) 2368static int cnic_service_bnx2x(void *data, void *status_blk)
@@ -3692,7 +3729,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
3692 cp->max_kwq_idx = MAX_KWQ_IDX; 3729 cp->max_kwq_idx = MAX_KWQ_IDX;
3693 cp->kwq_prod_idx = 0; 3730 cp->kwq_prod_idx = 0;
3694 cp->kwq_con_idx = 0; 3731 cp->kwq_con_idx = 0;
3695 cp->cnic_local_flags |= CNIC_LCL_FL_KWQ_INIT; 3732 set_bit(CNIC_LCL_FL_KWQ_INIT, &cp->cnic_local_flags);
3696 3733
3697 if (CHIP_NUM(cp) == CHIP_NUM_5706 || CHIP_NUM(cp) == CHIP_NUM_5708) 3734 if (CHIP_NUM(cp) == CHIP_NUM_5706 || CHIP_NUM(cp) == CHIP_NUM_5708)
3698 cp->kwq_con_idx_ptr = &sblk->status_rx_quick_consumer_index15; 3735 cp->kwq_con_idx_ptr = &sblk->status_rx_quick_consumer_index15;
@@ -4170,6 +4207,8 @@ static void cnic_init_rings(struct cnic_dev *dev)
4170 for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) 4207 for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++)
4171 CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]); 4208 CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]);
4172 4209
4210 set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
4211
4173 cnic_init_bnx2x_tx_ring(dev); 4212 cnic_init_bnx2x_tx_ring(dev);
4174 cnic_init_bnx2x_rx_ring(dev); 4213 cnic_init_bnx2x_rx_ring(dev);
4175 4214
@@ -4177,6 +4216,15 @@ static void cnic_init_rings(struct cnic_dev *dev)
4177 l5_data.phy_address.hi = 0; 4216 l5_data.phy_address.hi = 0;
4178 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, 4217 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP,
4179 BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); 4218 BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
4219 i = 0;
4220 while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) &&
4221 ++i < 10)
4222 msleep(1);
4223
4224 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
4225 netdev_err(dev->netdev,
4226 "iSCSI CLIENT_SETUP did not complete\n");
4227 cnic_kwq_completion(dev, 1);
4180 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); 4228 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1);
4181 } 4229 }
4182} 4230}
@@ -4189,14 +4237,25 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
4189 struct cnic_local *cp = dev->cnic_priv; 4237 struct cnic_local *cp = dev->cnic_priv;
4190 u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); 4238 u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
4191 union l5cm_specific_data l5_data; 4239 union l5cm_specific_data l5_data;
4240 int i;
4192 4241
4193 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0); 4242 cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0);
4194 4243
4244 set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
4245
4195 l5_data.phy_address.lo = cli; 4246 l5_data.phy_address.lo = cli;
4196 l5_data.phy_address.hi = 0; 4247 l5_data.phy_address.hi = 0;
4197 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_HALT, 4248 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_HALT,
4198 BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); 4249 BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
4199 msleep(10); 4250 i = 0;
4251 while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) &&
4252 ++i < 10)
4253 msleep(1);
4254
4255 if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
4256 netdev_err(dev->netdev,
4257 "iSCSI CLIENT_HALT did not complete\n");
4258 cnic_kwq_completion(dev, 1);
4200 4259
4201 memset(&l5_data, 0, sizeof(l5_data)); 4260 memset(&l5_data, 0, sizeof(l5_data));
4202 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, 4261 cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL,
@@ -4317,7 +4376,15 @@ static void cnic_stop_hw(struct cnic_dev *dev)
4317{ 4376{
4318 if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) { 4377 if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
4319 struct cnic_local *cp = dev->cnic_priv; 4378 struct cnic_local *cp = dev->cnic_priv;
4379 int i = 0;
4320 4380
4381 /* Need to wait for the ring shutdown event to complete
4382 * before clearing the CNIC_UP flag.
4383 */
4384 while (cp->uio_dev != -1 && i < 15) {
4385 msleep(100);
4386 i++;
4387 }
4321 clear_bit(CNIC_F_CNIC_UP, &dev->flags); 4388 clear_bit(CNIC_F_CNIC_UP, &dev->flags);
4322 rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL); 4389 rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL);
4323 synchronize_rcu(); 4390 synchronize_rcu();
@@ -4628,7 +4695,6 @@ static void __exit cnic_exit(void)
4628{ 4695{
4629 unregister_netdevice_notifier(&cnic_netdev_notifier); 4696 unregister_netdevice_notifier(&cnic_netdev_notifier);
4630 cnic_release(); 4697 cnic_release();
4631 return;
4632} 4698}
4633 4699
4634module_init(cnic_init); 4700module_init(cnic_init);