linux/drivers/net/pch_gbe/pch_gbe_ethtool.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1999 - 2010 Intel Corporation.
   3 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
   4 *
   5 * This code was derived from the Intel e1000e Linux driver.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; version 2 of the License.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
  19 */
  20#include "pch_gbe.h"
  21#include "pch_gbe_api.h"
  22
  23/**
  24 * pch_gbe_stats - Stats item infomation
  25 */
  26struct pch_gbe_stats {
  27        char string[ETH_GSTRING_LEN];
  28        size_t size;
  29        size_t offset;
  30};
  31
  32#define PCH_GBE_STAT(m)                                         \
  33{                                                               \
  34        .string = #m,                                           \
  35        .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m),       \
  36        .offset = offsetof(struct pch_gbe_hw_stats, m),         \
  37}
  38
  39/**
  40 * pch_gbe_gstrings_stats - ethtool information status name list
  41 */
  42static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {
  43        PCH_GBE_STAT(rx_packets),
  44        PCH_GBE_STAT(tx_packets),
  45        PCH_GBE_STAT(rx_bytes),
  46        PCH_GBE_STAT(tx_bytes),
  47        PCH_GBE_STAT(rx_errors),
  48        PCH_GBE_STAT(tx_errors),
  49        PCH_GBE_STAT(rx_dropped),
  50        PCH_GBE_STAT(tx_dropped),
  51        PCH_GBE_STAT(multicast),
  52        PCH_GBE_STAT(collisions),
  53        PCH_GBE_STAT(rx_crc_errors),
  54        PCH_GBE_STAT(rx_frame_errors),
  55        PCH_GBE_STAT(rx_alloc_buff_failed),
  56        PCH_GBE_STAT(tx_length_errors),
  57        PCH_GBE_STAT(tx_aborted_errors),
  58        PCH_GBE_STAT(tx_carrier_errors),
  59        PCH_GBE_STAT(tx_timeout_count),
  60        PCH_GBE_STAT(tx_restart_count),
  61        PCH_GBE_STAT(intr_rx_dsc_empty_count),
  62        PCH_GBE_STAT(intr_rx_frame_err_count),
  63        PCH_GBE_STAT(intr_rx_fifo_err_count),
  64        PCH_GBE_STAT(intr_rx_dma_err_count),
  65        PCH_GBE_STAT(intr_tx_fifo_err_count),
  66        PCH_GBE_STAT(intr_tx_dma_err_count),
  67        PCH_GBE_STAT(intr_tcpip_err_count)
  68};
  69
  70#define PCH_GBE_QUEUE_STATS_LEN 0
  71#define PCH_GBE_GLOBAL_STATS_LEN        ARRAY_SIZE(pch_gbe_gstrings_stats)
  72#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
  73
  74#define PCH_GBE_MAC_REGS_LEN    (sizeof(struct pch_gbe_regs) / 4)
  75#define PCH_GBE_REGS_LEN        (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
  76/**
  77 * pch_gbe_get_settings - Get device-specific settings
  78 * @netdev: Network interface device structure
  79 * @ecmd:   Ethtool command
  80 * Returns
  81 *      0:                      Successful.
  82 *      Negative value:         Failed.
  83 */
  84static int pch_gbe_get_settings(struct net_device *netdev,
  85                                 struct ethtool_cmd *ecmd)
  86{
  87        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
  88        int ret;
  89
  90        ret = mii_ethtool_gset(&adapter->mii, ecmd);
  91        ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);
  92        ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
  93
  94        if (!netif_carrier_ok(adapter->netdev))
  95                ecmd->speed = -1;
  96        return ret;
  97}
  98
  99/**
 100 * pch_gbe_set_settings - Set device-specific settings
 101 * @netdev: Network interface device structure
 102 * @ecmd:   Ethtool command
 103 * Returns
 104 *      0:                      Successful.
 105 *      Negative value:         Failed.
 106 */
 107static int pch_gbe_set_settings(struct net_device *netdev,
 108                                 struct ethtool_cmd *ecmd)
 109{
 110        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 111        struct pch_gbe_hw *hw = &adapter->hw;
 112        int ret;
 113
 114        pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
 115
 116        if (ecmd->speed == USHRT_MAX) {
 117                ecmd->speed = SPEED_1000;
 118                ecmd->duplex = DUPLEX_FULL;
 119        }
 120        ret = mii_ethtool_sset(&adapter->mii, ecmd);
 121        if (ret) {
 122                pr_err("Error: mii_ethtool_sset\n");
 123                return ret;
 124        }
 125        hw->mac.link_speed = ecmd->speed;
 126        hw->mac.link_duplex = ecmd->duplex;
 127        hw->phy.autoneg_advertised = ecmd->advertising;
 128        hw->mac.autoneg = ecmd->autoneg;
 129        pch_gbe_hal_phy_sw_reset(hw);
 130
 131        /* reset the link */
 132        if (netif_running(adapter->netdev)) {
 133                pch_gbe_down(adapter);
 134                ret = pch_gbe_up(adapter);
 135        } else {
 136                pch_gbe_reset(adapter);
 137        }
 138        return ret;
 139}
 140
 141/**
 142 * pch_gbe_get_regs_len - Report the size of device registers
 143 * @netdev: Network interface device structure
 144 * Returns: the size of device registers.
 145 */
 146static int pch_gbe_get_regs_len(struct net_device *netdev)
 147{
 148        return PCH_GBE_REGS_LEN * (int)sizeof(u32);
 149}
 150
 151/**
 152 * pch_gbe_get_drvinfo - Report driver information
 153 * @netdev:  Network interface device structure
 154 * @drvinfo: Driver information structure
 155 */
 156static void pch_gbe_get_drvinfo(struct net_device *netdev,
 157                                 struct ethtool_drvinfo *drvinfo)
 158{
 159        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 160
 161        strcpy(drvinfo->driver, KBUILD_MODNAME);
 162        strcpy(drvinfo->version, pch_driver_version);
 163        strcpy(drvinfo->fw_version, "N/A");
 164        strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
 165        drvinfo->regdump_len = pch_gbe_get_regs_len(netdev);
 166}
 167
 168/**
 169 * pch_gbe_get_regs - Get device registers
 170 * @netdev: Network interface device structure
 171 * @regs:   Ethtool register structure
 172 * @p:      Buffer pointer of read device register date
 173 */
 174static void pch_gbe_get_regs(struct net_device *netdev,
 175                                struct ethtool_regs *regs, void *p)
 176{
 177        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 178        struct pch_gbe_hw *hw = &adapter->hw;
 179        struct pci_dev *pdev = adapter->pdev;
 180        u32 *regs_buff = p;
 181        u16 i, tmp;
 182
 183        regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;
 184        for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)
 185                *regs_buff++ = ioread32(&hw->reg->INT_ST + i);
 186        /* PHY register */
 187        for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {
 188                pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp);
 189                *regs_buff++ = tmp;
 190        }
 191}
 192
 193/**
 194 * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
 195 * @netdev: Network interface device structure
 196 * @wol:    Wake-on-Lan information
 197 */
 198static void pch_gbe_get_wol(struct net_device *netdev,
 199                                struct ethtool_wolinfo *wol)
 200{
 201        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 202
 203        wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
 204        wol->wolopts = 0;
 205
 206        if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))
 207                wol->wolopts |= WAKE_UCAST;
 208        if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))
 209                wol->wolopts |= WAKE_MCAST;
 210        if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))
 211                wol->wolopts |= WAKE_BCAST;
 212        if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))
 213                wol->wolopts |= WAKE_MAGIC;
 214}
 215
 216/**
 217 * pch_gbe_set_wol - Turn Wake-on-Lan on or off
 218 * @netdev: Network interface device structure
 219 * @wol:    Pointer of wake-on-Lan information straucture
 220 * Returns
 221 *      0:                      Successful.
 222 *      Negative value:         Failed.
 223 */
 224static int pch_gbe_set_wol(struct net_device *netdev,
 225                                struct ethtool_wolinfo *wol)
 226{
 227        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 228
 229        if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))
 230                return -EOPNOTSUPP;
 231        /* these settings will always override what we currently have */
 232        adapter->wake_up_evt = 0;
 233
 234        if ((wol->wolopts & WAKE_UCAST))
 235                adapter->wake_up_evt |= PCH_GBE_WLC_IND;
 236        if ((wol->wolopts & WAKE_MCAST))
 237                adapter->wake_up_evt |= PCH_GBE_WLC_MLT;
 238        if ((wol->wolopts & WAKE_BCAST))
 239                adapter->wake_up_evt |= PCH_GBE_WLC_BR;
 240        if ((wol->wolopts & WAKE_MAGIC))
 241                adapter->wake_up_evt |= PCH_GBE_WLC_MP;
 242        return 0;
 243}
 244
 245/**
 246 * pch_gbe_nway_reset - Restart autonegotiation
 247 * @netdev: Network interface device structure
 248 * Returns
 249 *      0:                      Successful.
 250 *      Negative value:         Failed.
 251 */
 252static int pch_gbe_nway_reset(struct net_device *netdev)
 253{
 254        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 255
 256        return mii_nway_restart(&adapter->mii);
 257}
 258
 259/**
 260 * pch_gbe_get_ringparam - Report ring sizes
 261 * @netdev:  Network interface device structure
 262 * @ring:    Ring param structure
 263 */
 264static void pch_gbe_get_ringparam(struct net_device *netdev,
 265                                        struct ethtool_ringparam *ring)
 266{
 267        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 268        struct pch_gbe_tx_ring *txdr = adapter->tx_ring;
 269        struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;
 270
 271        ring->rx_max_pending = PCH_GBE_MAX_RXD;
 272        ring->tx_max_pending = PCH_GBE_MAX_TXD;
 273        ring->rx_mini_max_pending = 0;
 274        ring->rx_jumbo_max_pending = 0;
 275        ring->rx_pending = rxdr->count;
 276        ring->tx_pending = txdr->count;
 277        ring->rx_mini_pending = 0;
 278        ring->rx_jumbo_pending = 0;
 279}
 280
 281/**
 282 * pch_gbe_set_ringparam - Set ring sizes
 283 * @netdev:  Network interface device structure
 284 * @ring:    Ring param structure
 285 * Returns
 286 *      0:                      Successful.
 287 *      Negative value:         Failed.
 288 */
 289static int pch_gbe_set_ringparam(struct net_device *netdev,
 290                                        struct ethtool_ringparam *ring)
 291{
 292        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 293        struct pch_gbe_tx_ring *txdr, *tx_old;
 294        struct pch_gbe_rx_ring *rxdr, *rx_old;
 295        int tx_ring_size, rx_ring_size;
 296        int err = 0;
 297
 298        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 299                return -EINVAL;
 300        tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);
 301        rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);
 302
 303        if ((netif_running(adapter->netdev)))
 304                pch_gbe_down(adapter);
 305        tx_old = adapter->tx_ring;
 306        rx_old = adapter->rx_ring;
 307
 308        txdr = kzalloc(tx_ring_size, GFP_KERNEL);
 309        if (!txdr) {
 310                err = -ENOMEM;
 311                goto err_alloc_tx;
 312        }
 313        rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
 314        if (!rxdr) {
 315                err = -ENOMEM;
 316                goto err_alloc_rx;
 317        }
 318        adapter->tx_ring = txdr;
 319        adapter->rx_ring = rxdr;
 320
 321        rxdr->count =
 322                clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
 323        rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);
 324
 325        txdr->count =
 326                clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
 327        txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);
 328
 329        if ((netif_running(adapter->netdev))) {
 330                /* Try to get new resources before deleting old */
 331                err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
 332                if (err)
 333                        goto err_setup_rx;
 334                err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
 335                if (err)
 336                        goto err_setup_tx;
 337                /* save the new, restore the old in order to free it,
 338                 * then restore the new back again */
 339#ifdef RINGFREE
 340                adapter->rx_ring = rx_old;
 341                adapter->tx_ring = tx_old;
 342                pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
 343                pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
 344                kfree(tx_old);
 345                kfree(rx_old);
 346                adapter->rx_ring = rxdr;
 347                adapter->tx_ring = txdr;
 348#else
 349                pch_gbe_free_rx_resources(adapter, rx_old);
 350                pch_gbe_free_tx_resources(adapter, tx_old);
 351                kfree(tx_old);
 352                kfree(rx_old);
 353                adapter->rx_ring = rxdr;
 354                adapter->tx_ring = txdr;
 355#endif
 356                err = pch_gbe_up(adapter);
 357        }
 358        return err;
 359
 360err_setup_tx:
 361        pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
 362err_setup_rx:
 363        adapter->rx_ring = rx_old;
 364        adapter->tx_ring = tx_old;
 365        kfree(rxdr);
 366err_alloc_rx:
 367        kfree(txdr);
 368err_alloc_tx:
 369        if (netif_running(adapter->netdev))
 370                pch_gbe_up(adapter);
 371        return err;
 372}
 373
 374/**
 375 * pch_gbe_get_pauseparam - Report pause parameters
 376 * @netdev:  Network interface device structure
 377 * @pause:   Pause parameters structure
 378 */
 379static void pch_gbe_get_pauseparam(struct net_device *netdev,
 380                                       struct ethtool_pauseparam *pause)
 381{
 382        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 383        struct pch_gbe_hw *hw = &adapter->hw;
 384
 385        pause->autoneg =
 386            ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 387
 388        if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {
 389                pause->rx_pause = 1;
 390        } else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {
 391                pause->tx_pause = 1;
 392        } else if (hw->mac.fc == PCH_GBE_FC_FULL) {
 393                pause->rx_pause = 1;
 394                pause->tx_pause = 1;
 395        }
 396}
 397
 398/**
 399 * pch_gbe_set_pauseparam - Set pause paramters
 400 * @netdev:  Network interface device structure
 401 * @pause:   Pause parameters structure
 402 * Returns
 403 *      0:                      Successful.
 404 *      Negative value:         Failed.
 405 */
 406static int pch_gbe_set_pauseparam(struct net_device *netdev,
 407                                       struct ethtool_pauseparam *pause)
 408{
 409        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 410        struct pch_gbe_hw *hw = &adapter->hw;
 411        int ret = 0;
 412
 413        hw->mac.fc_autoneg = pause->autoneg;
 414        if ((pause->rx_pause) && (pause->tx_pause))
 415                hw->mac.fc = PCH_GBE_FC_FULL;
 416        else if ((pause->rx_pause) && (!pause->tx_pause))
 417                hw->mac.fc = PCH_GBE_FC_RX_PAUSE;
 418        else if ((!pause->rx_pause) && (pause->tx_pause))
 419                hw->mac.fc = PCH_GBE_FC_TX_PAUSE;
 420        else if ((!pause->rx_pause) && (!pause->tx_pause))
 421                hw->mac.fc = PCH_GBE_FC_NONE;
 422
 423        if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
 424                if ((netif_running(adapter->netdev))) {
 425                        pch_gbe_down(adapter);
 426                        ret = pch_gbe_up(adapter);
 427                } else {
 428                        pch_gbe_reset(adapter);
 429                }
 430        } else {
 431                ret = pch_gbe_mac_force_mac_fc(hw);
 432        }
 433        return ret;
 434}
 435
 436/**
 437 * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off
 438 * @netdev:  Network interface device structure
 439 * Returns
 440 *      true(1):  Checksum On
 441 *      false(0): Checksum Off
 442 */
 443static u32 pch_gbe_get_rx_csum(struct net_device *netdev)
 444{
 445        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 446
 447        return adapter->rx_csum;
 448}
 449
 450/**
 451 * pch_gbe_set_rx_csum - Turn receive checksum on or off
 452 * @netdev:  Network interface device structure
 453 * @data:    Checksum On[true] or Off[false]
 454 * Returns
 455 *      0:                      Successful.
 456 *      Negative value:         Failed.
 457 */
 458static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
 459{
 460        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 461
 462        adapter->rx_csum = data;
 463        if ((netif_running(netdev)))
 464                pch_gbe_reinit_locked(adapter);
 465        else
 466                pch_gbe_reset(adapter);
 467
 468        return 0;
 469}
 470
 471/**
 472 * pch_gbe_set_tx_csum - Turn transmit checksums on or off
 473 * @netdev: Network interface device structure
 474 * @data:   Checksum on[true] or off[false]
 475 * Returns
 476 *      0:                      Successful.
 477 *      Negative value:         Failed.
 478 */
 479static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
 480{
 481        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 482
 483        adapter->tx_csum = data;
 484        return ethtool_op_set_tx_ipv6_csum(netdev, data);
 485}
 486
 487/**
 488 * pch_gbe_get_strings - Return a set of strings that describe the requested
 489 *                       objects
 490 * @netdev:    Network interface device structure
 491 * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
 492 * @data:      Pointer of read string data.
 493 */
 494static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,
 495                                        u8 *data)
 496{
 497        u8 *p = data;
 498        int i;
 499
 500        switch (stringset) {
 501        case (u32) ETH_SS_STATS:
 502                for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
 503                        memcpy(p, pch_gbe_gstrings_stats[i].string,
 504                               ETH_GSTRING_LEN);
 505                        p += ETH_GSTRING_LEN;
 506                }
 507                break;
 508        }
 509}
 510
 511/**
 512 * pch_gbe_get_ethtool_stats - Return statistics about the device
 513 * @netdev: Network interface device structure
 514 * @stats:  Ethtool statue structure
 515 * @data:   Pointer of read status area
 516 */
 517static void pch_gbe_get_ethtool_stats(struct net_device *netdev,
 518                                  struct ethtool_stats *stats, u64 *data)
 519{
 520        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 521        int i;
 522        const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;
 523        char *hw_stats = (char *)&adapter->stats;
 524
 525        pch_gbe_update_stats(adapter);
 526        for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
 527                char *p = hw_stats + gstats->offset;
 528                data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);
 529                gstats++;
 530        }
 531}
 532
 533static int pch_gbe_get_sset_count(struct net_device *netdev, int sset)
 534{
 535        switch (sset) {
 536        case ETH_SS_STATS:
 537                return PCH_GBE_STATS_LEN;
 538        default:
 539                return -EOPNOTSUPP;
 540        }
 541}
 542
 543static const struct ethtool_ops pch_gbe_ethtool_ops = {
 544        .get_settings = pch_gbe_get_settings,
 545        .set_settings = pch_gbe_set_settings,
 546        .get_drvinfo = pch_gbe_get_drvinfo,
 547        .get_regs_len = pch_gbe_get_regs_len,
 548        .get_regs = pch_gbe_get_regs,
 549        .get_wol = pch_gbe_get_wol,
 550        .set_wol = pch_gbe_set_wol,
 551        .nway_reset = pch_gbe_nway_reset,
 552        .get_link = ethtool_op_get_link,
 553        .get_ringparam = pch_gbe_get_ringparam,
 554        .set_ringparam = pch_gbe_set_ringparam,
 555        .get_pauseparam = pch_gbe_get_pauseparam,
 556        .set_pauseparam = pch_gbe_set_pauseparam,
 557        .get_rx_csum = pch_gbe_get_rx_csum,
 558        .set_rx_csum = pch_gbe_set_rx_csum,
 559        .set_tx_csum = pch_gbe_set_tx_csum,
 560        .get_strings = pch_gbe_get_strings,
 561        .get_ethtool_stats = pch_gbe_get_ethtool_stats,
 562        .get_sset_count = pch_gbe_get_sset_count,
 563};
 564
 565void pch_gbe_set_ethtool_ops(struct net_device *netdev)
 566{
 567        SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
 568}
 569