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 { 552 struct aq_nic_s *aq_nic = netdev_priv(ndev); 553 struct aq_nic_cfg_s *cfg; 554 555 cfg = aq_nic_get_cfg(aq_nic); 556 557 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || 558 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { 559 coal->rx_coalesce_usecs = cfg->rx_itr; 560 coal->tx_coalesce_usecs = cfg->tx_itr; 561 coal->rx_max_coalesced_frames = 0; 562 coal->tx_max_coalesced_frames = 0; 563 } else { 564 coal->rx_coalesce_usecs = 0; 565 coal->tx_coalesce_usecs = 0; 566 coal->rx_max_coalesced_frames = 1; 567 coal->tx_max_coalesced_frames = 1; 568 } 569 570 return 0; 571 } 572 573 static int aq_ethtool_set_coalesce(struct net_device *ndev, 574 struct ethtool_coalesce *coal) 575 { 576 struct aq_nic_s *aq_nic = netdev_priv(ndev); 577 struct aq_nic_cfg_s *cfg; 578 579 cfg = aq_nic_get_cfg(aq_nic); 580 581 /* Atlantic only supports timing based coalescing 582 */ 583 if (coal->rx_max_coalesced_frames > 1 || 584 coal->tx_max_coalesced_frames > 1) 585 return -EOPNOTSUPP; 586 587 /* We do not support frame counting. Check this 588 */ 589 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) 590 return -EOPNOTSUPP; 591 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) 592 return -EOPNOTSUPP; 593 594 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || 595 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) 596 return -EINVAL; 597 598 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; 599 600 cfg->rx_itr = coal->rx_coalesce_usecs; 601 cfg->tx_itr = coal->tx_coalesce_usecs; 602 603 return aq_nic_update_interrupt_moderation_settings(aq_nic); 604 } 605 606 static void aq_ethtool_get_wol(struct net_device *ndev, 607 struct ethtool_wolinfo *wol) 608 { 609 struct aq_nic_s *aq_nic = netdev_priv(ndev); 610 struct aq_nic_cfg_s *cfg; 611 612 cfg = aq_nic_get_cfg(aq_nic); 613 614 wol->supported = AQ_NIC_WOL_MODES; 615 wol->wolopts = cfg->wol; 616 } 617 618 static int aq_ethtool_set_wol(struct net_device *ndev, 619 struct ethtool_wolinfo *wol) 620 { 621 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); 622 struct aq_nic_s *aq_nic = netdev_priv(ndev); 623 struct aq_nic_cfg_s *cfg; 624 int err = 0; 625 626 cfg = aq_nic_get_cfg(aq_nic); 627 628 if (wol->wolopts & ~AQ_NIC_WOL_MODES) 629 return -EOPNOTSUPP; 630 631 cfg->wol = wol->wolopts; 632 633 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol); 634 635 return err; 636 } 637 638 static int aq_ethtool_get_ts_info(struct net_device *ndev, 639 struct ethtool_ts_info *info) 640 { 641 struct aq_nic_s *aq_nic = netdev_priv(ndev); 642 643 ethtool_op_get_ts_info(ndev, info); 644 645 if (!aq_nic->aq_ptp) 646 return 0; 647 648 info->so_timestamping |= 649 SOF_TIMESTAMPING_TX_HARDWARE | 650 SOF_TIMESTAMPING_RX_HARDWARE | 651 SOF_TIMESTAMPING_RAW_HARDWARE; 652 653 info->tx_types = BIT(HWTSTAMP_TX_OFF) | 654 BIT(HWTSTAMP_TX_ON); 655 656 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); 657 658 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 659 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 660 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); 661 662 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) 663 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp)); 664 #endif 665 666 return 0; 667 } 668 669 static u32 eee_mask_to_ethtool_mask(u32 speed) 670 { 671 u32 rate = 0; 672 673 if (speed & AQ_NIC_RATE_EEE_10G) 674 rate |= SUPPORTED_10000baseT_Full; 675 676 if (speed & AQ_NIC_RATE_EEE_1G) 677 rate |= SUPPORTED_1000baseT_Full; 678 679 if (speed & AQ_NIC_RATE_EEE_100M) 680 rate |= SUPPORTED_100baseT_Full; 681 682 return rate; 683 } 684 685 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee) 686 { 687 struct aq_nic_s *aq_nic = netdev_priv(ndev); 688 u32 rate, supported_rates; 689 int err = 0; 690 691 if (!aq_nic->aq_fw_ops->get_eee_rate) 692 return -EOPNOTSUPP; 693 694 mutex_lock(&aq_nic->fwreq_mutex); 695 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 696 &supported_rates); 697 mutex_unlock(&aq_nic->fwreq_mutex); 698 if (err < 0) 699 return err; 700 701 eee->supported = eee_mask_to_ethtool_mask(supported_rates); 702 703 if (aq_nic->aq_nic_cfg.eee_speeds) 704 eee->advertised = eee->supported; 705 706 eee->lp_advertised = eee_mask_to_ethtool_mask(rate); 707 708 eee->eee_enabled = !!eee->advertised; 709 710 eee->tx_lpi_enabled = eee->eee_enabled; 711 if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK) 712 eee->eee_active = true; 713 714 return 0; 715 } 716 717 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee) 718 { 719 struct aq_nic_s *aq_nic = netdev_priv(ndev); 720 u32 rate, supported_rates; 721 struct aq_nic_cfg_s *cfg; 722 int err = 0; 723 724 cfg = aq_nic_get_cfg(aq_nic); 725 726 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate || 727 !aq_nic->aq_fw_ops->set_eee_rate)) 728 return -EOPNOTSUPP; 729 730 mutex_lock(&aq_nic->fwreq_mutex); 731 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 732 &supported_rates); 733 mutex_unlock(&aq_nic->fwreq_mutex); 734 if (err < 0) 735 return err; 736 737 if (eee->eee_enabled) { 738 rate = supported_rates; 739 cfg->eee_speeds = rate; 740 } else { 741 rate = 0; 742 cfg->eee_speeds = 0; 743 } 744 745 mutex_lock(&aq_nic->fwreq_mutex); 746 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate); 747 mutex_unlock(&aq_nic->fwreq_mutex); 748 749 return err; 750 } 751 752 static int aq_ethtool_nway_reset(struct net_device *ndev) 753 { 754 struct aq_nic_s *aq_nic = netdev_priv(ndev); 755 int err = 0; 756 757 if (unlikely(!aq_nic->aq_fw_ops->renegotiate)) 758 return -EOPNOTSUPP; 759 760 if (netif_running(ndev)) { 761 mutex_lock(&aq_nic->fwreq_mutex); 762 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw); 763 mutex_unlock(&aq_nic->fwreq_mutex); 764 } 765 766 return err; 767 } 768 769 static void aq_ethtool_get_pauseparam(struct net_device *ndev, 770 struct ethtool_pauseparam *pause) 771 { 772 struct aq_nic_s *aq_nic = netdev_priv(ndev); 773 int fc = aq_nic->aq_nic_cfg.fc.req; 774 775 pause->autoneg = 0; 776 777 pause->rx_pause = !!(fc & AQ_NIC_FC_RX); 778 pause->tx_pause = !!(fc & AQ_NIC_FC_TX); 779 } 780 781 static int aq_ethtool_set_pauseparam(struct net_device *ndev, 782 struct ethtool_pauseparam *pause) 783 { 784 struct aq_nic_s *aq_nic = netdev_priv(ndev); 785 int err = 0; 786 787 if (!aq_nic->aq_fw_ops->set_flow_control) 788 return -EOPNOTSUPP; 789 790 if (pause->autoneg == AUTONEG_ENABLE) 791 return -EOPNOTSUPP; 792 793 if (pause->rx_pause) 794 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX; 795 else 796 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX; 797 798 if (pause->tx_pause) 799 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX; 800 else 801 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX; 802 803 mutex_lock(&aq_nic->fwreq_mutex); 804 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw); 805 mutex_unlock(&aq_nic->fwreq_mutex); 806 807 return err; 808 } 809 810 static void aq_get_ringparam(struct net_device *ndev, 811 struct ethtool_ringparam *ring) 812 { 813 struct aq_nic_s *aq_nic = netdev_priv(ndev); 814 struct aq_nic_cfg_s *cfg; 815 816 cfg = aq_nic_get_cfg(aq_nic); 817 818 ring->rx_pending = cfg->rxds; 819 ring->tx_pending = cfg->txds; 820 821 ring->rx_max_pending = cfg->aq_hw_caps->rxds_max; 822 ring->tx_max_pending = cfg->aq_hw_caps->txds_max; 823 } 824 825 static int aq_set_ringparam(struct net_device *ndev, 826 struct ethtool_ringparam *ring) 827 { 828 struct aq_nic_s *aq_nic = netdev_priv(ndev); 829 const struct aq_hw_caps_s *hw_caps; 830 bool ndev_running = false; 831 struct aq_nic_cfg_s *cfg; 832 int err = 0; 833 834 cfg = aq_nic_get_cfg(aq_nic); 835 hw_caps = cfg->aq_hw_caps; 836 837 if (ring->rx_mini_pending || ring->rx_jumbo_pending) { 838 err = -EOPNOTSUPP; 839 goto err_exit; 840 } 841 842 if (netif_running(ndev)) { 843 ndev_running = true; 844 dev_close(ndev); 845 } 846 847 cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); 848 cfg->rxds = min(cfg->rxds, hw_caps->rxds_max); 849 cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE); 850 851 cfg->txds = max(ring->tx_pending, hw_caps->txds_min); 852 cfg->txds = min(cfg->txds, hw_caps->txds_max); 853 cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE); 854 855 err = aq_nic_realloc_vectors(aq_nic); 856 if (err) 857 goto err_exit; 858 859 if (ndev_running) 860 err = dev_open(ndev, NULL); 861 862 err_exit: 863 return err; 864 } 865 866 static u32 aq_get_msg_level(struct net_device *ndev) 867 { 868 struct aq_nic_s *aq_nic = netdev_priv(ndev); 869 870 return aq_nic->msg_enable; 871 } 872 873 static void aq_set_msg_level(struct net_device *ndev, u32 data) 874 { 875 struct aq_nic_s *aq_nic = netdev_priv(ndev); 876 877 aq_nic->msg_enable = data; 878 } 879 880 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev) 881 { 882 struct aq_nic_s *aq_nic = netdev_priv(ndev); 883 884 return aq_nic->aq_nic_cfg.priv_flags; 885 } 886 887 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags) 888 { 889 struct aq_nic_s *aq_nic = netdev_priv(ndev); 890 struct aq_nic_cfg_s *cfg; 891 u32 priv_flags; 892 int ret = 0; 893 894 cfg = aq_nic_get_cfg(aq_nic); 895 priv_flags = cfg->priv_flags; 896 897 if (flags & ~AQ_PRIV_FLAGS_MASK) 898 return -EOPNOTSUPP; 899 900 if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) { 901 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n"); 902 return -EINVAL; 903 } 904 905 cfg->priv_flags = flags; 906 907 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) { 908 if (netif_running(ndev)) { 909 dev_close(ndev); 910 911 dev_open(ndev, NULL); 912 } 913 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) { 914 ret = aq_nic_set_loopback(aq_nic); 915 } 916 917 return ret; 918 } 919 920 static int aq_ethtool_get_phy_tunable(struct net_device *ndev, 921 const struct ethtool_tunable *tuna, void *data) 922 { 923 struct aq_nic_s *aq_nic = netdev_priv(ndev); 924 925 switch (tuna->id) { 926 case ETHTOOL_PHY_EDPD: { 927 u16 *val = data; 928 929 *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0; 930 break; 931 } 932 case ETHTOOL_PHY_DOWNSHIFT: { 933 u8 *val = data; 934 935 *val = (u8)aq_nic->aq_nic_cfg.downshift_counter; 936 break; 937 } 938 default: 939 return -EOPNOTSUPP; 940 } 941 942 return 0; 943 } 944 945 static int aq_ethtool_set_phy_tunable(struct net_device *ndev, 946 const struct ethtool_tunable *tuna, const void *data) 947 { 948 int err = -EOPNOTSUPP; 949 struct aq_nic_s *aq_nic = netdev_priv(ndev); 950 951 switch (tuna->id) { 952 case ETHTOOL_PHY_EDPD: { 953 const u16 *val = data; 954 955 err = aq_nic_set_media_detect(aq_nic, *val); 956 break; 957 } 958 case ETHTOOL_PHY_DOWNSHIFT: { 959 const u8 *val = data; 960 961 err = aq_nic_set_downshift(aq_nic, *val); 962 break; 963 } 964 default: 965 break; 966 } 967 968 return err; 969 } 970 971 const struct ethtool_ops aq_ethtool_ops = { 972 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 973 ETHTOOL_COALESCE_MAX_FRAMES, 974 .get_link = aq_ethtool_get_link, 975 .get_regs_len = aq_ethtool_get_regs_len, 976 .get_regs = aq_ethtool_get_regs, 977 .get_drvinfo = aq_ethtool_get_drvinfo, 978 .get_strings = aq_ethtool_get_strings, 979 .set_phys_id = aq_ethtool_set_phys_id, 980 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size, 981 .get_wol = aq_ethtool_get_wol, 982 .set_wol = aq_ethtool_set_wol, 983 .nway_reset = aq_ethtool_nway_reset, 984 .get_ringparam = aq_get_ringparam, 985 .set_ringparam = aq_set_ringparam, 986 .get_eee = aq_ethtool_get_eee, 987 .set_eee = aq_ethtool_set_eee, 988 .get_pauseparam = aq_ethtool_get_pauseparam, 989 .set_pauseparam = aq_ethtool_set_pauseparam, 990 .get_rxfh_key_size = aq_ethtool_get_rss_key_size, 991 .get_rxfh = aq_ethtool_get_rss, 992 .set_rxfh = aq_ethtool_set_rss, 993 .get_rxnfc = aq_ethtool_get_rxnfc, 994 .set_rxnfc = aq_ethtool_set_rxnfc, 995 .get_msglevel = aq_get_msg_level, 996 .set_msglevel = aq_set_msg_level, 997 .get_sset_count = aq_ethtool_get_sset_count, 998 .get_ethtool_stats = aq_ethtool_stats, 999 .get_priv_flags = aq_ethtool_get_priv_flags, 1000 .set_priv_flags = aq_ethtool_set_priv_flags, 1001 .get_link_ksettings = aq_ethtool_get_link_ksettings, 1002 .set_link_ksettings = aq_ethtool_set_link_ksettings, 1003 .get_coalesce = aq_ethtool_get_coalesce, 1004 .set_coalesce = aq_ethtool_set_coalesce, 1005 .get_ts_info = aq_ethtool_get_ts_info, 1006 .get_phy_tunable = aq_ethtool_get_phy_tunable, 1007 .set_phy_tunable = aq_ethtool_set_phy_tunable, 1008 }; 1009