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