1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * aQuantia Corporation Network Driver 4 * Copyright (C) 2014-2019 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_ptp.h" 13 #include "aq_filters.h" 14 15 #include <linux/ptp_clock_kernel.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; 22 23 regs_count = aq_nic_get_regs_count(aq_nic); 24 25 memset(p, 0, regs_count * sizeof(u32)); 26 aq_nic_get_regs(aq_nic, regs, p); 27 } 28 29 static int aq_ethtool_get_regs_len(struct net_device *ndev) 30 { 31 struct aq_nic_s *aq_nic = netdev_priv(ndev); 32 u32 regs_count; 33 34 regs_count = aq_nic_get_regs_count(aq_nic); 35 36 return regs_count * sizeof(u32); 37 } 38 39 static u32 aq_ethtool_get_link(struct net_device *ndev) 40 { 41 return ethtool_op_get_link(ndev); 42 } 43 44 static int aq_ethtool_get_link_ksettings(struct net_device *ndev, 45 struct ethtool_link_ksettings *cmd) 46 { 47 struct aq_nic_s *aq_nic = netdev_priv(ndev); 48 49 aq_nic_get_link_ksettings(aq_nic, cmd); 50 cmd->base.speed = netif_carrier_ok(ndev) ? 51 aq_nic_get_link_speed(aq_nic) : 0U; 52 53 return 0; 54 } 55 56 static int 57 aq_ethtool_set_link_ksettings(struct net_device *ndev, 58 const struct ethtool_link_ksettings *cmd) 59 { 60 struct aq_nic_s *aq_nic = netdev_priv(ndev); 61 62 return aq_nic_set_link_ksettings(aq_nic, cmd); 63 } 64 65 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { 66 "InPackets", 67 "InUCast", 68 "InMCast", 69 "InBCast", 70 "InErrors", 71 "OutPackets", 72 "OutUCast", 73 "OutMCast", 74 "OutBCast", 75 "InUCastOctets", 76 "OutUCastOctets", 77 "InMCastOctets", 78 "OutMCastOctets", 79 "InBCastOctets", 80 "OutBCastOctets", 81 "InOctets", 82 "OutOctets", 83 "InPacketsDma", 84 "OutPacketsDma", 85 "InOctetsDma", 86 "OutOctetsDma", 87 "InDroppedDma", 88 }; 89 90 static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = { 91 "Queue[%d] InPackets", 92 "Queue[%d] OutPackets", 93 "Queue[%d] Restarts", 94 "Queue[%d] InJumboPackets", 95 "Queue[%d] InLroPackets", 96 "Queue[%d] InErrors", 97 }; 98 99 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = { 100 "DMASystemLoopback", 101 "PKTSystemLoopback", 102 "DMANetworkLoopback", 103 "PHYInternalLoopback", 104 "PHYExternalLoopback", 105 }; 106 107 static void aq_ethtool_stats(struct net_device *ndev, 108 struct ethtool_stats *stats, u64 *data) 109 { 110 struct aq_nic_s *aq_nic = netdev_priv(ndev); 111 struct aq_nic_cfg_s *cfg; 112 113 cfg = aq_nic_get_cfg(aq_nic); 114 115 memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) + 116 ARRAY_SIZE(aq_ethtool_queue_stat_names) * 117 cfg->vecs) * sizeof(u64)); 118 aq_nic_get_stats(aq_nic, data); 119 } 120 121 static void aq_ethtool_get_drvinfo(struct net_device *ndev, 122 struct ethtool_drvinfo *drvinfo) 123 { 124 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); 125 struct aq_nic_s *aq_nic = netdev_priv(ndev); 126 struct aq_nic_cfg_s *cfg; 127 u32 firmware_version; 128 u32 regs_count; 129 130 cfg = aq_nic_get_cfg(aq_nic); 131 firmware_version = aq_nic_get_fw_version(aq_nic); 132 regs_count = aq_nic_get_regs_count(aq_nic); 133 134 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver)); 135 136 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), 137 "%u.%u.%u", firmware_version >> 24, 138 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU); 139 140 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", 141 sizeof(drvinfo->bus_info)); 142 drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) + 143 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); 144 drvinfo->testinfo_len = 0; 145 drvinfo->regdump_len = regs_count; 146 drvinfo->eedump_len = 0; 147 } 148 149 static void aq_ethtool_get_strings(struct net_device *ndev, 150 u32 stringset, u8 *data) 151 { 152 struct aq_nic_s *aq_nic = netdev_priv(ndev); 153 struct aq_nic_cfg_s *cfg; 154 u8 *p = data; 155 int i, si; 156 157 cfg = aq_nic_get_cfg(aq_nic); 158 159 switch (stringset) { 160 case ETH_SS_STATS: 161 memcpy(p, aq_ethtool_stat_names, 162 sizeof(aq_ethtool_stat_names)); 163 p = p + sizeof(aq_ethtool_stat_names); 164 for (i = 0; i < cfg->vecs; i++) { 165 for (si = 0; 166 si < ARRAY_SIZE(aq_ethtool_queue_stat_names); 167 si++) { 168 snprintf(p, ETH_GSTRING_LEN, 169 aq_ethtool_queue_stat_names[si], i); 170 p += ETH_GSTRING_LEN; 171 } 172 } 173 break; 174 case ETH_SS_PRIV_FLAGS: 175 memcpy(p, aq_ethtool_priv_flag_names, 176 sizeof(aq_ethtool_priv_flag_names)); 177 break; 178 } 179 } 180 181 static int aq_ethtool_set_phys_id(struct net_device *ndev, 182 enum ethtool_phys_id_state state) 183 { 184 struct aq_nic_s *aq_nic = netdev_priv(ndev); 185 struct aq_hw_s *hw = aq_nic->aq_hw; 186 int ret = 0; 187 188 if (!aq_nic->aq_fw_ops->led_control) 189 return -EOPNOTSUPP; 190 191 mutex_lock(&aq_nic->fwreq_mutex); 192 193 switch (state) { 194 case ETHTOOL_ID_ACTIVE: 195 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK | 196 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4); 197 break; 198 case ETHTOOL_ID_INACTIVE: 199 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT); 200 break; 201 default: 202 break; 203 } 204 205 mutex_unlock(&aq_nic->fwreq_mutex); 206 207 return ret; 208 } 209 210 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) 211 { 212 struct aq_nic_s *aq_nic = netdev_priv(ndev); 213 struct aq_nic_cfg_s *cfg; 214 int ret = 0; 215 216 cfg = aq_nic_get_cfg(aq_nic); 217 218 switch (stringset) { 219 case ETH_SS_STATS: 220 ret = ARRAY_SIZE(aq_ethtool_stat_names) + 221 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); 222 break; 223 case ETH_SS_PRIV_FLAGS: 224 ret = ARRAY_SIZE(aq_ethtool_priv_flag_names); 225 break; 226 default: 227 ret = -EOPNOTSUPP; 228 } 229 230 return ret; 231 } 232 233 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev) 234 { 235 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX; 236 } 237 238 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev) 239 { 240 struct aq_nic_s *aq_nic = netdev_priv(ndev); 241 struct aq_nic_cfg_s *cfg; 242 243 cfg = aq_nic_get_cfg(aq_nic); 244 245 return sizeof(cfg->aq_rss.hash_secret_key); 246 } 247 248 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key, 249 u8 *hfunc) 250 { 251 struct aq_nic_s *aq_nic = netdev_priv(ndev); 252 struct aq_nic_cfg_s *cfg; 253 unsigned int i = 0U; 254 255 cfg = aq_nic_get_cfg(aq_nic); 256 257 if (hfunc) 258 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ 259 if (indir) { 260 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++) 261 indir[i] = cfg->aq_rss.indirection_table[i]; 262 } 263 if (key) 264 memcpy(key, cfg->aq_rss.hash_secret_key, 265 sizeof(cfg->aq_rss.hash_secret_key)); 266 267 return 0; 268 } 269 270 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir, 271 const u8 *key, const u8 hfunc) 272 { 273 struct aq_nic_s *aq_nic = netdev_priv(netdev); 274 struct aq_nic_cfg_s *cfg; 275 unsigned int i = 0U; 276 u32 rss_entries; 277 int err = 0; 278 279 cfg = aq_nic_get_cfg(aq_nic); 280 rss_entries = cfg->aq_rss.indirection_table_size; 281 282 /* We do not allow change in unsupported parameters */ 283 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 284 return -EOPNOTSUPP; 285 /* Fill out the redirection table */ 286 if (indir) 287 for (i = 0; i < rss_entries; i++) 288 cfg->aq_rss.indirection_table[i] = indir[i]; 289 290 /* Fill out the rss hash key */ 291 if (key) { 292 memcpy(cfg->aq_rss.hash_secret_key, key, 293 sizeof(cfg->aq_rss.hash_secret_key)); 294 err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw, 295 &cfg->aq_rss); 296 if (err) 297 return err; 298 } 299 300 err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss); 301 302 return err; 303 } 304 305 static int aq_ethtool_get_rxnfc(struct net_device *ndev, 306 struct ethtool_rxnfc *cmd, 307 u32 *rule_locs) 308 { 309 struct aq_nic_s *aq_nic = netdev_priv(ndev); 310 struct aq_nic_cfg_s *cfg; 311 int err = 0; 312 313 cfg = aq_nic_get_cfg(aq_nic); 314 315 switch (cmd->cmd) { 316 case ETHTOOL_GRXRINGS: 317 cmd->data = cfg->vecs; 318 break; 319 case ETHTOOL_GRXCLSRLCNT: 320 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic); 321 break; 322 case ETHTOOL_GRXCLSRULE: 323 err = aq_get_rxnfc_rule(aq_nic, cmd); 324 break; 325 case ETHTOOL_GRXCLSRLALL: 326 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs); 327 break; 328 default: 329 err = -EOPNOTSUPP; 330 break; 331 } 332 333 return err; 334 } 335 336 static int aq_ethtool_set_rxnfc(struct net_device *ndev, 337 struct ethtool_rxnfc *cmd) 338 { 339 struct aq_nic_s *aq_nic = netdev_priv(ndev); 340 int err = 0; 341 342 switch (cmd->cmd) { 343 case ETHTOOL_SRXCLSRLINS: 344 err = aq_add_rxnfc_rule(aq_nic, cmd); 345 break; 346 case ETHTOOL_SRXCLSRLDEL: 347 err = aq_del_rxnfc_rule(aq_nic, cmd); 348 break; 349 default: 350 err = -EOPNOTSUPP; 351 break; 352 } 353 354 return err; 355 } 356 357 static int aq_ethtool_get_coalesce(struct net_device *ndev, 358 struct ethtool_coalesce *coal) 359 { 360 struct aq_nic_s *aq_nic = netdev_priv(ndev); 361 struct aq_nic_cfg_s *cfg; 362 363 cfg = aq_nic_get_cfg(aq_nic); 364 365 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || 366 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { 367 coal->rx_coalesce_usecs = cfg->rx_itr; 368 coal->tx_coalesce_usecs = cfg->tx_itr; 369 coal->rx_max_coalesced_frames = 0; 370 coal->tx_max_coalesced_frames = 0; 371 } else { 372 coal->rx_coalesce_usecs = 0; 373 coal->tx_coalesce_usecs = 0; 374 coal->rx_max_coalesced_frames = 1; 375 coal->tx_max_coalesced_frames = 1; 376 } 377 378 return 0; 379 } 380 381 static int aq_ethtool_set_coalesce(struct net_device *ndev, 382 struct ethtool_coalesce *coal) 383 { 384 struct aq_nic_s *aq_nic = netdev_priv(ndev); 385 struct aq_nic_cfg_s *cfg; 386 387 cfg = aq_nic_get_cfg(aq_nic); 388 389 /* This is not yet supported 390 */ 391 if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce) 392 return -EOPNOTSUPP; 393 394 /* Atlantic only supports timing based coalescing 395 */ 396 if (coal->rx_max_coalesced_frames > 1 || 397 coal->rx_coalesce_usecs_irq || 398 coal->rx_max_coalesced_frames_irq) 399 return -EOPNOTSUPP; 400 401 if (coal->tx_max_coalesced_frames > 1 || 402 coal->tx_coalesce_usecs_irq || 403 coal->tx_max_coalesced_frames_irq) 404 return -EOPNOTSUPP; 405 406 /* We do not support frame counting. Check this 407 */ 408 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) 409 return -EOPNOTSUPP; 410 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) 411 return -EOPNOTSUPP; 412 413 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || 414 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) 415 return -EINVAL; 416 417 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; 418 419 cfg->rx_itr = coal->rx_coalesce_usecs; 420 cfg->tx_itr = coal->tx_coalesce_usecs; 421 422 return aq_nic_update_interrupt_moderation_settings(aq_nic); 423 } 424 425 static void aq_ethtool_get_wol(struct net_device *ndev, 426 struct ethtool_wolinfo *wol) 427 { 428 struct aq_nic_s *aq_nic = netdev_priv(ndev); 429 struct aq_nic_cfg_s *cfg; 430 431 cfg = aq_nic_get_cfg(aq_nic); 432 433 wol->supported = AQ_NIC_WOL_MODES; 434 wol->wolopts = cfg->wol; 435 } 436 437 static int aq_ethtool_set_wol(struct net_device *ndev, 438 struct ethtool_wolinfo *wol) 439 { 440 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); 441 struct aq_nic_s *aq_nic = netdev_priv(ndev); 442 struct aq_nic_cfg_s *cfg; 443 int err = 0; 444 445 cfg = aq_nic_get_cfg(aq_nic); 446 447 if (wol->wolopts & ~AQ_NIC_WOL_MODES) 448 return -EOPNOTSUPP; 449 450 cfg->wol = wol->wolopts; 451 452 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol); 453 454 return err; 455 } 456 457 static int aq_ethtool_get_ts_info(struct net_device *ndev, 458 struct ethtool_ts_info *info) 459 { 460 struct aq_nic_s *aq_nic = netdev_priv(ndev); 461 462 ethtool_op_get_ts_info(ndev, info); 463 464 if (!aq_nic->aq_ptp) 465 return 0; 466 467 info->so_timestamping |= 468 SOF_TIMESTAMPING_TX_HARDWARE | 469 SOF_TIMESTAMPING_RX_HARDWARE | 470 SOF_TIMESTAMPING_RAW_HARDWARE; 471 472 info->tx_types = BIT(HWTSTAMP_TX_OFF) | 473 BIT(HWTSTAMP_TX_ON); 474 475 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); 476 477 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 478 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 479 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); 480 481 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp)); 482 483 return 0; 484 } 485 486 static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed) 487 { 488 u32 rate = 0; 489 490 if (speed & AQ_NIC_RATE_EEE_10G) 491 rate |= SUPPORTED_10000baseT_Full; 492 493 if (speed & AQ_NIC_RATE_EEE_2GS) 494 rate |= SUPPORTED_2500baseX_Full; 495 496 if (speed & AQ_NIC_RATE_EEE_1G) 497 rate |= SUPPORTED_1000baseT_Full; 498 499 return rate; 500 } 501 502 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee) 503 { 504 struct aq_nic_s *aq_nic = netdev_priv(ndev); 505 u32 rate, supported_rates; 506 int err = 0; 507 508 if (!aq_nic->aq_fw_ops->get_eee_rate) 509 return -EOPNOTSUPP; 510 511 mutex_lock(&aq_nic->fwreq_mutex); 512 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 513 &supported_rates); 514 mutex_unlock(&aq_nic->fwreq_mutex); 515 if (err < 0) 516 return err; 517 518 eee->supported = eee_mask_to_ethtool_mask(supported_rates); 519 520 if (aq_nic->aq_nic_cfg.eee_speeds) 521 eee->advertised = eee->supported; 522 523 eee->lp_advertised = eee_mask_to_ethtool_mask(rate); 524 525 eee->eee_enabled = !!eee->advertised; 526 527 eee->tx_lpi_enabled = eee->eee_enabled; 528 if (eee->advertised & eee->lp_advertised) 529 eee->eee_active = true; 530 531 return 0; 532 } 533 534 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee) 535 { 536 struct aq_nic_s *aq_nic = netdev_priv(ndev); 537 u32 rate, supported_rates; 538 struct aq_nic_cfg_s *cfg; 539 int err = 0; 540 541 cfg = aq_nic_get_cfg(aq_nic); 542 543 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate || 544 !aq_nic->aq_fw_ops->set_eee_rate)) 545 return -EOPNOTSUPP; 546 547 mutex_lock(&aq_nic->fwreq_mutex); 548 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 549 &supported_rates); 550 mutex_unlock(&aq_nic->fwreq_mutex); 551 if (err < 0) 552 return err; 553 554 if (eee->eee_enabled) { 555 rate = supported_rates; 556 cfg->eee_speeds = rate; 557 } else { 558 rate = 0; 559 cfg->eee_speeds = 0; 560 } 561 562 mutex_lock(&aq_nic->fwreq_mutex); 563 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate); 564 mutex_unlock(&aq_nic->fwreq_mutex); 565 566 return err; 567 } 568 569 static int aq_ethtool_nway_reset(struct net_device *ndev) 570 { 571 struct aq_nic_s *aq_nic = netdev_priv(ndev); 572 int err = 0; 573 574 if (unlikely(!aq_nic->aq_fw_ops->renegotiate)) 575 return -EOPNOTSUPP; 576 577 if (netif_running(ndev)) { 578 mutex_lock(&aq_nic->fwreq_mutex); 579 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw); 580 mutex_unlock(&aq_nic->fwreq_mutex); 581 } 582 583 return err; 584 } 585 586 static void aq_ethtool_get_pauseparam(struct net_device *ndev, 587 struct ethtool_pauseparam *pause) 588 { 589 struct aq_nic_s *aq_nic = netdev_priv(ndev); 590 u32 fc = aq_nic->aq_nic_cfg.fc.req; 591 592 pause->autoneg = 0; 593 594 pause->rx_pause = !!(fc & AQ_NIC_FC_RX); 595 pause->tx_pause = !!(fc & AQ_NIC_FC_TX); 596 597 } 598 599 static int aq_ethtool_set_pauseparam(struct net_device *ndev, 600 struct ethtool_pauseparam *pause) 601 { 602 struct aq_nic_s *aq_nic = netdev_priv(ndev); 603 int err = 0; 604 605 if (!aq_nic->aq_fw_ops->set_flow_control) 606 return -EOPNOTSUPP; 607 608 if (pause->autoneg == AUTONEG_ENABLE) 609 return -EOPNOTSUPP; 610 611 if (pause->rx_pause) 612 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX; 613 else 614 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX; 615 616 if (pause->tx_pause) 617 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX; 618 else 619 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX; 620 621 mutex_lock(&aq_nic->fwreq_mutex); 622 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw); 623 mutex_unlock(&aq_nic->fwreq_mutex); 624 625 return err; 626 } 627 628 static void aq_get_ringparam(struct net_device *ndev, 629 struct ethtool_ringparam *ring) 630 { 631 struct aq_nic_s *aq_nic = netdev_priv(ndev); 632 struct aq_nic_cfg_s *cfg; 633 634 cfg = aq_nic_get_cfg(aq_nic); 635 636 ring->rx_pending = cfg->rxds; 637 ring->tx_pending = cfg->txds; 638 639 ring->rx_max_pending = cfg->aq_hw_caps->rxds_max; 640 ring->tx_max_pending = cfg->aq_hw_caps->txds_max; 641 } 642 643 static int aq_set_ringparam(struct net_device *ndev, 644 struct ethtool_ringparam *ring) 645 { 646 struct aq_nic_s *aq_nic = netdev_priv(ndev); 647 const struct aq_hw_caps_s *hw_caps; 648 bool ndev_running = false; 649 struct aq_nic_cfg_s *cfg; 650 int err = 0; 651 652 cfg = aq_nic_get_cfg(aq_nic); 653 hw_caps = cfg->aq_hw_caps; 654 655 if (ring->rx_mini_pending || ring->rx_jumbo_pending) { 656 err = -EOPNOTSUPP; 657 goto err_exit; 658 } 659 660 if (netif_running(ndev)) { 661 ndev_running = true; 662 dev_close(ndev); 663 } 664 665 aq_nic_free_vectors(aq_nic); 666 667 cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); 668 cfg->rxds = min(cfg->rxds, hw_caps->rxds_max); 669 cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE); 670 671 cfg->txds = max(ring->tx_pending, hw_caps->txds_min); 672 cfg->txds = min(cfg->txds, hw_caps->txds_max); 673 cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE); 674 675 for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < cfg->vecs; 676 aq_nic->aq_vecs++) { 677 aq_nic->aq_vec[aq_nic->aq_vecs] = 678 aq_vec_alloc(aq_nic, aq_nic->aq_vecs, cfg); 679 if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) { 680 err = -ENOMEM; 681 goto err_exit; 682 } 683 } 684 if (ndev_running) 685 err = dev_open(ndev, NULL); 686 687 err_exit: 688 return err; 689 } 690 691 static u32 aq_get_msg_level(struct net_device *ndev) 692 { 693 struct aq_nic_s *aq_nic = netdev_priv(ndev); 694 695 return aq_nic->msg_enable; 696 } 697 698 static void aq_set_msg_level(struct net_device *ndev, u32 data) 699 { 700 struct aq_nic_s *aq_nic = netdev_priv(ndev); 701 702 aq_nic->msg_enable = data; 703 } 704 705 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev) 706 { 707 struct aq_nic_s *aq_nic = netdev_priv(ndev); 708 709 return aq_nic->aq_nic_cfg.priv_flags; 710 } 711 712 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags) 713 { 714 struct aq_nic_s *aq_nic = netdev_priv(ndev); 715 struct aq_nic_cfg_s *cfg; 716 u32 priv_flags; 717 718 cfg = aq_nic_get_cfg(aq_nic); 719 priv_flags = cfg->priv_flags; 720 721 if (flags & ~AQ_PRIV_FLAGS_MASK) 722 return -EOPNOTSUPP; 723 724 if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) { 725 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n"); 726 return -EINVAL; 727 } 728 729 cfg->priv_flags = flags; 730 731 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) { 732 if (netif_running(ndev)) { 733 dev_close(ndev); 734 735 dev_open(ndev, NULL); 736 } 737 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) { 738 aq_nic_set_loopback(aq_nic); 739 } 740 741 return 0; 742 } 743 744 const struct ethtool_ops aq_ethtool_ops = { 745 .get_link = aq_ethtool_get_link, 746 .get_regs_len = aq_ethtool_get_regs_len, 747 .get_regs = aq_ethtool_get_regs, 748 .get_drvinfo = aq_ethtool_get_drvinfo, 749 .get_strings = aq_ethtool_get_strings, 750 .set_phys_id = aq_ethtool_set_phys_id, 751 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size, 752 .get_wol = aq_ethtool_get_wol, 753 .set_wol = aq_ethtool_set_wol, 754 .nway_reset = aq_ethtool_nway_reset, 755 .get_ringparam = aq_get_ringparam, 756 .set_ringparam = aq_set_ringparam, 757 .get_eee = aq_ethtool_get_eee, 758 .set_eee = aq_ethtool_set_eee, 759 .get_pauseparam = aq_ethtool_get_pauseparam, 760 .set_pauseparam = aq_ethtool_set_pauseparam, 761 .get_rxfh_key_size = aq_ethtool_get_rss_key_size, 762 .get_rxfh = aq_ethtool_get_rss, 763 .set_rxfh = aq_ethtool_set_rss, 764 .get_rxnfc = aq_ethtool_get_rxnfc, 765 .set_rxnfc = aq_ethtool_set_rxnfc, 766 .get_msglevel = aq_get_msg_level, 767 .set_msglevel = aq_set_msg_level, 768 .get_sset_count = aq_ethtool_get_sset_count, 769 .get_ethtool_stats = aq_ethtool_stats, 770 .get_priv_flags = aq_ethtool_get_priv_flags, 771 .set_priv_flags = aq_ethtool_set_priv_flags, 772 .get_link_ksettings = aq_ethtool_get_link_ksettings, 773 .set_link_ksettings = aq_ethtool_set_link_ksettings, 774 .get_coalesce = aq_ethtool_get_coalesce, 775 .set_coalesce = aq_ethtool_set_coalesce, 776 .get_ts_info = aq_ethtool_get_ts_info, 777 }; 778