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