aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2011-03-31 20:04:22 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-31 20:04:22 -0400
commitfab0dc89f0d98459c6ce7fa27422949ac15837fa (patch)
treecd7d169e81ff9028d746f2540302d677b17f30cf /drivers/net/cnic.c
parent3b7f817e47bb66ae4d82ed73689a521af70a5410 (diff)
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>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 8cca60e43444..5dfbff06631c 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2966,31 +2966,36 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
2966 return 0; 2966 return 0;
2967} 2967}
2968 2968
2969static void cnic_ulp_stop(struct cnic_dev *dev) 2969static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type)
2970{ 2970{
2971 struct cnic_local *cp = dev->cnic_priv; 2971 struct cnic_ulp_ops *ulp_ops;
2972 int if_type;
2973
2974 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
2975 2972
2976 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { 2973 if (if_type == CNIC_ULP_ISCSI)
2977 struct cnic_ulp_ops *ulp_ops; 2974 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
2978 2975
2979 mutex_lock(&cnic_lock); 2976 mutex_lock(&cnic_lock);
2980 ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], 2977 ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
2981 lockdep_is_held(&cnic_lock)); 2978 lockdep_is_held(&cnic_lock));
2982 if (!ulp_ops) { 2979 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); 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])) 2986 if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
2990 ulp_ops->cnic_stop(cp->ulp_handle[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]); 2989 clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
2993 } 2990}
2991
2992static 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);
2994} 2999}
2995 3000
2996static void cnic_ulp_start(struct cnic_dev *dev) 3001static void cnic_ulp_start(struct cnic_dev *dev)
@@ -3039,6 +3044,12 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
3039 3044
3040 cnic_put(dev); 3045 cnic_put(dev);
3041 break; 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 case CNIC_CTL_COMPLETION_CMD: { 3053 case CNIC_CTL_COMPLETION_CMD: {
3043 u32 cid = BNX2X_SW_CID(info->data.comp.cid); 3054 u32 cid = BNX2X_SW_CID(info->data.comp.cid);
3044 u32 l5_cid; 3055 u32 l5_cid;
@@ -3562,8 +3573,12 @@ static void cnic_init_csk_state(struct cnic_sock *csk)
3562 3573
3563static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr) 3574static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
3564{ 3575{
3576 struct cnic_local *cp = csk->dev->cnic_priv;
3565 int err = 0; 3577 int err = 0;
3566 3578
3579 if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
3580 return -EOPNOTSUPP;
3581
3567 if (!cnic_in_use(csk)) 3582 if (!cnic_in_use(csk))
3568 return -EINVAL; 3583 return -EINVAL;
3569 3584
@@ -3965,6 +3980,17 @@ static void cnic_delete_task(struct work_struct *work)
3965 cp = container_of(work, struct cnic_local, delete_task.work); 3980 cp = container_of(work, struct cnic_local, delete_task.work);
3966 dev = cp->dev; 3981 dev = cp->dev;
3967 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 }
3993
3968 for (i = 0; i < cp->max_cid_space; i++) { 3994 for (i = 0; i < cp->max_cid_space; i++) {
3969 struct cnic_context *ctx = &cp->ctx_tbl[i]; 3995 struct cnic_context *ctx = &cp->ctx_tbl[i];
3970 3996