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