xref: /linux/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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 
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 
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 
44 static u32 aq_ethtool_get_link(struct net_device *ndev)
45 {
46 	return ethtool_op_get_link(ndev);
47 }
48 
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
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 
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 
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 
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 
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 
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 
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 
430 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
431 {
432 	return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
433 }
434 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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