Commit fab0dc89f0d98459c6ce7fa27422949ac15837fa

Authored by Dmitry Kravkov
Committed by David S. Miller
1 parent 3b7f817e47

bnx2x, cnic: Disable iSCSI if DCBX negotiation is successful

With current bnx2x firmware 6.2.9, iSCSI is not supported in DCB
network, so we need to disable it.  Add cnic command to disconnect
iSCSI connections and prevent future connections when DCBX negotiation
succeeds.

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 6 changed files with 83 additions and 23 deletions Side-by-side Diff

drivers/net/bnx2x/bnx2x_dcb.c
... ... @@ -571,6 +571,28 @@
571 571 {
572 572 switch (state) {
573 573 case BNX2X_DCBX_STATE_NEG_RECEIVED:
  574 +#ifdef BCM_CNIC
  575 + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
  576 + struct cnic_ops *c_ops;
  577 + struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
  578 + bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
  579 + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
  580 + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
  581 +
  582 + rcu_read_lock();
  583 + c_ops = rcu_dereference(bp->cnic_ops);
  584 + if (c_ops) {
  585 + bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
  586 + rcu_read_unlock();
  587 + return;
  588 + }
  589 + rcu_read_unlock();
  590 + }
  591 +
  592 + /* fall through if no CNIC initialized */
  593 + case BNX2X_DCBX_STATE_ISCSI_STOPPED:
  594 +#endif
  595 +
574 596 {
575 597 DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
576 598 #ifdef BCM_DCBNL
drivers/net/bnx2x/bnx2x_dcb.h
... ... @@ -183,9 +183,13 @@
183 183  
184 184 enum {
185 185 BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
186   - BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
187   - BNX2X_DCBX_STATE_TX_RELEASED = 0x4
  186 +#ifdef BCM_CNIC
  187 + BNX2X_DCBX_STATE_ISCSI_STOPPED,
  188 +#endif
  189 + BNX2X_DCBX_STATE_TX_PAUSED,
  190 + BNX2X_DCBX_STATE_TX_RELEASED
188 191 };
  192 +
189 193 void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
190 194  
191 195 /* DCB netlink */
drivers/net/bnx2x/bnx2x_main.c
... ... @@ -10342,6 +10342,11 @@
10342 10342 break;
10343 10343 }
10344 10344  
  10345 + case DRV_CTL_ISCSI_STOPPED_CMD: {
  10346 + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED);
  10347 + break;
  10348 + }
  10349 +
10345 10350 default:
10346 10351 BNX2X_ERR("unknown command %x\n", ctl->cmd);
10347 10352 rc = -EINVAL;
... ... @@ -2966,33 +2966,38 @@
2966 2966 return 0;
2967 2967 }
2968 2968  
2969   -static void cnic_ulp_stop(struct cnic_dev *dev)
  2969 +static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type)
2970 2970 {
2971   - struct cnic_local *cp = dev->cnic_priv;
2972   - int if_type;
  2971 + struct cnic_ulp_ops *ulp_ops;
2973 2972  
2974   - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
  2973 + if (if_type == CNIC_ULP_ISCSI)
  2974 + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
2975 2975  
2976   - for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
2977   - struct cnic_ulp_ops *ulp_ops;
2978   -
2979   - mutex_lock(&cnic_lock);
2980   - ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
2981   - lockdep_is_held(&cnic_lock));
2982   - if (!ulp_ops) {
2983   - mutex_unlock(&cnic_lock);
2984   - continue;
2985   - }
2986   - set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
  2976 + mutex_lock(&cnic_lock);
  2977 + ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
  2978 + lockdep_is_held(&cnic_lock));
  2979 + if (!ulp_ops) {
2987 2980 mutex_unlock(&cnic_lock);
  2981 + return;
  2982 + }
  2983 + set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
  2984 + mutex_unlock(&cnic_lock);
2988 2985  
2989   - if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
2990   - ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
  2986 + if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
  2987 + ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
2991 2988  
2992   - clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
2993   - }
  2989 + clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
