cnic: Finetune iSCSI connection reset.
[deliverable/linux.git] / drivers / net / cnic.c
index 4332b3a2fafbacec6705b650da28cea157032fc5..40865aac2afaf496b1902e8c025820d1aa7f9bea 100644 (file)
@@ -10,6 +10,8 @@
  * Modified and maintained by: Michael Chan <mchan@broadcom.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -47,7 +49,6 @@
 #include "cnic_defs.h"
 
 #define DRV_MODULE_NAME                "cnic"
-#define PFX DRV_MODULE_NAME    ": "
 
 static char version[] __devinitdata =
        "Broadcom NetXtreme II CNIC Driver " DRV_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
@@ -409,14 +410,13 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
        struct cnic_dev *dev;
 
        if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-               printk(KERN_ERR PFX "cnic_register_driver: Bad type %d\n",
-                      ulp_type);
+               pr_err("%s: Bad type %d\n", __func__, ulp_type);
                return -EINVAL;
        }
        mutex_lock(&cnic_lock);
        if (cnic_ulp_tbl[ulp_type]) {
-               printk(KERN_ERR PFX "cnic_register_driver: Type %d has already "
-                                   "been registered\n", ulp_type);
+               pr_err("%s: Type %d has already been registered\n",
+                      __func__, ulp_type);
                mutex_unlock(&cnic_lock);
                return -EBUSY;
        }
@@ -455,15 +455,14 @@ int cnic_unregister_driver(int ulp_type)
        int i = 0;
 
        if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-               printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
-                      ulp_type);
+               pr_err("%s: Bad type %d\n", __func__, ulp_type);
                return -EINVAL;
        }
        mutex_lock(&cnic_lock);
        ulp_ops = cnic_ulp_tbl[ulp_type];
        if (!ulp_ops) {
-               printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not "
-                                   "been registered\n", ulp_type);
+               pr_err("%s: Type %d has not been registered\n",
+                      __func__, ulp_type);
                goto out_unlock;
        }
        read_lock(&cnic_dev_lock);
@@ -471,8 +470,8 @@ int cnic_unregister_driver(int ulp_type)
                struct cnic_local *cp = dev->cnic_priv;
 
                if (rcu_dereference(cp->ulp_ops[ulp_type])) {
-                       printk(KERN_ERR PFX "cnic_unregister_driver: Type %d "
-                              "still has devices registered\n", ulp_type);
+                       pr_err("%s: Type %d still has devices registered\n",
+                              __func__, ulp_type);
                        read_unlock(&cnic_dev_lock);
                        goto out_unlock;
                }
@@ -492,8 +491,7 @@ int cnic_unregister_driver(int ulp_type)
        }
 
        if (atomic_read(&ulp_ops->ref_count) != 0)
-               printk(KERN_WARNING PFX "%s: Failed waiting for ref count to go"
-                                       " to zero.\n", dev->netdev->name);
+               netdev_warn(dev->netdev, "Failed waiting for ref count to go to zero\n");
        return 0;
 
 out_unlock:
@@ -511,20 +509,19 @@ static int cnic_register_device(struct cnic_dev *dev, int ulp_type,
        struct cnic_ulp_ops *ulp_ops;
 
        if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-               printk(KERN_ERR PFX "cnic_register_device: Bad type %d\n",
-                      ulp_type);
+               pr_err("%s: Bad type %d\n", __func__, ulp_type);
                return -EINVAL;
        }
        mutex_lock(&cnic_lock);
        if (cnic_ulp_tbl[ulp_type] == NULL) {
-               printk(KERN_ERR PFX "cnic_register_device: Driver with type %d "
-                                   "has not been registered\n", ulp_type);
+               pr_err("%s: Driver with type %d has not been registered\n",
+                      __func__, ulp_type);
                mutex_unlock(&cnic_lock);
                return -EAGAIN;
        }
        if (rcu_dereference(cp->ulp_ops[ulp_type])) {
-               printk(KERN_ERR PFX "cnic_register_device: Type %d has already "
-                      "been registered to this device\n", ulp_type);
+               pr_err("%s: Type %d has already been registered to this device\n",
+                      __func__, ulp_type);
                mutex_unlock(&cnic_lock);
                return -EBUSY;
        }
@@ -552,8 +549,7 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
        int i = 0;
 
        if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-               printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
-                      ulp_type);
+               pr_err("%s: Bad type %d\n", __func__, ulp_type);
                return -EINVAL;
        }
        mutex_lock(&cnic_lock);
