xref: /linux/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c (revision 489a5b81abbc4e1a29303dea27d1d5cc75276ea1)
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/ethtool.h>
19 #include <linux/linkmode.h>
20 #include <linux/ptp_clock_kernel.h>
21 
22 static void aq_ethtool_get_regs(struct net_device *ndev,
23 				struct ethtool_regs *regs, void *p)
24 {
25 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
26 	u32 regs_count;
27 
28 	regs_count = aq_nic_get_regs_count(aq_nic);
29 
30 	memset(p, 0, regs_count * sizeof(u32));
31 	aq_nic_get_regs(aq_nic, regs, p);
32 }
33 
34 static int aq_ethtool_get_regs_len(struct net_device *ndev)
35 {
36 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
37 	u32 regs_count;
38 
39 	regs_count = aq_nic_get_regs_count(aq_nic);
40 
41 	return regs_count * sizeof(u32);
42 }
43 
44 static u32 aq_ethtool_get_link(struct net_device *ndev)
45 {
46 	return ethtool_op_get_link(ndev);
47 }
48 
49 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
50 					 struct ethtool_link_ksettings *cmd)
51 {
52 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
53 
54 	aq_nic_get_link_ksettings(aq_nic, cmd);
55 	cmd->base.speed = netif_carrier_ok(ndev) ?
56 				aq_nic_get_link_speed(aq_nic) : 0U;
57 
58 	return 0;
59 }
60 
61 static int
62 aq_ethtool_set_link_ksettings(struct net_device *ndev,
63 			      const struct ethtool_link_ksettings *cmd)
64 {
65 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
66 
67 	return aq_nic_set_link_ksettings(aq_nic, cmd);
68 }
69 
70 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
71 	"InPackets",
72 	"InUCast",
73 	"InMCast",
74 	"InBCast",
75 	"InErrors",
76 	"OutPackets",
77 	"OutUCast",
78 	"OutMCast",
79 	"OutBCast",
80 	"InUCastOctets",
81 	"OutUCastOctets",
82 	"InMCastOctets",
83 	"OutMCastOctets",
84 	"InBCastOctets",
85 	"OutBCastOctets",
86 	"InOctets",
87 	"OutOctets",
88 	"InPacketsDma",
89 	"OutPacketsDma",
90 	"InOctetsDma",
91 	"OutOctetsDma",
92 	"InDroppedDma",
93 };
94 
95 static const char * const aq_ethtool_queue_rx_stat_names[] = {
96 	"%sQueue[%d] InPackets",
97 	"%sQueue[%d] InJumboPackets",
98 	"%sQueue[%d] InLroPackets",
99 	"%sQueue[%d] InErrors",
100 	"%sQueue[%d] AllocFails",
101 	"%sQueue[%d] SkbAllocFails",
102 	"%sQueue[%d] Polls",
103 	"%sQueue[%d] PageFlips",
104 	"%sQueue[%d] PageReuses",
105 	"%sQueue[%d] PageFrees",
106 	"%sQueue[%d] XdpAbort",
107 	"%sQueue[%d] XdpDrop",
108 	"%sQueue[%d] XdpPass",
109 	"%sQueue[%d] XdpTx",
110 	"%sQueue[%d] XdpInvalid",
111 	"%sQueue[%d] XdpRedirect",
112 };
113 
114 static const char * const aq_ethtool_queue_tx_stat_names[] = {
115 	"%sQueue[%d] OutPackets",
116 	"%sQueue[%d] Restarts",
117 };
118 
119 #if IS_ENABLED(CONFIG_MACSEC)
120 static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
121 	"MACSec InCtlPackets",
122 	"MACSec InTaggedMissPackets",
123 	"MACSec InUntaggedMissPackets",
124 	"MACSec InNotagPackets",
125 	"MACSec InUntaggedPackets",
126 	"MACSec InBadTagPackets",
127 	"MACSec InNoSciPackets",
128 	"MACSec InUnknownSciPackets",
129 	"MACSec InCtrlPortPassPackets",
130 	"MACSec InUnctrlPortPassPackets",
131 	"MACSec InCtrlPortFailPackets",
132 	"MACSec InUnctrlPortFailPackets",
133 	"MACSec InTooLongPackets",
134 	"MACSec InIgpocCtlPackets",
135 	"MACSec InEccErrorPackets",
136 	"MACSec InUnctrlHitDropRedir",
137 	"MACSec OutCtlPackets",
138 	"MACSec OutUnknownSaPackets",
139 	"MACSec OutUntaggedPackets",
140 	"MACSec OutTooLong",
141 	"MACSec OutEccErrorPackets",
142 	"MACSec OutUnctrlHitDropRedir",
143 };
144 
145 static const char * const aq_macsec_txsc_stat_names[] = {
146 	"MACSecTXSC%d ProtectedPkts",
147 	"MACSecTXSC%d EncryptedPkts",
148 	"MACSecTXSC%d ProtectedOctets",
149 	"MACSecTXSC%d EncryptedOctets",
150 };
151 
152 static const char * const aq_macsec_txsa_stat_names[] = {
153 	"MACSecTXSC%dSA%d HitDropRedirect",
154 	"MACSecTXSC%dSA%d Protected2Pkts",
155 	"MACSecTXSC%dSA%d ProtectedPkts",
156 	"MACSecTXSC%dSA%d EncryptedPkts",
157 };
158 
159 static const char * const aq_macsec_rxsa_stat_names[] = {
160 	"MACSecRXSC%dSA%d UntaggedHitPkts",
161 	"MACSecRXSC%dSA%d CtrlHitDrpRedir",
162 	"MACSecRXSC%dSA%d NotUsingSa",
163 	"MACSecRXSC%dSA%d UnusedSa",
164 	"MACSecRXSC%dSA%d NotValidPkts",
165 	"MACSecRXSC%dSA%d InvalidPkts",
166 	"MACSecRXSC%dSA%d OkPkts",
167 	"MACSecRXSC%dSA%d LatePkts",
168 	"MACSecRXSC%dSA%d DelayedPkts",
169 	"MACSecRXSC%dSA%d UncheckedPkts",
170 	"MACSecRXSC%dSA%d ValidatedOctets",
171 	"MACSecRXSC%dSA%d DecryptedOctets",
172 };
173 #endif
174 
175 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
176 	"DMASystemLoopback",
177 	"PKTSystemLoopback",
178 	"DMANetworkLoopback",
179 	"PHYInternalLoopback",
180 	"PHYExternalLoopback",
181 };
182 
183 static u32 aq_ethtool_n_stats(struct net_device *ndev)
184 {
185 	const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
186 	const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
187 	struct aq_nic_s *nic = netdev_priv(ndev);
188 	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
189 	u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
190 		      (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
191 
192 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
193 	n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
194 		   tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
195 #endif
196 
197 #if IS_ENABLED(CONFIG_MACSEC)
198 	if (nic->macsec_cfg) {
199 		n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
200 			   ARRAY_SIZE(aq_macsec_txsc_stat_names) *
201 				   aq_macsec_tx_sc_cnt(nic) +
202 			   ARRAY_SIZE(aq_macsec_txsa_stat_names) *
203 				   aq_macsec_tx_sa_cnt(nic) +
204 			   ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
205 				   aq_macsec_rx_sa_cnt(nic);
206 	}
207 #endif
208 
209 	return n_stats;
210 }
211 
212 static void aq_ethtool_stats(struct net_device *ndev,
213 			     struct ethtool_stats *stats, u64 *data)
214 {
215 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
216 
217 	memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
218 	data = aq_nic_get_stats(aq_nic, data);
219 #if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
220 	data = aq_ptp_get_stats(aq_nic, data);
221 #endif
222 #if IS_ENABLED(CONFIG_MACSEC)
223 	data = aq_macsec_get_stats(aq_nic, data);
224 #endif
225 }
226 
227 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
228 				   struct ethtool_drvinfo *drvinfo)
229 {
230 	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
231 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
232 	u32 firmware_version;
233 	u32 regs_count;
234 
235 	firmware_version = aq_nic_get_fw_version(aq_nic);
236 	regs_count = aq_nic_get_regs_count(aq_nic);
237 
238 	strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
239 
240 	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
241 		 "%u.%u.%u", firmware_version >> 24,
242 		 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
243 
244 	strscpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
245 		sizeof(drvinfo->bus_info));
246 	drvinfo->n_stats = aq_ethtool_n_stats(ndev);
247 	drvinfo->testinfo_len = 0;
248 	drvinfo->regdump_len = regs_count;
249 	drvinfo->eedump_len = 0;
250 }
251 
252 static void aq_ethtool_get_strings(struct net_device *ndev,
253 				   u32 stringset, u8 *data)
254 {
255 	struct aq_nic_s *nic = netdev_priv(ndev);
256 	struct aq_nic_cfg_s *cfg;
257 	u8 *p = data;
258 	int i, si;
259 #if IS_ENABLED(CONFIG_MACSEC)
260 	int sa;
261 #endif
262 
263 	cfg = aq_nic_get_cfg(nic);
264 
265 	switch (stringset) {
266 	case ETH_SS_STATS: {
267 		const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
268 		const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
269 		char tc_string[8];
270 		unsigned int tc;
271 
272 		memset(tc_string, 0, sizeof(tc_string));
273 		memcpy(p, aq_ethtool_stat_names,
274 		       sizeof(aq_ethtool_stat_names));
275 		p = p + sizeof(aq_ethtool_stat_names);
276 
277 		for (tc = 0; tc < cfg->tcs; tc++) {
278 			if (cfg->is_qos)
279 				snprintf(tc_string, 8, "TC%u ", tc);
280 
281 			for (i = 0; i < cfg->vecs; i++) {
282 				for (si = 0; si < rx_stat_cnt; si++) {
283 					ethtool_sprintf(&p,
284 					     aq_ethtool_queue_rx_stat_names[si],
285 					     tc_string,
286 					     AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
287 				}
288 				for (si = 0; si < tx_stat_cnt; si++) {
289 					ethtool_sprintf(&p,
290 					     aq_ethtool_queue_tx_stat_names[si],
291 					     tc_string,
292 					     AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
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 					ethtool_sprintf(&p,
308 						 aq_ethtool_queue_rx_stat_names[si],
309 						 tc_string,
310 						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
311 				}
312 				if (i >= tx_ring_cnt)
313 					continue;
314 				for (si = 0; si < tx_stat_cnt; si++) {
315 					ethtool_sprintf(&p,
316 						 aq_ethtool_queue_tx_stat_names[si],
317 						 tc_string,
318 						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
319 				}
320 			}
321 		}
322 #endif
323 #if IS_ENABLED(CONFIG_MACSEC)
324 		if (!nic->macsec_cfg)
325 			break;
326 
327 		memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
328 		p = p + sizeof(aq_macsec_stat_names);
329 		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
330 			struct aq_macsec_txsc *aq_txsc;
331 
332 			if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
333 				continue;
334 
335 			for (si = 0;
336 				si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
337 				si++) {
338 				ethtool_sprintf(&p,
339 					 aq_macsec_txsc_stat_names[si], i);
340 			}
341 			aq_txsc = &nic->macsec_cfg->aq_txsc[i];
342 			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
343 				if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
344 					continue;
345 				for (si = 0;
346 				     si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
347 				     si++) {
348 					ethtool_sprintf(&p,
349 						 aq_macsec_txsa_stat_names[si],
350 						 i, sa);
351 				}
352 			}
353 		}
354 		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
355 			struct aq_macsec_rxsc *aq_rxsc;
356 
357 			if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
358 				continue;
359 
360 			aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
361 			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
362 				if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
363 					continue;
364 				for (si = 0;
365 				     si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
366 				     si++) {
367 					ethtool_sprintf(&p,
368 						 aq_macsec_rxsa_stat_names[si],
369 						 i, sa);
370 				}
371 			}
372 		}
373 #endif
374 		break;
375 	}
376 	case ETH_SS_PRIV_FLAGS:
377 		memcpy(p, aq_ethtool_priv_flag_names,
378 		       sizeof(aq_ethtool_priv_flag_names));
379 		break;
380 	}
381 }
382 
383 static int aq_ethtool_set_phys_id(struct net_device *ndev,
384 				  enum ethtool_phys_id_state state)
385 {
386 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
387 	struct aq_hw_s *hw = aq_nic->aq_hw;
388 	int ret = 0;
389 
390 	if (!aq_nic->aq_fw_ops->led_control)
391 		return -EOPNOTSUPP;
392 
393 	mutex_lock(&aq_nic->fwreq_mutex);
394 
395 	switch (state) {
396 	case ETHTOOL_ID_ACTIVE:
397 		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
398 				 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
399 		break;
400 	case ETHTOOL_ID_INACTIVE:
401 		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
402 		break;
403 	default:
404 		break;
405 	}
406 
407 	mutex_unlock(&aq_nic->fwreq_mutex);
408 
409 	return ret;
410 }
411 
412 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
413 {
414 	int ret = 0;
415 
416 	switch (stringset) {
417 	case ETH_SS_STATS:
418 		ret = aq_ethtool_n_stats(ndev);
419 		break;
420 	case ETH_SS_PRIV_FLAGS:
421 		ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
422 		break;
423 	default:
424 		ret = -EOPNOTSUPP;
425 	}
426 
427 	return ret;
428 }
429 
430 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
431 {
432 	return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
433 }
434 
435 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
436 {
437 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
438 	struct aq_nic_cfg_s *cfg;
439 
440 	cfg = aq_nic_get_cfg(aq_nic);
441 
442 	return sizeof(cfg->aq_rss.hash_secret_key);
443 }
444 
445 static int aq_ethtool_get_rss(struct net_device *ndev,
446 			      struct ethtool_rxfh_param *rxfh)
447 {
448 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
449 	struct aq_nic_cfg_s *cfg;
450 	unsigned int i = 0U;
451 
452 	cfg = aq_nic_get_cfg(aq_nic);
453 
454 	rxfh->hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
455 	if (rxfh->indir) {
456 		for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
457 			rxfh->indir[i] = cfg->aq_rss.indirection_table[i];
458 	}
459 	if (rxfh->key)
460 		memcpy(rxfh->key, cfg->aq_rss.hash_secret_key,
461 		       sizeof(cfg->aq_rss.hash_secret_key));
462 
463 	return 0;
464 }
465 
466 static int aq_ethtool_set_rss(struct net_device *netdev,
467 			      struct ethtool_rxfh_param *rxfh,
468 			      struct netlink_ext_ack *extack)
469 {
470 	struct aq_nic_s *aq_nic = netdev_priv(netdev);
471 	struct aq_nic_cfg_s *cfg;
472 	unsigned int i = 0U;
473 	u32 rss_entries;
474 	int err = 0;
475 
476 	cfg = aq_nic_get_cfg(aq_nic);
477 	rss_entries = cfg->aq_rss.indirection_table_size;
478 
479 	/* We do not allow change in unsupported parameters */
480 	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
481 	    rxfh->hfunc != ETH_RSS_HASH_TOP)
482 		return -EOPNOTSUPP;
483 	/* Fill out the redirection table */
484 	if (rxfh->indir)
485 		for (i = 0; i < rss_entries; i++)
486 			cfg->aq_rss.indirection_table[i] = rxfh->indir[i];
487 
488 	/* Fill out the rss hash key */
489 	if (rxfh->key) {
490 		memcpy(cfg->aq_rss.hash_secret_key, rxfh->key,
491 		       sizeof(cfg->aq_rss.hash_secret_key));
492 		err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
493 			&cfg->aq_rss);
494 		if (err)
495 			return err;
496 	}
497 
498 	err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
499 
500 	return err;
501 }
502 
503 static u32 aq_ethtool_get_rx_ring_count(struct net_device *ndev)
504 {
505 	struct aq_nic_cfg_s *cfg;
506 	struct aq_nic_s *aq_nic;
507 
508 	aq_nic = netdev_priv(ndev);
509 	cfg = aq_nic_get_cfg(aq_nic);
510 
511 	return cfg->vecs;
512 }
513 
514 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
515 				struct ethtool_rxnfc *cmd,
516 				u32 *rule_locs)
517 {
518 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
519 	int err = 0;
520 
521 	switch (cmd->cmd) {
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 kernel_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 void eee_mask_to_ethtool_mask(unsigned long *mode, u32 speed)
685 {
686 	if (speed & AQ_NIC_RATE_EEE_10G)
687 		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, mode);
688 
689 	if (speed & AQ_NIC_RATE_EEE_1G)
690 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mode);
691 
692 	if (speed & AQ_NIC_RATE_EEE_100M)
693 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mode);
694 }
695 
696 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_keee *eee)
697 {
698 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
699 	u32 rate, supported_rates;
700 	int err = 0;
701 
702 	if (!aq_nic->aq_fw_ops->get_eee_rate)
703 		return -EOPNOTSUPP;
704 
705 	mutex_lock(&aq_nic->fwreq_mutex);
706 	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
707 					      &supported_rates);
708 	mutex_unlock(&aq_nic->fwreq_mutex);
709 	if (err < 0)
710 		return err;
711 
712 	eee_mask_to_ethtool_mask(eee->supported, supported_rates);
713 
714 	if (aq_nic->aq_nic_cfg.eee_speeds)
715 		linkmode_copy(eee->advertised, eee->supported);
716 
717 	eee_mask_to_ethtool_mask(eee->lp_advertised, rate);
718 
719 	eee->eee_enabled = !linkmode_empty(eee->advertised);
720 
721 	eee->tx_lpi_enabled = eee->eee_enabled;
722 	if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
723 		eee->eee_active = true;
724 
725 	return 0;
726 }
727 
728 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_keee *eee)
729 {
730 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
731 	u32 rate, supported_rates;
732 	struct aq_nic_cfg_s *cfg;
733 	int err = 0;
734 
735 	cfg = aq_nic_get_cfg(aq_nic);
736 
737 	if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
738 		     !aq_nic->aq_fw_ops->set_eee_rate))
739 		return -EOPNOTSUPP;
740 
741 	mutex_lock(&aq_nic->fwreq_mutex);
742 	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
743 					      &supported_rates);
744 	mutex_unlock(&aq_nic->fwreq_mutex);
745 	if (err < 0)
746 		return err;
747 
748 	if (eee->eee_enabled) {
749 		rate = supported_rates;
750 		cfg->eee_speeds = rate;
751 	} else {
752 		rate = 0;
753 		cfg->eee_speeds = 0;
754 	}
755 
756 	mutex_lock(&aq_nic->fwreq_mutex);
757 	err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
758 	mutex_unlock(&aq_nic->fwreq_mutex);
759 
760 	return err;
761 }
762 
763 static int aq_ethtool_nway_reset(struct net_device *ndev)
764 {
765 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
766 	int err = 0;
767 
768 	if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
769 		return -EOPNOTSUPP;
770 
771 	if (netif_running(ndev)) {
772 		mutex_lock(&aq_nic->fwreq_mutex);
773 		err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
774 		mutex_unlock(&aq_nic->fwreq_mutex);
775 	}
776 
777 	return err;
778 }
779 
780 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
781 				      struct ethtool_pauseparam *pause)
782 {
783 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
784 	int fc = aq_nic->aq_nic_cfg.fc.req;
785 
786 	pause->autoneg = 0;
787 
788 	pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
789 	pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
790 }
791 
792 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
793 				     struct ethtool_pauseparam *pause)
794 {
795 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
796 	int err = 0;
797 
798 	if (!aq_nic->aq_fw_ops->set_flow_control)
799 		return -EOPNOTSUPP;
800 
801 	if (pause->autoneg == AUTONEG_ENABLE)
802 		return -EOPNOTSUPP;
803 
804 	if (pause->rx_pause)
805 		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
806 	else
807 		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
808 
809 	if (pause->tx_pause)
810 		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
811 	else
812 		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
813 
814 	mutex_lock(&aq_nic->fwreq_mutex);
815 	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
816 	mutex_unlock(&aq_nic->fwreq_mutex);
817 
818 	return err;
819 }
820 
821 static void aq_get_ringparam(struct net_device *ndev,
822 			     struct ethtool_ringparam *ring,
823 			     struct kernel_ethtool_ringparam *kernel_ring,
824 			     struct netlink_ext_ack *extack)
825 {
826 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
827 	struct aq_nic_cfg_s *cfg;
828 
829 	cfg = aq_nic_get_cfg(aq_nic);
830 
831 	ring->rx_pending = cfg->rxds;
832 	ring->tx_pending = cfg->txds;
833 
834 	ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
835 	ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
836 }
837 
838 static int aq_set_ringparam(struct net_device *ndev,
839 			    struct ethtool_ringparam *ring,
840 			    struct kernel_ethtool_ringparam *kernel_ring,
841 			    struct netlink_ext_ack *extack)
842 {
843 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
844 	const struct aq_hw_caps_s *hw_caps;
845 	bool ndev_running = false;
846 	struct aq_nic_cfg_s *cfg;
847 	int err = 0;
848 
849 	cfg = aq_nic_get_cfg(aq_nic);
850 	hw_caps = cfg->aq_hw_caps;
851 
852 	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
853 		err = -EOPNOTSUPP;
854 		goto err_exit;
855 	}
856 
857 	if (netif_running(ndev)) {
858 		ndev_running = true;
859 		aq_ndev_close(ndev);
860 	}
861 
862 	cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
863 	cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
864 	cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
865 
866 	cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
867 	cfg->txds = min(cfg->txds, hw_caps->txds_max);
868 	cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
869 
870 	err = aq_nic_realloc_vectors(aq_nic);
871 	if (err)
872 		goto err_exit;
873 
874 	if (ndev_running)
875 		err = aq_ndev_open(ndev);
876 
877 err_exit:
878 	return err;
879 }
880 
881 static u32 aq_get_msg_level(struct net_device *ndev)
882 {
883 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
884 
885 	return aq_nic->msg_enable;
886 }
887 
888 static void aq_set_msg_level(struct net_device *ndev, u32 data)
889 {
890 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
891 
892 	aq_nic->msg_enable = data;
893 }
894 
895 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
896 {
897 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
898 
899 	return aq_nic->aq_nic_cfg.priv_flags;
900 }
901 
902 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
903 {
904 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
905 	struct aq_nic_cfg_s *cfg;
906 	u32 priv_flags;
907 	int ret = 0;
908 
909 	cfg = aq_nic_get_cfg(aq_nic);
910 	priv_flags = cfg->priv_flags;
911 
912 	if (flags & ~AQ_PRIV_FLAGS_MASK)
913 		return -EOPNOTSUPP;
914 
915 	if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
916 		netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
917 		return -EINVAL;
918 	}
919 
920 	cfg->priv_flags = flags;
921 
922 	if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
923 		if (netif_running(ndev)) {
924 			dev_close(ndev);
925 
926 			dev_open(ndev, NULL);
927 		}
928 	} else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
929 		ret = aq_nic_set_loopback(aq_nic);
930 	}
931 
932 	return ret;
933 }
934 
935 static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
936 				      const struct ethtool_tunable *tuna, void *data)
937 {
938 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
939 
940 	switch (tuna->id) {
941 	case ETHTOOL_PHY_EDPD: {
942 		u16 *val = data;
943 
944 		*val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
945 		break;
946 	}
947 	case ETHTOOL_PHY_DOWNSHIFT: {
948 		u8 *val = data;
949 
950 		*val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
951 		break;
952 	}
953 	default:
954 		return -EOPNOTSUPP;
955 	}
956 
957 	return 0;
958 }
959 
960 static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
961 				      const struct ethtool_tunable *tuna, const void *data)
962 {
963 	int err = -EOPNOTSUPP;
964 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
965 
966 	switch (tuna->id) {
967 	case ETHTOOL_PHY_EDPD: {
968 		const u16 *val = data;
969 
970 		err = aq_nic_set_media_detect(aq_nic, *val);
971 		break;
972 	}
973 	case ETHTOOL_PHY_DOWNSHIFT: {
974 		const u8 *val = data;
975 
976 		err = aq_nic_set_downshift(aq_nic, *val);
977 		break;
978 	}
979 	default:
980 		break;
981 	}
982 
983 	return err;
984 }
985 
986 static int aq_ethtool_get_module_info(struct net_device *ndev,
987 				      struct ethtool_modinfo *modinfo)
988 {
989 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
990 	u8 compliance_val, dom_type;
991 	int err;
992 
993 	/* Module EEPROM is only supported for controllers with external PHY */
994 	if (aq_nic->aq_nic_cfg.aq_hw_caps->media_type != AQ_HW_MEDIA_TYPE_FIBRE ||
995 	    !aq_nic->aq_hw_ops->hw_read_module_eeprom)
996 		return -EOPNOTSUPP;
997 
998 	err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
999 		SFF_8472_ID_ADDR, SFF_8472_COMP_ADDR, 1, &compliance_val);
1000 	if (err)
1001 		return err;
1002 
1003 	err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
1004 		SFF_8472_ID_ADDR, SFF_8472_DOM_TYPE_ADDR, 1, &dom_type);
1005 	if (err)
1006 		return err;
1007 
1008 	if (dom_type & SFF_8472_ADDRESS_CHANGE_REQ_MASK || compliance_val == 0x00) {
1009 		modinfo->type = ETH_MODULE_SFF_8079;
1010 		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1011 	} else {
1012 		modinfo->type = ETH_MODULE_SFF_8472;
1013 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1014 	}
1015 	return 0;
1016 }
1017 
1018 static int aq_ethtool_get_module_eeprom(struct net_device *ndev,
1019 					struct ethtool_eeprom *ee, unsigned char *data)
1020 {
1021 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
1022 	unsigned int first, last, len;
1023 	int err;
1024 
1025 	if (!aq_nic->aq_hw_ops->hw_read_module_eeprom)
1026 		return -EOPNOTSUPP;
1027 
1028 	first = ee->offset;
1029 	last = ee->offset + ee->len;
1030 
1031 	if (first < ETH_MODULE_SFF_8079_LEN) {
1032 		len = min(last, ETH_MODULE_SFF_8079_LEN);
1033 		len -= first;
1034 
1035 		err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
1036 			SFF_8472_ID_ADDR, first, len, data);
1037 		if (err)
1038 			return err;
1039 
1040 		first += len;
1041 		data += len;
1042 	}
1043 	if (first < ETH_MODULE_SFF_8472_LEN && last > ETH_MODULE_SFF_8079_LEN) {
1044 		len = min(last, ETH_MODULE_SFF_8472_LEN);
1045 		len -= first;
1046 		first -= ETH_MODULE_SFF_8079_LEN;
1047 
1048 		err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
1049 			SFF_8472_DIAGNOSTICS_ADDR, first, len, data);
1050 		if (err)
1051 			return err;
1052 	}
1053 	return 0;
1054 }
1055 
1056 const struct ethtool_ops aq_ethtool_ops = {
1057 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1058 				     ETHTOOL_COALESCE_MAX_FRAMES,
1059 	.get_link            = aq_ethtool_get_link,
1060 	.get_regs_len        = aq_ethtool_get_regs_len,
1061 	.get_regs            = aq_ethtool_get_regs,
1062 	.get_drvinfo         = aq_ethtool_get_drvinfo,
1063 	.get_strings         = aq_ethtool_get_strings,
1064 	.set_phys_id         = aq_ethtool_set_phys_id,
1065 	.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
1066 	.get_wol             = aq_ethtool_get_wol,
1067 	.set_wol             = aq_ethtool_set_wol,
1068 	.nway_reset          = aq_ethtool_nway_reset,
1069 	.get_ringparam       = aq_get_ringparam,
1070 	.set_ringparam       = aq_set_ringparam,
1071 	.get_eee             = aq_ethtool_get_eee,
1072 	.set_eee             = aq_ethtool_set_eee,
1073 	.get_pauseparam      = aq_ethtool_get_pauseparam,
1074 	.set_pauseparam      = aq_ethtool_set_pauseparam,
1075 	.get_rxfh_key_size   = aq_ethtool_get_rss_key_size,
1076 	.get_rxfh            = aq_ethtool_get_rss,
1077 	.set_rxfh            = aq_ethtool_set_rss,
1078 	.get_rxnfc           = aq_ethtool_get_rxnfc,
1079 	.set_rxnfc           = aq_ethtool_set_rxnfc,
1080 	.get_rx_ring_count   = aq_ethtool_get_rx_ring_count,
1081 	.get_msglevel        = aq_get_msg_level,
1082 	.set_msglevel        = aq_set_msg_level,
1083 	.get_sset_count      = aq_ethtool_get_sset_count,
1084 	.get_ethtool_stats   = aq_ethtool_stats,
1085 	.get_priv_flags      = aq_ethtool_get_priv_flags,
1086 	.set_priv_flags      = aq_ethtool_set_priv_flags,
1087 	.get_link_ksettings  = aq_ethtool_get_link_ksettings,
1088 	.set_link_ksettings  = aq_ethtool_set_link_ksettings,
1089 	.get_coalesce	     = aq_ethtool_get_coalesce,
1090 	.set_coalesce	     = aq_ethtool_set_coalesce,
1091 	.get_ts_info         = aq_ethtool_get_ts_info,
1092 	.get_phy_tunable     = aq_ethtool_get_phy_tunable,
1093 	.set_phy_tunable     = aq_ethtool_set_phy_tunable,
1094 	.get_module_info     = aq_ethtool_get_module_info,
1095 	.get_module_eeprom   = aq_ethtool_get_module_eeprom,
1096 };
1097