qlcnic: fix LED test when interface is down.
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Thu, 16 Dec 2010 22:59:00 +0000 (22:59 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 17 Dec 2010 19:39:01 +0000 (11:39 -0800)
When interface is down, create temporary context to config LED.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
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

index f267da4..4028d0c 100644 (file)
@@ -925,6 +925,7 @@ struct qlcnic_ipaddr {
 
 #define QLCNIC_INTERRUPT_TEST          1
 #define QLCNIC_LOOPBACK_TEST           2
+#define QLCNIC_LED_TEST                3
 
 #define QLCNIC_FILTER_AGE      80
 #define QLCNIC_READD_AGE       20
index 0eaf31b..1e7af70 100644 (file)
@@ -834,16 +834,27 @@ static int qlcnic_set_tso(struct net_device *dev, u32 data)
 static int qlcnic_blink_led(struct net_device *dev, u32 val)
 {
        struct qlcnic_adapter *adapter = netdev_priv(dev);
+       int max_sds_rings = adapter->max_sds_rings;
+       int dev_down = 0;
        int ret;
 
-       if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
-               return -EIO;
+       if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
+               dev_down = 1;
+               if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+                       return -EIO;
+
+               ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
+               if (ret) {
+                       clear_bit(__QLCNIC_RESETTING, &adapter->state);
+                       return ret;
+               }
+       }
 
        ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
        if (ret) {
                dev_err(&adapter->pdev->dev,
                        "Failed to set LED blink state.\n");
-               return ret;
+               goto done;
        }
 
        msleep_interruptible(val * 1000);
@@ -852,10 +863,16 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val)
        if (ret) {
                dev_err(&adapter->pdev->dev,
                        "Failed to reset LED blink state.\n");
-               return ret;
+               goto done;
        }
 
-       return 0;
+done:
+       if (dev_down) {
+               qlcnic_diag_free_res(dev, max_sds_rings);
+               clear_bit(__QLCNIC_RESETTING, &adapter->state);
+       }
+       return ret;
+
 }
 
 static void