diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 5e0051b94ae7..48a96ed6b7d0 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -68,54 +68,6 @@ static void efx_ethtool_get_regs(struct net_device *net_dev, efx_nic_get_regs(efx, buf); } -static void efx_ethtool_self_test(struct net_device *net_dev, - struct ethtool_test *test, u64 *data) -{ - struct efx_nic *efx = netdev_priv(net_dev); - struct efx_self_tests *efx_tests; - bool already_up; - int rc = -ENOMEM; - - efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); - if (!efx_tests) - goto fail; - - if (efx->state != STATE_READY) { - rc = -EBUSY; - goto out; - } - - netif_info(efx, drv, efx->net_dev, "starting %sline testing\n", - (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); - - /* We need rx buffers and interrupts. */ - already_up = (efx->net_dev->flags & IFF_UP); - if (!already_up) { - rc = dev_open(efx->net_dev, NULL); - if (rc) { - netif_err(efx, drv, efx->net_dev, - "failed opening device.\n"); - goto out; - } - } - - rc = efx_selftest(efx, efx_tests, test->flags); - - if (!already_up) - dev_close(efx->net_dev); - - netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n", - rc == 0 ? "passed" : "failed", - (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); - -out: - efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data); - kfree(efx_tests); -fail: - if (rc) - test->flags |= ETH_TEST_FL_FAILED; -} - /* * Each channel has a single IRQ and moderation timer, started by any * completion (or other event). Unless the module parameter @@ -255,18 +207,6 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, return efx->type->set_wol(efx, wol->wolopts); } -static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) -{ - struct efx_nic *efx = netdev_priv(net_dev); - int rc; - - rc = efx->type->map_reset_flags(flags); - if (rc < 0) - return rc; - - return efx_reset(efx, rc); -} - static int efx_ethtool_get_ts_info(struct net_device *net_dev, struct ethtool_ts_info *ts_info) { @@ -281,39 +221,6 @@ static int efx_ethtool_get_ts_info(struct net_device *net_dev, return 0; } -static int efx_ethtool_get_module_eeprom(struct net_device *net_dev, - struct ethtool_eeprom *ee, - u8 *data) -{ - struct efx_nic *efx = netdev_priv(net_dev); - int ret; - - if (!efx->phy_op || !efx->phy_op->get_module_eeprom) - return -EOPNOTSUPP; - - mutex_lock(&efx->mac_lock); - ret = efx->phy_op->get_module_eeprom(efx, ee, data); - mutex_unlock(&efx->mac_lock); - - return ret; -} - -static int efx_ethtool_get_module_info(struct net_device *net_dev, - struct ethtool_modinfo *modinfo) -{ - struct efx_nic *efx = netdev_priv(net_dev); - int ret; - - if (!efx->phy_op || !efx->phy_op->get_module_info) - return -EOPNOTSUPP; - - mutex_lock(&efx->mac_lock); - ret = efx->phy_op->get_module_info(efx, modinfo); - mutex_unlock(&efx->mac_lock); - - return ret; -} - const struct ethtool_ops efx_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_USECS_IRQ | diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c index d7d8795eb1d3..c96595e50234 100644 --- a/drivers/net/ethernet/sfc/ethtool_common.c +++ b/drivers/net/ethernet/sfc/ethtool_common.c @@ -125,6 +125,54 @@ void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable) efx->msg_enable = msg_enable; } +void efx_ethtool_self_test(struct net_device *net_dev, + struct ethtool_test *test, u64 *data) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct efx_self_tests *efx_tests; + bool already_up; + int rc = -ENOMEM; + + efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); + if (!efx_tests) + goto fail; + + if (efx->state != STATE_READY) { + rc = -EBUSY; + goto out; + } + + netif_info(efx, drv, efx->net_dev, "starting %sline testing\n", + (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); + + /* We need rx buffers and interrupts. */ + already_up = (efx->net_dev->flags & IFF_UP); + if (!already_up) { + rc = dev_open(efx->net_dev, NULL); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed opening device.\n"); + goto out; + } + } + + rc = efx_selftest(efx, efx_tests, test->flags); + + if (!already_up) + dev_close(efx->net_dev); + + netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n", + rc == 0 ? "passed" : "failed", + (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); + +out: + efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data); + kfree(efx_tests); +fail: + if (rc) + test->flags |= ETH_TEST_FL_FAILED; +} + /* Restart autonegotiation */ int efx_ethtool_nway_reset(struct net_device *net_dev) { @@ -1273,3 +1321,48 @@ int efx_ethtool_set_rxfh_context(struct net_device *net_dev, mutex_unlock(&efx->rss_lock); return rc; } + +int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) +{ + struct efx_nic *efx = netdev_priv(net_dev); + int rc; + + rc = efx->type->map_reset_flags(flags); + if (rc < 0) + return rc; + + return efx_reset(efx, rc); +} + +int efx_ethtool_get_module_eeprom(struct net_device *net_dev, + struct ethtool_eeprom *ee, + u8 *data) +{ + struct efx_nic *efx = netdev_priv(net_dev); + int ret; + + if (!efx->phy_op || !efx->phy_op->get_module_eeprom) + return -EOPNOTSUPP; + + mutex_lock(&efx->mac_lock); + ret = efx->phy_op->get_module_eeprom(efx, ee, data); + mutex_unlock(&efx->mac_lock); + + return ret; +} + +int efx_ethtool_get_module_info(struct net_device *net_dev, + struct ethtool_modinfo *modinfo) +{ + struct efx_nic *efx = netdev_priv(net_dev); + int ret; + + if (!efx->phy_op || !efx->phy_op->get_module_info) + return -EOPNOTSUPP; + + mutex_lock(&efx->mac_lock); + ret = efx->phy_op->get_module_info(efx, modinfo); + mutex_unlock(&efx->mac_lock); + + return ret; +} diff --git a/drivers/net/ethernet/sfc/ethtool_common.h b/drivers/net/ethernet/sfc/ethtool_common.h index 024a78ce0905..7bfbbd08a1ef 100644 --- a/drivers/net/ethernet/sfc/ethtool_common.h +++ b/drivers/net/ethernet/sfc/ethtool_common.h @@ -15,6 +15,8 @@ void efx_ethtool_get_drvinfo(struct net_device *net_dev, struct ethtool_drvinfo *info); u32 efx_ethtool_get_msglevel(struct net_device *net_dev); void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable); +void efx_ethtool_self_test(struct net_device *net_dev, + struct ethtool_test *test, u64 *data); int efx_ethtool_nway_reset(struct net_device *net_dev); void efx_ethtool_get_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause); @@ -53,4 +55,10 @@ int efx_ethtool_set_rxfh_context(struct net_device *net_dev, const u32 *indir, const u8 *key, const u8 hfunc, u32 *rss_context, bool delete); +int efx_ethtool_reset(struct net_device *net_dev, u32 *flags); +int efx_ethtool_get_module_eeprom(struct net_device *net_dev, + struct ethtool_eeprom *ee, + u8 *data); +int efx_ethtool_get_module_info(struct net_device *net_dev, + struct ethtool_modinfo *modinfo); #endif