e1000: Fixes for packet split related issues
[powerpc.git] / drivers / net / e1000 / e1000_ethtool.c
index 237247f..183b583 100644 (file)
@@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter *adapter);
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
 extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 extern void e1000_update_stats(struct e1000_adapter *adapter);
 
 struct e1000_stats {
@@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
        { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
        { "rx_long_byte_count", E1000_STAT(stats.gorcl) },
        { "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
-       { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
+       { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
+       { "rx_header_split", E1000_STAT(rx_hdr_split) },
 };
 #define E1000_STATS_LEN        \
        sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
@@ -105,7 +106,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 static int
 e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        if(hw->media_type == e1000_media_type_copper) {
@@ -141,9 +142,9 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                                     SUPPORTED_FIBRE |
                                     SUPPORTED_Autoneg);
 
-               ecmd->advertising = (SUPPORTED_1000baseT_Full |
-                                    SUPPORTED_FIBRE |
-                                    SUPPORTED_Autoneg);
+               ecmd->advertising = (ADVERTISED_1000baseT_Full |
+                                    ADVERTISED_FIBRE |
+                                    ADVERTISED_Autoneg);
 
                ecmd->port = PORT_FIBRE;
 
@@ -179,13 +180,24 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 static int
 e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        if(ecmd->autoneg == AUTONEG_ENABLE) {
                hw->autoneg = 1;
-               hw->autoneg_advertised = 0x002F;
-               ecmd->advertising = 0x002F;
+               if(hw->media_type == e1000_media_type_fiber)
+                       hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
+                                    ADVERTISED_FIBRE |
+                                    ADVERTISED_Autoneg;
+               else 
+                       hw->autoneg_advertised = ADVERTISED_10baseT_Half |
+                                                 ADVERTISED_10baseT_Full |
+                                                 ADVERTISED_100baseT_Half |
+                                                 ADVERTISED_100baseT_Full |
+                                                 ADVERTISED_1000baseT_Full|
+                                                 ADVERTISED_Autoneg |
+                                                 ADVERTISED_TP;
+               ecmd->advertising = hw->autoneg_advertised;
        } else
                if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
                        return -EINVAL;
@@ -206,7 +218,7 @@ static void
 e1000_get_pauseparam(struct net_device *netdev,
                      struct ethtool_pauseparam *pause)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        pause->autoneg = 
@@ -226,7 +238,7 @@ static int
 e1000_set_pauseparam(struct net_device *netdev,
                      struct ethtool_pauseparam *pause)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        
        adapter->fc_autoneg = pause->autoneg;
@@ -259,14 +271,14 @@ e1000_set_pauseparam(struct net_device *netdev,
 static uint32_t
 e1000_get_rx_csum(struct net_device *netdev)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        return adapter->rx_csum;
 }
 
 static int
 e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        adapter->rx_csum = data;
 
        if(netif_running(netdev)) {
@@ -286,7 +298,7 @@ e1000_get_tx_csum(struct net_device *netdev)
 static int
 e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
 
        if(adapter->hw.mac_type < e1000_82543) {
                if (!data)
@@ -306,8 +318,8 @@ e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
 static int
 e1000_set_tso(struct net_device *netdev, uint32_t data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
-       if ((adapter->hw.mac_type < e1000_82544) ||
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       if((adapter->hw.mac_type < e1000_82544) ||
            (adapter->hw.mac_type == e1000_82547)) 
                return data ? -EINVAL : 0;
 
@@ -322,14 +334,14 @@ e1000_set_tso(struct net_device *netdev, uint32_t data)
 static uint32_t
 e1000_get_msglevel(struct net_device *netdev)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        return adapter->msg_enable;
 }
 
 static void
 e1000_set_msglevel(struct net_device *netdev, uint32_t data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        adapter->msg_enable = data;
 }
 
@@ -344,7 +356,7 @@ static void
 e1000_get_regs(struct net_device *netdev,
               struct ethtool_regs *regs, void *p)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        uint32_t *regs_buff = p;
        uint16_t phy_data;
@@ -432,7 +444,7 @@ e1000_get_regs(struct net_device *netdev,
 static int
 e1000_get_eeprom_len(struct net_device *netdev)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        return adapter->hw.eeprom.word_size * 2;
 }
 
@@ -440,7 +452,7 @@ static int
 e1000_get_eeprom(struct net_device *netdev,
                       struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        uint16_t *eeprom_buff;
        int first_word, last_word;
@@ -486,7 +498,7 @@ static int
 e1000_set_eeprom(struct net_device *netdev,
                       struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        uint16_t *eeprom_buff;
        void *ptr;
@@ -547,7 +559,7 @@ static void
 e1000_get_drvinfo(struct net_device *netdev,
                        struct ethtool_drvinfo *drvinfo)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
 
        strncpy(drvinfo->driver,  e1000_driver_name, 32);
        strncpy(drvinfo->version, e1000_driver_version, 32);
@@ -563,10 +575,10 @@ static void
 e1000_get_ringparam(struct net_device *netdev,
                     struct ethtool_ringparam *ring)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        e1000_mac_type mac_type = adapter->hw.mac_type;
-       struct e1000_desc_ring *txdr = &adapter->tx_ring;
-       struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+       struct e1000_tx_ring *txdr = adapter->tx_ring;
+       struct e1000_rx_ring *rxdr = adapter->rx_ring;
 
        ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
                E1000_MAX_82544_RXD;
@@ -584,22 +596,42 @@ static int
 e1000_set_ringparam(struct net_device *netdev,
                     struct ethtool_ringparam *ring)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        e1000_mac_type mac_type = adapter->hw.mac_type;
-       struct e1000_desc_ring *txdr = &adapter->tx_ring;
-       struct e1000_desc_ring *rxdr = &adapter->rx_ring;
-       struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
-       int err;
+       struct e1000_tx_ring *txdr, *tx_old, *tx_new;
+       struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+       int i, err, tx_ring_size, rx_ring_size;
+
+       tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+       rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+
+       if (netif_running(adapter->netdev))
+               e1000_down(adapter);
 
        tx_old = adapter->tx_ring;
        rx_old = adapter->rx_ring;
 
+       adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
+       if (!adapter->tx_ring) {
+               err = -ENOMEM;
+               goto err_setup_rx;
+       }
+       memset(adapter->tx_ring, 0, tx_ring_size);
+
+       adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
+       if (!adapter->rx_ring) {
+               kfree(adapter->tx_ring);
+               err = -ENOMEM;
+               goto err_setup_rx;
+       }
+       memset(adapter->rx_ring, 0, rx_ring_size);
+
+       txdr = adapter->tx_ring;
+       rxdr = adapter->rx_ring;
+
        if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
                return -EINVAL;
 
-       if(netif_running(adapter->netdev))
-               e1000_down(adapter);
-
        rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
        rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
                E1000_MAX_RXD : E1000_MAX_82544_RXD));
@@ -610,11 +642,16 @@ e1000_set_ringparam(struct net_device *netdev,
                E1000_MAX_TXD : E1000_MAX_82544_TXD));
        E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 
 
+       for (i = 0; i < adapter->num_queues; i++) {
+               txdr[i].count = txdr->count;
+               rxdr[i].count = rxdr->count;
+       }
+
        if(netif_running(adapter->netdev)) {
                /* Try to get new resources before deleting old */
-               if((err = e1000_setup_rx_resources(adapter)))
+               if ((err = e1000_setup_all_rx_resources(adapter)))
                        goto err_setup_rx;
-               if((err = e1000_setup_tx_resources(adapter)))
+               if ((err = e1000_setup_all_tx_resources(adapter)))
                        goto err_setup_tx;
 
                /* save the new, restore the old in order to free it,
@@ -624,8 +661,10 @@ e1000_set_ringparam(struct net_device *netdev,
                tx_new = adapter->tx_ring;
                adapter->rx_ring = rx_old;
                adapter->tx_ring = tx_old;
-               e1000_free_rx_resources(adapter);
-               e1000_free_tx_resources(adapter);
+               e1000_free_all_rx_resources(adapter);
+               e1000_free_all_tx_resources(adapter);
+               kfree(tx_old);
+               kfree(rx_old);
                adapter->rx_ring = rx_new;
                adapter->tx_ring = tx_new;
                if((err = e1000_up(adapter)))
@@ -634,7 +673,7 @@ e1000_set_ringparam(struct net_device *netdev,
 
        return 0;
 err_setup_tx:
-       e1000_free_rx_resources(adapter);
+       e1000_free_all_rx_resources(adapter);
 err_setup_rx:
        adapter->rx_ring = rx_old;
        adapter->tx_ring = tx_old;
@@ -651,6 +690,9 @@ err_setup_rx:
                E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
                value = E1000_READ_REG(&adapter->hw, R);                       \
                if(value != (test[pat] & W & M)) {                             \
+                       DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
+                               "0x%08X expected 0x%08X\n",                    \
+                               E1000_##R, value, (test[pat] & W & M));        \
                        *data = (adapter->hw.mac_type < e1000_82543) ?         \
                                E1000_82542_##R : E1000_##R;                   \
                        return 1;                                              \
@@ -663,7 +705,9 @@ err_setup_rx:
        uint32_t value;                                                        \
        E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
        value = E1000_READ_REG(&adapter->hw, R);                               \
-       if ((W & M) != (value & M)) {                                          \
+       if((W & M) != (value & M)) {                                          \
+               DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
+                       "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
                *data = (adapter->hw.mac_type < e1000_82543) ?                 \
                        E1000_82542_##R : E1000_##R;                           \
                return 1;                                                      \
@@ -673,18 +717,38 @@ err_setup_rx:
 static int
 e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
 {
-       uint32_t value;
-       uint32_t i;
+       uint32_t value, before, after;
+       uint32_t i, toggle;
 
        /* The status register is Read Only, so a write should fail.
         * Some bits that get toggled are ignored.
         */
-       value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833));
-       E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF));
-       if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) {
+        switch (adapter->hw.mac_type) {
+       /* there are several bits on newer hardware that are r/w */
+       case e1000_82571:
+       case e1000_82572:
+               toggle = 0x7FFFF3FF;
+               break;
+       case e1000_82573:
+               toggle = 0x7FFFF033;
+               break;
+       default:
+               toggle = 0xFFFFF833;
+               break;
+       }
+
+       before = E1000_READ_REG(&adapter->hw, STATUS);
+       value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
+       E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
+       after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
+       if(value != after) {
+               DPRINTK(DRV, ERR, "failed STATUS register test got: "
+                       "0x%08X expected: 0x%08X\n", after, value);
                *data = 1;
                return 1;
        }
+       /* restore previous status */
+       E1000_WRITE_REG(&adapter->hw, STATUS, before);
 
        REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
        REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
@@ -766,7 +830,7 @@ e1000_test_intr(int irq,
                struct pt_regs *regs)
 {
        struct net_device *netdev = (struct net_device *) data;
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
 
        adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
 
@@ -867,8 +931,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
 static void
 e1000_free_desc_rings(struct e1000_adapter *adapter)
 {
-       struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-       struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+       struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+       struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
        int i;
 
@@ -910,8 +974,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
 static int
 e1000_setup_desc_rings(struct e1000_adapter *adapter)
 {
-       struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-       struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+       struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+       struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
        uint32_t rctl;
        int size, i, ret_val;
@@ -1214,6 +1278,9 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
        case e1000_82541_rev_2:
        case e1000_82547:
        case e1000_82547_rev_2:
+       case e1000_82571:
+       case e1000_82572:
+       case e1000_82573:
                return e1000_integrated_phy_loopback(adapter);
                break;
 
@@ -1308,8 +1375,8 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
 static int
 e1000_run_loopback_test(struct e1000_adapter *adapter)
 {
-       struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-       struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+       struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+       struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
        int i, j, k, l, lc, good_cnt, ret_val=0;
        unsigned long time;
@@ -1422,7 +1489,7 @@ static void
 e1000_diag_test(struct net_device *netdev,
                   struct ethtool_test *eth_test, uint64_t *data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        boolean_t if_running = netif_running(netdev);
 
        if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
@@ -1482,7 +1549,7 @@ e1000_diag_test(struct net_device *netdev,
 static void
 e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        switch(adapter->hw.device_id) {
@@ -1527,7 +1594,7 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 static int
 e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        switch(adapter->hw.device_id) {
@@ -1588,22 +1655,31 @@ e1000_led_blink_callback(unsigned long data)
 static int
 e1000_phys_id(struct net_device *netdev, uint32_t data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
 
        if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
                data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
 
-       if(!adapter->blink_timer.function) {
-               init_timer(&adapter->blink_timer);
-               adapter->blink_timer.function = e1000_led_blink_callback;
-               adapter->blink_timer.data = (unsigned long) adapter;
+       if(adapter->hw.mac_type < e1000_82571) {
+               if(!adapter->blink_timer.function) {
+                       init_timer(&adapter->blink_timer);
+                       adapter->blink_timer.function = e1000_led_blink_callback;
+                       adapter->blink_timer.data = (unsigned long) adapter;
+               }
+               e1000_setup_led(&adapter->hw);
+               mod_timer(&adapter->blink_timer, jiffies);
+               msleep_interruptible(data * 1000);
+               del_timer_sync(&adapter->blink_timer);
+       }
+       else {
+               E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
+                       E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
+                       (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+                       (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
+                       (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
+               msleep_interruptible(data * 1000);
        }
 
-       e1000_setup_led(&adapter->hw);
-       mod_timer(&adapter->blink_timer, jiffies);
-
-       msleep_interruptible(data * 1000);
-       del_timer_sync(&adapter->blink_timer);
        e1000_led_off(&adapter->hw);
        clear_bit(E1000_LED_ON, &adapter->led_status);
        e1000_cleanup_led(&adapter->hw);
@@ -1614,7 +1690,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
 static int
 e1000_nway_reset(struct net_device *netdev)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        if(netif_running(netdev)) {
                e1000_down(adapter);
                e1000_up(adapter);
@@ -1632,7 +1708,7 @@ static void
 e1000_get_ethtool_stats(struct net_device *netdev, 
                struct ethtool_stats *stats, uint64_t *data)
 {
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        int i;
 
        e1000_update_stats(adapter);
@@ -1698,6 +1774,7 @@ struct ethtool_ops e1000_ethtool_ops = {
        .phys_id                = e1000_phys_id,
        .get_stats_count        = e1000_get_stats_count,
        .get_ethtool_stats      = e1000_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 void e1000_set_ethtool_ops(struct net_device *netdev)