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