@@ -561,8 +557,8 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
                rcu_assign_pointer(cp->ulp_ops[ulp_type], NULL);
                cnic_put(dev);
        } else {
-               printk(KERN_ERR PFX "cnic_unregister_device: device not "
-                      "registered to this ulp type %d\n", ulp_type);
+               pr_err("%s: device not registered to this ulp type %d\n",
+                      __func__, ulp_type);
                mutex_unlock(&cnic_lock);
                return -EINVAL;
        }
@@ -576,8 +572,7 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
                i++;
        }
        if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
-               printk(KERN_WARNING PFX "%s: Failed waiting for ULP up call"
-                                       " to complete.\n", dev->netdev->name);
+               netdev_warn(dev->netdev, "Failed waiting for ULP up call to complete\n");
 
        return 0;
 }
@@ -1865,8 +1860,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
        }
 
        if (sizeof(*conn_buf) > CNIC_KWQ16_DATA_SIZE) {
-               printk(KERN_ERR PFX "%s: conn_buf size too big\n",
-                              dev->netdev->name);
+               netdev_err(dev->netdev, "conn_buf size too big\n");
                return -ENOMEM;
        }
        conn_buf = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
@@ -2026,13 +2020,13 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
                        break;
                default:
                        ret = 0;
-                       printk(KERN_ERR PFX "%s: Unknown type of KWQE(0x%x)\n",
-                              dev->netdev->name, opcode);
+                       netdev_err(dev->netdev, "Unknown type of KWQE(0x%x)\n",
+                                  opcode);
                        break;
                }
                if (ret < 0)
-                       printk(KERN_ERR PFX "%s: KWQE(0x%x) failed\n",
-                              dev->netdev->name, opcode);
+                       netdev_err(dev->netdev, "KWQE(0x%x) failed\n",
+                                  opcode);
                i += work;
        }
        return 0;
@@ -2074,8 +2068,8 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
                else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L2)
                        goto end;
                else {
-                       printk(KERN_ERR PFX "%s: Unknown type of KCQE(0x%x)\n",
-                              dev->netdev->name, kcqe_op_flag);
+                       netdev_err(dev->netdev, "Unknown type of KCQE(0x%x)\n",
+                                  kcqe_op_flag);
                        goto end;
                }
 
@@ -2513,7 +2507,7 @@ static int cnic_cm_offload_pg(struct cnic_sock *csk)
        l4kwqe->sa5 = dev->mac_addr[5];
 
        l4kwqe->etype = ETH_P_IP;
-       l4kwqe->ipid_count = DEF_IPID_COUNT;
+       l4kwqe->ipid_start = DEF_IPID_START;
        l4kwqe->host_opaque = csk->l5_cid;
 
        if (csk->vlan_id) {
@@ -3052,6 +3046,14 @@ static void cnic_cm_process_offld_pg(struct cnic_dev *dev, struct l4_kcq *kcqe)
                clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
                goto done;
        }
+       /* Possible PG kcqe status:  SUCCESS, OFFLOADED_PG, or CTX_ALLOC_FAIL */
+       if (kcqe->status == L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL) {
+               clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
+               cnic_cm_upcall(cp, csk,
+                              L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE);
+               goto done;
+       }
+
        csk->pg_cid = kcqe->pg_cid;
        set_bit(SK_F_PG_OFFLD_COMPLETE, &csk->flags);
        cnic_cm_conn_req(csk);
@@ -3089,6 +3091,13 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
        }
 
        switch (opcode) {
+       case L5CM_RAMROD_CMD_ID_TCP_CONNECT:
+               if (l4kcqe->status != 0) {
+                       clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
+                       cnic_cm_upcall(cp, csk,
+                                      L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE);
+               }
+               break;
        case L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE:
                if (l4kcqe->status == 0)
                        set_bit(SK_F_OFFLD_COMPLETE, &csk->flags);
@@ -3099,7 +3108,10 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
                break;
 
        case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED:
-               if (test_and_clear_bit(SK_F_OFFLD_COMPLETE, &csk->flags))
+               if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+                       cnic_cm_upcall(cp, csk, opcode);
+                       break;
+               } else if (test_and_clear_bit(SK_F_OFFLD_COMPLETE, &csk->flags))
                        csk->state = opcode;
                /* fall through */
        case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:
@@ -3163,6 +3175,16 @@ static int cnic_ready_to_close(struct cnic_sock *csk, u32 opcode)
                if (!test_and_set_bit(SK_F_CLOSING, &csk->flags))
                        return 1;
        }
