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