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