175a6faf6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2ce6a690cSNikita Danilov /* Atlantic Network Driver
3ce6a690cSNikita Danilov *
4ce6a690cSNikita Danilov * Copyright (C) 2014-2019 aQuantia Corporation
5ce6a690cSNikita Danilov * Copyright (C) 2019-2020 Marvell International Ltd.
6c5760d03SDavid VomLehn */
7c5760d03SDavid VomLehn
8c5760d03SDavid VomLehn /* File aq_ethtool.c: Definition of ethertool related functions. */
9c5760d03SDavid VomLehn
10c5760d03SDavid VomLehn #include "aq_ethtool.h"
11c5760d03SDavid VomLehn #include "aq_nic.h"
12c1af5427SAnton Mikaev #include "aq_vec.h"
1384989af0SEgor Pomozov #include "aq_ptp.h"
148d0bcb01SDmitry Bogdanov #include "aq_filters.h"
15aec0f1aaSDmitry Bogdanov #include "aq_macsec.h"
16*2a838911SIzabela Bakollari #include "aq_main.h"
17c5760d03SDavid VomLehn
1884989af0SEgor Pomozov #include <linux/ptp_clock_kernel.h>
1984989af0SEgor Pomozov
aq_ethtool_get_regs(struct net_device * ndev,struct ethtool_regs * regs,void * p)20c5760d03SDavid VomLehn static void aq_ethtool_get_regs(struct net_device *ndev,
21c5760d03SDavid VomLehn struct ethtool_regs *regs, void *p)
22c5760d03SDavid VomLehn {
23c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
247b0c342fSNikita Danilov u32 regs_count;
257b0c342fSNikita Danilov
267b0c342fSNikita Danilov regs_count = aq_nic_get_regs_count(aq_nic);
27c5760d03SDavid VomLehn
28c5760d03SDavid VomLehn memset(p, 0, regs_count * sizeof(u32));
29c5760d03SDavid VomLehn aq_nic_get_regs(aq_nic, regs, p);
30c5760d03SDavid VomLehn }
31c5760d03SDavid VomLehn
aq_ethtool_get_regs_len(struct net_device * ndev)32c5760d03SDavid VomLehn static int aq_ethtool_get_regs_len(struct net_device *ndev)
33c5760d03SDavid VomLehn {
34c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
357b0c342fSNikita Danilov u32 regs_count;
367b0c342fSNikita Danilov
377b0c342fSNikita Danilov regs_count = aq_nic_get_regs_count(aq_nic);
38c5760d03SDavid VomLehn
39c5760d03SDavid VomLehn return regs_count * sizeof(u32);
40c5760d03SDavid VomLehn }
41c5760d03SDavid VomLehn
aq_ethtool_get_link(struct net_device * ndev)42c5760d03SDavid VomLehn static u32 aq_ethtool_get_link(struct net_device *ndev)
43c5760d03SDavid VomLehn {
44c5760d03SDavid VomLehn return ethtool_op_get_link(ndev);
45c5760d03SDavid VomLehn }
46c5760d03SDavid VomLehn
aq_ethtool_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)47f8244ab5SPhilippe Reynes static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
48f8244ab5SPhilippe Reynes struct ethtool_link_ksettings *cmd)
49c5760d03SDavid VomLehn {
50c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
51c5760d03SDavid VomLehn
52f8244ab5SPhilippe Reynes aq_nic_get_link_ksettings(aq_nic, cmd);
53f8244ab5SPhilippe Reynes cmd->base.speed = netif_carrier_ok(ndev) ?
54f8244ab5SPhilippe Reynes aq_nic_get_link_speed(aq_nic) : 0U;
55c5760d03SDavid VomLehn
56c5760d03SDavid VomLehn return 0;
57c5760d03SDavid VomLehn }
58c5760d03SDavid VomLehn
59f8244ab5SPhilippe Reynes static int
aq_ethtool_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)60f8244ab5SPhilippe Reynes aq_ethtool_set_link_ksettings(struct net_device *ndev,
61f8244ab5SPhilippe Reynes const struct ethtool_link_ksettings *cmd)
62c5760d03SDavid VomLehn {
63c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
64c5760d03SDavid VomLehn
65f8244ab5SPhilippe Reynes return aq_nic_set_link_ksettings(aq_nic, cmd);
66c5760d03SDavid VomLehn }
67c5760d03SDavid VomLehn
68c5760d03SDavid VomLehn static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
69c5760d03SDavid VomLehn "InPackets",
70c5760d03SDavid VomLehn "InUCast",
71c5760d03SDavid VomLehn "InMCast",
72c5760d03SDavid VomLehn "InBCast",
73c5760d03SDavid VomLehn "InErrors",
74c5760d03SDavid VomLehn "OutPackets",
75c5760d03SDavid VomLehn "OutUCast",
76c5760d03SDavid VomLehn "OutMCast",
77c5760d03SDavid VomLehn "OutBCast",
7898bc036dSIgor Russkikh "InUCastOctets",
7998bc036dSIgor Russkikh "OutUCastOctets",
8098bc036dSIgor Russkikh "InMCastOctets",
8198bc036dSIgor Russkikh "OutMCastOctets",
8298bc036dSIgor Russkikh "InBCastOctets",
8398bc036dSIgor Russkikh "OutBCastOctets",
8498bc036dSIgor Russkikh "InOctets",
8598bc036dSIgor Russkikh "OutOctets",
86c5760d03SDavid VomLehn "InPacketsDma",
87c5760d03SDavid VomLehn "OutPacketsDma",
88c5760d03SDavid VomLehn "InOctetsDma",
89c5760d03SDavid VomLehn "OutOctetsDma",
90c5760d03SDavid VomLehn "InDroppedDma",
915d8d84e9SIgor Russkikh };
925d8d84e9SIgor Russkikh
93508f2e3dSMark Starovoytov static const char * const aq_ethtool_queue_rx_stat_names[] = {
944272ba8bSMark Starovoytov "%sQueue[%d] InPackets",
954272ba8bSMark Starovoytov "%sQueue[%d] InJumboPackets",
964272ba8bSMark Starovoytov "%sQueue[%d] InLroPackets",
974272ba8bSMark Starovoytov "%sQueue[%d] InErrors",
98aa7e17a3SDmitry Bogdanov "%sQueue[%d] AllocFails",
99aa7e17a3SDmitry Bogdanov "%sQueue[%d] SkbAllocFails",
100aa7e17a3SDmitry Bogdanov "%sQueue[%d] Polls",
10126efaef7STaehee Yoo "%sQueue[%d] PageFlips",
10226efaef7STaehee Yoo "%sQueue[%d] PageReuses",
10326efaef7STaehee Yoo "%sQueue[%d] PageFrees",
10426efaef7STaehee Yoo "%sQueue[%d] XdpAbort",
10526efaef7STaehee Yoo "%sQueue[%d] XdpDrop",
10626efaef7STaehee Yoo "%sQueue[%d] XdpPass",
10726efaef7STaehee Yoo "%sQueue[%d] XdpTx",
10826efaef7STaehee Yoo "%sQueue[%d] XdpInvalid",
10926efaef7STaehee Yoo "%sQueue[%d] XdpRedirect",
110c5760d03SDavid VomLehn };
111c5760d03SDavid VomLehn
112508f2e3dSMark Starovoytov static const char * const aq_ethtool_queue_tx_stat_names[] = {
113508f2e3dSMark Starovoytov "%sQueue[%d] OutPackets",
114508f2e3dSMark Starovoytov "%sQueue[%d] Restarts",
115508f2e3dSMark Starovoytov };
116508f2e3dSMark Starovoytov
117aec0f1aaSDmitry Bogdanov #if IS_ENABLED(CONFIG_MACSEC)
118aec0f1aaSDmitry Bogdanov static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
119aec0f1aaSDmitry Bogdanov "MACSec InCtlPackets",
120aec0f1aaSDmitry Bogdanov "MACSec InTaggedMissPackets",
121aec0f1aaSDmitry Bogdanov "MACSec InUntaggedMissPackets",
122aec0f1aaSDmitry Bogdanov "MACSec InNotagPackets",
123aec0f1aaSDmitry Bogdanov "MACSec InUntaggedPackets",
124aec0f1aaSDmitry Bogdanov "MACSec InBadTagPackets",
125aec0f1aaSDmitry Bogdanov "MACSec InNoSciPackets",
126aec0f1aaSDmitry Bogdanov "MACSec InUnknownSciPackets",
127aec0f1aaSDmitry Bogdanov "MACSec InCtrlPortPassPackets",
128aec0f1aaSDmitry Bogdanov "MACSec InUnctrlPortPassPackets",
129aec0f1aaSDmitry Bogdanov "MACSec InCtrlPortFailPackets",
130aec0f1aaSDmitry Bogdanov "MACSec InUnctrlPortFailPackets",
131aec0f1aaSDmitry Bogdanov "MACSec InTooLongPackets",
132aec0f1aaSDmitry Bogdanov "MACSec InIgpocCtlPackets",
133aec0f1aaSDmitry Bogdanov "MACSec InEccErrorPackets",
134aec0f1aaSDmitry Bogdanov "MACSec InUnctrlHitDropRedir",
135aec0f1aaSDmitry Bogdanov "MACSec OutCtlPackets",
136aec0f1aaSDmitry Bogdanov "MACSec OutUnknownSaPackets",
137aec0f1aaSDmitry Bogdanov "MACSec OutUntaggedPackets",
138aec0f1aaSDmitry Bogdanov "MACSec OutTooLong",
139aec0f1aaSDmitry Bogdanov "MACSec OutEccErrorPackets",
140aec0f1aaSDmitry Bogdanov "MACSec OutUnctrlHitDropRedir",
141aec0f1aaSDmitry Bogdanov };
142aec0f1aaSDmitry Bogdanov
1433a8b4454SMark Starovoytov static const char * const aq_macsec_txsc_stat_names[] = {
144aec0f1aaSDmitry Bogdanov "MACSecTXSC%d ProtectedPkts",
145aec0f1aaSDmitry Bogdanov "MACSecTXSC%d EncryptedPkts",
146aec0f1aaSDmitry Bogdanov "MACSecTXSC%d ProtectedOctets",
147aec0f1aaSDmitry Bogdanov "MACSecTXSC%d EncryptedOctets",
148aec0f1aaSDmitry Bogdanov };
149aec0f1aaSDmitry Bogdanov
1503a8b4454SMark Starovoytov static const char * const aq_macsec_txsa_stat_names[] = {
151aec0f1aaSDmitry Bogdanov "MACSecTXSC%dSA%d HitDropRedirect",
152aec0f1aaSDmitry Bogdanov "MACSecTXSC%dSA%d Protected2Pkts",
153aec0f1aaSDmitry Bogdanov "MACSecTXSC%dSA%d ProtectedPkts",
154aec0f1aaSDmitry Bogdanov "MACSecTXSC%dSA%d EncryptedPkts",
155aec0f1aaSDmitry Bogdanov };
156aec0f1aaSDmitry Bogdanov
1573a8b4454SMark Starovoytov static const char * const aq_macsec_rxsa_stat_names[] = {
158aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d UntaggedHitPkts",
159aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d CtrlHitDrpRedir",
160aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d NotUsingSa",
161aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d UnusedSa",
162aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d NotValidPkts",
163aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d InvalidPkts",
164aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d OkPkts",
165aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d LatePkts",
166aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d DelayedPkts",
167aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d UncheckedPkts",
168aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d ValidatedOctets",
169aec0f1aaSDmitry Bogdanov "MACSecRXSC%dSA%d DecryptedOctets",
170aec0f1aaSDmitry Bogdanov };
171aec0f1aaSDmitry Bogdanov #endif
172aec0f1aaSDmitry Bogdanov
173ea4b4d7fSIgor Russkikh static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
174ea4b4d7fSIgor Russkikh "DMASystemLoopback",
175ea4b4d7fSIgor Russkikh "PKTSystemLoopback",
176ea4b4d7fSIgor Russkikh "DMANetworkLoopback",
177ea4b4d7fSIgor Russkikh "PHYInternalLoopback",
178ea4b4d7fSIgor Russkikh "PHYExternalLoopback",
179ea4b4d7fSIgor Russkikh };
180ea4b4d7fSIgor Russkikh
aq_ethtool_n_stats(struct net_device * ndev)181aec0f1aaSDmitry Bogdanov static u32 aq_ethtool_n_stats(struct net_device *ndev)
182aec0f1aaSDmitry Bogdanov {
183508f2e3dSMark Starovoytov const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
184508f2e3dSMark Starovoytov const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
185aec0f1aaSDmitry Bogdanov struct aq_nic_s *nic = netdev_priv(ndev);
186aec0f1aaSDmitry Bogdanov struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
187aec0f1aaSDmitry Bogdanov u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
188508f2e3dSMark Starovoytov (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
189aec0f1aaSDmitry Bogdanov
19014b539a3SPavel Belous #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
19114b539a3SPavel Belous n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
19214b539a3SPavel Belous tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
19314b539a3SPavel Belous #endif
19414b539a3SPavel Belous
195aec0f1aaSDmitry Bogdanov #if IS_ENABLED(CONFIG_MACSEC)
196aec0f1aaSDmitry Bogdanov if (nic->macsec_cfg) {
197aec0f1aaSDmitry Bogdanov n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
198aec0f1aaSDmitry Bogdanov ARRAY_SIZE(aq_macsec_txsc_stat_names) *
199aec0f1aaSDmitry Bogdanov aq_macsec_tx_sc_cnt(nic) +
200aec0f1aaSDmitry Bogdanov ARRAY_SIZE(aq_macsec_txsa_stat_names) *
201aec0f1aaSDmitry Bogdanov aq_macsec_tx_sa_cnt(nic) +
202aec0f1aaSDmitry Bogdanov ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
203aec0f1aaSDmitry Bogdanov aq_macsec_rx_sa_cnt(nic);
204aec0f1aaSDmitry Bogdanov }
205aec0f1aaSDmitry Bogdanov #endif
206aec0f1aaSDmitry Bogdanov
207aec0f1aaSDmitry Bogdanov return n_stats;
208aec0f1aaSDmitry Bogdanov }
209aec0f1aaSDmitry Bogdanov
aq_ethtool_stats(struct net_device * ndev,struct ethtool_stats * stats,u64 * data)210c5760d03SDavid VomLehn static void aq_ethtool_stats(struct net_device *ndev,
211c5760d03SDavid VomLehn struct ethtool_stats *stats, u64 *data)
212c5760d03SDavid VomLehn {
213c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
2147b0c342fSNikita Danilov
215aec0f1aaSDmitry Bogdanov memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
216aec0f1aaSDmitry Bogdanov data = aq_nic_get_stats(aq_nic, data);
21714b539a3SPavel Belous #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
21814b539a3SPavel Belous data = aq_ptp_get_stats(aq_nic, data);
21914b539a3SPavel Belous #endif
220aec0f1aaSDmitry Bogdanov #if IS_ENABLED(CONFIG_MACSEC)
221aec0f1aaSDmitry Bogdanov data = aq_macsec_get_stats(aq_nic, data);
222aec0f1aaSDmitry Bogdanov #endif
223c5760d03SDavid VomLehn }
224c5760d03SDavid VomLehn
aq_ethtool_get_drvinfo(struct net_device * ndev,struct ethtool_drvinfo * drvinfo)225c5760d03SDavid VomLehn static void aq_ethtool_get_drvinfo(struct net_device *ndev,
226c5760d03SDavid VomLehn struct ethtool_drvinfo *drvinfo)
227c5760d03SDavid VomLehn {
228c5760d03SDavid VomLehn struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
2297b0c342fSNikita Danilov struct aq_nic_s *aq_nic = netdev_priv(ndev);
2307b0c342fSNikita Danilov u32 firmware_version;
2317b0c342fSNikita Danilov u32 regs_count;
2327b0c342fSNikita Danilov
2337b0c342fSNikita Danilov firmware_version = aq_nic_get_fw_version(aq_nic);
2347b0c342fSNikita Danilov regs_count = aq_nic_get_regs_count(aq_nic);
235c5760d03SDavid VomLehn
236c5760d03SDavid VomLehn strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
237c5760d03SDavid VomLehn
238c5760d03SDavid VomLehn snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
239c5760d03SDavid VomLehn "%u.%u.%u", firmware_version >> 24,
240c5760d03SDavid VomLehn (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
241c5760d03SDavid VomLehn
242f029c781SWolfram Sang strscpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
243c5760d03SDavid VomLehn sizeof(drvinfo->bus_info));
244aec0f1aaSDmitry Bogdanov drvinfo->n_stats = aq_ethtool_n_stats(ndev);
245c5760d03SDavid VomLehn drvinfo->testinfo_len = 0;
246c5760d03SDavid VomLehn drvinfo->regdump_len = regs_count;
247c5760d03SDavid VomLehn drvinfo->eedump_len = 0;
248c5760d03SDavid VomLehn }
249c5760d03SDavid VomLehn
aq_ethtool_get_strings(struct net_device * ndev,u32 stringset,u8 * data)250c5760d03SDavid VomLehn static void aq_ethtool_get_strings(struct net_device *ndev,
251c5760d03SDavid VomLehn u32 stringset, u8 *data)
252c5760d03SDavid VomLehn {
2534272ba8bSMark Starovoytov struct aq_nic_s *nic = netdev_priv(ndev);
2547b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
2555d8d84e9SIgor Russkikh u8 *p = data;
2567b0c342fSNikita Danilov int i, si;
257aec0f1aaSDmitry Bogdanov #if IS_ENABLED(CONFIG_MACSEC)
258aec0f1aaSDmitry Bogdanov int sa;
259aec0f1aaSDmitry Bogdanov #endif
2607b0c342fSNikita Danilov
2614272ba8bSMark Starovoytov cfg = aq_nic_get_cfg(nic);
262c5760d03SDavid VomLehn
263ea4b4d7fSIgor Russkikh switch (stringset) {
2644272ba8bSMark Starovoytov case ETH_SS_STATS: {
265508f2e3dSMark Starovoytov const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
266508f2e3dSMark Starovoytov const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
2674272ba8bSMark Starovoytov char tc_string[8];
2684272ba8bSMark Starovoytov int tc;
2694272ba8bSMark Starovoytov
2704272ba8bSMark Starovoytov memset(tc_string, 0, sizeof(tc_string));
271ff83dbf2SNikita Danilov memcpy(p, aq_ethtool_stat_names,
2725d8d84e9SIgor Russkikh sizeof(aq_ethtool_stat_names));
2735d8d84e9SIgor Russkikh p = p + sizeof(aq_ethtool_stat_names);
2744272ba8bSMark Starovoytov
2754272ba8bSMark Starovoytov for (tc = 0; tc < cfg->tcs; tc++) {
2764272ba8bSMark Starovoytov if (cfg->is_qos)
2774272ba8bSMark Starovoytov snprintf(tc_string, 8, "TC%d ", tc);
2784272ba8bSMark Starovoytov
2795d8d84e9SIgor Russkikh for (i = 0; i < cfg->vecs; i++) {
280508f2e3dSMark Starovoytov for (si = 0; si < rx_stat_cnt; si++) {
2815d8d84e9SIgor Russkikh snprintf(p, ETH_GSTRING_LEN,
282508f2e3dSMark Starovoytov aq_ethtool_queue_rx_stat_names[si],
283508f2e3dSMark Starovoytov tc_string,
284508f2e3dSMark Starovoytov AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
285508f2e3dSMark Starovoytov p += ETH_GSTRING_LEN;
286508f2e3dSMark Starovoytov }
287508f2e3dSMark Starovoytov for (si = 0; si < tx_stat_cnt; si++) {
288508f2e3dSMark Starovoytov snprintf(p, ETH_GSTRING_LEN,
289508f2e3dSMark Starovoytov aq_ethtool_queue_tx_stat_names[si],
2904272ba8bSMark Starovoytov tc_string,
291b9e98926SMark Starovoytov AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
2925d8d84e9SIgor Russkikh p += ETH_GSTRING_LEN;
2935d8d84e9SIgor Russkikh }
2945d8d84e9SIgor Russkikh }
2954272ba8bSMark Starovoytov }
29614b539a3SPavel Belous #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
29714b539a3SPavel Belous if (nic->aq_ptp) {
29814b539a3SPavel Belous const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX);
29914b539a3SPavel Belous const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
30014b539a3SPavel Belous unsigned int ptp_ring_idx =
30114b539a3SPavel Belous aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode);
30214b539a3SPavel Belous
30314b539a3SPavel Belous snprintf(tc_string, 8, "PTP ");
30414b539a3SPavel Belous
30514b539a3SPavel Belous for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) {
30614b539a3SPavel Belous for (si = 0; si < rx_stat_cnt; si++) {
30714b539a3SPavel Belous snprintf(p, ETH_GSTRING_LEN,
30814b539a3SPavel Belous aq_ethtool_queue_rx_stat_names[si],
30914b539a3SPavel Belous tc_string,
31014b539a3SPavel Belous i ? PTP_HWST_RING_IDX : ptp_ring_idx);
31114b539a3SPavel Belous p += ETH_GSTRING_LEN;
31214b539a3SPavel Belous }
31314b539a3SPavel Belous if (i >= tx_ring_cnt)
31414b539a3SPavel Belous continue;
31514b539a3SPavel Belous for (si = 0; si < tx_stat_cnt; si++) {
31614b539a3SPavel Belous snprintf(p, ETH_GSTRING_LEN,
31714b539a3SPavel Belous aq_ethtool_queue_tx_stat_names[si],
31814b539a3SPavel Belous tc_string,
31914b539a3SPavel Belous i ? PTP_HWST_RING_IDX : ptp_ring_idx);
32014b539a3SPavel Belous p += ETH_GSTRING_LEN;
32114b539a3SPavel Belous }
32214b539a3SPavel Belous }
32314b539a3SPavel Belous }
32414b539a3SPavel Belous #endif
325aec0f1aaSDmitry Bogdanov #if IS_ENABLED(CONFIG_MACSEC)
3264272ba8bSMark Starovoytov if (!nic->macsec_cfg)
327aec0f1aaSDmitry Bogdanov break;
328aec0f1aaSDmitry Bogdanov
329aec0f1aaSDmitry Bogdanov memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
330aec0f1aaSDmitry Bogdanov p = p + sizeof(aq_macsec_stat_names);
331aec0f1aaSDmitry Bogdanov for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
332aec0f1aaSDmitry Bogdanov struct aq_macsec_txsc *aq_txsc;
333aec0f1aaSDmitry Bogdanov
3344272ba8bSMark Starovoytov if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
335aec0f1aaSDmitry Bogdanov continue;
336aec0f1aaSDmitry Bogdanov
337aec0f1aaSDmitry Bogdanov for (si = 0;
338aec0f1aaSDmitry Bogdanov si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
339aec0f1aaSDmitry Bogdanov si++) {
340aec0f1aaSDmitry Bogdanov snprintf(p, ETH_GSTRING_LEN,
341aec0f1aaSDmitry Bogdanov aq_macsec_txsc_stat_names[si], i);
342aec0f1aaSDmitry Bogdanov p += ETH_GSTRING_LEN;
343aec0f1aaSDmitry Bogdanov }
3444272ba8bSMark Starovoytov aq_txsc = &nic->macsec_cfg->aq_txsc[i];
345aec0f1aaSDmitry Bogdanov for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
346aec0f1aaSDmitry Bogdanov if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
347aec0f1aaSDmitry Bogdanov continue;
348aec0f1aaSDmitry Bogdanov for (si = 0;
349aec0f1aaSDmitry Bogdanov si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
350aec0f1aaSDmitry Bogdanov si++) {
351aec0f1aaSDmitry Bogdanov snprintf(p, ETH_GSTRING_LEN,
352aec0f1aaSDmitry Bogdanov aq_macsec_txsa_stat_names[si],
353aec0f1aaSDmitry Bogdanov i, sa);
354aec0f1aaSDmitry Bogdanov p += ETH_GSTRING_LEN;
355aec0f1aaSDmitry Bogdanov }
356aec0f1aaSDmitry Bogdanov }
357aec0f1aaSDmitry Bogdanov }
358aec0f1aaSDmitry Bogdanov for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
359aec0f1aaSDmitry Bogdanov struct aq_macsec_rxsc *aq_rxsc;
360aec0f1aaSDmitry Bogdanov
3614272ba8bSMark Starovoytov if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
362aec0f1aaSDmitry Bogdanov continue;
363aec0f1aaSDmitry Bogdanov
3644272ba8bSMark Starovoytov aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
365aec0f1aaSDmitry Bogdanov for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
366aec0f1aaSDmitry Bogdanov if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
367aec0f1aaSDmitry Bogdanov continue;
368aec0f1aaSDmitry Bogdanov for (si = 0;
369aec0f1aaSDmitry Bogdanov si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
370aec0f1aaSDmitry Bogdanov si++) {
371aec0f1aaSDmitry Bogdanov snprintf(p, ETH_GSTRING_LEN,
372aec0f1aaSDmitry Bogdanov aq_macsec_rxsa_stat_names[si],
373aec0f1aaSDmitry Bogdanov i, sa);
374aec0f1aaSDmitry Bogdanov p += ETH_GSTRING_LEN;
375aec0f1aaSDmitry Bogdanov }
376aec0f1aaSDmitry Bogdanov }
377aec0f1aaSDmitry Bogdanov }
378aec0f1aaSDmitry Bogdanov #endif
379ea4b4d7fSIgor Russkikh break;
3804272ba8bSMark Starovoytov }
381ea4b4d7fSIgor Russkikh case ETH_SS_PRIV_FLAGS:
382ea4b4d7fSIgor Russkikh memcpy(p, aq_ethtool_priv_flag_names,
383ea4b4d7fSIgor Russkikh sizeof(aq_ethtool_priv_flag_names));
384ea4b4d7fSIgor Russkikh break;
3855d8d84e9SIgor Russkikh }
386c5760d03SDavid VomLehn }
387c5760d03SDavid VomLehn
aq_ethtool_set_phys_id(struct net_device * ndev,enum ethtool_phys_id_state state)388d1287ce4SNikita Danilov static int aq_ethtool_set_phys_id(struct net_device *ndev,
389d1287ce4SNikita Danilov enum ethtool_phys_id_state state)
390d1287ce4SNikita Danilov {
391d1287ce4SNikita Danilov struct aq_nic_s *aq_nic = netdev_priv(ndev);
392d1287ce4SNikita Danilov struct aq_hw_s *hw = aq_nic->aq_hw;
393d1287ce4SNikita Danilov int ret = 0;
394d1287ce4SNikita Danilov
395d1287ce4SNikita Danilov if (!aq_nic->aq_fw_ops->led_control)
396d1287ce4SNikita Danilov return -EOPNOTSUPP;
397d1287ce4SNikita Danilov
398d1287ce4SNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
399d1287ce4SNikita Danilov
400d1287ce4SNikita Danilov switch (state) {
401d1287ce4SNikita Danilov case ETHTOOL_ID_ACTIVE:
402d1287ce4SNikita Danilov ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
403d1287ce4SNikita Danilov AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
404d1287ce4SNikita Danilov break;
405d1287ce4SNikita Danilov case ETHTOOL_ID_INACTIVE:
406d1287ce4SNikita Danilov ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
407d1287ce4SNikita Danilov break;
408d1287ce4SNikita Danilov default:
409d1287ce4SNikita Danilov break;
410d1287ce4SNikita Danilov }
411d1287ce4SNikita Danilov
412d1287ce4SNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
413d1287ce4SNikita Danilov
414d1287ce4SNikita Danilov return ret;
415d1287ce4SNikita Danilov }
416d1287ce4SNikita Danilov
aq_ethtool_get_sset_count(struct net_device * ndev,int stringset)417c5760d03SDavid VomLehn static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
418c5760d03SDavid VomLehn {
4197b0c342fSNikita Danilov int ret = 0;
4207b0c342fSNikita Danilov
421c5760d03SDavid VomLehn switch (stringset) {
422c5760d03SDavid VomLehn case ETH_SS_STATS:
423aec0f1aaSDmitry Bogdanov ret = aq_ethtool_n_stats(ndev);
424c5760d03SDavid VomLehn break;
425ea4b4d7fSIgor Russkikh case ETH_SS_PRIV_FLAGS:
426ea4b4d7fSIgor Russkikh ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
427ea4b4d7fSIgor Russkikh break;
428c5760d03SDavid VomLehn default:
429c5760d03SDavid VomLehn ret = -EOPNOTSUPP;
430c5760d03SDavid VomLehn }
4317b0c342fSNikita Danilov
432c5760d03SDavid VomLehn return ret;
433c5760d03SDavid VomLehn }
434c5760d03SDavid VomLehn
aq_ethtool_get_rss_indir_size(struct net_device * ndev)435c5760d03SDavid VomLehn static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
436c5760d03SDavid VomLehn {
437c5760d03SDavid VomLehn return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
438c5760d03SDavid VomLehn }
439c5760d03SDavid VomLehn
aq_ethtool_get_rss_key_size(struct net_device * ndev)440c5760d03SDavid VomLehn static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
441c5760d03SDavid VomLehn {
442c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
4437b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
4447b0c342fSNikita Danilov
4457b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
446c5760d03SDavid VomLehn
447c5760d03SDavid VomLehn return sizeof(cfg->aq_rss.hash_secret_key);
448c5760d03SDavid VomLehn }
449c5760d03SDavid VomLehn
aq_ethtool_get_rss(struct net_device * ndev,u32 * indir,u8 * key,u8 * hfunc)450c5760d03SDavid VomLehn static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
451c5760d03SDavid VomLehn u8 *hfunc)
452c5760d03SDavid VomLehn {
453c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
4547b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
455c5760d03SDavid VomLehn unsigned int i = 0U;
456c5760d03SDavid VomLehn
4577b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
4587b0c342fSNikita Danilov
459c5760d03SDavid VomLehn if (hfunc)
460c5760d03SDavid VomLehn *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
461c5760d03SDavid VomLehn if (indir) {
462c5760d03SDavid VomLehn for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
463c5760d03SDavid VomLehn indir[i] = cfg->aq_rss.indirection_table[i];
464c5760d03SDavid VomLehn }
465c5760d03SDavid VomLehn if (key)
466c5760d03SDavid VomLehn memcpy(key, cfg->aq_rss.hash_secret_key,
467c5760d03SDavid VomLehn sizeof(cfg->aq_rss.hash_secret_key));
4687b0c342fSNikita Danilov
469c5760d03SDavid VomLehn return 0;
470c5760d03SDavid VomLehn }
471c5760d03SDavid VomLehn
aq_ethtool_set_rss(struct net_device * netdev,const u32 * indir,const u8 * key,const u8 hfunc)47239163767SDmitry Bogdanov static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
47339163767SDmitry Bogdanov const u8 *key, const u8 hfunc)
47439163767SDmitry Bogdanov {
47539163767SDmitry Bogdanov struct aq_nic_s *aq_nic = netdev_priv(netdev);
47639163767SDmitry Bogdanov struct aq_nic_cfg_s *cfg;
47739163767SDmitry Bogdanov unsigned int i = 0U;
47839163767SDmitry Bogdanov u32 rss_entries;
47939163767SDmitry Bogdanov int err = 0;
48039163767SDmitry Bogdanov
48139163767SDmitry Bogdanov cfg = aq_nic_get_cfg(aq_nic);
48239163767SDmitry Bogdanov rss_entries = cfg->aq_rss.indirection_table_size;
48339163767SDmitry Bogdanov
48439163767SDmitry Bogdanov /* We do not allow change in unsupported parameters */
48539163767SDmitry Bogdanov if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
48639163767SDmitry Bogdanov return -EOPNOTSUPP;
48739163767SDmitry Bogdanov /* Fill out the redirection table */
48839163767SDmitry Bogdanov if (indir)
48939163767SDmitry Bogdanov for (i = 0; i < rss_entries; i++)
49039163767SDmitry Bogdanov cfg->aq_rss.indirection_table[i] = indir[i];
49139163767SDmitry Bogdanov
49239163767SDmitry Bogdanov /* Fill out the rss hash key */
49339163767SDmitry Bogdanov if (key) {
49439163767SDmitry Bogdanov memcpy(cfg->aq_rss.hash_secret_key, key,
49539163767SDmitry Bogdanov sizeof(cfg->aq_rss.hash_secret_key));
49639163767SDmitry Bogdanov err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
49739163767SDmitry Bogdanov &cfg->aq_rss);
49839163767SDmitry Bogdanov if (err)
49939163767SDmitry Bogdanov return err;
50039163767SDmitry Bogdanov }
50139163767SDmitry Bogdanov
50239163767SDmitry Bogdanov err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
50339163767SDmitry Bogdanov
50439163767SDmitry Bogdanov return err;
50539163767SDmitry Bogdanov }
50639163767SDmitry Bogdanov
aq_ethtool_get_rxnfc(struct net_device * ndev,struct ethtool_rxnfc * cmd,u32 * rule_locs)507c5760d03SDavid VomLehn static int aq_ethtool_get_rxnfc(struct net_device *ndev,
508c5760d03SDavid VomLehn struct ethtool_rxnfc *cmd,
509c5760d03SDavid VomLehn u32 *rule_locs)
510c5760d03SDavid VomLehn {
511c5760d03SDavid VomLehn struct aq_nic_s *aq_nic = netdev_priv(ndev);
5127b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
513c5760d03SDavid VomLehn int err = 0;
514c5760d03SDavid VomLehn
5157b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
5167b0c342fSNikita Danilov
517c5760d03SDavid VomLehn switch (cmd->cmd) {
518c5760d03SDavid VomLehn case ETHTOOL_GRXRINGS:
519c5760d03SDavid VomLehn cmd->data = cfg->vecs;
520c5760d03SDavid VomLehn break;
5218d0bcb01SDmitry Bogdanov case ETHTOOL_GRXCLSRLCNT:
5228d0bcb01SDmitry Bogdanov cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
5238d0bcb01SDmitry Bogdanov break;
5248d0bcb01SDmitry Bogdanov case ETHTOOL_GRXCLSRULE:
5258d0bcb01SDmitry Bogdanov err = aq_get_rxnfc_rule(aq_nic, cmd);
5268d0bcb01SDmitry Bogdanov break;
5278d0bcb01SDmitry Bogdanov case ETHTOOL_GRXCLSRLALL:
5288d0bcb01SDmitry Bogdanov err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
5298d0bcb01SDmitry Bogdanov break;
5308d0bcb01SDmitry Bogdanov default:
5318d0bcb01SDmitry Bogdanov err = -EOPNOTSUPP;
5328d0bcb01SDmitry Bogdanov break;
5338d0bcb01SDmitry Bogdanov }
534c5760d03SDavid VomLehn
5358d0bcb01SDmitry Bogdanov return err;
5368d0bcb01SDmitry Bogdanov }
5378d0bcb01SDmitry Bogdanov
aq_ethtool_set_rxnfc(struct net_device * ndev,struct ethtool_rxnfc * cmd)5388d0bcb01SDmitry Bogdanov static int aq_ethtool_set_rxnfc(struct net_device *ndev,
5398d0bcb01SDmitry Bogdanov struct ethtool_rxnfc *cmd)
5408d0bcb01SDmitry Bogdanov {
5418d0bcb01SDmitry Bogdanov struct aq_nic_s *aq_nic = netdev_priv(ndev);
5427b0c342fSNikita Danilov int err = 0;
5438d0bcb01SDmitry Bogdanov
5448d0bcb01SDmitry Bogdanov switch (cmd->cmd) {
5458d0bcb01SDmitry Bogdanov case ETHTOOL_SRXCLSRLINS:
5468d0bcb01SDmitry Bogdanov err = aq_add_rxnfc_rule(aq_nic, cmd);
5478d0bcb01SDmitry Bogdanov break;
5488d0bcb01SDmitry Bogdanov case ETHTOOL_SRXCLSRLDEL:
5498d0bcb01SDmitry Bogdanov err = aq_del_rxnfc_rule(aq_nic, cmd);
5508d0bcb01SDmitry Bogdanov break;
551c5760d03SDavid VomLehn default:
552c5760d03SDavid VomLehn err = -EOPNOTSUPP;
553c5760d03SDavid VomLehn break;
554c5760d03SDavid VomLehn }
555c5760d03SDavid VomLehn
556c5760d03SDavid VomLehn return err;
557c5760d03SDavid VomLehn }
558c5760d03SDavid VomLehn
aq_ethtool_get_coalesce(struct net_device * ndev,struct ethtool_coalesce * coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)5592660d226SWei Yongjun static int aq_ethtool_get_coalesce(struct net_device *ndev,
560f3ccfda1SYufeng Mo struct ethtool_coalesce *coal,
561f3ccfda1SYufeng Mo struct kernel_ethtool_coalesce *kernel_coal,
562f3ccfda1SYufeng Mo struct netlink_ext_ack *extack)
563b82ee71aSIgor Russkikh {
564b82ee71aSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
5657b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
5667b0c342fSNikita Danilov
5677b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
568b82ee71aSIgor Russkikh
569b82ee71aSIgor Russkikh if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
570b82ee71aSIgor Russkikh cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
571b82ee71aSIgor Russkikh coal->rx_coalesce_usecs = cfg->rx_itr;
572b82ee71aSIgor Russkikh coal->tx_coalesce_usecs = cfg->tx_itr;
573b82ee71aSIgor Russkikh coal->rx_max_coalesced_frames = 0;
574b82ee71aSIgor Russkikh coal->tx_max_coalesced_frames = 0;
575b82ee71aSIgor Russkikh } else {
576b82ee71aSIgor Russkikh coal->rx_coalesce_usecs = 0;
577b82ee71aSIgor Russkikh coal->tx_coalesce_usecs = 0;
578b82ee71aSIgor Russkikh coal->rx_max_coalesced_frames = 1;
579b82ee71aSIgor Russkikh coal->tx_max_coalesced_frames = 1;
580b82ee71aSIgor Russkikh }
5817b0c342fSNikita Danilov
582b82ee71aSIgor Russkikh return 0;
583b82ee71aSIgor Russkikh }
584b82ee71aSIgor Russkikh
aq_ethtool_set_coalesce(struct net_device * ndev,struct ethtool_coalesce * coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)5852660d226SWei Yongjun static int aq_ethtool_set_coalesce(struct net_device *ndev,
586f3ccfda1SYufeng Mo struct ethtool_coalesce *coal,
587f3ccfda1SYufeng Mo struct kernel_ethtool_coalesce *kernel_coal,
588f3ccfda1SYufeng Mo struct netlink_ext_ack *extack)
589b82ee71aSIgor Russkikh {
590b82ee71aSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
5917b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
5927b0c342fSNikita Danilov
5937b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
594b82ee71aSIgor Russkikh
595b82ee71aSIgor Russkikh /* Atlantic only supports timing based coalescing
596b82ee71aSIgor Russkikh */
597b82ee71aSIgor Russkikh if (coal->rx_max_coalesced_frames > 1 ||
598fcca747fSJakub Kicinski coal->tx_max_coalesced_frames > 1)
599b82ee71aSIgor Russkikh return -EOPNOTSUPP;
600b82ee71aSIgor Russkikh
601b82ee71aSIgor Russkikh /* We do not support frame counting. Check this
602b82ee71aSIgor Russkikh */
603b82ee71aSIgor Russkikh if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
604b82ee71aSIgor Russkikh return -EOPNOTSUPP;
605b82ee71aSIgor Russkikh if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
606b82ee71aSIgor Russkikh return -EOPNOTSUPP;
607b82ee71aSIgor Russkikh
608b82ee71aSIgor Russkikh if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
609b82ee71aSIgor Russkikh coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
610b82ee71aSIgor Russkikh return -EINVAL;
611b82ee71aSIgor Russkikh
612b82ee71aSIgor Russkikh cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
613b82ee71aSIgor Russkikh
614b82ee71aSIgor Russkikh cfg->rx_itr = coal->rx_coalesce_usecs;
615b82ee71aSIgor Russkikh cfg->tx_itr = coal->tx_coalesce_usecs;
616b82ee71aSIgor Russkikh
617b82ee71aSIgor Russkikh return aq_nic_update_interrupt_moderation_settings(aq_nic);
618b82ee71aSIgor Russkikh }
619b82ee71aSIgor Russkikh
aq_ethtool_get_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)620a0da96c0SYana Esina static void aq_ethtool_get_wol(struct net_device *ndev,
621a0da96c0SYana Esina struct ethtool_wolinfo *wol)
622a0da96c0SYana Esina {
623a0da96c0SYana Esina struct aq_nic_s *aq_nic = netdev_priv(ndev);
6247b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
6257b0c342fSNikita Danilov
6267b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
627a0da96c0SYana Esina
628837c6378SNikita Danilov wol->supported = AQ_NIC_WOL_MODES;
629837c6378SNikita Danilov wol->wolopts = cfg->wol;
630a0da96c0SYana Esina }
631a0da96c0SYana Esina
aq_ethtool_set_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)632a0da96c0SYana Esina static int aq_ethtool_set_wol(struct net_device *ndev,
633a0da96c0SYana Esina struct ethtool_wolinfo *wol)
634a0da96c0SYana Esina {
635a0da96c0SYana Esina struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
636a0da96c0SYana Esina struct aq_nic_s *aq_nic = netdev_priv(ndev);
6377b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
638a0da96c0SYana Esina int err = 0;
639a0da96c0SYana Esina
6407b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
6417b0c342fSNikita Danilov
642837c6378SNikita Danilov if (wol->wolopts & ~AQ_NIC_WOL_MODES)
643837c6378SNikita Danilov return -EOPNOTSUPP;
644837c6378SNikita Danilov
645837c6378SNikita Danilov cfg->wol = wol->wolopts;
646837c6378SNikita Danilov
647837c6378SNikita Danilov err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
648a0da96c0SYana Esina
649a0da96c0SYana Esina return err;
650a0da96c0SYana Esina }
651a0da96c0SYana Esina
aq_ethtool_get_ts_info(struct net_device * ndev,struct ethtool_ts_info * info)65284989af0SEgor Pomozov static int aq_ethtool_get_ts_info(struct net_device *ndev,
65384989af0SEgor Pomozov struct ethtool_ts_info *info)
65484989af0SEgor Pomozov {
65584989af0SEgor Pomozov struct aq_nic_s *aq_nic = netdev_priv(ndev);
65684989af0SEgor Pomozov
65784989af0SEgor Pomozov ethtool_op_get_ts_info(ndev, info);
65884989af0SEgor Pomozov
65984989af0SEgor Pomozov if (!aq_nic->aq_ptp)
66084989af0SEgor Pomozov return 0;
66184989af0SEgor Pomozov
66284989af0SEgor Pomozov info->so_timestamping |=
66384989af0SEgor Pomozov SOF_TIMESTAMPING_TX_HARDWARE |
66484989af0SEgor Pomozov SOF_TIMESTAMPING_RX_HARDWARE |
66584989af0SEgor Pomozov SOF_TIMESTAMPING_RAW_HARDWARE;
66684989af0SEgor Pomozov
66784989af0SEgor Pomozov info->tx_types = BIT(HWTSTAMP_TX_OFF) |
66884989af0SEgor Pomozov BIT(HWTSTAMP_TX_ON);
66984989af0SEgor Pomozov
67084989af0SEgor Pomozov info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
67184989af0SEgor Pomozov
67284989af0SEgor Pomozov info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
67384989af0SEgor Pomozov BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
67484989af0SEgor Pomozov BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
67584989af0SEgor Pomozov
6764378b882SIgor Russkikh #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
67784989af0SEgor Pomozov info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
6784378b882SIgor Russkikh #endif
67984989af0SEgor Pomozov
68084989af0SEgor Pomozov return 0;
68184989af0SEgor Pomozov }
68284989af0SEgor Pomozov
eee_mask_to_ethtool_mask(u32 speed)683ce6a690cSNikita Danilov static u32 eee_mask_to_ethtool_mask(u32 speed)
68492ab6407SYana Esina {
68592ab6407SYana Esina u32 rate = 0;
68692ab6407SYana Esina
68792ab6407SYana Esina if (speed & AQ_NIC_RATE_EEE_10G)
68892ab6407SYana Esina rate |= SUPPORTED_10000baseT_Full;
68992ab6407SYana Esina
69092ab6407SYana Esina if (speed & AQ_NIC_RATE_EEE_1G)
69192ab6407SYana Esina rate |= SUPPORTED_1000baseT_Full;
69292ab6407SYana Esina
6933d464aadSIgor Russkikh if (speed & AQ_NIC_RATE_EEE_100M)
6943d464aadSIgor Russkikh rate |= SUPPORTED_100baseT_Full;
6953d464aadSIgor Russkikh
69692ab6407SYana Esina return rate;
69792ab6407SYana Esina }
69892ab6407SYana Esina
aq_ethtool_get_eee(struct net_device * ndev,struct ethtool_eee * eee)69992ab6407SYana Esina static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
70092ab6407SYana Esina {
70192ab6407SYana Esina struct aq_nic_s *aq_nic = netdev_priv(ndev);
70292ab6407SYana Esina u32 rate, supported_rates;
70392ab6407SYana Esina int err = 0;
70492ab6407SYana Esina
70592ab6407SYana Esina if (!aq_nic->aq_fw_ops->get_eee_rate)
70692ab6407SYana Esina return -EOPNOTSUPP;
70792ab6407SYana Esina
708f5dce08aSNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
70992ab6407SYana Esina err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
71092ab6407SYana Esina &supported_rates);
711f5dce08aSNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
71292ab6407SYana Esina if (err < 0)
71392ab6407SYana Esina return err;
71492ab6407SYana Esina
71592ab6407SYana Esina eee->supported = eee_mask_to_ethtool_mask(supported_rates);
71692ab6407SYana Esina
71792ab6407SYana Esina if (aq_nic->aq_nic_cfg.eee_speeds)
71892ab6407SYana Esina eee->advertised = eee->supported;
71992ab6407SYana Esina
72092ab6407SYana Esina eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
72192ab6407SYana Esina
72292ab6407SYana Esina eee->eee_enabled = !!eee->advertised;
72392ab6407SYana Esina
72492ab6407SYana Esina eee->tx_lpi_enabled = eee->eee_enabled;
725ce6a690cSNikita Danilov if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
72692ab6407SYana Esina eee->eee_active = true;
72792ab6407SYana Esina
72892ab6407SYana Esina return 0;
72992ab6407SYana Esina }
73092ab6407SYana Esina
aq_ethtool_set_eee(struct net_device * ndev,struct ethtool_eee * eee)73192ab6407SYana Esina static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
73292ab6407SYana Esina {
73392ab6407SYana Esina struct aq_nic_s *aq_nic = netdev_priv(ndev);
73492ab6407SYana Esina u32 rate, supported_rates;
73592ab6407SYana Esina struct aq_nic_cfg_s *cfg;
73692ab6407SYana Esina int err = 0;
73792ab6407SYana Esina
73892ab6407SYana Esina cfg = aq_nic_get_cfg(aq_nic);
73992ab6407SYana Esina
74092ab6407SYana Esina if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
74192ab6407SYana Esina !aq_nic->aq_fw_ops->set_eee_rate))
74292ab6407SYana Esina return -EOPNOTSUPP;
74392ab6407SYana Esina
744f5dce08aSNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
74592ab6407SYana Esina err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
74692ab6407SYana Esina &supported_rates);
747f5dce08aSNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
74892ab6407SYana Esina if (err < 0)
74992ab6407SYana Esina return err;
75092ab6407SYana Esina
75192ab6407SYana Esina if (eee->eee_enabled) {
75292ab6407SYana Esina rate = supported_rates;
75392ab6407SYana Esina cfg->eee_speeds = rate;
75492ab6407SYana Esina } else {
75592ab6407SYana Esina rate = 0;
75692ab6407SYana Esina cfg->eee_speeds = 0;
75792ab6407SYana Esina }
75892ab6407SYana Esina
759f5dce08aSNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
760f5dce08aSNikita Danilov err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
761f5dce08aSNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
762f5dce08aSNikita Danilov
763f5dce08aSNikita Danilov return err;
76492ab6407SYana Esina }
76592ab6407SYana Esina
aq_ethtool_nway_reset(struct net_device * ndev)766b8d68b62SAnton Mikaev static int aq_ethtool_nway_reset(struct net_device *ndev)
767b8d68b62SAnton Mikaev {
768b8d68b62SAnton Mikaev struct aq_nic_s *aq_nic = netdev_priv(ndev);
769f5dce08aSNikita Danilov int err = 0;
770b8d68b62SAnton Mikaev
771b8d68b62SAnton Mikaev if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
772b8d68b62SAnton Mikaev return -EOPNOTSUPP;
773b8d68b62SAnton Mikaev
774f5dce08aSNikita Danilov if (netif_running(ndev)) {
775f5dce08aSNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
776f5dce08aSNikita Danilov err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
777f5dce08aSNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
778f5dce08aSNikita Danilov }
779b8d68b62SAnton Mikaev
780f5dce08aSNikita Danilov return err;
781b8d68b62SAnton Mikaev }
782b8d68b62SAnton Mikaev
aq_ethtool_get_pauseparam(struct net_device * ndev,struct ethtool_pauseparam * pause)783288551deSIgor Russkikh static void aq_ethtool_get_pauseparam(struct net_device *ndev,
784288551deSIgor Russkikh struct ethtool_pauseparam *pause)
785288551deSIgor Russkikh {
786288551deSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
787e39b8ffeSNikita Danilov int fc = aq_nic->aq_nic_cfg.fc.req;
788288551deSIgor Russkikh
789288551deSIgor Russkikh pause->autoneg = 0;
790288551deSIgor Russkikh
79135e8e8b4SIgor Russkikh pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
79235e8e8b4SIgor Russkikh pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
793288551deSIgor Russkikh }
794288551deSIgor Russkikh
aq_ethtool_set_pauseparam(struct net_device * ndev,struct ethtool_pauseparam * pause)795288551deSIgor Russkikh static int aq_ethtool_set_pauseparam(struct net_device *ndev,
796288551deSIgor Russkikh struct ethtool_pauseparam *pause)
797288551deSIgor Russkikh {
798288551deSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
799288551deSIgor Russkikh int err = 0;
800288551deSIgor Russkikh
801288551deSIgor Russkikh if (!aq_nic->aq_fw_ops->set_flow_control)
802288551deSIgor Russkikh return -EOPNOTSUPP;
803288551deSIgor Russkikh
804288551deSIgor Russkikh if (pause->autoneg == AUTONEG_ENABLE)
805288551deSIgor Russkikh return -EOPNOTSUPP;
806288551deSIgor Russkikh
807288551deSIgor Russkikh if (pause->rx_pause)
8088009bb19SNikita Danilov aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
809288551deSIgor Russkikh else
8108009bb19SNikita Danilov aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
811288551deSIgor Russkikh
812288551deSIgor Russkikh if (pause->tx_pause)
8138009bb19SNikita Danilov aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
814288551deSIgor Russkikh else
8158009bb19SNikita Danilov aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
816288551deSIgor Russkikh
817f5dce08aSNikita Danilov mutex_lock(&aq_nic->fwreq_mutex);
818288551deSIgor Russkikh err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
819f5dce08aSNikita Danilov mutex_unlock(&aq_nic->fwreq_mutex);
820288551deSIgor Russkikh
821288551deSIgor Russkikh return err;
822288551deSIgor Russkikh }
823288551deSIgor Russkikh
aq_get_ringparam(struct net_device * ndev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)824c1af5427SAnton Mikaev static void aq_get_ringparam(struct net_device *ndev,
82574624944SHao Chen struct ethtool_ringparam *ring,
82674624944SHao Chen struct kernel_ethtool_ringparam *kernel_ring,
82774624944SHao Chen struct netlink_ext_ack *extack)
828c1af5427SAnton Mikaev {
829c1af5427SAnton Mikaev struct aq_nic_s *aq_nic = netdev_priv(ndev);
8307b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
831c1af5427SAnton Mikaev
8327b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
833c1af5427SAnton Mikaev
8347b0c342fSNikita Danilov ring->rx_pending = cfg->rxds;
8357b0c342fSNikita Danilov ring->tx_pending = cfg->txds;
8367b0c342fSNikita Danilov
8377b0c342fSNikita Danilov ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
8387b0c342fSNikita Danilov ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
839c1af5427SAnton Mikaev }
840c1af5427SAnton Mikaev
aq_set_ringparam(struct net_device * ndev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)841c1af5427SAnton Mikaev static int aq_set_ringparam(struct net_device *ndev,
84274624944SHao Chen struct ethtool_ringparam *ring,
84374624944SHao Chen struct kernel_ethtool_ringparam *kernel_ring,
84474624944SHao Chen struct netlink_ext_ack *extack)
845c1af5427SAnton Mikaev {
846c1af5427SAnton Mikaev struct aq_nic_s *aq_nic = netdev_priv(ndev);
8477b0c342fSNikita Danilov const struct aq_hw_caps_s *hw_caps;
8487b0c342fSNikita Danilov bool ndev_running = false;
8497b0c342fSNikita Danilov struct aq_nic_cfg_s *cfg;
8507b0c342fSNikita Danilov int err = 0;
8517b0c342fSNikita Danilov
8527b0c342fSNikita Danilov cfg = aq_nic_get_cfg(aq_nic);
8537b0c342fSNikita Danilov hw_caps = cfg->aq_hw_caps;
854c1af5427SAnton Mikaev
855c1af5427SAnton Mikaev if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
856c1af5427SAnton Mikaev err = -EOPNOTSUPP;
857c1af5427SAnton Mikaev goto err_exit;
858c1af5427SAnton Mikaev }
859c1af5427SAnton Mikaev
860c1af5427SAnton Mikaev if (netif_running(ndev)) {
861c1af5427SAnton Mikaev ndev_running = true;
862*2a838911SIzabela Bakollari aq_ndev_close(ndev);
863c1af5427SAnton Mikaev }
864c1af5427SAnton Mikaev
8657b0c342fSNikita Danilov cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
8667b0c342fSNikita Danilov cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
8677b0c342fSNikita Danilov cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
868c1af5427SAnton Mikaev
8697b0c342fSNikita Danilov cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
8707b0c342fSNikita Danilov cfg->txds = min(cfg->txds, hw_caps->txds_max);
8717b0c342fSNikita Danilov cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
872c1af5427SAnton Mikaev
87314ef766bSMark Starovoytov err = aq_nic_realloc_vectors(aq_nic);
87414ef766bSMark Starovoytov if (err)
875c1af5427SAnton Mikaev goto err_exit;
87614ef766bSMark Starovoytov
877c1af5427SAnton Mikaev if (ndev_running)
878*2a838911SIzabela Bakollari err = aq_ndev_open(ndev);
879c1af5427SAnton Mikaev
880c1af5427SAnton Mikaev err_exit:
881c1af5427SAnton Mikaev return err;
882c1af5427SAnton Mikaev }
883c1af5427SAnton Mikaev
aq_get_msg_level(struct net_device * ndev)88458128fa0SNikita Danilov static u32 aq_get_msg_level(struct net_device *ndev)
88558128fa0SNikita Danilov {
88658128fa0SNikita Danilov struct aq_nic_s *aq_nic = netdev_priv(ndev);
88758128fa0SNikita Danilov
88858128fa0SNikita Danilov return aq_nic->msg_enable;
88958128fa0SNikita Danilov }
89058128fa0SNikita Danilov
aq_set_msg_level(struct net_device * ndev,u32 data)89158128fa0SNikita Danilov static void aq_set_msg_level(struct net_device *ndev, u32 data)
89258128fa0SNikita Danilov {
89358128fa0SNikita Danilov struct aq_nic_s *aq_nic = netdev_priv(ndev);
89458128fa0SNikita Danilov
89558128fa0SNikita Danilov aq_nic->msg_enable = data;
89658128fa0SNikita Danilov }
89758128fa0SNikita Danilov
aq_ethtool_get_priv_flags(struct net_device * ndev)8987b094968Szhengbin static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
899ea4b4d7fSIgor Russkikh {
900ea4b4d7fSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
901ea4b4d7fSIgor Russkikh
902ea4b4d7fSIgor Russkikh return aq_nic->aq_nic_cfg.priv_flags;
903ea4b4d7fSIgor Russkikh }
904ea4b4d7fSIgor Russkikh
aq_ethtool_set_priv_flags(struct net_device * ndev,u32 flags)9057b094968Szhengbin static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
906ea4b4d7fSIgor Russkikh {
907ea4b4d7fSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
908ea4b4d7fSIgor Russkikh struct aq_nic_cfg_s *cfg;
909ea4b4d7fSIgor Russkikh u32 priv_flags;
910ecab7870SDmitry Bogdanov int ret = 0;
911ea4b4d7fSIgor Russkikh
912ea4b4d7fSIgor Russkikh cfg = aq_nic_get_cfg(aq_nic);
913ea4b4d7fSIgor Russkikh priv_flags = cfg->priv_flags;
914ea4b4d7fSIgor Russkikh
915ea4b4d7fSIgor Russkikh if (flags & ~AQ_PRIV_FLAGS_MASK)
916ea4b4d7fSIgor Russkikh return -EOPNOTSUPP;
917ea4b4d7fSIgor Russkikh
918b42726fcSNikita Danilov if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
919b42726fcSNikita Danilov netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
920b42726fcSNikita Danilov return -EINVAL;
921b42726fcSNikita Danilov }
922b42726fcSNikita Danilov
923ea4b4d7fSIgor Russkikh cfg->priv_flags = flags;
924ea4b4d7fSIgor Russkikh
925ea4b4d7fSIgor Russkikh if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
926ea4b4d7fSIgor Russkikh if (netif_running(ndev)) {
927ea4b4d7fSIgor Russkikh dev_close(ndev);
928ea4b4d7fSIgor Russkikh
929ea4b4d7fSIgor Russkikh dev_open(ndev, NULL);
930ea4b4d7fSIgor Russkikh }
931ea4b4d7fSIgor Russkikh } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
932ecab7870SDmitry Bogdanov ret = aq_nic_set_loopback(aq_nic);
933ea4b4d7fSIgor Russkikh }
934ea4b4d7fSIgor Russkikh
935ecab7870SDmitry Bogdanov return ret;
936ea4b4d7fSIgor Russkikh }
937ea4b4d7fSIgor Russkikh
aq_ethtool_get_phy_tunable(struct net_device * ndev,const struct ethtool_tunable * tuna,void * data)938e193c3abSIgor Russkikh static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
939e193c3abSIgor Russkikh const struct ethtool_tunable *tuna, void *data)
940e193c3abSIgor Russkikh {
941e193c3abSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
942e193c3abSIgor Russkikh
943e193c3abSIgor Russkikh switch (tuna->id) {
94460db5e40SIgor Russkikh case ETHTOOL_PHY_EDPD: {
94560db5e40SIgor Russkikh u16 *val = data;
94660db5e40SIgor Russkikh
94760db5e40SIgor Russkikh *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
94860db5e40SIgor Russkikh break;
94960db5e40SIgor Russkikh }
950e193c3abSIgor Russkikh case ETHTOOL_PHY_DOWNSHIFT: {
951e193c3abSIgor Russkikh u8 *val = data;
952e193c3abSIgor Russkikh
953e193c3abSIgor Russkikh *val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
954e193c3abSIgor Russkikh break;
955e193c3abSIgor Russkikh }
956e193c3abSIgor Russkikh default:
957e193c3abSIgor Russkikh return -EOPNOTSUPP;
958e193c3abSIgor Russkikh }
959e193c3abSIgor Russkikh
960e193c3abSIgor Russkikh return 0;
961e193c3abSIgor Russkikh }
962e193c3abSIgor Russkikh
aq_ethtool_set_phy_tunable(struct net_device * ndev,const struct ethtool_tunable * tuna,const void * data)963e193c3abSIgor Russkikh static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
964e193c3abSIgor Russkikh const struct ethtool_tunable *tuna, const void *data)
965e193c3abSIgor Russkikh {
966e193c3abSIgor Russkikh int err = -EOPNOTSUPP;
967e193c3abSIgor Russkikh struct aq_nic_s *aq_nic = netdev_priv(ndev);
968e193c3abSIgor Russkikh
969e193c3abSIgor Russkikh switch (tuna->id) {
97060db5e40SIgor Russkikh case ETHTOOL_PHY_EDPD: {
97160db5e40SIgor Russkikh const u16 *val = data;
97260db5e40SIgor Russkikh
97360db5e40SIgor Russkikh err = aq_nic_set_media_detect(aq_nic, *val);
97460db5e40SIgor Russkikh break;
97560db5e40SIgor Russkikh }
976e193c3abSIgor Russkikh case ETHTOOL_PHY_DOWNSHIFT: {
977e193c3abSIgor Russkikh const u8 *val = data;
978e193c3abSIgor Russkikh
979e193c3abSIgor Russkikh err = aq_nic_set_downshift(aq_nic, *val);
980e193c3abSIgor Russkikh break;
981e193c3abSIgor Russkikh }
982e193c3abSIgor Russkikh default:
983e193c3abSIgor Russkikh break;
984e193c3abSIgor Russkikh }
985e193c3abSIgor Russkikh
986e193c3abSIgor Russkikh return err;
987e193c3abSIgor Russkikh }
988e193c3abSIgor Russkikh
989c5760d03SDavid VomLehn const struct ethtool_ops aq_ethtool_ops = {
990fcca747fSJakub Kicinski .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
991fcca747fSJakub Kicinski ETHTOOL_COALESCE_MAX_FRAMES,
992c5760d03SDavid VomLehn .get_link = aq_ethtool_get_link,
993c5760d03SDavid VomLehn .get_regs_len = aq_ethtool_get_regs_len,
994c5760d03SDavid VomLehn .get_regs = aq_ethtool_get_regs,
995c5760d03SDavid VomLehn .get_drvinfo = aq_ethtool_get_drvinfo,
996c5760d03SDavid VomLehn .get_strings = aq_ethtool_get_strings,
997d1287ce4SNikita Danilov .set_phys_id = aq_ethtool_set_phys_id,
998c5760d03SDavid VomLehn .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
999a0da96c0SYana Esina .get_wol = aq_ethtool_get_wol,
1000a0da96c0SYana Esina .set_wol = aq_ethtool_set_wol,
1001b8d68b62SAnton Mikaev .nway_reset = aq_ethtool_nway_reset,
1002c1af5427SAnton Mikaev .get_ringparam = aq_get_ringparam,
1003c1af5427SAnton Mikaev .set_ringparam = aq_set_ringparam,
100492ab6407SYana Esina .get_eee = aq_ethtool_get_eee,
100592ab6407SYana Esina .set_eee = aq_ethtool_set_eee,
1006288551deSIgor Russkikh .get_pauseparam = aq_ethtool_get_pauseparam,
1007288551deSIgor Russkikh .set_pauseparam = aq_ethtool_set_pauseparam,
1008c5760d03SDavid VomLehn .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
1009c5760d03SDavid VomLehn .get_rxfh = aq_ethtool_get_rss,
101039163767SDmitry Bogdanov .set_rxfh = aq_ethtool_set_rss,
1011c5760d03SDavid VomLehn .get_rxnfc = aq_ethtool_get_rxnfc,
10128d0bcb01SDmitry Bogdanov .set_rxnfc = aq_ethtool_set_rxnfc,
101358128fa0SNikita Danilov .get_msglevel = aq_get_msg_level,
101458128fa0SNikita Danilov .set_msglevel = aq_set_msg_level,
1015c5760d03SDavid VomLehn .get_sset_count = aq_ethtool_get_sset_count,
1016f8244ab5SPhilippe Reynes .get_ethtool_stats = aq_ethtool_stats,
1017ea4b4d7fSIgor Russkikh .get_priv_flags = aq_ethtool_get_priv_flags,
1018ea4b4d7fSIgor Russkikh .set_priv_flags = aq_ethtool_set_priv_flags,
1019f8244ab5SPhilippe Reynes .get_link_ksettings = aq_ethtool_get_link_ksettings,
1020f8244ab5SPhilippe Reynes .set_link_ksettings = aq_ethtool_set_link_ksettings,
1021b82ee71aSIgor Russkikh .get_coalesce = aq_ethtool_get_coalesce,
1022b82ee71aSIgor Russkikh .set_coalesce = aq_ethtool_set_coalesce,
102384989af0SEgor Pomozov .get_ts_info = aq_ethtool_get_ts_info,
1024e193c3abSIgor Russkikh .get_phy_tunable = aq_ethtool_get_phy_tunable,
1025e193c3abSIgor Russkikh .set_phy_tunable = aq_ethtool_set_phy_tunable,
1026c5760d03SDavid VomLehn };
1027