qlcnic: define error code for loopback test
authorAmit Kumar Salecha <amit.salecha@qlogic.com>
Thu, 14 Jul 2011 03:16:54 +0000 (03:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 14 Jul 2011 15:49:44 +0000 (08:49 -0700)
o Defined error code such as fw not responding, test already running and
  cable not connected.
o Check Fw capability before performing loopback test.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/qlcnic/qlcnic.h
drivers/net/qlcnic/qlcnic_ethtool.c
drivers/net/qlcnic/qlcnic_init.c

index 3ae24501911e2ff9730920e80b412c1e68b1892b..f6e54a8e349d18fa5782f5e19dd1808961214686 100644 (file)
@@ -822,6 +822,7 @@ struct qlcnic_mac_list_s {
 #define QLCNIC_FW_CAPABILITY_BDG               BIT_8
 #define QLCNIC_FW_CAPABILITY_FVLANTX           BIT_9
 #define QLCNIC_FW_CAPABILITY_HW_LRO            BIT_10
+#define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK    BIT_27
 
 /* module types */
 #define LINKEVENT_MODULE_NOT_PRESENT                   1
@@ -936,6 +937,12 @@ struct qlcnic_ipaddr {
 #define QLCNIC_READD_AGE       20
 #define QLCNIC_LB_MAX_FILTERS  64
 
+/* QLCNIC Driver Error Code */
+#define QLCNIC_FW_NOT_RESPOND          51
+#define QLCNIC_TEST_IN_PROGRESS                52
+#define QLCNIC_UNDEFINED_ERROR         53
+#define QLCNIC_LB_CABLE_NOT_CONN       54
+
 struct qlcnic_filter {
        struct hlist_node fnode;
        u8 faddr[ETH_ALEN];
@@ -1007,7 +1014,7 @@ struct qlcnic_adapter {
        u8 max_mac_filters;
        u8 dev_state;
        u8 diag_test;
-       u8 diag_cnt;
+       char diag_cnt;
        u8 reset_ack_timeo;
        u8 dev_init_timeo;
        u16 msg_enable;
index 3ea04e7da91744135988d8c65a30248755738582..72a723d5c988949f8b6b92462a6207a1529c4974 100644 (file)
@@ -756,6 +756,11 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
        int loop = 0;
        int ret;
 
+       if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
+               netdev_info(netdev, "Firmware is not loopback test capable\n");
+               return -EOPNOTSUPP;
+       }
+
        netdev_info(netdev, "%s loopback test in progress\n",
                   mode == QLCNIC_ILB_MODE ? "internal" : "external");
        if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
@@ -765,8 +770,7 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
        }
 
        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
-               return -EIO;
-
+               return -EBUSY;
 
        ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
        if (ret)
@@ -778,20 +782,21 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
        if (ret)
                goto free_res;
 
+       adapter->diag_cnt = 0;
        do {
                msleep(500);
                qlcnic_process_rcv_ring_diag(sds_ring);
-               if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
-                       break;
+               if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
+                       netdev_info(netdev, "firmware didnt respond to loopback"
+                               " configure request\n");
+                       ret = -QLCNIC_FW_NOT_RESPOND;
+                       goto free_res;
+               } else if (adapter->diag_cnt) {
+                       ret = adapter->diag_cnt;
+                       goto free_res;
+               }
        } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
 
-       if (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)) {
-               netdev_info(netdev, "firmware didnt respond to loopback "
-                               "configure request\n");
-               ret = adapter->ahw->loopback_state;
-               goto free_res;
-       }
-
        ret = qlcnic_do_lb_test(adapter);
 
        qlcnic_clear_lb_mode(adapter);
index 6ec1baa85f6a59891f24b58bd3eb3d7baf49c161..ee8a3982395ebce8503fc04ced5ae27ac7aecb41 100644 (file)
@@ -1354,10 +1354,16 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
                        break;
                case 1:
                        dev_info(dev, "loopback already in progress\n");
+                       adapter->diag_cnt = -QLCNIC_TEST_IN_PROGRESS;
+                       break;
+               case 2:
+                       dev_info(dev, "loopback cable is not connected\n");
+                       adapter->diag_cnt = -QLCNIC_LB_CABLE_NOT_CONN;
                        break;
                default:
                        dev_info(dev, "loopback configure request failed,"
                                        " ret %x\n", ret);
+                       adapter->diag_cnt = -QLCNIC_UNDEFINED_ERROR;
                        break;
                }
                break;