1 // SPDX-License-Identifier: GPL-2.0-only
3 * aQuantia Corporation Network Driver
4 * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
7 /* File aq_ethtool.c: Definition of ethertool related functions. */
9 #include "aq_ethtool.h"
13 #include "aq_filters.h"
14 #include "aq_macsec.h"
16 #include <linux/ptp_clock_kernel.h>
18 static void aq_ethtool_get_regs(struct net_device
*ndev
,
19 struct ethtool_regs
*regs
, void *p
)
21 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
24 regs_count
= aq_nic_get_regs_count(aq_nic
);
26 memset(p
, 0, regs_count
* sizeof(u32
));
27 aq_nic_get_regs(aq_nic
, regs
, p
);
30 static int aq_ethtool_get_regs_len(struct net_device
*ndev
)
32 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
35 regs_count
= aq_nic_get_regs_count(aq_nic
);
37 return regs_count
* sizeof(u32
);
40 static u32
aq_ethtool_get_link(struct net_device
*ndev
)
42 return ethtool_op_get_link(ndev
);
45 static int aq_ethtool_get_link_ksettings(struct net_device
*ndev
,
46 struct ethtool_link_ksettings
*cmd
)
48 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
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;
58 aq_ethtool_set_link_ksettings(struct net_device
*ndev
,
59 const struct ethtool_link_ksettings
*cmd
)
61 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
63 return aq_nic_set_link_ksettings(aq_nic
, cmd
);
66 static const char aq_ethtool_stat_names
[][ETH_GSTRING_LEN
] = {
91 static const char aq_ethtool_queue_stat_names
[][ETH_GSTRING_LEN
] = {
92 "Queue[%d] InPackets",
93 "Queue[%d] OutPackets",
95 "Queue[%d] InJumboPackets",
96 "Queue[%d] InLroPackets",
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",
122 "MACSec OutEccErrorPackets",
123 "MACSec OutUnctrlHitDropRedir",
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",
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",
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",
156 static const char aq_ethtool_priv_flag_names
[][ETH_GSTRING_LEN
] = {
159 "DMANetworkLoopback",
160 "PHYInternalLoopback",
161 "PHYExternalLoopback",
164 static u32
aq_ethtool_n_stats(struct net_device
*ndev
)
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
;
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
);
186 static void aq_ethtool_stats(struct net_device
*ndev
,
187 struct ethtool_stats
*stats
, u64
*data
)
189 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
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
);
198 static void aq_ethtool_get_drvinfo(struct net_device
*ndev
,
199 struct ethtool_drvinfo
*drvinfo
)
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
;
206 firmware_version
= aq_nic_get_fw_version(aq_nic
);
207 regs_count
= aq_nic_get_regs_count(aq_nic
);
209 strlcat(drvinfo
->driver
, AQ_CFG_DRV_NAME
, sizeof(drvinfo
->driver
));
211 snprintf(drvinfo
->fw_version
, sizeof(drvinfo
->fw_version
),
212 "%u.%u.%u", firmware_version
>> 24,
213 (firmware_version
>> 16) & 0xFFU
, firmware_version
& 0xFFFFU
);
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;
223 static void aq_ethtool_get_strings(struct net_device
*ndev
,
224 u32 stringset
, u8
*data
)
226 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
227 struct aq_nic_cfg_s
*cfg
;
230 #if IS_ENABLED(CONFIG_MACSEC)
234 cfg
= aq_nic_get_cfg(aq_nic
);
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
++) {
243 si
< ARRAY_SIZE(aq_ethtool_queue_stat_names
);
245 snprintf(p
, ETH_GSTRING_LEN
,
246 aq_ethtool_queue_stat_names
[si
], i
);
247 p
+= ETH_GSTRING_LEN
;
250 #if IS_ENABLED(CONFIG_MACSEC)
251 if (!aq_nic
->macsec_cfg
)
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
;
259 if (!(test_bit(i
, &aq_nic
->macsec_cfg
->txsc_idx_busy
)))
263 si
< ARRAY_SIZE(aq_macsec_txsc_stat_names
);
265 snprintf(p
, ETH_GSTRING_LEN
,
266 aq_macsec_txsc_stat_names
[si
], i
);
267 p
+= ETH_GSTRING_LEN
;
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
)))
274 si
< ARRAY_SIZE(aq_macsec_txsa_stat_names
);
276 snprintf(p
, ETH_GSTRING_LEN
,
277 aq_macsec_txsa_stat_names
[si
],
279 p
+= ETH_GSTRING_LEN
;
283 for (i
= 0; i
< AQ_MACSEC_MAX_SC
; i
++) {
284 struct aq_macsec_rxsc
*aq_rxsc
;
286 if (!(test_bit(i
, &aq_nic
->macsec_cfg
->rxsc_idx_busy
)))
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
)))
294 si
< ARRAY_SIZE(aq_macsec_rxsa_stat_names
);
296 snprintf(p
, ETH_GSTRING_LEN
,
297 aq_macsec_rxsa_stat_names
[si
],
299 p
+= ETH_GSTRING_LEN
;
305 case ETH_SS_PRIV_FLAGS
:
306 memcpy(p
, aq_ethtool_priv_flag_names
,
307 sizeof(aq_ethtool_priv_flag_names
));
312 static int aq_ethtool_set_phys_id(struct net_device
*ndev
,
313 enum ethtool_phys_id_state state
)
315 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
316 struct aq_hw_s
*hw
= aq_nic
->aq_hw
;
319 if (!aq_nic
->aq_fw_ops
->led_control
)
322 mutex_lock(&aq_nic
->fwreq_mutex
);
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);
329 case ETHTOOL_ID_INACTIVE
:
330 ret
= aq_nic
->aq_fw_ops
->led_control(hw
, AQ_HW_LED_DEFAULT
);
336 mutex_unlock(&aq_nic
->fwreq_mutex
);
341 static int aq_ethtool_get_sset_count(struct net_device
*ndev
, int stringset
)
347 ret
= aq_ethtool_n_stats(ndev
);
349 case ETH_SS_PRIV_FLAGS
:
350 ret
= ARRAY_SIZE(aq_ethtool_priv_flag_names
);
359 static u32
aq_ethtool_get_rss_indir_size(struct net_device
*ndev
)
361 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX
;
364 static u32
aq_ethtool_get_rss_key_size(struct net_device
*ndev
)
366 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
367 struct aq_nic_cfg_s
*cfg
;
369 cfg
= aq_nic_get_cfg(aq_nic
);
371 return sizeof(cfg
->aq_rss
.hash_secret_key
);
374 static int aq_ethtool_get_rss(struct net_device
*ndev
, u32
*indir
, u8
*key
,
377 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
378 struct aq_nic_cfg_s
*cfg
;
381 cfg
= aq_nic_get_cfg(aq_nic
);
384 *hfunc
= ETH_RSS_HASH_TOP
; /* Toeplitz */
386 for (i
= 0; i
< AQ_CFG_RSS_INDIRECTION_TABLE_MAX
; i
++)
387 indir
[i
] = cfg
->aq_rss
.indirection_table
[i
];
390 memcpy(key
, cfg
->aq_rss
.hash_secret_key
,
391 sizeof(cfg
->aq_rss
.hash_secret_key
));
396 static int aq_ethtool_set_rss(struct net_device
*netdev
, const u32
*indir
,
397 const u8
*key
, const u8 hfunc
)
399 struct aq_nic_s
*aq_nic
= netdev_priv(netdev
);
400 struct aq_nic_cfg_s
*cfg
;
405 cfg
= aq_nic_get_cfg(aq_nic
);
406 rss_entries
= cfg
->aq_rss
.indirection_table_size
;
408 /* We do not allow change in unsupported parameters */
409 if (hfunc
!= ETH_RSS_HASH_NO_CHANGE
&& hfunc
!= ETH_RSS_HASH_TOP
)
411 /* Fill out the redirection table */
413 for (i
= 0; i
< rss_entries
; i
++)
414 cfg
->aq_rss
.indirection_table
[i
] = indir
[i
];
416 /* Fill out the rss hash 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
,
426 err
= aq_nic
->aq_hw_ops
->hw_rss_set(aq_nic
->aq_hw
, &cfg
->aq_rss
);
431 static int aq_ethtool_get_rxnfc(struct net_device
*ndev
,
432 struct ethtool_rxnfc
*cmd
,
435 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
436 struct aq_nic_cfg_s
*cfg
;
439 cfg
= aq_nic_get_cfg(aq_nic
);
442 case ETHTOOL_GRXRINGS
:
443 cmd
->data
= cfg
->vecs
;
445 case ETHTOOL_GRXCLSRLCNT
:
446 cmd
->rule_cnt
= aq_get_rxnfc_count_all_rules(aq_nic
);
448 case ETHTOOL_GRXCLSRULE
:
449 err
= aq_get_rxnfc_rule(aq_nic
, cmd
);
451 case ETHTOOL_GRXCLSRLALL
:
452 err
= aq_get_rxnfc_all_rules(aq_nic
, cmd
, rule_locs
);
462 static int aq_ethtool_set_rxnfc(struct net_device
*ndev
,
463 struct ethtool_rxnfc
*cmd
)
465 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
469 case ETHTOOL_SRXCLSRLINS
:
470 err
= aq_add_rxnfc_rule(aq_nic
, cmd
);
472 case ETHTOOL_SRXCLSRLDEL
:
473 err
= aq_del_rxnfc_rule(aq_nic
, cmd
);
483 static int aq_ethtool_get_coalesce(struct net_device
*ndev
,
484 struct ethtool_coalesce
*coal
)
486 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
487 struct aq_nic_cfg_s
*cfg
;
489 cfg
= aq_nic_get_cfg(aq_nic
);
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;
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;
507 static int aq_ethtool_set_coalesce(struct net_device
*ndev
,
508 struct ethtool_coalesce
*coal
)
510 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
511 struct aq_nic_cfg_s
*cfg
;
513 cfg
= aq_nic_get_cfg(aq_nic
);
515 /* Atlantic only supports timing based coalescing
517 if (coal
->rx_max_coalesced_frames
> 1 ||
518 coal
->tx_max_coalesced_frames
> 1)
521 /* We do not support frame counting. Check this
523 if (!(coal
->rx_max_coalesced_frames
== !coal
->rx_coalesce_usecs
))
525 if (!(coal
->tx_max_coalesced_frames
== !coal
->tx_coalesce_usecs
))
528 if (coal
->rx_coalesce_usecs
> AQ_CFG_INTERRUPT_MODERATION_USEC_MAX
||
529 coal
->tx_coalesce_usecs
> AQ_CFG_INTERRUPT_MODERATION_USEC_MAX
)
532 cfg
->itr
= AQ_CFG_INTERRUPT_MODERATION_ON
;
534 cfg
->rx_itr
= coal
->rx_coalesce_usecs
;
535 cfg
->tx_itr
= coal
->tx_coalesce_usecs
;
537 return aq_nic_update_interrupt_moderation_settings(aq_nic
);
540 static void aq_ethtool_get_wol(struct net_device
*ndev
,
541 struct ethtool_wolinfo
*wol
)
543 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
544 struct aq_nic_cfg_s
*cfg
;
546 cfg
= aq_nic_get_cfg(aq_nic
);
548 wol
->supported
= AQ_NIC_WOL_MODES
;
549 wol
->wolopts
= cfg
->wol
;
552 static int aq_ethtool_set_wol(struct net_device
*ndev
,
553 struct ethtool_wolinfo
*wol
)
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
;
560 cfg
= aq_nic_get_cfg(aq_nic
);
562 if (wol
->wolopts
& ~AQ_NIC_WOL_MODES
)
565 cfg
->wol
= wol
->wolopts
;
567 err
= device_set_wakeup_enable(&pdev
->dev
, !!cfg
->wol
);
572 static int aq_ethtool_get_ts_info(struct net_device
*ndev
,
573 struct ethtool_ts_info
*info
)
575 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
577 ethtool_op_get_ts_info(ndev
, info
);
582 info
->so_timestamping
|=
583 SOF_TIMESTAMPING_TX_HARDWARE
|
584 SOF_TIMESTAMPING_RX_HARDWARE
|
585 SOF_TIMESTAMPING_RAW_HARDWARE
;
587 info
->tx_types
= BIT(HWTSTAMP_TX_OFF
) |
590 info
->rx_filters
= BIT(HWTSTAMP_FILTER_NONE
);
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
);
596 info
->phc_index
= ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic
->aq_ptp
));
601 static enum hw_atl_fw2x_rate
eee_mask_to_ethtool_mask(u32 speed
)
605 if (speed
& AQ_NIC_RATE_EEE_10G
)
606 rate
|= SUPPORTED_10000baseT_Full
;
608 if (speed
& AQ_NIC_RATE_EEE_2GS
)
609 rate
|= SUPPORTED_2500baseX_Full
;
611 if (speed
& AQ_NIC_RATE_EEE_1G
)
612 rate
|= SUPPORTED_1000baseT_Full
;
617 static int aq_ethtool_get_eee(struct net_device
*ndev
, struct ethtool_eee
*eee
)
619 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
620 u32 rate
, supported_rates
;
623 if (!aq_nic
->aq_fw_ops
->get_eee_rate
)
626 mutex_lock(&aq_nic
->fwreq_mutex
);
627 err
= aq_nic
->aq_fw_ops
->get_eee_rate(aq_nic
->aq_hw
, &rate
,
629 mutex_unlock(&aq_nic
->fwreq_mutex
);
633 eee
->supported
= eee_mask_to_ethtool_mask(supported_rates
);
635 if (aq_nic
->aq_nic_cfg
.eee_speeds
)
636 eee
->advertised
= eee
->supported
;
638 eee
->lp_advertised
= eee_mask_to_ethtool_mask(rate
);
640 eee
->eee_enabled
= !!eee
->advertised
;
642 eee
->tx_lpi_enabled
= eee
->eee_enabled
;
643 if (eee
->advertised
& eee
->lp_advertised
)
644 eee
->eee_active
= true;
649 static int aq_ethtool_set_eee(struct net_device
*ndev
, struct ethtool_eee
*eee
)
651 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
652 u32 rate
, supported_rates
;
653 struct aq_nic_cfg_s
*cfg
;
656 cfg
= aq_nic_get_cfg(aq_nic
);
658 if (unlikely(!aq_nic
->aq_fw_ops
->get_eee_rate
||
659 !aq_nic
->aq_fw_ops
->set_eee_rate
))
662 mutex_lock(&aq_nic
->fwreq_mutex
);
663 err
= aq_nic
->aq_fw_ops
->get_eee_rate(aq_nic
->aq_hw
, &rate
,
665 mutex_unlock(&aq_nic
->fwreq_mutex
);
669 if (eee
->eee_enabled
) {
670 rate
= supported_rates
;
671 cfg
->eee_speeds
= rate
;
677 mutex_lock(&aq_nic
->fwreq_mutex
);
678 err
= aq_nic
->aq_fw_ops
->set_eee_rate(aq_nic
->aq_hw
, rate
);
679 mutex_unlock(&aq_nic
->fwreq_mutex
);
684 static int aq_ethtool_nway_reset(struct net_device
*ndev
)
686 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
689 if (unlikely(!aq_nic
->aq_fw_ops
->renegotiate
))
692 if (netif_running(ndev
)) {
693 mutex_lock(&aq_nic
->fwreq_mutex
);
694 err
= aq_nic
->aq_fw_ops
->renegotiate(aq_nic
->aq_hw
);
695 mutex_unlock(&aq_nic
->fwreq_mutex
);
701 static void aq_ethtool_get_pauseparam(struct net_device
*ndev
,
702 struct ethtool_pauseparam
*pause
)
704 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
705 u32 fc
= aq_nic
->aq_nic_cfg
.fc
.req
;
709 pause
->rx_pause
= !!(fc
& AQ_NIC_FC_RX
);
710 pause
->tx_pause
= !!(fc
& AQ_NIC_FC_TX
);
714 static int aq_ethtool_set_pauseparam(struct net_device
*ndev
,
715 struct ethtool_pauseparam
*pause
)
717 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
720 if (!aq_nic
->aq_fw_ops
->set_flow_control
)
723 if (pause
->autoneg
== AUTONEG_ENABLE
)
727 aq_nic
->aq_hw
->aq_nic_cfg
->fc
.req
|= AQ_NIC_FC_RX
;
729 aq_nic
->aq_hw
->aq_nic_cfg
->fc
.req
&= ~AQ_NIC_FC_RX
;
732 aq_nic
->aq_hw
->aq_nic_cfg
->fc
.req
|= AQ_NIC_FC_TX
;
734 aq_nic
->aq_hw
->aq_nic_cfg
->fc
.req
&= ~AQ_NIC_FC_TX
;
736 mutex_lock(&aq_nic
->fwreq_mutex
);
737 err
= aq_nic
->aq_fw_ops
->set_flow_control(aq_nic
->aq_hw
);
738 mutex_unlock(&aq_nic
->fwreq_mutex
);
743 static void aq_get_ringparam(struct net_device
*ndev
,
744 struct ethtool_ringparam
*ring
)
746 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
747 struct aq_nic_cfg_s
*cfg
;
749 cfg
= aq_nic_get_cfg(aq_nic
);
751 ring
->rx_pending
= cfg
->rxds
;
752 ring
->tx_pending
= cfg
->txds
;
754 ring
->rx_max_pending
= cfg
->aq_hw_caps
->rxds_max
;
755 ring
->tx_max_pending
= cfg
->aq_hw_caps
->txds_max
;
758 static int aq_set_ringparam(struct net_device
*ndev
,
759 struct ethtool_ringparam
*ring
)
761 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
762 const struct aq_hw_caps_s
*hw_caps
;
763 bool ndev_running
= false;
764 struct aq_nic_cfg_s
*cfg
;
767 cfg
= aq_nic_get_cfg(aq_nic
);
768 hw_caps
= cfg
->aq_hw_caps
;
770 if (ring
->rx_mini_pending
|| ring
->rx_jumbo_pending
) {
775 if (netif_running(ndev
)) {
780 aq_nic_free_vectors(aq_nic
);
782 cfg
->rxds
= max(ring
->rx_pending
, hw_caps
->rxds_min
);
783 cfg
->rxds
= min(cfg
->rxds
, hw_caps
->rxds_max
);
784 cfg
->rxds
= ALIGN(cfg
->rxds
, AQ_HW_RXD_MULTIPLE
);
786 cfg
->txds
= max(ring
->tx_pending
, hw_caps
->txds_min
);
787 cfg
->txds
= min(cfg
->txds
, hw_caps
->txds_max
);
788 cfg
->txds
= ALIGN(cfg
->txds
, AQ_HW_TXD_MULTIPLE
);
790 for (aq_nic
->aq_vecs
= 0; aq_nic
->aq_vecs
< cfg
->vecs
;
792 aq_nic
->aq_vec
[aq_nic
->aq_vecs
] =
793 aq_vec_alloc(aq_nic
, aq_nic
->aq_vecs
, cfg
);
794 if (unlikely(!aq_nic
->aq_vec
[aq_nic
->aq_vecs
])) {
800 err
= dev_open(ndev
, NULL
);
806 static u32
aq_get_msg_level(struct net_device
*ndev
)
808 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
810 return aq_nic
->msg_enable
;
813 static void aq_set_msg_level(struct net_device
*ndev
, u32 data
)
815 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
817 aq_nic
->msg_enable
= data
;
820 static u32
aq_ethtool_get_priv_flags(struct net_device
*ndev
)
822 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
824 return aq_nic
->aq_nic_cfg
.priv_flags
;
827 static int aq_ethtool_set_priv_flags(struct net_device
*ndev
, u32 flags
)
829 struct aq_nic_s
*aq_nic
= netdev_priv(ndev
);
830 struct aq_nic_cfg_s
*cfg
;
833 cfg
= aq_nic_get_cfg(aq_nic
);
834 priv_flags
= cfg
->priv_flags
;
836 if (flags
& ~AQ_PRIV_FLAGS_MASK
)
839 if (hweight32((flags
| priv_flags
) & AQ_HW_LOOPBACK_MASK
) > 1) {
840 netdev_info(ndev
, "Can't enable more than one loopback simultaneously\n");
844 cfg
->priv_flags
= flags
;
846 if ((priv_flags
^ flags
) & BIT(AQ_HW_LOOPBACK_DMA_NET
)) {
847 if (netif_running(ndev
)) {
850 dev_open(ndev
, NULL
);
852 } else if ((priv_flags
^ flags
) & AQ_HW_LOOPBACK_MASK
) {
853 aq_nic_set_loopback(aq_nic
);
859 const struct ethtool_ops aq_ethtool_ops
= {
860 .supported_coalesce_params
= ETHTOOL_COALESCE_USECS
|
861 ETHTOOL_COALESCE_MAX_FRAMES
,
862 .get_link
= aq_ethtool_get_link
,
863 .get_regs_len
= aq_ethtool_get_regs_len
,
864 .get_regs
= aq_ethtool_get_regs
,
865 .get_drvinfo
= aq_ethtool_get_drvinfo
,
866 .get_strings
= aq_ethtool_get_strings
,
867 .set_phys_id
= aq_ethtool_set_phys_id
,
868 .get_rxfh_indir_size
= aq_ethtool_get_rss_indir_size
,
869 .get_wol
= aq_ethtool_get_wol
,
870 .set_wol
= aq_ethtool_set_wol
,
871 .nway_reset
= aq_ethtool_nway_reset
,
872 .get_ringparam
= aq_get_ringparam
,
873 .set_ringparam
= aq_set_ringparam
,
874 .get_eee
= aq_ethtool_get_eee
,
875 .set_eee
= aq_ethtool_set_eee
,
876 .get_pauseparam
= aq_ethtool_get_pauseparam
,
877 .set_pauseparam
= aq_ethtool_set_pauseparam
,
878 .get_rxfh_key_size
= aq_ethtool_get_rss_key_size
,
879 .get_rxfh
= aq_ethtool_get_rss
,
880 .set_rxfh
= aq_ethtool_set_rss
,
881 .get_rxnfc
= aq_ethtool_get_rxnfc
,
882 .set_rxnfc
= aq_ethtool_set_rxnfc
,
883 .get_msglevel
= aq_get_msg_level
,
884 .set_msglevel
= aq_set_msg_level
,
885 .get_sset_count
= aq_ethtool_get_sset_count
,
886 .get_ethtool_stats
= aq_ethtool_stats
,
887 .get_priv_flags
= aq_ethtool_get_priv_flags
,
888 .set_priv_flags
= aq_ethtool_set_priv_flags
,
889 .get_link_ksettings
= aq_ethtool_get_link_ksettings
,
890 .set_link_ksettings
= aq_ethtool_set_link_ksettings
,
891 .get_coalesce
= aq_ethtool_get_coalesce
,
892 .set_coalesce
= aq_ethtool_set_coalesce
,
893 .get_ts_info
= aq_ethtool_get_ts_info
,