diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index f267da42f243..4028d0c08f2c 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -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 diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 0eaf31bf8a0d..1e7af709d395 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -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