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