Messages in this thread Patch in this message | | | From | David Decotigny <> | Subject | [PATCH net-next v1 2/4] net-e1000e: enable ethtool loopback support | Date | Mon, 21 Nov 2011 15:19:58 -0800 |
| |
This allows ethtool to activate loopback via the get/set_features API.
Tested: - HW = 80003ES2LAN (copper), x86_64 - incoming external 200Mbps, loopback on/off, verified that incoming stream resumed - incoming external 200Mbps, ifconfig down, loopback on/off, ifconfig up, verified that incoming stream resumed - incoming external 200Mbps, loopback on, ifconfig down, loopback off, ifconfig up, verified that incoming stream resumed - the same with a pktgen when loopback is enabled: verifying that tx_packets = rx_packets + rx_missed_errors, and that tx_packets is very close to pktgen_packets (1 or 2 packets difference, not more). Note that rx_missed_errors >> 0 - artificially simulated failure of enabling loopback -> reported by set_features and kept loopback feature marked as not configured.
Signed-off-by: David Decotigny <david.decotigny@google.com> --- drivers/net/ethernet/intel/e1000e/e1000.h | 2 ++ drivers/net/ethernet/intel/e1000e/ethtool.c | 6 +++--- drivers/net/ethernet/intel/e1000e/netdev.c | 21 ++++++++++++++++++++- 3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 9fe18d1..786cf31 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -485,6 +485,8 @@ extern const char e1000e_driver_version[]; extern void e1000e_check_options(struct e1000_adapter *adapter); extern void e1000e_set_ethtool_ops(struct net_device *netdev); +extern int e1000_loopback_setup(struct e1000_adapter *adapter); +extern void e1000_loopback_cleanup(struct e1000_adapter *adapter); extern int e1000e_up(struct e1000_adapter *adapter); extern void e1000e_down(struct e1000_adapter *adapter); diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index fb2c28e..259add2 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1410,7 +1410,7 @@ static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter) return 0; } -static int e1000_setup_loopback_test(struct e1000_adapter *adapter) +int e1000_loopback_setup(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl; @@ -1438,7 +1438,7 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter) return 7; } -static void e1000_loopback_cleanup(struct e1000_adapter *adapter) +void e1000_loopback_cleanup(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl; @@ -1593,7 +1593,7 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data) if (*data) goto out; - *data = e1000_setup_loopback_test(adapter); + *data = e1000_loopback_setup(adapter); if (*data) goto err_loopback; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index b63f316..25102e6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3256,6 +3256,14 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000_configure_rx(adapter); adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), GFP_KERNEL); + + if (adapter->netdev->features & NETIF_F_LOOPBACK) { + if (e1000_loopback_setup(adapter)) { + e_warn("Could not activate loopback mode\n"); + adapter->netdev->features &= ~NETIF_F_LOOPBACK; + } else + e_info("Loopback mode activated\n"); + } } /** @@ -5914,9 +5922,17 @@ static int e1000_set_features(struct net_device *netdev, adapter->flags |= FLAG_TSO_FORCE; if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | - NETIF_F_RXCSUM))) + NETIF_F_RXCSUM | NETIF_F_LOOPBACK))) return retval; + /* disable loopback if requested */ + if ((changed & NETIF_F_LOOPBACK) && (!(features & NETIF_F_LOOPBACK))) { + netdev_dbg(netdev, "Disabling loopback mode\n"); + e1000_loopback_cleanup(adapter); + } + /* otherwise loopback is enabled via e1000e_reinit_locked + * below and each time the device is up'ed */ + if (netif_running(netdev)) e1000e_reinit_locked(adapter); else @@ -6113,6 +6129,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* Set user-changeable features (subset of all device features) */ netdev->hw_features = netdev->features; + /* Add capabilities, disabled by default */ + netdev->hw_features |= NETIF_F_LOOPBACK; + if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) netdev->features |= NETIF_F_HW_VLAN_FILTER; -- 1.7.3.1
| |