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
aq_ethtool_get_regs(struct net_device * ndev,struct ethtool_regs * regs,void * p)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
aq_ethtool_get_regs_len(struct net_device * ndev)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
aq_ethtool_get_link(struct net_device * ndev)41 static u32 aq_ethtool_get_link(struct net_device *ndev)
42 {
43 return ethtool_op_get_link(ndev);
44 }
45
aq_ethtool_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)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
aq_ethtool_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)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
aq_ethtool_n_stats(struct net_device * ndev)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
aq_ethtool_stats(struct net_device * ndev,struct ethtool_stats * stats,u64 * data)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
aq_ethtool_get_drvinfo(struct net_device * ndev,struct ethtool_drvinfo * drvinfo)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
aq_ethtool_get_strings(struct net_device * ndev,u32 stringset,u8 * data)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
aq_ethtool_set_phys_id(struct net_device * ndev,enum ethtool_phys_id_state state)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
aq_ethtool_get_sset_count(struct net_device * ndev,int stringset)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
aq_ethtool_get_rss_indir_size(struct net_device * ndev)425 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
426 {
427 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
428 }
429
aq_ethtool_get_rss_key_size(struct net_device * ndev)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
aq_ethtool_get_rss(struct net_device * ndev,u32 * indir,u8 * key,u8 * hfunc)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
aq_ethtool_set_rss(struct net_device * netdev,const u32 * indir,const u8 * key,const u8 hfunc)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
aq_ethtool_get_rxnfc(struct net_device * ndev,struct ethtool_rxnfc * cmd,u32 * rule_locs)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
aq_ethtool_set_rxnfc(struct net_device * ndev,struct ethtool_rxnfc * cmd)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
aq_ethtool_get_coalesce(struct net_device * ndev,struct ethtool_coalesce * coal)549 static int aq_ethtool_get_coalesce(struct net_device *ndev,
550 struct ethtool_coalesce *coal)
551 {
552 struct aq_nic_s *aq_nic = netdev_priv(ndev);
553 struct aq_nic_cfg_s *cfg;
554
555 cfg = aq_nic_get_cfg(aq_nic);
556
557 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
558 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
559 coal->rx_coalesce_usecs = cfg->rx_itr;
560 coal->tx_coalesce_usecs = cfg->tx_itr;
561 coal->rx_max_coalesced_frames = 0;
562 coal->tx_max_coalesced_frames = 0;
563 } else {
564 coal->rx_coalesce_usecs = 0;
565 coal->tx_coalesce_usecs = 0;
566 coal->rx_max_coalesced_frames = 1;
567 coal->tx_max_coalesced_frames = 1;
568 }
569
570 return 0;
571 }
572
aq_ethtool_set_coalesce(struct net_device * ndev,struct ethtool_coalesce * coal)573 static int aq_ethtool_set_coalesce(struct net_device *ndev,
574 struct ethtool_coalesce *coal)
575 {
576 struct aq_nic_s *aq_nic = netdev_priv(ndev);
577 struct aq_nic_cfg_s *cfg;
578
579 cfg = aq_nic_get_cfg(aq_nic);
580
581 /* Atlantic only supports timing based coalescing
582 */
583 if (coal->rx_max_coalesced_frames > 1 ||
584 coal->tx_max_coalesced_frames > 1)
585 return -EOPNOTSUPP;
586
587 /* We do not support frame counting. Check this
588 */
589 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
590 return -EOPNOTSUPP;
591 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
592 return -EOPNOTSUPP;
593
594 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
595 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
596 return -EINVAL;
597
598 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
599
600 cfg->rx_itr = coal->rx_coalesce_usecs;
601 cfg->tx_itr = coal->tx_coalesce_usecs;
602
603 return aq_nic_update_interrupt_moderation_settings(aq_nic);
604 }
605
aq_ethtool_get_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)606 static void aq_ethtool_get_wol(struct net_device *ndev,
607 struct ethtool_wolinfo *wol)
608 {
609 struct aq_nic_s *aq_nic = netdev_priv(ndev);
610 struct aq_nic_cfg_s *cfg;
611
612 cfg = aq_nic_get_cfg(aq_nic);
613
614 wol->supported = AQ_NIC_WOL_MODES;
615 wol->wolopts = cfg->wol;
616 }
617
aq_ethtool_set_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)618 static int aq_ethtool_set_wol(struct net_device *ndev,
619 struct ethtool_wolinfo *wol)
620 {
621 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
622 struct aq_nic_s *aq_nic = netdev_priv(ndev);
623 struct aq_nic_cfg_s *cfg;
624 int err = 0;
625
626 cfg = aq_nic_get_cfg(aq_nic);
627
628 if (wol->wolopts & ~AQ_NIC_WOL_MODES)
629 return -EOPNOTSUPP;
630
631 cfg->wol = wol->wolopts;
632
633 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
634
635 return err;
636 }
637
aq_ethtool_get_ts_info(struct net_device * ndev,struct ethtool_ts_info * info)638 static int aq_ethtool_get_ts_info(struct net_device *ndev,
639 struct ethtool_ts_info *info)
640 {
641 struct aq_nic_s *aq_nic = netdev_priv(ndev);
642
643 ethtool_op_get_ts_info(ndev, info);
644
645 if (!aq_nic->aq_ptp)
646 return 0;
647
648 info->so_timestamping |=
649 SOF_TIMESTAMPING_TX_HARDWARE |
650 SOF_TIMESTAMPING_RX_HARDWARE |
651 SOF_TIMESTAMPING_RAW_HARDWARE;
652
653 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
654 BIT(HWTSTAMP_TX_ON);
655
656 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
657
658 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
659 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
660 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
661
662 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
663 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
664 #endif
665
666 return 0;
667 }
668
eee_mask_to_ethtool_mask(u32 speed)669 static u32 eee_mask_to_ethtool_mask(u32 speed)
670 {
671 u32 rate = 0;
672
673 if (speed & AQ_NIC_RATE_EEE_10G)
674 rate |= SUPPORTED_10000baseT_Full;
675
676 if (speed & AQ_NIC_RATE_EEE_1G)
677 rate |= SUPPORTED_1000baseT_Full;
678
679 if (speed & AQ_NIC_RATE_EEE_100M)
680 rate |= SUPPORTED_100baseT_Full;
681
682 return rate;
683 }
684
aq_ethtool_get_eee(struct net_device * ndev,struct ethtool_eee * eee)685 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
686 {
687 struct aq_nic_s *aq_nic = netdev_priv(ndev);
688 u32 rate, supported_rates;
689 int err = 0;
690
691 if (!aq_nic->aq_fw_ops->get_eee_rate)
692 return -EOPNOTSUPP;
693
694 mutex_lock(&aq_nic->fwreq_mutex);
695 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
696 &supported_rates);
697 mutex_unlock(&aq_nic->fwreq_mutex);
698 if (err < 0)
699 return err;
700
701 eee->supported = eee_mask_to_ethtool_mask(supported_rates);
702
703 if (aq_nic->aq_nic_cfg.eee_speeds)
704 eee->advertised = eee->supported;
705
706 eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
707
708 eee->eee_enabled = !!eee->advertised;
709
710 eee->tx_lpi_enabled = eee->eee_enabled;
711 if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
712 eee->eee_active = true;
713
714 return 0;
715 }
716
aq_ethtool_set_eee(struct net_device * ndev,struct ethtool_eee * eee)717 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
718 {
719 struct aq_nic_s *aq_nic = netdev_priv(ndev);
720 u32 rate, supported_rates;
721 struct aq_nic_cfg_s *cfg;
722 int err = 0;
723
724 cfg = aq_nic_get_cfg(aq_nic);
725
726 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
727 !aq_nic->aq_fw_ops->set_eee_rate))
728 return -EOPNOTSUPP;
729
730 mutex_lock(&aq_nic->fwreq_mutex);
731 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
732 &supported_rates);
733 mutex_unlock(&aq_nic->fwreq_mutex);
734 if (err < 0)
735 return err;
736
737 if (eee->eee_enabled) {
738 rate = supported_rates;
739 cfg->eee_speeds = rate;
740 } else {
741 rate = 0;
742 cfg->eee_speeds = 0;
743 }
744
745 mutex_lock(&aq_nic->fwreq_mutex);
746 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
747 mutex_unlock(&aq_nic->fwreq_mutex);
748
749 return err;
750 }
751
aq_ethtool_nway_reset(struct net_device * ndev)752 static int aq_ethtool_nway_reset(struct net_device *ndev)
753 {
754 struct aq_nic_s *aq_nic = netdev_priv(ndev);
755 int err = 0;
756
757 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
758 return -EOPNOTSUPP;
759
760 if (netif_running(ndev)) {
761 mutex_lock(&aq_nic->fwreq_mutex);
762 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
763 mutex_unlock(&aq_nic->fwreq_mutex);
764 }
765
766 return err;
767 }
768
aq_ethtool_get_pauseparam(struct net_device * ndev,struct ethtool_pauseparam * pause)769 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
770 struct ethtool_pauseparam *pause)
771 {
772 struct aq_nic_s *aq_nic = netdev_priv(ndev);
773 int fc = aq_nic->aq_nic_cfg.fc.req;
774
775 pause->autoneg = 0;
776
777 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
778 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
779 }
780
aq_ethtool_set_pauseparam(struct net_device * ndev,struct ethtool_pauseparam * pause)781 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
782 struct ethtool_pauseparam *pause)
783 {
784 struct aq_nic_s *aq_nic = netdev_priv(ndev);
785 int err = 0;
786
787 if (!aq_nic->aq_fw_ops->set_flow_control)
788 return -EOPNOTSUPP;
789
790 if (pause->autoneg == AUTONEG_ENABLE)
791 return -EOPNOTSUPP;
792
793 if (pause->rx_pause)
794 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
795 else
796 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
797
798 if (pause->tx_pause)
799 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
800 else
801 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
802
803 mutex_lock(&aq_nic->fwreq_mutex);
804 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
805 mutex_unlock(&aq_nic->fwreq_mutex);
806
807 return err;
808 }
809
aq_get_ringparam(struct net_device * ndev,struct ethtool_ringparam * ring)810 static void aq_get_ringparam(struct net_device *ndev,
811 struct ethtool_ringparam *ring)
812 {
813 struct aq_nic_s *aq_nic = netdev_priv(ndev);
814 struct aq_nic_cfg_s *cfg;
815
816 cfg = aq_nic_get_cfg(aq_nic);
817
818 ring->rx_pending = cfg->rxds;
819 ring->tx_pending = cfg->txds;
820
821 ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
822 ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
823 }
824
aq_set_ringparam(struct net_device * ndev,struct ethtool_ringparam * ring)825 static int aq_set_ringparam(struct net_device *ndev,
826 struct ethtool_ringparam *ring)
827 {
828 struct aq_nic_s *aq_nic = netdev_priv(ndev);
829 const struct aq_hw_caps_s *hw_caps;
830 bool ndev_running = false;
831 struct aq_nic_cfg_s *cfg;
832 int err = 0;
833
834 cfg = aq_nic_get_cfg(aq_nic);
835 hw_caps = cfg->aq_hw_caps;
836
837 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
838 err = -EOPNOTSUPP;
839 goto err_exit;
840 }
841
842 if (netif_running(ndev)) {
843 ndev_running = true;
844 dev_close(ndev);
845 }
846
847 cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
848 cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
849 cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
850
851 cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
852 cfg->txds = min(cfg->txds, hw_caps->txds_max);
853 cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
854
855 err = aq_nic_realloc_vectors(aq_nic);
856 if (err)
857 goto err_exit;
858
859 if (ndev_running)
860 err = dev_open(ndev, NULL);
861
862 err_exit:
863 return err;
864 }
865
aq_get_msg_level(struct net_device * ndev)866 static u32 aq_get_msg_level(struct net_device *ndev)
867 {
868 struct aq_nic_s *aq_nic = netdev_priv(ndev);
869
870 return aq_nic->msg_enable;
871 }
872
aq_set_msg_level(struct net_device * ndev,u32 data)873 static void aq_set_msg_level(struct net_device *ndev, u32 data)
874 {
875 struct aq_nic_s *aq_nic = netdev_priv(ndev);
876
877 aq_nic->msg_enable = data;
878 }
879
aq_ethtool_get_priv_flags(struct net_device * ndev)880 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
881 {
882 struct aq_nic_s *aq_nic = netdev_priv(ndev);
883
884 return aq_nic->aq_nic_cfg.priv_flags;
885 }
886
aq_ethtool_set_priv_flags(struct net_device * ndev,u32 flags)887 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
888 {
889 struct aq_nic_s *aq_nic = netdev_priv(ndev);
890 struct aq_nic_cfg_s *cfg;
891 u32 priv_flags;
892 int ret = 0;
893
894 cfg = aq_nic_get_cfg(aq_nic);
895 priv_flags = cfg->priv_flags;
896
897 if (flags & ~AQ_PRIV_FLAGS_MASK)
898 return -EOPNOTSUPP;
899
900 if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
901 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
902 return -EINVAL;
903 }
904
905 cfg->priv_flags = flags;
906
907 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
908 if (netif_running(ndev)) {
909 dev_close(ndev);
910
911 dev_open(ndev, NULL);
912 }
913 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
914 ret = aq_nic_set_loopback(aq_nic);
915 }
916
917 return ret;
918 }
919
aq_ethtool_get_phy_tunable(struct net_device * ndev,const struct ethtool_tunable * tuna,void * data)920 static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
921 const struct ethtool_tunable *tuna, void *data)
922 {
923 struct aq_nic_s *aq_nic = netdev_priv(ndev);
924
925 switch (tuna->id) {
926 case ETHTOOL_PHY_EDPD: {
927 u16 *val = data;
928
929 *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
930 break;
931 }
932 case ETHTOOL_PHY_DOWNSHIFT: {
933 u8 *val = data;
934
935 *val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
936 break;
937 }
938 default:
939 return -EOPNOTSUPP;
940 }
941
942 return 0;
943 }
944
aq_ethtool_set_phy_tunable(struct net_device * ndev,const struct ethtool_tunable * tuna,const void * data)945 static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
946 const struct ethtool_tunable *tuna, const void *data)
947 {
948 int err = -EOPNOTSUPP;
949 struct aq_nic_s *aq_nic = netdev_priv(ndev);
950
951 switch (tuna->id) {
952 case ETHTOOL_PHY_EDPD: {
953 const u16 *val = data;
954
955 err = aq_nic_set_media_detect(aq_nic, *val);
956 break;
957 }
958 case ETHTOOL_PHY_DOWNSHIFT: {
959 const u8 *val = data;
960
961 err = aq_nic_set_downshift(aq_nic, *val);
962 break;
963 }
964 default:
965 break;
966 }
967
968 return err;
969 }
970
971 const struct ethtool_ops aq_ethtool_ops = {
972 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
973 ETHTOOL_COALESCE_MAX_FRAMES,
974 .get_link = aq_ethtool_get_link,
975 .get_regs_len = aq_ethtool_get_regs_len,
976 .get_regs = aq_ethtool_get_regs,
977 .get_drvinfo = aq_ethtool_get_drvinfo,
978 .get_strings = aq_ethtool_get_strings,
979 .set_phys_id = aq_ethtool_set_phys_id,
980 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
981 .get_wol = aq_ethtool_get_wol,
982 .set_wol = aq_ethtool_set_wol,
983 .nway_reset = aq_ethtool_nway_reset,
984 .get_ringparam = aq_get_ringparam,
985 .set_ringparam = aq_set_ringparam,
986 .get_eee = aq_ethtool_get_eee,
987 .set_eee = aq_ethtool_set_eee,
988 .get_pauseparam = aq_ethtool_get_pauseparam,
989 .set_pauseparam = aq_ethtool_set_pauseparam,
990 .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
991 .get_rxfh = aq_ethtool_get_rss,
992 .set_rxfh = aq_ethtool_set_rss,
993 .get_rxnfc = aq_ethtool_get_rxnfc,
994 .set_rxnfc = aq_ethtool_set_rxnfc,
995 .get_msglevel = aq_get_msg_level,
996 .set_msglevel = aq_set_msg_level,
997 .get_sset_count = aq_ethtool_get_sset_count,
998 .get_ethtool_stats = aq_ethtool_stats,
999 .get_priv_flags = aq_ethtool_get_priv_flags,
1000 .set_priv_flags = aq_ethtool_set_priv_flags,
1001 .get_link_ksettings = aq_ethtool_get_link_ksettings,
1002 .set_link_ksettings = aq_ethtool_set_link_ksettings,
1003 .get_coalesce = aq_ethtool_get_coalesce,
1004 .set_coalesce = aq_ethtool_set_coalesce,
1005 .get_ts_info = aq_ethtool_get_ts_info,
1006 .get_phy_tunable = aq_ethtool_get_phy_tunable,
1007 .set_phy_tunable = aq_ethtool_set_phy_tunable,
1008 };
1009