Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dmitry Kravkov and committed by
David S. Miller
fab0dc89 3b7f817e

+84 -24
+22
drivers/net/bnx2x/bnx2x_dcb.c
··· 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
+6 -2
drivers/net/bnx2x/bnx2x_dcb.h
··· 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 */
+5
drivers/net/bnx2x/bnx2x_main.c
··· 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;
+46 -20
drivers/net/cnic.c
··· 2966 2966 return 0; 2967 2967 } 2968 2968 2969 + static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type) 2970 + { 2971 + struct cnic_ulp_ops *ulp_ops; 2972 + 2973 + if (if_type == CNIC_ULP_ISCSI) 2974 + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); 2975 + 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) { 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); 2985 + 2986 + if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) 2987 + ulp_ops->cnic_stop(cp->ulp_handle[if_type]); 2988 + 2989 + clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); 2990 + } 2991 + 2969 2992 static void cnic_ulp_stop(struct cnic_dev *dev) 2970 2993 { 2971 2994 struct cnic_local *cp = dev->cnic_priv; 2972 2995 int if_type; 2973 2996 2974 - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); 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]); 2987 - mutex_unlock(&cnic_lock); 2988 - 2989 - if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) 2990 - ulp_ops->cnic_stop(cp->ulp_handle[if_type]); 2991 - 2992 - clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); 2993 - } 2997 + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) 2998 + cnic_ulp_stop_one(cp, if_type); 2994 2999 } 2995 3000 2996 3001 static void cnic_ulp_start(struct cnic_dev *dev) ··· 3044 3039 3045 3040 cnic_put(dev); 3046 3041 break; 3042 + case CNIC_CTL_STOP_ISCSI_CMD: { 3043 + struct cnic_local *cp = dev->cnic_priv; 3044 + set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags); 3045 + queue_delayed_work(cnic_wq, &cp->delete_task, 0); 3046 + break; 3047 + } 3047 3048 case CNIC_CTL_COMPLETION_CMD: { 3048 3049 u32 cid = BNX2X_SW_CID(info->data.comp.cid); 3049 3050 u32 l5_cid; ··· 3573 3562 3574 3563 static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr) 3575 3564 { 3565 + struct cnic_local *cp = csk->dev->cnic_priv; 3576 3566 int err = 0; 3567 + 3568 + if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI) 3569 + return -EOPNOTSUPP; 3577 3570 3578 3571 if (!cnic_in_use(csk)) 3579 3572 return -EINVAL; ··· 3979 3964 3980 3965 cp = container_of(work, struct cnic_local, delete_task.work); 3981 3966 dev = cp->dev; 3967 + 3968 + if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) { 3969 + struct drv_ctl_info info; 3970 + 3971 + rtnl_lock(); 3972 + cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI); 3973 + rtnl_unlock(); 3974 + 3975 + info.cmd = DRV_CTL_ISCSI_STOPPED_CMD; 3976 + cp->ethdev->drv_ctl(dev->netdev, &info); 3977 + } 3982 3978 3983 3979 for (i = 0; i < cp->max_cid_space; i++) { 3984 3980 struct cnic_context *ctx = &cp->ctx_tbl[i];
+1
drivers/net/cnic.h
··· 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
+4 -2
drivers/net/cnic_if.h
··· 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 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 ··· 95 94 #define DRV_CTL_START_L2_CMD 0x106 96 95 #define DRV_CTL_STOP_L2_CMD 0x107 97 96 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c 97 + #define DRV_CTL_ISCSI_STOPPED_CMD 0x10d 98 98 99 99 struct cnic_ctl_completion { 100 100 u32 cid;