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