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