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