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