linux/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * aQuantia Corporation Network Driver
   4 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
   5 */
   6
   7/* File aq_ethtool.c: Definition of ethertool related functions. */
   8
   9#include "aq_ethtool.h"
  10#include "aq_nic.h"
  11#include "aq_vec.h"
  12#include "aq_filters.h"
  13
  14static void aq_ethtool_get_regs(struct net_device *ndev,
  15                                struct ethtool_regs *regs, void *p)
  16{
  17        struct aq_nic_s *aq_nic = netdev_priv(ndev);
  18        u32 regs_count = aq_nic_get_regs_count(aq_nic);
  19
  20        memset(p, 0, regs_count * sizeof(u32));
  21        aq_nic_get_regs(aq_nic, regs, p);
  22}
  23
  24static int aq_ethtool_get_regs_len(struct net_device *ndev)
  25{
  26        struct aq_nic_s *aq_nic = netdev_priv(ndev);
  27        u32 regs_count = aq_nic_get_regs_count(aq_nic);
  28
  29        return regs_count * sizeof(u32);
  30}
  31
  32static u32 aq_ethtool_get_link(struct net_device *ndev)
  33{
  34        return ethtool_op_get_link(ndev);
  35}
  36
  37static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
  38                                         struct ethtool_link_ksettings *cmd)
  39{
  40        struct aq_nic_s *aq_nic = netdev_priv(ndev);
  41
  42        aq_nic_get_link_ksettings(aq_nic, cmd);
  43        cmd->base.speed = netif_carrier_ok(ndev) ?
  44                                aq_nic_get_link_speed(aq_nic) : 0U;
  45
  46        return 0;
  47}
  48
  49static int
  50aq_ethtool_set_link_ksettings(struct net_device *ndev,
  51                              const struct ethtool_link_ksettings *cmd)
  52{
  53        struct aq_nic_s *aq_nic = netdev_priv(ndev);
  54
  55        return aq_nic_set_link_ksettings(aq_nic, cmd);
  56}
  57
  58static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
  59        "InPackets",
  60        "InUCast",
  61        "InMCast",
  62        "InBCast",
  63        "InErrors",
  64        "OutPackets",
  65        "OutUCast",
  66        "OutMCast",
  67        "OutBCast",
  68        "InUCastOctets",
  69        "OutUCastOctets",
  70        "InMCastOctets",
  71        "OutMCastOctets",
  72        "InBCastOctets",
  73        "OutBCastOctets",
  74        "InOctets",
  75        "OutOctets",
  76        "InPacketsDma",
  77        "OutPacketsDma",
  78        "InOctetsDma",
  79        "OutOctetsDma",
  80        "InDroppedDma",
  81};
  82
  83static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
  84        "Queue[%d] InPackets",
  85        "Queue[%d] OutPackets",
  86        "Queue[%d] Restarts",
  87        "Queue[%d] InJumboPackets",
  88        "Queue[%d] InLroPackets",
  89        "Queue[%d] InErrors",
  90};
  91
  92static void aq_ethtool_stats(struct net_device *ndev,
  93                             struct ethtool_stats *stats, u64 *data)
  94{
  95        struct aq_nic_s *aq_nic = netdev_priv(ndev);
  96        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
  97
  98        memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
  99                         ARRAY_SIZE(aq_ethtool_queue_stat_names) *
 100                         cfg->vecs) * sizeof(u64));
 101        aq_nic_get_stats(aq_nic, data);
 102}
 103
 104static void aq_ethtool_get_drvinfo(struct net_device *ndev,
 105                                   struct ethtool_drvinfo *drvinfo)
 106{
 107        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 108        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 109        struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
 110        u32 firmware_version = aq_nic_get_fw_version(aq_nic);
 111        u32 regs_count = aq_nic_get_regs_count(aq_nic);
 112
 113        strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
 114        strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version));
 115
 116        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 117                 "%u.%u.%u", firmware_version >> 24,
 118                 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
 119
 120        strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
 121                sizeof(drvinfo->bus_info));
 122        drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
 123                cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
 124        drvinfo->testinfo_len = 0;
 125        drvinfo->regdump_len = regs_count;
 126        drvinfo->eedump_len = 0;
 127}
 128
 129static void aq_ethtool_get_strings(struct net_device *ndev,
 130                                   u32 stringset, u8 *data)
 131{
 132        int i, si;
 133        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 134        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 135        u8 *p = data;
 136
 137        if (stringset == ETH_SS_STATS) {
 138                memcpy(p, aq_ethtool_stat_names,
 139                       sizeof(aq_ethtool_stat_names));
 140                p = p + sizeof(aq_ethtool_stat_names);
 141                for (i = 0; i < cfg->vecs; i++) {
 142                        for (si = 0;
 143                                si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
 144                                si++) {
 145                                snprintf(p, ETH_GSTRING_LEN,
 146                                         aq_ethtool_queue_stat_names[si], i);
 147                                p += ETH_GSTRING_LEN;
 148                        }
 149                }
 150        }
 151}
 152
 153static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
 154{
 155        int ret = 0;
 156        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 157        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 158
 159        switch (stringset) {
 160        case ETH_SS_STATS:
 161                ret = ARRAY_SIZE(aq_ethtool_stat_names) +
 162                        cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
 163                break;
 164        default:
 165                ret = -EOPNOTSUPP;
 166        }
 167        return ret;
 168}
 169
 170static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
 171{
 172        return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
 173}
 174
 175static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
 176{
 177        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 178        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 179
 180        return sizeof(cfg->aq_rss.hash_secret_key);
 181}
 182
 183static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
 184                              u8 *hfunc)
 185{
 186        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 187        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 188        unsigned int i = 0U;
 189
 190        if (hfunc)
 191                *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
 192        if (indir) {
 193                for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
 194                        indir[i] = cfg->aq_rss.indirection_table[i];
 195        }
 196        if (key)
 197                memcpy(key, cfg->aq_rss.hash_secret_key,
 198                       sizeof(cfg->aq_rss.hash_secret_key));
 199        return 0;
 200}
 201
 202static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
 203                              const u8 *key, const u8 hfunc)
 204{
 205        struct aq_nic_s *aq_nic = netdev_priv(netdev);
 206        struct aq_nic_cfg_s *cfg;
 207        unsigned int i = 0U;
 208        u32 rss_entries;
 209        int err = 0;
 210
 211        cfg = aq_nic_get_cfg(aq_nic);
 212        rss_entries = cfg->aq_rss.indirection_table_size;
 213
 214        /* We do not allow change in unsupported parameters */
 215        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 216                return -EOPNOTSUPP;
 217        /* Fill out the redirection table */
 218        if (indir)
 219                for (i = 0; i < rss_entries; i++)
 220                        cfg->aq_rss.indirection_table[i] = indir[i];
 221
 222        /* Fill out the rss hash key */
 223        if (key) {
 224                memcpy(cfg->aq_rss.hash_secret_key, key,
 225                       sizeof(cfg->aq_rss.hash_secret_key));
 226                err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
 227                        &cfg->aq_rss);
 228                if (err)
 229                        return err;
 230        }
 231
 232        err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
 233
 234        return err;
 235}
 236
 237static int aq_ethtool_get_rxnfc(struct net_device *ndev,
 238                                struct ethtool_rxnfc *cmd,
 239                                u32 *rule_locs)
 240{
 241        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 242        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 243        int err = 0;
 244
 245        switch (cmd->cmd) {
 246        case ETHTOOL_GRXRINGS:
 247                cmd->data = cfg->vecs;
 248                break;
 249        case ETHTOOL_GRXCLSRLCNT:
 250                cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
 251                break;
 252        case ETHTOOL_GRXCLSRULE:
 253                err = aq_get_rxnfc_rule(aq_nic, cmd);
 254                break;
 255        case ETHTOOL_GRXCLSRLALL:
 256                err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
 257                break;
 258        default:
 259                err = -EOPNOTSUPP;
 260                break;
 261        }
 262
 263        return err;
 264}
 265
 266static int aq_ethtool_set_rxnfc(struct net_device *ndev,
 267                                struct ethtool_rxnfc *cmd)
 268{
 269        int err = 0;
 270        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 271
 272        switch (cmd->cmd) {
 273        case ETHTOOL_SRXCLSRLINS:
 274                err = aq_add_rxnfc_rule(aq_nic, cmd);
 275                break;
 276        case ETHTOOL_SRXCLSRLDEL:
 277                err = aq_del_rxnfc_rule(aq_nic, cmd);
 278                break;
 279        default:
 280                err = -EOPNOTSUPP;
 281                break;
 282        }
 283
 284        return err;
 285}
 286
 287static int aq_ethtool_get_coalesce(struct net_device *ndev,
 288                                   struct ethtool_coalesce *coal)
 289{
 290        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 291        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 292
 293        if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
 294            cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
 295                coal->rx_coalesce_usecs = cfg->rx_itr;
 296                coal->tx_coalesce_usecs = cfg->tx_itr;
 297                coal->rx_max_coalesced_frames = 0;
 298                coal->tx_max_coalesced_frames = 0;
 299        } else {
 300                coal->rx_coalesce_usecs = 0;
 301                coal->tx_coalesce_usecs = 0;
 302                coal->rx_max_coalesced_frames = 1;
 303                coal->tx_max_coalesced_frames = 1;
 304        }
 305        return 0;
 306}
 307
 308static int aq_ethtool_set_coalesce(struct net_device *ndev,
 309                                   struct ethtool_coalesce *coal)
 310{
 311        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 312        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 313
 314        /* This is not yet supported
 315         */
 316        if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
 317                return -EOPNOTSUPP;
 318
 319        /* Atlantic only supports timing based coalescing
 320         */
 321        if (coal->rx_max_coalesced_frames > 1 ||
 322            coal->rx_coalesce_usecs_irq ||
 323            coal->rx_max_coalesced_frames_irq)
 324                return -EOPNOTSUPP;
 325
 326        if (coal->tx_max_coalesced_frames > 1 ||
 327            coal->tx_coalesce_usecs_irq ||
 328            coal->tx_max_coalesced_frames_irq)
 329                return -EOPNOTSUPP;
 330
 331        /* We do not support frame counting. Check this
 332         */
 333        if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
 334                return -EOPNOTSUPP;
 335        if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
 336                return -EOPNOTSUPP;
 337
 338        if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
 339            coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
 340                return -EINVAL;
 341
 342        cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
 343
 344        cfg->rx_itr = coal->rx_coalesce_usecs;
 345        cfg->tx_itr = coal->tx_coalesce_usecs;
 346
 347        return aq_nic_update_interrupt_moderation_settings(aq_nic);
 348}
 349
 350static void aq_ethtool_get_wol(struct net_device *ndev,
 351                               struct ethtool_wolinfo *wol)
 352{
 353        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 354        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 355
 356        wol->supported = WAKE_MAGIC;
 357        wol->wolopts = 0;
 358
 359        if (cfg->wol)
 360                wol->wolopts |= WAKE_MAGIC;
 361}
 362
 363static int aq_ethtool_set_wol(struct net_device *ndev,
 364                              struct ethtool_wolinfo *wol)
 365{
 366        struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
 367        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 368        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 369        int err = 0;
 370
 371        if (wol->wolopts & WAKE_MAGIC)
 372                cfg->wol |= AQ_NIC_WOL_ENABLED;
 373        else
 374                cfg->wol &= ~AQ_NIC_WOL_ENABLED;
 375        err = device_set_wakeup_enable(&pdev->dev, wol->wolopts);
 376
 377        return err;
 378}
 379
 380static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
 381{
 382        u32 rate = 0;
 383
 384        if (speed & AQ_NIC_RATE_EEE_10G)
 385                rate |= SUPPORTED_10000baseT_Full;
 386
 387        if (speed & AQ_NIC_RATE_EEE_2GS)
 388                rate |= SUPPORTED_2500baseX_Full;
 389
 390        if (speed & AQ_NIC_RATE_EEE_1G)
 391                rate |= SUPPORTED_1000baseT_Full;
 392
 393        return rate;
 394}
 395
 396static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
 397{
 398        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 399        u32 rate, supported_rates;
 400        int err = 0;
 401
 402        if (!aq_nic->aq_fw_ops->get_eee_rate)
 403                return -EOPNOTSUPP;
 404
 405        mutex_lock(&aq_nic->fwreq_mutex);
 406        err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
 407                                              &supported_rates);
 408        mutex_unlock(&aq_nic->fwreq_mutex);
 409        if (err < 0)
 410                return err;
 411
 412        eee->supported = eee_mask_to_ethtool_mask(supported_rates);
 413
 414        if (aq_nic->aq_nic_cfg.eee_speeds)
 415                eee->advertised = eee->supported;
 416
 417        eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
 418
 419        eee->eee_enabled = !!eee->advertised;
 420
 421        eee->tx_lpi_enabled = eee->eee_enabled;
 422        if (eee->advertised & eee->lp_advertised)
 423                eee->eee_active = true;
 424
 425        return 0;
 426}
 427
 428static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
 429{
 430        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 431        u32 rate, supported_rates;
 432        struct aq_nic_cfg_s *cfg;
 433        int err = 0;
 434
 435        cfg = aq_nic_get_cfg(aq_nic);
 436
 437        if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
 438                     !aq_nic->aq_fw_ops->set_eee_rate))
 439                return -EOPNOTSUPP;
 440
 441        mutex_lock(&aq_nic->fwreq_mutex);
 442        err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
 443                                              &supported_rates);
 444        mutex_unlock(&aq_nic->fwreq_mutex);
 445        if (err < 0)
 446                return err;
 447
 448        if (eee->eee_enabled) {
 449                rate = supported_rates;
 450                cfg->eee_speeds = rate;
 451        } else {
 452                rate = 0;
 453                cfg->eee_speeds = 0;
 454        }
 455
 456        mutex_lock(&aq_nic->fwreq_mutex);
 457        err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
 458        mutex_unlock(&aq_nic->fwreq_mutex);
 459
 460        return err;
 461}
 462
 463static int aq_ethtool_nway_reset(struct net_device *ndev)
 464{
 465        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 466        int err = 0;
 467
 468        if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
 469                return -EOPNOTSUPP;
 470
 471        if (netif_running(ndev)) {
 472                mutex_lock(&aq_nic->fwreq_mutex);
 473                err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
 474                mutex_unlock(&aq_nic->fwreq_mutex);
 475        }
 476
 477        return err;
 478}
 479
 480static void aq_ethtool_get_pauseparam(struct net_device *ndev,
 481                                      struct ethtool_pauseparam *pause)
 482{
 483        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 484        u32 fc = aq_nic->aq_nic_cfg.flow_control;
 485
 486        pause->autoneg = 0;
 487
 488        pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
 489        pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
 490
 491}
 492
 493static int aq_ethtool_set_pauseparam(struct net_device *ndev,
 494                                     struct ethtool_pauseparam *pause)
 495{
 496        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 497        int err = 0;
 498
 499        if (!aq_nic->aq_fw_ops->set_flow_control)
 500                return -EOPNOTSUPP;
 501
 502        if (pause->autoneg == AUTONEG_ENABLE)
 503                return -EOPNOTSUPP;
 504
 505        if (pause->rx_pause)
 506                aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
 507        else
 508                aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
 509
 510        if (pause->tx_pause)
 511                aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
 512        else
 513                aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
 514
 515        mutex_lock(&aq_nic->fwreq_mutex);
 516        err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
 517        mutex_unlock(&aq_nic->fwreq_mutex);
 518
 519        return err;
 520}
 521
 522static void aq_get_ringparam(struct net_device *ndev,
 523                             struct ethtool_ringparam *ring)
 524{
 525        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 526        struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
 527
 528        ring->rx_pending = aq_nic_cfg->rxds;
 529        ring->tx_pending = aq_nic_cfg->txds;
 530
 531        ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max;
 532        ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max;
 533}
 534
 535static int aq_set_ringparam(struct net_device *ndev,
 536                            struct ethtool_ringparam *ring)
 537{
 538        int err = 0;
 539        bool ndev_running = false;
 540        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 541        struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
 542        const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps;
 543
 544        if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
 545                err = -EOPNOTSUPP;
 546                goto err_exit;
 547        }
 548
 549        if (netif_running(ndev)) {
 550                ndev_running = true;
 551                dev_close(ndev);
 552        }
 553
 554        aq_nic_free_vectors(aq_nic);
 555
 556        aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
 557        aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max);
 558        aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE);
 559
 560        aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
 561        aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max);
 562        aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE);
 563
 564        for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs;
 565             aq_nic->aq_vecs++) {
 566                aq_nic->aq_vec[aq_nic->aq_vecs] =
 567                    aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg);
 568                if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
 569                        err = -ENOMEM;
 570                        goto err_exit;
 571                }
 572        }
 573        if (ndev_running)
 574                err = dev_open(ndev, NULL);
 575
 576err_exit:
 577        return err;
 578}
 579
 580const struct ethtool_ops aq_ethtool_ops = {
 581        .get_link            = aq_ethtool_get_link,
 582        .get_regs_len        = aq_ethtool_get_regs_len,
 583        .get_regs            = aq_ethtool_get_regs,
 584        .get_drvinfo         = aq_ethtool_get_drvinfo,
 585        .get_strings         = aq_ethtool_get_strings,
 586        .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
 587        .get_wol             = aq_ethtool_get_wol,
 588        .set_wol             = aq_ethtool_set_wol,
 589        .nway_reset          = aq_ethtool_nway_reset,
 590        .get_ringparam       = aq_get_ringparam,
 591        .set_ringparam       = aq_set_ringparam,
 592        .get_eee             = aq_ethtool_get_eee,
 593        .set_eee             = aq_ethtool_set_eee,
 594        .get_pauseparam      = aq_ethtool_get_pauseparam,
 595        .set_pauseparam      = aq_ethtool_set_pauseparam,
 596        .get_rxfh_key_size   = aq_ethtool_get_rss_key_size,
 597        .get_rxfh            = aq_ethtool_get_rss,
 598        .set_rxfh            = aq_ethtool_set_rss,
 599        .get_rxnfc           = aq_ethtool_get_rxnfc,
 600        .set_rxnfc           = aq_ethtool_set_rxnfc,
 601        .get_sset_count      = aq_ethtool_get_sset_count,
 602        .get_ethtool_stats   = aq_ethtool_stats,
 603        .get_link_ksettings  = aq_ethtool_get_link_ksettings,
 604        .set_link_ksettings  = aq_ethtool_set_link_ksettings,
 605        .get_coalesce        = aq_ethtool_get_coalesce,
 606        .set_coalesce        = aq_ethtool_set_coalesce,
 607};
 608