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 14 static 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 24 static 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 32 static u32 aq_ethtool_get_link(struct net_device *ndev) 33 { 34 return ethtool_op_get_link(ndev); 35 } 36 37 static 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 49 static int 50 aq_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 58 static 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 83 static 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 92 static 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 104 static 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 129 static 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 153 static 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 170 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev) 171 { 172 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX; 173 } 174 175 static 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 183 static 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 202 static 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 237 static 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 266 static 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 287 static 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 308 static 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 350 static 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 363 static 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 380 static 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 396 static 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 428 static 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 463 static 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 480 static 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 493 static 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 522 static 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 535 static 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 576 err_exit: 577 return err; 578 } 579 580 const 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