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