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