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