aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic
diff options
context:
space:
mode:
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>2011-10-28 08:57:15 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-30 03:09:41 -0400
commit10ee0faed92c8af4baebd633372136a6608a41ea (patch)
treebd9390dfecf81ec40c2cdb12f97d4c7e7224132e /drivers/net/ethernet/qlogic
parent445b62dfd934394807c12aee06d3f20cf70c93b4 (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')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c45
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c39
3 files changed, 57 insertions, 31 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 2fd1ba8fee4a..7ed53dbb8646 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
36 36
37#define _QLCNIC_LINUX_MAJOR 5 37#define _QLCNIC_LINUX_MAJOR 5
38#define _QLCNIC_LINUX_MINOR 0 38#define _QLCNIC_LINUX_MINOR 0
39#define _QLCNIC_LINUX_SUBVERSION 24 39#define _QLCNIC_LINUX_SUBVERSION 25
40#define QLCNIC_LINUX_VERSIONID "5.0.24" 40#define QLCNIC_LINUX_VERSIONID "5.0.25"
41#define QLCNIC_DRV_IDC_VER 0x01 41#define QLCNIC_DRV_IDC_VER 0x01
42#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ 42#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
43 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) 43 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
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,
935{ 935{
936 struct qlcnic_adapter *adapter = netdev_priv(dev); 936 struct qlcnic_adapter *adapter = netdev_priv(dev);
937 int max_sds_rings = adapter->max_sds_rings; 937 int max_sds_rings = adapter->max_sds_rings;
938 int err = -EIO, active = 1;
939
940 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
941 netdev_warn(dev, "LED test not supported for non "
942 "privilege function\n");
943 return -EOPNOTSUPP;
944 }
938 945
939 switch (state) { 946 switch (state) {
940 case ETHTOOL_ID_ACTIVE: 947 case ETHTOOL_ID_ACTIVE:
941 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) 948 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
942 return -EBUSY; 949 return -EBUSY;
943 950
944 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 951 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
945 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 952 break;
946 return -EIO;
947 953
948 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) { 954 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
949 clear_bit(__QLCNIC_RESETTING, &adapter->state); 955 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
950 return -EIO; 956 break;
951 }
952 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); 957 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
953 } 958 }
954 959
955 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) 960 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
956 return 0; 961 err = 0;
962 break;
963 }
957 964
958 dev_err(&adapter->pdev->dev, 965 dev_err(&adapter->pdev->dev,
959 "Failed to set LED blink state.\n"); 966 "Failed to set LED blink state.\n");
960 break; 967 break;
961 968
962 case ETHTOOL_ID_INACTIVE: 969 case ETHTOOL_ID_INACTIVE:
970 active = 0;
971
972 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
973 break;
974
975 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
976 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
977 break;
978 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
979 }
980
963 if (adapter->nic_ops->config_led(adapter, 0, 0xf)) 981 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
964 dev_err(&adapter->pdev->dev, 982 dev_err(&adapter->pdev->dev,
965 "Failed to reset LED blink state.\n"); 983 "Failed to reset LED blink state.\n");
@@ -970,14 +988,13 @@ static int qlcnic_set_led(struct net_device *dev,
970 return -EINVAL; 988 return -EINVAL;
971 } 989 }
972 990
973 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) { 991 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
974 qlcnic_diag_free_res(dev, max_sds_rings); 992 qlcnic_diag_free_res(dev, max_sds_rings);
975 clear_bit(__QLCNIC_RESETTING, &adapter->state);
976 }
977 993
978 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); 994 if (!active || err)
995 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
979 996
980 return -EIO; 997 return err;
981} 998}
982 999
983static void 1000static void
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 2edffcec930f..0bd163828e33 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3504,11 +3504,16 @@ qlcnic_store_beacon(struct device *dev,
3504{ 3504{
3505 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 3505 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3506 int max_sds_rings = adapter->max_sds_rings; 3506 int max_sds_rings = adapter->max_sds_rings;
3507 int dev_down = 0;
3508 u16 beacon; 3507 u16 beacon;
3509 u8 b_state, b_rate; 3508 u8 b_state, b_rate;
3510 int err; 3509 int err;
3511 3510
3511 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
3512 dev_warn(dev, "LED test not supported for non "
3513 "privilege function\n");
3514 return -EOPNOTSUPP;
3515 }
3516
3512 if (len != sizeof(u16)) 3517 if (len != sizeof(u16))
3513 return QL_STATUS_INVALID_PARAM; 3518 return QL_STATUS_INVALID_PARAM;
3514 3519
@@ -3520,36 +3525,40 @@ qlcnic_store_beacon(struct device *dev,
3520 if (adapter->ahw->beacon_state == b_state) 3525 if (adapter->ahw->beacon_state == b_state)
3521 return len; 3526 return len;
3522 3527
3528 rtnl_lock();
3529
3523 if (!adapter->ahw->beacon_state) 3530 if (!adapter->ahw->beacon_state)
3524 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) 3531 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
3532 rtnl_unlock();
3525 return -EBUSY; 3533 return -EBUSY;
3534 }
3535
3536 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
3537 err = -EIO;
3538 goto out;
3539 }
3526 3540
3527 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 3541 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
3528 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
3529 return -EIO;
3530 err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST); 3542 err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
3531 if (err) { 3543 if (err)
3532 clear_bit(__QLCNIC_RESETTING, &adapter->state); 3544 goto out;
3533 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); 3545 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
3534 return err;
3535 }
3536 dev_down = 1;
3537 } 3546 }
3538 3547
3539 err = qlcnic_config_led(adapter, b_state, b_rate); 3548 err = qlcnic_config_led(adapter, b_state, b_rate);
3540 3549
3541 if (!err) { 3550 if (!err) {
3542 adapter->ahw->beacon_state = b_state;
3543 err = len; 3551 err = len;
3552 adapter->ahw->beacon_state = b_state;
3544 } 3553 }
3545 3554
3546 if (dev_down) { 3555 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
3547 qlcnic_diag_free_res(adapter->netdev, max_sds_rings); 3556 qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
3548 clear_bit(__QLCNIC_RESETTING, &adapter->state);
3549 }
3550 3557
3551 if (!b_state) 3558 out:
3559 if (!adapter->ahw->beacon_state)
3552 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); 3560 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
3561 rtnl_unlock();
3553 3562
3554 return err; 3563 return err;
3555} 3564}