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