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