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