1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Atlantic Network Driver
4 * Copyright (C) 2014-2019 aQuantia Corporation
5 * Copyright (C) 2019-2020 Marvell International Ltd.
8 /* File aq_ethtool.c: Definition of ethertool related functions. */
10 #include "aq_ethtool.h"
14 #include "aq_filters.h"
15 #include "aq_macsec.h"
17 #include <linux/ptp_clock_kernel.h>
19 static void aq_ethtool_get_regs(struct net_device *ndev,
20 struct ethtool_regs *regs, void *p)
22 struct aq_nic_s *aq_nic = netdev_priv(ndev);
25 regs_count = aq_nic_get_regs_count(aq_nic);
27 memset(p, 0, regs_count * sizeof(u32));
28 aq_nic_get_regs(aq_nic, regs, p);
31 static int aq_ethtool_get_regs_len(struct net_device *ndev)
33 struct aq_nic_s *aq_nic = netdev_priv(ndev);
36 regs_count = aq_nic_get_regs_count(aq_nic);
38 return regs_count * sizeof(u32);
41 static u32 aq_ethtool_get_link(struct net_device *ndev)
43 return ethtool_op_get_link(ndev);
46 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
47 struct ethtool_link_ksettings *cmd)
49 struct aq_nic_s *aq_nic = netdev_priv(ndev);
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;
59 aq_ethtool_set_link_ksettings(struct net_device *ndev,
60 const struct ethtool_link_ksettings *cmd)
62 struct aq_nic_s *aq_nic = netdev_priv(ndev);
64 return aq_nic_set_link_ksettings(aq_nic, cmd);
67 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
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",
102 static const char * const aq_ethtool_queue_tx_stat_names[] = {
103 "%sQueue[%d] OutPackets",
104 "%sQueue[%d] Restarts",
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",
129 "MACSec OutEccErrorPackets",
130 "MACSec OutUnctrlHitDropRedir",
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",
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",
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",
163 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
166 "DMANetworkLoopback",
167 "PHYInternalLoopback",
168 "PHYExternalLoopback",
171 static u32 aq_ethtool_n_stats(struct net_device *ndev)
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;
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);
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);
200 static void aq_ethtool_stats(struct net_device *ndev,
201 struct ethtool_stats *stats, u64 *data)
203 struct aq_nic_s *aq_nic = netdev_priv(ndev);
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);
210 #if IS_ENABLED(CONFIG_MACSEC)
211 data = aq_macsec_get_stats(aq_nic, data);
215 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
216 struct ethtool_drvinfo *drvinfo)
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;
223 firmware_version = aq_nic_get_fw_version(aq_nic);
224 regs_count = aq_nic_get_regs_count(aq_nic);
226 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
228 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
229 "%u.%u.%u", firmware_version >> 24,
230 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
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;
240 static void aq_ethtool_get_strings(struct net_device *ndev,
241 u32 stringset, u8 *data)
243 struct aq_nic_s *nic = netdev_priv(ndev);
244 struct aq_nic_cfg_s *cfg;
247 #if IS_ENABLED(CONFIG_MACSEC)
251 cfg = aq_nic_get_cfg(nic);
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);
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);
265 for (tc = 0; tc < cfg->tcs; tc++) {
267 snprintf(tc_string, 8, "TC%d ", tc);
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],
274 AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
275 p += ETH_GSTRING_LEN;
277 for (si = 0; si < tx_stat_cnt; si++) {
278 snprintf(p, ETH_GSTRING_LEN,
279 aq_ethtool_queue_tx_stat_names[si],
281 AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
282 p += ETH_GSTRING_LEN;
286 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
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);
293 snprintf(tc_string, 8, "PTP ");
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],
300 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
301 p += ETH_GSTRING_LEN;
303 if (i >= tx_ring_cnt)
305 for (si = 0; si < tx_stat_cnt; si++) {
306 snprintf(p, ETH_GSTRING_LEN,
307 aq_ethtool_queue_tx_stat_names[si],
309 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
310 p += ETH_GSTRING_LEN;
315 #if IS_ENABLED(CONFIG_MACSEC)
316 if (!nic->macsec_cfg)
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;
324 if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
328 si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
330 snprintf(p, ETH_GSTRING_LEN,
331 aq_macsec_txsc_stat_names[si], i);
332 p += ETH_GSTRING_LEN;
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)))
339 si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
341 snprintf(p, ETH_GSTRING_LEN,
342 aq_macsec_txsa_stat_names[si],
344 p += ETH_GSTRING_LEN;
348 for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
349 struct aq_macsec_rxsc *aq_rxsc;
351 if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
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)))
359 si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
361 snprintf(p, ETH_GSTRING_LEN,
362 aq_macsec_rxsa_stat_names[si],
364 p += ETH_GSTRING_LEN;
371 case ETH_SS_PRIV_FLAGS:
372 memcpy(p, aq_ethtool_priv_flag_names,
373 sizeof(aq_ethtool_priv_flag_names));
378 static int aq_ethtool_set_phys_id(struct net_device *ndev,
379 enum ethtool_phys_id_state state)
381 struct aq_nic_s *aq_nic = netdev_priv(ndev);
382 struct aq_hw_s *hw = aq_nic->aq_hw;
385 if (!aq_nic->aq_fw_ops->led_control)
388 mutex_lock(&aq_nic->fwreq_mutex);
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);
395 case ETHTOOL_ID_INACTIVE:
396 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
402 mutex_unlock(&aq_nic->fwreq_mutex);
407 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
413 ret = aq_ethtool_n_stats(ndev);
415 case ETH_SS_PRIV_FLAGS:
416 ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
425 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
427 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
430 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
432 struct aq_nic_s *aq_nic = netdev_priv(ndev);
433 struct aq_nic_cfg_s *cfg;
435 cfg = aq_nic_get_cfg(aq_nic);
437 return sizeof(cfg->aq_rss.hash_secret_key);
440 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
443 struct aq_nic_s *aq_nic = netdev_priv(ndev);
444 struct aq_nic_cfg_s *cfg;
447 cfg = aq_nic_get_cfg(aq_nic);
450 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
452 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
453 indir[i] = cfg->aq_rss.indirection_table[i];
456 memcpy(key, cfg->aq_rss.hash_secret_key,
457 sizeof(cfg->aq_rss.hash_secret_key));
462 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
463 const u8 *key, const u8 hfunc)
465 struct aq_nic_s *aq_nic = netdev_priv(netdev);
466 struct aq_nic_cfg_s *cfg;
471 cfg = aq_nic_get_cfg(aq_nic);
472 rss_entries = cfg->aq_rss.indirection_table_size;
474 /* We do not allow change in unsupported parameters */
475 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
477 /* Fill out the redirection table */
479 for (i = 0; i < rss_entries; i++)
480 cfg->aq_rss.indirection_table[i] = indir[i];
482 /* Fill out the rss hash 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,
492 err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
497 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
498 struct ethtool_rxnfc *cmd,
501 struct aq_nic_s *aq_nic = netdev_priv(ndev);
502 struct aq_nic_cfg_s *cfg;
505 cfg = aq_nic_get_cfg(aq_nic);
508 case ETHTOOL_GRXRINGS:
509 cmd->data = cfg->vecs;
511 case ETHTOOL_GRXCLSRLCNT:
512 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
514 case ETHTOOL_GRXCLSRULE:
515 err = aq_get_rxnfc_rule(aq_nic, cmd);
517 case ETHTOOL_GRXCLSRLALL:
518 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
528 static int aq_ethtool_set_rxnfc(struct net_device *ndev,
529 struct ethtool_rxnfc *cmd)
531 struct aq_nic_s *aq_nic = netdev_priv(ndev);
535 case ETHTOOL_SRXCLSRLINS:
536 err = aq_add_rxnfc_rule(aq_nic, cmd);
538 case ETHTOOL_SRXCLSRLDEL:
539 err = aq_del_rxnfc_rule(aq_nic, cmd);
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)
554 struct aq_nic_s *aq_nic = netdev_priv(ndev);
555 struct aq_nic_cfg_s *cfg;
557 cfg = aq_nic_get_cfg(aq_nic);
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;
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;
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)
580 struct aq_nic_s *aq_nic = netdev_priv(ndev);
581 struct aq_nic_cfg_s *cfg;
583 cfg = aq_nic_get_cfg(aq_nic);
585 /* Atlantic only supports timing based coalescing
587 if (coal->rx_max_coalesced_frames > 1 ||
588 coal->tx_max_coalesced_frames > 1)
591 /* We do not support frame counting. Check this
593 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
595 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
598 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
599 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
602 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
604 cfg->rx_itr = coal->rx_coalesce_usecs;
605 cfg->tx_itr = coal->tx_coalesce_usecs;
607 return aq_nic_update_interrupt_moderation_settings(aq_nic);
610 static void aq_ethtool_get_wol(struct net_device *ndev,
611 struct ethtool_wolinfo *wol)
613 struct aq_nic_s *aq_nic = netdev_priv(ndev);
614 struct aq_nic_cfg_s *cfg;
616 cfg = aq_nic_get_cfg(aq_nic);
618 wol->supported = AQ_NIC_WOL_MODES;
619 wol->wolopts = cfg->wol;
622 static int aq_ethtool_set_wol(struct net_device *ndev,
623 struct ethtool_wolinfo *wol)
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;
630 cfg = aq_nic_get_cfg(aq_nic);
632 if (wol->wolopts & ~AQ_NIC_WOL_MODES)
635 cfg->wol = wol->wolopts;
637 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
642 static int aq_ethtool_get_ts_info(struct net_device *ndev,
643 struct ethtool_ts_info *info)
645 struct aq_nic_s *aq_nic = netdev_priv(ndev);
647 ethtool_op_get_ts_info(ndev, info);
652 info->so_timestamping |=
653 SOF_TIMESTAMPING_TX_HARDWARE |
654 SOF_TIMESTAMPING_RX_HARDWARE |
655 SOF_TIMESTAMPING_RAW_HARDWARE;
657 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
660 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
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);
666 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
667 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
673 static u32 eee_mask_to_ethtool_mask(u32 speed)
677 if (speed & AQ_NIC_RATE_EEE_10G)
678 rate |= SUPPORTED_10000baseT_Full;
680 if (speed & AQ_NIC_RATE_EEE_1G)
681 rate |= SUPPORTED_1000baseT_Full;
683 if (speed & AQ_NIC_RATE_EEE_100M)
684 rate |= SUPPORTED_100baseT_Full;
689 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
691 struct aq_nic_s *aq_nic = netdev_priv(ndev);
692 u32 rate, supported_rates;
695 if (!aq_nic->aq_fw_ops->get_eee_rate)
698 mutex_lock(&aq_nic->fwreq_mutex);
699 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
701 mutex_unlock(&aq_nic->fwreq_mutex);
705 eee->supported = eee_mask_to_ethtool_mask(supported_rates);
707 if (aq_nic->aq_nic_cfg.eee_speeds)
708 eee->advertised = eee->supported;
710 eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
712 eee->eee_enabled = !!eee->advertised;
714 eee->tx_lpi_enabled = eee->eee_enabled;
715 if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
716 eee->eee_active = true;
721 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
723 struct aq_nic_s *aq_nic = netdev_priv(ndev);
724 u32 rate, supported_rates;
725 struct aq_nic_cfg_s *cfg;
728 cfg = aq_nic_get_cfg(aq_nic);
730 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
731 !aq_nic->aq_fw_ops->set_eee_rate))
734 mutex_lock(&aq_nic->fwreq_mutex);
735 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
737 mutex_unlock(&aq_nic->fwreq_mutex);
741 if (eee->eee_enabled) {
742 rate = supported_rates;
743 cfg->eee_speeds = rate;
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);
756 static int aq_ethtool_nway_reset(struct net_device *ndev)
758 struct aq_nic_s *aq_nic = netdev_priv(ndev);
761 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
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);
773 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
774 struct ethtool_pauseparam *pause)
776 struct aq_nic_s *aq_nic = netdev_priv(ndev);
777 int fc = aq_nic->aq_nic_cfg.fc.req;
781 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
782 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
785 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
786 struct ethtool_pauseparam *pause)
788 struct aq_nic_s *aq_nic = netdev_priv(ndev);
791 if (!aq_nic->aq_fw_ops->set_flow_control)
794 if (pause->autoneg == AUTONEG_ENABLE)
798 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
800 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
803 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
805 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
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);
814 static void aq_get_ringparam(struct net_device *ndev,
815 struct ethtool_ringparam *ring)
817 struct aq_nic_s *aq_nic = netdev_priv(ndev);
818 struct aq_nic_cfg_s *cfg;
820 cfg = aq_nic_get_cfg(aq_nic);
822 ring->rx_pending = cfg->rxds;
823 ring->tx_pending = cfg->txds;
825 ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
826 ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
829 static int aq_set_ringparam(struct net_device *ndev,
830 struct ethtool_ringparam *ring)
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;
838 cfg = aq_nic_get_cfg(aq_nic);
839 hw_caps = cfg->aq_hw_caps;
841 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
846 if (netif_running(ndev)) {
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);
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);
859 err = aq_nic_realloc_vectors(aq_nic);
864 err = dev_open(ndev, NULL);
870 static u32 aq_get_msg_level(struct net_device *ndev)
872 struct aq_nic_s *aq_nic = netdev_priv(ndev);
874 return aq_nic->msg_enable;
877 static void aq_set_msg_level(struct net_device *ndev, u32 data)
879 struct aq_nic_s *aq_nic = netdev_priv(ndev);
881 aq_nic->msg_enable = data;
884 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
886 struct aq_nic_s *aq_nic = netdev_priv(ndev);
888 return aq_nic->aq_nic_cfg.priv_flags;
891 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
893 struct aq_nic_s *aq_nic = netdev_priv(ndev);
894 struct aq_nic_cfg_s *cfg;
898 cfg = aq_nic_get_cfg(aq_nic);
899 priv_flags = cfg->priv_flags;
901 if (flags & ~AQ_PRIV_FLAGS_MASK)
904 if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
905 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
909 cfg->priv_flags = flags;
911 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
912 if (netif_running(ndev)) {
915 dev_open(ndev, NULL);
917 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
918 ret = aq_nic_set_loopback(aq_nic);
924 static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
925 const struct ethtool_tunable *tuna, void *data)
927 struct aq_nic_s *aq_nic = netdev_priv(ndev);
930 case ETHTOOL_PHY_EDPD: {
933 *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
936 case ETHTOOL_PHY_DOWNSHIFT: {
939 *val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
949 static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
950 const struct ethtool_tunable *tuna, const void *data)
952 int err = -EOPNOTSUPP;
953 struct aq_nic_s *aq_nic = netdev_priv(ndev);
956 case ETHTOOL_PHY_EDPD: {
957 const u16 *val = data;
959 err = aq_nic_set_media_detect(aq_nic, *val);
962 case ETHTOOL_PHY_DOWNSHIFT: {
963 const u8 *val = data;
965 err = aq_nic_set_downshift(aq_nic, *val);
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,