+       /* 57710+ only  workaround to handle unsolicited RESET_COMP
+        * which will be treated like a RESET RCVD notification
+        * which triggers the clean up procedure
+        */
+       else if (opcode == L4_KCQE_OPCODE_VALUE_RESET_COMP) {
+               if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) {
+                       csk->state = L4_KCQE_OPCODE_VALUE_RESET_RECEIVED;
+                       return 1;
+               }
+       }
        return 0;
 }
 
@@ -3172,10 +3194,8 @@ static void cnic_close_bnx2_conn(struct cnic_sock *csk, u32 opcode)
        struct cnic_local *cp = dev->cnic_priv;
 
        clear_bit(SK_F_CONNECT_START, &csk->flags);
-       if (cnic_ready_to_close(csk, opcode)) {
-               cnic_close_conn(csk);
-               cnic_cm_upcall(cp, csk, opcode);
-       }
+       cnic_close_conn(csk);
+       cnic_cm_upcall(cp, csk, opcode);
 }
 
 static void cnic_cm_stop_bnx2_hw(struct cnic_dev *dev)
@@ -3435,8 +3455,7 @@ static int cnic_init_bnx2_irq(struct cnic_dev *dev)
        return 0;
 
 failed:
-       printk(KERN_ERR PFX "%s: " "KCQ index not resetting to 0.\n",
-              dev->netdev->name);
+       netdev_err(dev->netdev, "KCQ index not resetting to 0\n");
        return -EBUSY;
 }
 
@@ -3758,8 +3777,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
 
        err = cnic_init_bnx2_irq(dev);
        if (err) {
-               printk(KERN_ERR PFX "%s: cnic_init_irq failed\n",
-                      dev->netdev->name);
+               netdev_err(dev->netdev, "cnic_init_irq failed\n");
                cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
                cnic_reg_wr_ind(dev, BNX2_COM_SCRATCH + 0x20, 0);
                return err;
@@ -4122,8 +4140,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
                           offsetof(struct cstorm_status_block_c,
                                    index_values[HC_INDEX_C_ISCSI_EQ_CONS]));
        if (eq_idx != 0) {
-               printk(KERN_ERR PFX "%s: EQ cons index %x != 0\n",
-                      dev->netdev->name, eq_idx);
+               netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx);
                return -EBUSY;
        }
        ret = cnic_init_bnx2x_irq(dev);
@@ -4208,8 +4225,7 @@ static int cnic_register_netdev(struct cnic_dev *dev)
 
        err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
        if (err)
-               printk(KERN_ERR PFX "%s: register_cnic failed\n",
-                      dev->netdev->name);
+               netdev_err(dev->netdev, "register_cnic failed\n");
 
        return err;
 }
@@ -4243,8 +4259,7 @@ static int cnic_start_hw(struct cnic_dev *dev)
 
        err = cp->alloc_resc(dev);
        if (err) {
-               printk(KERN_ERR PFX "%s: allocate resource failure\n",
-                      dev->netdev->name);
+               netdev_err(dev->netdev, "allocate resource failure\n");
                goto err1;
        }
 
@@ -4326,10 +4341,9 @@ static void cnic_free_dev(struct cnic_dev *dev)
                i++;
        }
        if (atomic_read(&dev->ref_count) != 0)
-               printk(KERN_ERR PFX "%s: Failed waiting for ref count to go"
-                                   " to zero.\n", dev->netdev->name);
+               netdev_err(dev->netdev, "Failed waiting for ref count to go to zero\n");
 
-       printk(KERN_INFO PFX "Removed CNIC device: %s\n", dev->netdev->name);
+       netdev_info(dev->netdev, "Removed CNIC device\n");
        dev_put(dev->netdev);
        kfree(dev);
 }
@@ -4345,8 +4359,7 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
 
        cdev = kzalloc(alloc_size , GFP_KERNEL);
        if (cdev == NULL) {
-               printk(KERN_ERR PFX "%s: allocate dev struct failure\n",
-                      dev->name);
+               netdev_err(dev, "allocate dev struct failure\n");
                return NULL;
        }
 
@@ -4364,7 +4377,7 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
 
        spin_lock_init(&cp->cnic_ulp_lock);
 
-       printk(KERN_INFO PFX "Added CNIC device: %s\n", dev->name);
+       netdev_info(dev, "Added CNIC device\n");
 
        return cdev;
 }
@@ -4605,7 +4618,7 @@ static int __init cnic_init(void)
 {
        int rc = 0;
 
-       printk(KERN_INFO "%s", version);
+       pr_info("%s", version);
 
        rc = register_netdevice_notifier(&cnic_netdev_notifier);
        if (rc) {
This page took 0.035132 seconds and 5 git commands to generate.