bnx2x, cnic: Disable iSCSI if DCBX negotiation is successful
authorDmitry Kravkov <dmitry@broadcom.com>
Fri, 1 Apr 2011 00:04:22 +0000 (17:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 1 Apr 2011 00:04:22 +0000 (17:04 -0700)
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>
drivers/net/bnx2x/bnx2x_dcb.c
drivers/net/bnx2x/bnx2x_dcb.h
drivers/net/bnx2x/bnx2x_main.c
drivers/net/cnic.c
drivers/net/cnic.h
drivers/net/cnic_if.h

index 9a24d79c71d93fc17f7ec60393cd3311156e4877..1214907d00d98fb5c633c18f6f84933a51ca816d 100644 (file)
@@ -571,6 +571,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
 {
        switch (state) {
        case BNX2X_DCBX_STATE_NEG_RECEIVED:
+#ifdef BCM_CNIC
+               if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+                       struct cnic_ops *c_ops;
+                       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+                       bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
+                       cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
+                       cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
+
+                       rcu_read_lock();
+                       c_ops = rcu_dereference(bp->cnic_ops);
+                       if (c_ops) {
+                               bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
+                               rcu_read_unlock();
+                               return;
+                       }
+                       rcu_read_unlock();
+               }
+
+               /* fall through if no CNIC initialized  */
+       case BNX2X_DCBX_STATE_ISCSI_STOPPED:
+#endif
+
                {
                        DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
 #ifdef BCM_DCBNL
index 71b8eda43bd0f27739cf33264104ad473a2fd0d8..1e14775a18cb4d00a4c7b65e682d97648398dfd5 100644 (file)
@@ -183,9 +183,13 @@ void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled);
 
 enum {
        BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
-       BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
-       BNX2X_DCBX_STATE_TX_RELEASED = 0x4
+#ifdef BCM_CNIC
+       BNX2X_DCBX_STATE_ISCSI_STOPPED,
+#endif
+       BNX2X_DCBX_STATE_TX_PAUSED,
+       BNX2X_DCBX_STATE_TX_RELEASED
 };
+
 void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
 
 /* DCB netlink */
index 32e64cc85d2cd09f869edbd67a7c3ab47afa8313..f3cf88918a9ea679d432072285f5dd251740d9aa 100644 (file)
@@ -10342,6 +10342,11 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
                break;
        }
 
+       case DRV_CTL_ISCSI_STOPPED_CMD: {
+               bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED);
+               break;
+       }
+
        default:
                BNX2X_ERR("unknown command %x\n", ctl->cmd);
                rc = -EINVAL;
index 8cca60e434444e2912ebb0141fb63710ffe499c1..5dfbff06631c39ffc1a40dc5bdd4243333cc3140 100644 (file)
@@ -2966,31 +2966,36 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
        return 0;
 }
 
-static void cnic_ulp_stop(struct cnic_dev *dev)
+static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type)
 {
-       struct cnic_local *cp = dev->cnic_priv;
-       int if_type;
-
-       cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+       struct cnic_ulp_ops *ulp_ops;
 
-       for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
-               struct cnic_ulp_ops *ulp_ops;
+       if (if_type == CNIC_ULP_ISCSI)
+               cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
 
-               mutex_lock(&cnic_lock);
-               ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
-                                                   lockdep_is_held(&cnic_lock));
-               if (!ulp_ops) {
-                       mutex_unlock(&cnic_lock);
-                       continue;
-               }
-               set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+       mutex_lock(&cnic_lock);
+       ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
+                                           lockdep_is_held(&cnic_lock));
+       if (!ulp_ops) {
                mutex_unlock(&cnic_lock);
+               return;
+       }
+       set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+       mutex_unlock(&cnic_lock);
 
-               if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
-                       ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
+       if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
+               ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
 
-               clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
-       }
+       clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+}
+
+static void cnic_ulp_stop(struct cnic_dev *dev)
+{
+       struct cnic_local *cp = dev->cnic_priv;
+       int if_type;
+
+       for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++)
+               cnic_ulp_stop_one(cp, if_type);
 }
 
 static void cnic_ulp_start(struct cnic_dev *dev)
@@ -3039,6 +3044,12 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
 
                cnic_put(dev);
                break;
+       case CNIC_CTL_STOP_ISCSI_CMD: {
+               struct cnic_local *cp = dev->cnic_priv;
+               set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags);
+               queue_delayed_work(cnic_wq, &cp->delete_task, 0);
+               break;
+       }
        case CNIC_CTL_COMPLETION_CMD: {
                u32 cid = BNX2X_SW_CID(info->data.comp.cid);
                u32 l5_cid;
@@ -3562,8 +3573,12 @@ static void cnic_init_csk_state(struct cnic_sock *csk)
 
 static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
 {
+       struct cnic_local *cp = csk->dev->cnic_priv;
        int err = 0;
 
+       if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
+               return -EOPNOTSUPP;
+
        if (!cnic_in_use(csk))
                return -EINVAL;
 
@@ -3965,6 +3980,17 @@ static void cnic_delete_task(struct work_struct *work)
        cp = container_of(work, struct cnic_local, delete_task.work);
        dev = cp->dev;
 
+       if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) {
+               struct drv_ctl_info info;
+
+               rtnl_lock();
+               cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);
+               rtnl_unlock();
+
+               info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
+               cp->ethdev->drv_ctl(dev->netdev, &info);
+       }
+
        for (i = 0; i < cp->max_cid_space; i++) {
                struct cnic_context *ctx = &cp->ctx_tbl[i];
 
index 4456260c653c3d289d0016d57af38ffa78921ded..3367a6d3a7743882e442a1e5efd8c81cb6839dd5 100644 (file)
@@ -226,6 +226,7 @@ struct cnic_local {
 #define        CNIC_LCL_FL_KWQ_INIT            0x0
 #define        CNIC_LCL_FL_L2_WAIT             0x1
 #define        CNIC_LCL_FL_RINGS_INITED        0x2
+#define        CNIC_LCL_FL_STOP_ISCSI          0x4
 
        struct cnic_dev *dev;
 
index e01b49ee35915a623f3b2bf377bb616ead139199..fdd8e46a90506e52ed2316a9a58b0b390ac2d28a 100644 (file)
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION    "2.2.13"
-#define CNIC_MODULE_RELDATE    "Jan 31, 2011"
+#define CNIC_MODULE_VERSION    "2.2.14"
+#define CNIC_MODULE_RELDATE    "Mar 30, 2011"
 
 #define CNIC_ULP_RDMA          0
 #define CNIC_ULP_ISCSI         1
@@ -85,6 +85,7 @@ struct kcqe {
 #define CNIC_CTL_STOP_CMD              1
 #define CNIC_CTL_START_CMD             2
 #define CNIC_CTL_COMPLETION_CMD                3
+#define CNIC_CTL_STOP_ISCSI_CMD                4
 
 #define DRV_CTL_IO_WR_CMD              0x101
 #define DRV_CTL_IO_RD_CMD              0x102
@@ -94,6 +95,7 @@ struct kcqe {
 #define DRV_CTL_START_L2_CMD           0x106
 #define DRV_CTL_STOP_L2_CMD            0x107
 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD  0x10c
+#define DRV_CTL_ISCSI_STOPPED_CMD      0x10d
 
 struct cnic_ctl_completion {
        u32     cid;
This page took 0.03651 seconds and 5 git commands to generate.