diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/ethtool.c')
-rw-r--r-- | drivers/net/ethernet/sfc/ethtool.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 229428915aa..0de8b07c24c 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -251,6 +251,9 @@ static void efx_fill_test(unsigned int test_index, u8 *strings, u64 *data, * @test_index: Starting index of the test * @strings: Ethtool strings, or %NULL * @data: Ethtool test results, or %NULL + * + * Fill in a block of loopback self-test entries. Return new test + * index. */ static int efx_fill_loopback_test(struct efx_nic *efx, struct efx_loopback_self_tests *lb_tests, @@ -290,6 +293,12 @@ static int efx_fill_loopback_test(struct efx_nic *efx, * @tests: Efx self-test results structure, or %NULL * @strings: Ethtool strings, or %NULL * @data: Ethtool test results, or %NULL + * + * Get self-test number of strings, strings, and/or test results. + * Return number of strings (== number of test results). + * + * The reason for merging these three functions is to make sure that + * they can never be inconsistent. */ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, struct efx_self_tests *tests, @@ -444,7 +453,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_self_tests *efx_tests; - int already_up; + bool already_up; int rc = -ENOMEM; efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); @@ -452,8 +461,8 @@ static void efx_ethtool_self_test(struct net_device *net_dev, goto fail; if (efx->state != STATE_READY) { - rc = -EIO; - goto fail1; + rc = -EBUSY; + goto out; } netif_info(efx, drv, efx->net_dev, "starting %sline testing\n", @@ -466,7 +475,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev, if (rc) { netif_err(efx, drv, efx->net_dev, "failed opening device.\n"); - goto fail1; + goto out; } } @@ -479,8 +488,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev, rc == 0 ? "passed" : "failed", (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); -fail1: - /* Fill ethtool results structures */ +out: efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data); kfree(efx_tests); fail: @@ -691,7 +699,6 @@ static void efx_ethtool_get_pauseparam(struct net_device *net_dev, pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO); } - static void efx_ethtool_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) { @@ -720,7 +727,7 @@ static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) } /* MAC address mask including only I/G bit */ -static const u8 mac_addr_ig_mask[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; +static const u8 mac_addr_ig_mask[ETH_ALEN] __aligned(2) = {0x01, 0, 0, 0, 0, 0}; #define IP4_ADDR_FULL_MASK ((__force __be32)~0) #define PORT_FULL_MASK ((__force __be16)~0) @@ -780,16 +787,16 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx, rule->flow_type = ETHER_FLOW; if (spec.match_flags & (EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG)) { - memcpy(mac_entry->h_dest, spec.loc_mac, ETH_ALEN); + ether_addr_copy(mac_entry->h_dest, spec.loc_mac); if (spec.match_flags & EFX_FILTER_MATCH_LOC_MAC) - memset(mac_mask->h_dest, ~0, ETH_ALEN); + eth_broadcast_addr(mac_mask->h_dest); else - memcpy(mac_mask->h_dest, mac_addr_ig_mask, - ETH_ALEN); + ether_addr_copy(mac_mask->h_dest, + mac_addr_ig_mask); } if (spec.match_flags & EFX_FILTER_MATCH_REM_MAC) { - memcpy(mac_entry->h_source, spec.rem_mac, ETH_ALEN); - memset(mac_mask->h_source, ~0, ETH_ALEN); + ether_addr_copy(mac_entry->h_source, spec.rem_mac); + eth_broadcast_addr(mac_mask->h_source); } if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) { mac_entry->h_proto = spec.ether_type; @@ -961,13 +968,13 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC; else return -EINVAL; - memcpy(spec.loc_mac, mac_entry->h_dest, ETH_ALEN); + ether_addr_copy(spec.loc_mac, mac_entry->h_dest); } if (!is_zero_ether_addr(mac_mask->h_source)) { if (!is_broadcast_ether_addr(mac_mask->h_source)) return -EINVAL; spec.match_flags |= EFX_FILTER_MATCH_REM_MAC; - memcpy(spec.rem_mac, mac_entry->h_source, ETH_ALEN); + ether_addr_copy(spec.rem_mac, mac_entry->h_source); } if (mac_mask->h_proto) { if (mac_mask->h_proto != ETHER_TYPE_FULL_MASK) |