diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_ethtool.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ethtool.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 3ea04e7..72a723d 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -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); |