diff options
author | Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> | 2011-10-28 12:57:15 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-30 03:09:41 -0400 |
commit | 10ee0faed92c8af4baebd633372136a6608a41ea (patch) | |
tree | bd9390dfecf81ec40c2cdb12f97d4c7e7224132e /drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |
parent | 445b62dfd934394807c12aee06d3f20cf70c93b4 (diff) |
qlcnic: fix beacon and LED test.
o Updated version number to 5.0.25
o Do not hold onto RESETTING_BIT for entire duration of LED/ beacon test.
Instead, just checking for RESETTING_BIT not set before sending config_led
command down to card.
o Take rtnl_lock instead of RESETTING_BIT for beacon test while sending
config_led command down to make sure interface cannot be brought up/ down.
o Allocate and free resources if interface is down before
sending the config_led command. This is to make sure config_led
command sending doesn't fail.
o Clear QLCNIC_LED_ENABLE bit if beacon/ LED test fails to start.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 5d8bec283267..8aa1c6e8667b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -935,31 +935,49 @@ static int qlcnic_set_led(struct net_device *dev, { struct qlcnic_adapter *adapter = netdev_priv(dev); int max_sds_rings = adapter->max_sds_rings; + int err = -EIO, active = 1; + + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { + netdev_warn(dev, "LED test not supported for non " + "privilege function\n"); + return -EOPNOTSUPP; + } switch (state) { case ETHTOOL_ID_ACTIVE: if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) return -EBUSY; - if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { - if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) - return -EIO; + if (test_bit(__QLCNIC_RESETTING, &adapter->state)) + break; - if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) { - clear_bit(__QLCNIC_RESETTING, &adapter->state); - return -EIO; - } + if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { + if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) + break; set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); } - if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) - return 0; + if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) { + err = 0; + break; + } dev_err(&adapter->pdev->dev, "Failed to set LED blink state.\n"); break; case ETHTOOL_ID_INACTIVE: + active = 0; + + if (test_bit(__QLCNIC_RESETTING, &adapter->state)) + break; + + if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { + if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) + break; + set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); + } + if (adapter->nic_ops->config_led(adapter, 0, 0xf)) dev_err(&adapter->pdev->dev, "Failed to reset LED blink state.\n"); @@ -970,14 +988,13 @@ static int qlcnic_set_led(struct net_device *dev, return -EINVAL; } - if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) { + if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) qlcnic_diag_free_res(dev, max_sds_rings); - clear_bit(__QLCNIC_RESETTING, &adapter->state); - } - clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); + if (!active || err) + clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); - return -EIO; + return err; } static void |