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