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