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