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