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