2994 2990 }
2995 2991  
  2992 +static void cnic_ulp_stop(struct cnic_dev *dev)
  2993 +{
  2994 + struct cnic_local *cp = dev->cnic_priv;
  2995 + int if_type;
  2996 +
  2997 + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++)
  2998 + cnic_ulp_stop_one(cp, if_type);
  2999 +}
  3000 +
2996 3001 static void cnic_ulp_start(struct cnic_dev *dev)
2997 3002 {
2998 3003 struct cnic_local *cp = dev->cnic_priv;
... ... @@ -3039,6 +3044,12 @@
3039 3044  
3040 3045 cnic_put(dev);
3041 3046 break;
  3047 + case CNIC_CTL_STOP_ISCSI_CMD: {
  3048 + struct cnic_local *cp = dev->cnic_priv;
  3049 + set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags);
  3050 + queue_delayed_work(cnic_wq, &cp->delete_task, 0);
  3051 + break;
  3052 + }
3042 3053 case CNIC_CTL_COMPLETION_CMD: {
3043 3054 u32 cid = BNX2X_SW_CID(info->data.comp.cid);
3044 3055 u32 l5_cid;
3045 3056  
... ... @@ -3562,8 +3573,12 @@
3562 3573  
3563 3574 static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
3564 3575 {
  3576 + struct cnic_local *cp = csk->dev->cnic_priv;
3565 3577 int err = 0;
3566 3578  
  3579 + if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
  3580 + return -EOPNOTSUPP;
  3581 +
3567 3582 if (!cnic_in_use(csk))
3568 3583 return -EINVAL;
3569 3584  
... ... @@ -3964,6 +3979,17 @@
3964 3979  
3965 3980 cp = container_of(work, struct cnic_local, delete_task.work);
3966 3981 dev = cp->dev;
  3982 +
  3983 + if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) {
  3984 + struct drv_ctl_info info;
  3985 +
  3986 + rtnl_lock();
  3987 + cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);
  3988 + rtnl_unlock();
  3989 +
  3990 + info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
  3991 + cp->ethdev->drv_ctl(dev->netdev, &info);
  3992 + }
3967 3993  
3968 3994 for (i = 0; i < cp->max_cid_space; i++) {
3969 3995 struct cnic_context *ctx = &cp->ctx_tbl[i];
... ... @@ -226,6 +226,7 @@
226 226 #define CNIC_LCL_FL_KWQ_INIT 0x0
227 227 #define CNIC_LCL_FL_L2_WAIT 0x1
228 228 #define CNIC_LCL_FL_RINGS_INITED 0x2
  229 +#define CNIC_LCL_FL_STOP_ISCSI 0x4
229 230  
230 231 struct cnic_dev *dev;
231 232  
drivers/net/cnic_if.h
... ... @@ -12,8 +12,8 @@
12 12 #ifndef CNIC_IF_H
13 13 #define CNIC_IF_H
14 14  
15   -#define CNIC_MODULE_VERSION "2.2.13"
16   -#define CNIC_MODULE_RELDATE "Jan 31, 2011"
  15 +#define CNIC_MODULE_VERSION "2.2.14"
  16 +#define CNIC_MODULE_RELDATE "Mar 30, 2011"
17 17  
18 18 #define CNIC_ULP_RDMA 0
19 19 #define CNIC_ULP_ISCSI 1
... ... @@ -85,6 +85,7 @@
85 85 #define CNIC_CTL_STOP_CMD 1
86 86 #define CNIC_CTL_START_CMD 2
87 87 #define CNIC_CTL_COMPLETION_CMD 3
  88 +#define CNIC_CTL_STOP_ISCSI_CMD 4
88 89  
89 90 #define DRV_CTL_IO_WR_CMD 0x101
90 91 #define DRV_CTL_IO_RD_CMD 0x102
... ... @@ -94,6 +95,7 @@
94 95 #define DRV_CTL_START_L2_CMD 0x106
95 96 #define DRV_CTL_STOP_L2_CMD 0x107
96 97 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c
  98 +#define DRV_CTL_ISCSI_STOPPED_CMD 0x10d
97 99  
98 100 struct cnic_ctl_completion {
99 101 u32 cid;