Commit fab0dc89f0d98459c6ce7fa27422949ac15837fa
Committed by
David S. Miller
1 parent
3b7f817e47
Exists in
master
and in
7 other branches
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; |
drivers/net/cnic.c
... | ... | @@ -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]; |
drivers/net/cnic.h
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; |