1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * aQuantia Corporation Network Driver
4  * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
5  */
6 
7 /* File aq_ethtool.c: Definition of ethertool related functions. */
8 
9 #include "aq_ethtool.h"
10 #include "aq_nic.h"
11 #include "aq_vec.h"
12 #include "aq_ptp.h"
13 #include "aq_filters.h"
14 #include "aq_macsec.h"
15 
16 #include <linux/ptp_clock_kernel.h>
17 
18 static void aq_ethtool_get_regs(struct net_device *ndev,
19 				struct ethtool_regs *regs, void *p)
20 {
21 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
22 	u32 regs_count;
23 
24 	regs_count = aq_nic_get_regs_count(aq_nic);
25 
26 	memset(p, 0, regs_count * sizeof(u32));
27 	aq_nic_get_regs(aq_nic, regs, p);
28 }
29 
30 static int aq_ethtool_get_regs_len(struct net_device *ndev)
31 {
32 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
33 	u32 regs_count;
34 
35 	regs_count = aq_nic_get_regs_count(aq_nic);
36 
37 	return regs_count * sizeof(u32);
38 }
39 
40 static u32 aq_ethtool_get_link(struct net_device *ndev)
41 {
42 	return ethtool_op_get_link(ndev);
43 }
44 
45 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
46 					 struct ethtool_link_ksettings *cmd)
47 {
48 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
49 
50 	aq_nic_get_link_ksettings(aq_nic, cmd);
51 	cmd->base.speed = netif_carrier_ok(ndev) ?
52 				aq_nic_get_link_speed(aq_nic) : 0U;
53 
54 	return 0;
55 }
56 
57 static int
58 aq_ethtool_set_link_ksettings(struct net_device *ndev,
59 			      const struct ethtool_link_ksettings *cmd)
60 {
61 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
62 
63 	return aq_nic_set_link_ksettings(aq_nic, cmd);
64 }
65 
66 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
67 	"InPackets",
68 	"InUCast",
69 	"InMCast",
70 	"InBCast",
71 	"InErrors",
72 	"OutPackets",
73 	"OutUCast",
74 	"OutMCast",
75 	"OutBCast",
76 	"InUCastOctets",
77 	"OutUCastOctets",
78 	"InMCastOctets",
79 	"OutMCastOctets",
80 	"InBCastOctets",
81 	"OutBCastOctets",
82 	"InOctets",
83 	"OutOctets",
84 	"InPacketsDma",
85 	"OutPacketsDma",
86 	"InOctetsDma",
87 	"OutOctetsDma",
88 	"InDroppedDma",
89 };
90 
91 static const char * const aq_ethtool_queue_stat_names[] = {
92 	"%sQueue[%d] InPackets",
93 	"%sQueue[%d] OutPackets",
94 	"%sQueue[%d] Restarts",
95 	"%sQueue[%d] InJumboPackets",
96 	"%sQueue[%d] InLroPackets",
97 	"%sQueue[%d] InErrors",
98 };
99 
100 #if IS_ENABLED(CONFIG_MACSEC)
101 static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
102 	"MACSec InCtlPackets",
103 	"MACSec InTaggedMissPackets",
104 	"MACSec InUntaggedMissPackets",
105 	"MACSec InNotagPackets",
106 	"MACSec InUntaggedPackets",
107 	"MACSec InBadTagPackets",
108 	"MACSec InNoSciPackets",
109 	"MACSec InUnknownSciPackets",
110 	"MACSec InCtrlPortPassPackets",
111 	"MACSec InUnctrlPortPassPackets",
112 	"MACSec InCtrlPortFailPackets",
113 	"MACSec InUnctrlPortFailPackets",
114 	"MACSec InTooLongPackets",
115 	"MACSec InIgpocCtlPackets",
116 	"MACSec InEccErrorPackets",
117 	"MACSec InUnctrlHitDropRedir",
118 	"MACSec OutCtlPackets",
119 	"MACSec OutUnknownSaPackets",
120 	"MACSec OutUntaggedPackets",
121 	"MACSec OutTooLong",
122 	"MACSec OutEccErrorPackets",
123 	"MACSec OutUnctrlHitDropRedir",
124 };
125 
126 static const char *aq_macsec_txsc_stat_names[] = {
127 	"MACSecTXSC%d ProtectedPkts",
128 	"MACSecTXSC%d EncryptedPkts",
129 	"MACSecTXSC%d ProtectedOctets",
130 	"MACSecTXSC%d EncryptedOctets",
131 };
132 
133 static const char *aq_macsec_txsa_stat_names[] = {
134 	"MACSecTXSC%dSA%d HitDropRedirect",
135 	"MACSecTXSC%dSA%d Protected2Pkts",
136 	"MACSecTXSC%dSA%d ProtectedPkts",
137 	"MACSecTXSC%dSA%d EncryptedPkts",
138 };
139 
140 static const char *aq_macsec_rxsa_stat_names[] = {
141 	"MACSecRXSC%dSA%d UntaggedHitPkts",
142 	"MACSecRXSC%dSA%d CtrlHitDrpRedir",
143 	"MACSecRXSC%dSA%d NotUsingSa",
144 	"MACSecRXSC%dSA%d UnusedSa",
145 	"MACSecRXSC%dSA%d NotValidPkts",
146 	"MACSecRXSC%dSA%d InvalidPkts",
147 	"MACSecRXSC%dSA%d OkPkts",
148 	"MACSecRXSC%dSA%d LatePkts",
149 	"MACSecRXSC%dSA%d DelayedPkts",
150 	"MACSecRXSC%dSA%d UncheckedPkts",
151 	"MACSecRXSC%dSA%d ValidatedOctets",
152 	"MACSecRXSC%dSA%d DecryptedOctets",
153 };
154 #endif
155 
156 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
157 	"DMASystemLoopback",
158 	"PKTSystemLoopback",
159 	"DMANetworkLoopback",
160 	"PHYInternalLoopback",
161 	"PHYExternalLoopback",
162 };
163 
164 static u32 aq_ethtool_n_stats(struct net_device *ndev)
165 {
166 	struct aq_nic_s *nic = netdev_priv(ndev);
167 	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
168 	u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
169 		      ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs *
170 			cfg->tcs;
171 
172 #if IS_ENABLED(CONFIG_MACSEC)
173 	if (nic->macsec_cfg) {
174 		n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
175 			   ARRAY_SIZE(aq_macsec_txsc_stat_names) *
176 				   aq_macsec_tx_sc_cnt(nic) +
177 			   ARRAY_SIZE(aq_macsec_txsa_stat_names) *
178 				   aq_macsec_tx_sa_cnt(nic) +
179 			   ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
180 				   aq_macsec_rx_sa_cnt(nic);
181 	}
182 #endif
183 
184 	return n_stats;
185 }
186 
187 static void aq_ethtool_stats(struct net_device *ndev,
188 			     struct ethtool_stats *stats, u64 *data)
189 {
190 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
191 
192 	memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
193 	data = aq_nic_get_stats(aq_nic, data);
194 #if IS_ENABLED(CONFIG_MACSEC)
195 	data = aq_macsec_get_stats(aq_nic, data);
196 #endif
197 }
198 
199 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
200 				   struct ethtool_drvinfo *drvinfo)
201 {
202 	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
203 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
204 	u32 firmware_version;
205 	u32 regs_count;
206 
207 	firmware_version = aq_nic_get_fw_version(aq_nic);
208 	regs_count = aq_nic_get_regs_count(aq_nic);
209 
210 	strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
211 
212 	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
213 		 "%u.%u.%u", firmware_version >> 24,
214 		 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
215 
216 	strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
217 		sizeof(drvinfo->bus_info));
218 	drvinfo->n_stats = aq_ethtool_n_stats(ndev);
219 	drvinfo->testinfo_len = 0;
220 	drvinfo->regdump_len = regs_count;
221 	drvinfo->eedump_len = 0;
222 }
223 
224 static void aq_ethtool_get_strings(struct net_device *ndev,
225 				   u32 stringset, u8 *data)
226 {
227 	struct aq_nic_s *nic = netdev_priv(ndev);
228 	struct aq_nic_cfg_s *cfg;
229 	u8 *p = data;
230 	int i, si;
231 #if IS_ENABLED(CONFIG_MACSEC)
232 	int sa;
233 #endif
234 
235 	cfg = aq_nic_get_cfg(nic);
236 
237 	switch (stringset) {
238 	case ETH_SS_STATS: {
239 		const int stat_cnt = ARRAY_SIZE(aq_ethtool_queue_stat_names);
240 		char tc_string[8];
241 		int tc;
242 
243 		memset(tc_string, 0, sizeof(tc_string));
244 		memcpy(p, aq_ethtool_stat_names,
245 		       sizeof(aq_ethtool_stat_names));
246 		p = p + sizeof(aq_ethtool_stat_names);
247 
248 		for (tc = 0; tc < cfg->tcs; tc++) {
249 			if (cfg->is_qos)
250 				snprintf(tc_string, 8, "TC%d ", tc);
251 
252 			for (i = 0; i < cfg->vecs; i++) {
253 				for (si = 0; si < stat_cnt; si++) {
254 					snprintf(p, ETH_GSTRING_LEN,
255 					     aq_ethtool_queue_stat_names[si],
256 					     tc_string,
257 					     AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
258 					p += ETH_GSTRING_LEN;
259 				}
260 			}
261 		}
262 #if IS_ENABLED(CONFIG_MACSEC)
263 		if (!nic->macsec_cfg)
264 			break;
265 
266 		memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
267 		p = p + sizeof(aq_macsec_stat_names);
268 		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
269 			struct aq_macsec_txsc *aq_txsc;
270 
271 			if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
272 				continue;
273 
274 			for (si = 0;
275 				si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
276 				si++) {
277 				snprintf(p, ETH_GSTRING_LEN,
278 					 aq_macsec_txsc_stat_names[si], i);
279 				p += ETH_GSTRING_LEN;
280 			}
281 			aq_txsc = &nic->macsec_cfg->aq_txsc[i];
282 			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
283 				if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
284 					continue;
285 				for (si = 0;
286 				     si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
287 				     si++) {
288 					snprintf(p, ETH_GSTRING_LEN,
289 						 aq_macsec_txsa_stat_names[si],
290 						 i, sa);
291 					p += ETH_GSTRING_LEN;
292 				}
293 			}
294 		}
295 		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
296 			struct aq_macsec_rxsc *aq_rxsc;
297 
298 			if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
299 				continue;
300 
301 			aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
302 			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
303 				if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
304 					continue;
305 				for (si = 0;
306 				     si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
307 				     si++) {
308 					snprintf(p, ETH_GSTRING_LEN,
309 						 aq_macsec_rxsa_stat_names[si],
310 						 i, sa);
311 					p += ETH_GSTRING_LEN;
312 				}
313 			}
314 		}
315 #endif
316 		break;
317 	}
318 	case ETH_SS_PRIV_FLAGS:
319 		memcpy(p, aq_ethtool_priv_flag_names,
320 		       sizeof(aq_ethtool_priv_flag_names));
321 		break;
322 	}
323 }
324 
325 static int aq_ethtool_set_phys_id(struct net_device *ndev,
326 				  enum ethtool_phys_id_state state)
327 {
328 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
329 	struct aq_hw_s *hw = aq_nic->aq_hw;
330 	int ret = 0;
331 
332 	if (!aq_nic->aq_fw_ops->led_control)
333 		return -EOPNOTSUPP;
334 
335 	mutex_lock(&aq_nic->fwreq_mutex);
336 
337 	switch (state) {
338 	case ETHTOOL_ID_ACTIVE:
339 		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
340 				 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
341 		break;
342 	case ETHTOOL_ID_INACTIVE:
343 		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
344 		break;
345 	default:
346 		break;
347 	}
348 
349 	mutex_unlock(&aq_nic->fwreq_mutex);
350 
351 	return ret;
352 }
353 
354 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
355 {
356 	int ret = 0;
357 
358 	switch (stringset) {
359 	case ETH_SS_STATS:
360 		ret = aq_ethtool_n_stats(ndev);
361 		break;
362 	case ETH_SS_PRIV_FLAGS:
363 		ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
364 		break;
365 	default:
366 		ret = -EOPNOTSUPP;
367 	}
368 
369 	return ret;
370 }
371 
372 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
373 {
374 	return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
375 }
376 
377 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
378 {
379 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
380 	struct aq_nic_cfg_s *cfg;
381 
382 	cfg = aq_nic_get_cfg(aq_nic);
383 
384 	return sizeof(cfg->aq_rss.hash_secret_key);
385 }
386 
387 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
388 			      u8 *hfunc)
389 {
390 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
391 	struct aq_nic_cfg_s *cfg;
392 	unsigned int i = 0U;
393 
394 	cfg = aq_nic_get_cfg(aq_nic);
395 
396 	if (hfunc)
397 		*hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
398 	if (indir) {
399 		for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
400 			indir[i] = cfg->aq_rss.indirection_table[i];
401 	}
402 	if (key)
403 		memcpy(key, cfg->aq_rss.hash_secret_key,
404 		       sizeof(cfg->aq_rss.hash_secret_key));
405 
406 	return 0;
407 }
408 
409 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
410 			      const u8 *key, const u8 hfunc)
411 {
412 	struct aq_nic_s *aq_nic = netdev_priv(netdev);
413 	struct aq_nic_cfg_s *cfg;
414 	unsigned int i = 0U;
415 	u32 rss_entries;
416 	int err = 0;
417 
418 	cfg = aq_nic_get_cfg(aq_nic);
419 	rss_entries = cfg->aq_rss.indirection_table_size;
420 
421 	/* We do not allow change in unsupported parameters */
422 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
423 		return -EOPNOTSUPP;
424 	/* Fill out the redirection table */
425 	if (indir)
426 		for (i = 0; i < rss_entries; i++)
427 			cfg->aq_rss.indirection_table[i] = indir[i];
428 
429 	/* Fill out the rss hash key */
430 	if (key) {
431 		memcpy(cfg->aq_rss.hash_secret_key, key,
432 		       sizeof(cfg->aq_rss.hash_secret_key));
433 		err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
434 			&cfg->aq_rss);
435 		if (err)
436 			return err;
437 	}
438 
439 	err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
440 
441 	return err;
442 }
443 
444 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
445 				struct ethtool_rxnfc *cmd,
446 				u32 *rule_locs)
447 {
448 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
449 	struct aq_nic_cfg_s *cfg;
450 	int err = 0;
451 
452 	cfg = aq_nic_get_cfg(aq_nic);
453 
454 	switch (cmd->cmd) {
455 	case ETHTOOL_GRXRINGS:
456 		cmd->data = cfg->vecs;
457 		break;
458 	case ETHTOOL_GRXCLSRLCNT:
459 		cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
460 		break;
461 	case ETHTOOL_GRXCLSRULE:
462 		err = aq_get_rxnfc_rule(aq_nic, cmd);
463 		break;
464 	case ETHTOOL_GRXCLSRLALL:
465 		err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
466 		break;
467 	default:
468 		err = -EOPNOTSUPP;
469 		break;
470 	}
471 
472 	return err;
473 }
474 
475 static int aq_ethtool_set_rxnfc(struct net_device *ndev,
476 				struct ethtool_rxnfc *cmd)
477 {
478 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
479 	int err = 0;
480 
481 	switch (cmd->cmd) {
482 	case ETHTOOL_SRXCLSRLINS:
483 		err = aq_add_rxnfc_rule(aq_nic, cmd);
484 		break;
485 	case ETHTOOL_SRXCLSRLDEL:
486 		err = aq_del_rxnfc_rule(aq_nic, cmd);
487 		break;
488 	default:
489 		err = -EOPNOTSUPP;
490 		break;
491 	}
492 
493 	return err;
494 }
495 
496 static int aq_ethtool_get_coalesce(struct net_device *ndev,
497 				   struct ethtool_coalesce *coal)
498 {
499 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
500 	struct aq_nic_cfg_s *cfg;
501 
502 	cfg = aq_nic_get_cfg(aq_nic);
503 
504 	if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
505 	    cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
506 		coal->rx_coalesce_usecs = cfg->rx_itr;
507 		coal->tx_coalesce_usecs = cfg->tx_itr;
508 		coal->rx_max_coalesced_frames = 0;
509 		coal->tx_max_coalesced_frames = 0;
510 	} else {
511 		coal->rx_coalesce_usecs = 0;
512 		coal->tx_coalesce_usecs = 0;
513 		coal->rx_max_coalesced_frames = 1;
514 		coal->tx_max_coalesced_frames = 1;
515 	}
516 
517 	return 0;
518 }
519 
520 static int aq_ethtool_set_coalesce(struct net_device *ndev,
521 				   struct ethtool_coalesce *coal)
522 {
523 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
524 	struct aq_nic_cfg_s *cfg;
525 
526 	cfg = aq_nic_get_cfg(aq_nic);
527 
528 	/* Atlantic only supports timing based coalescing
529 	 */
530 	if (coal->rx_max_coalesced_frames > 1 ||
531 	    coal->tx_max_coalesced_frames > 1)
532 		return -EOPNOTSUPP;
533 
534 	/* We do not support frame counting. Check this
535 	 */
536 	if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
537 		return -EOPNOTSUPP;
538 	if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
539 		return -EOPNOTSUPP;
540 
541 	if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
542 	    coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
543 		return -EINVAL;
544 
545 	cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
546 
547 	cfg->rx_itr = coal->rx_coalesce_usecs;
548 	cfg->tx_itr = coal->tx_coalesce_usecs;
549 
550 	return aq_nic_update_interrupt_moderation_settings(aq_nic);
551 }
552 
553 static void aq_ethtool_get_wol(struct net_device *ndev,
554 			       struct ethtool_wolinfo *wol)
555 {
556 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
557 	struct aq_nic_cfg_s *cfg;
558 
559 	cfg = aq_nic_get_cfg(aq_nic);
560 
561 	wol->supported = AQ_NIC_WOL_MODES;
562 	wol->wolopts = cfg->wol;
563 }
564 
565 static int aq_ethtool_set_wol(struct net_device *ndev,
566 			      struct ethtool_wolinfo *wol)
567 {
568 	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
569 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
570 	struct aq_nic_cfg_s *cfg;
571 	int err = 0;
572 
573 	cfg = aq_nic_get_cfg(aq_nic);
574 
575 	if (wol->wolopts & ~AQ_NIC_WOL_MODES)
576 		return -EOPNOTSUPP;
577 
578 	cfg->wol = wol->wolopts;
579 
580 	err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
581 
582 	return err;
583 }
584 
585 static int aq_ethtool_get_ts_info(struct net_device *ndev,
586 				  struct ethtool_ts_info *info)
587 {
588 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
589 
590 	ethtool_op_get_ts_info(ndev, info);
591 
592 	if (!aq_nic->aq_ptp)
593 		return 0;
594 
595 	info->so_timestamping |=
596 		SOF_TIMESTAMPING_TX_HARDWARE |
597 		SOF_TIMESTAMPING_RX_HARDWARE |
598 		SOF_TIMESTAMPING_RAW_HARDWARE;
599 
600 	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
601 			 BIT(HWTSTAMP_TX_ON);
602 
603 	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
604 
605 	info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
606 			    BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
607 			    BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
608 
609 	info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
610 
611 	return 0;
612 }
613 
614 static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
615 {
616 	u32 rate = 0;
617 
618 	if (speed & AQ_NIC_RATE_EEE_10G)
619 		rate |= SUPPORTED_10000baseT_Full;
620 
621 	if (speed & AQ_NIC_RATE_EEE_2G5)
622 		rate |= SUPPORTED_2500baseX_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 (eee->advertised & eee->lp_advertised)
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 	u32 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 
730 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
731 				     struct ethtool_pauseparam *pause)
732 {
733 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
734 	int err = 0;
735 
736 	if (!aq_nic->aq_fw_ops->set_flow_control)
737 		return -EOPNOTSUPP;
738 
739 	if (pause->autoneg == AUTONEG_ENABLE)
740 		return -EOPNOTSUPP;
741 
742 	if (pause->rx_pause)
743 		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
744 	else
745 		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
746 
747 	if (pause->tx_pause)
748 		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
749 	else
750 		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
751 
752 	mutex_lock(&aq_nic->fwreq_mutex);
753 	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
754 	mutex_unlock(&aq_nic->fwreq_mutex);
755 
756 	return err;
757 }
758 
759 static void aq_get_ringparam(struct net_device *ndev,
760 			     struct ethtool_ringparam *ring)
761 {
762 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
763 	struct aq_nic_cfg_s *cfg;
764 
765 	cfg = aq_nic_get_cfg(aq_nic);
766 
767 	ring->rx_pending = cfg->rxds;
768 	ring->tx_pending = cfg->txds;
769 
770 	ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
771 	ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
772 }
773 
774 static int aq_set_ringparam(struct net_device *ndev,
775 			    struct ethtool_ringparam *ring)
776 {
777 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
778 	const struct aq_hw_caps_s *hw_caps;
779 	bool ndev_running = false;
780 	struct aq_nic_cfg_s *cfg;
781 	int err = 0;
782 
783 	cfg = aq_nic_get_cfg(aq_nic);
784 	hw_caps = cfg->aq_hw_caps;
785 
786 	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
787 		err = -EOPNOTSUPP;
788 		goto err_exit;
789 	}
790 
791 	if (netif_running(ndev)) {
792 		ndev_running = true;
793 		dev_close(ndev);
794 	}
795 
796 	cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
797 	cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
798 	cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
799 
800 	cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
801 	cfg->txds = min(cfg->txds, hw_caps->txds_max);
802 	cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
803 
804 	err = aq_nic_realloc_vectors(aq_nic);
805 	if (err)
806 		goto err_exit;
807 
808 	if (ndev_running)
809 		err = dev_open(ndev, NULL);
810 
811 err_exit:
812 	return err;
813 }
814 
815 static u32 aq_get_msg_level(struct net_device *ndev)
816 {
817 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
818 
819 	return aq_nic->msg_enable;
820 }
821 
822 static void aq_set_msg_level(struct net_device *ndev, u32 data)
823 {
824 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
825 
826 	aq_nic->msg_enable = data;
827 }
828 
829 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
830 {
831 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
832 
833 	return aq_nic->aq_nic_cfg.priv_flags;
834 }
835 
836 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
837 {
838 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
839 	struct aq_nic_cfg_s *cfg;
840 	u32 priv_flags;
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 		aq_nic_set_loopback(aq_nic);
863 	}
864 
865 	return 0;
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