1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <linux/ethtool.h>
5 #include <linux/netdevice.h>
6 #include <linux/pci.h>
7 
8 #include "fbnic.h"
9 #include "fbnic_netdev.h"
10 #include "fbnic_tlv.h"
11 
12 struct fbnic_stat {
13 	u8 string[ETH_GSTRING_LEN];
14 	unsigned int size;
15 	unsigned int offset;
16 };
17 
18 #define FBNIC_STAT_FIELDS(type, name, stat) { \
19 	.string = name, \
20 	.size = sizeof_field(struct type, stat), \
21 	.offset = offsetof(struct type, stat), \
22 }
23 
24 /* Hardware statistics not captured in rtnl_link_stats */
25 #define FBNIC_HW_STAT(name, stat) \
26 	FBNIC_STAT_FIELDS(fbnic_hw_stats, name, stat)
27 
28 static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
29 	/* RPC */
30 	FBNIC_HW_STAT("rpc_unkn_etype", rpc.unkn_etype),
31 	FBNIC_HW_STAT("rpc_unkn_ext_hdr", rpc.unkn_ext_hdr),
32 	FBNIC_HW_STAT("rpc_ipv4_frag", rpc.ipv4_frag),
33 	FBNIC_HW_STAT("rpc_ipv6_frag", rpc.ipv6_frag),
34 	FBNIC_HW_STAT("rpc_ipv4_esp", rpc.ipv4_esp),
35 	FBNIC_HW_STAT("rpc_ipv6_esp", rpc.ipv6_esp),
36 	FBNIC_HW_STAT("rpc_tcp_opt_err", rpc.tcp_opt_err),
37 	FBNIC_HW_STAT("rpc_out_of_hdr_err", rpc.out_of_hdr_err),
38 };
39 
40 #define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
41 #define FBNIC_HW_STATS_LEN	FBNIC_HW_FIXED_STATS_LEN
42 
43 static void
fbnic_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)44 fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
45 {
46 	struct fbnic_net *fbn = netdev_priv(netdev);
47 	struct fbnic_dev *fbd = fbn->fbd;
48 
49 	fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
50 				    sizeof(drvinfo->fw_version));
51 }
52 
fbnic_get_regs_len(struct net_device * netdev)53 static int fbnic_get_regs_len(struct net_device *netdev)
54 {
55 	struct fbnic_net *fbn = netdev_priv(netdev);
56 
57 	return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
58 }
59 
fbnic_get_regs(struct net_device * netdev,struct ethtool_regs * regs,void * data)60 static void fbnic_get_regs(struct net_device *netdev,
61 			   struct ethtool_regs *regs, void *data)
62 {
63 	struct fbnic_net *fbn = netdev_priv(netdev);
64 
65 	fbnic_csr_get_regs(fbn->fbd, data, &regs->version);
66 }
67 
fbnic_clone_create(struct fbnic_net * orig)68 static struct fbnic_net *fbnic_clone_create(struct fbnic_net *orig)
69 {
70 	struct fbnic_net *clone;
71 
72 	clone = kmemdup(orig, sizeof(*orig), GFP_KERNEL);
73 	if (!clone)
74 		return NULL;
75 
76 	memset(clone->tx, 0, sizeof(clone->tx));
77 	memset(clone->rx, 0, sizeof(clone->rx));
78 	memset(clone->napi, 0, sizeof(clone->napi));
79 	return clone;
80 }
81 
fbnic_clone_swap_cfg(struct fbnic_net * orig,struct fbnic_net * clone)82 static void fbnic_clone_swap_cfg(struct fbnic_net *orig,
83 				 struct fbnic_net *clone)
84 {
85 	swap(clone->rcq_size, orig->rcq_size);
86 	swap(clone->hpq_size, orig->hpq_size);
87 	swap(clone->ppq_size, orig->ppq_size);
88 	swap(clone->txq_size, orig->txq_size);
89 	swap(clone->num_rx_queues, orig->num_rx_queues);
90 	swap(clone->num_tx_queues, orig->num_tx_queues);
91 	swap(clone->num_napi, orig->num_napi);
92 }
93 
fbnic_aggregate_vector_counters(struct fbnic_net * fbn,struct fbnic_napi_vector * nv)94 static void fbnic_aggregate_vector_counters(struct fbnic_net *fbn,
95 					    struct fbnic_napi_vector *nv)
96 {
97 	int i, j;
98 
99 	for (i = 0; i < nv->txt_count; i++) {
100 		fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].sub0);
101 		fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].sub1);
102 		fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].cmpl);
103 	}
104 
105 	for (j = 0; j < nv->rxt_count; j++, i++) {
106 		fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].sub0);
107 		fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].sub1);
108 		fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].cmpl);
109 	}
110 }
111 
fbnic_clone_swap(struct fbnic_net * orig,struct fbnic_net * clone)112 static void fbnic_clone_swap(struct fbnic_net *orig,
113 			     struct fbnic_net *clone)
114 {
115 	struct fbnic_dev *fbd = orig->fbd;
116 	unsigned int i;
117 
118 	for (i = 0; i < max(clone->num_napi, orig->num_napi); i++)
119 		fbnic_synchronize_irq(fbd, FBNIC_NON_NAPI_VECTORS + i);
120 	for (i = 0; i < orig->num_napi; i++)
121 		fbnic_aggregate_vector_counters(orig, orig->napi[i]);
122 
123 	fbnic_clone_swap_cfg(orig, clone);
124 
125 	for (i = 0; i < ARRAY_SIZE(orig->napi); i++)
126 		swap(clone->napi[i], orig->napi[i]);
127 	for (i = 0; i < ARRAY_SIZE(orig->tx); i++)
128 		swap(clone->tx[i], orig->tx[i]);
129 	for (i = 0; i < ARRAY_SIZE(orig->rx); i++)
130 		swap(clone->rx[i], orig->rx[i]);
131 }
132 
fbnic_clone_free(struct fbnic_net * clone)133 static void fbnic_clone_free(struct fbnic_net *clone)
134 {
135 	kfree(clone);
136 }
137 
fbnic_get_strings(struct net_device * dev,u32 sset,u8 * data)138 static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
139 {
140 	int i;
141 
142 	switch (sset) {
143 	case ETH_SS_STATS:
144 		for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
145 			ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
146 		break;
147 	}
148 }
149 
fbnic_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * data)150 static void fbnic_get_ethtool_stats(struct net_device *dev,
151 				    struct ethtool_stats *stats, u64 *data)
152 {
153 	struct fbnic_net *fbn = netdev_priv(dev);
154 	const struct fbnic_stat *stat;
155 	int i;
156 
157 	fbnic_get_hw_stats(fbn->fbd);
158 
159 	for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
160 		stat = &fbnic_gstrings_hw_stats[i];
161 		data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
162 	}
163 }
164 
fbnic_get_sset_count(struct net_device * dev,int sset)165 static int fbnic_get_sset_count(struct net_device *dev, int sset)
166 {
167 	switch (sset) {
168 	case ETH_SS_STATS:
169 		return FBNIC_HW_STATS_LEN;
170 	default:
171 		return -EOPNOTSUPP;
172 	}
173 }
174 
fbnic_get_rss_hash_idx(u32 flow_type)175 static int fbnic_get_rss_hash_idx(u32 flow_type)
176 {
177 	switch (flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
178 	case TCP_V4_FLOW:
179 		return FBNIC_TCP4_HASH_OPT;
180 	case TCP_V6_FLOW:
181 		return FBNIC_TCP6_HASH_OPT;
182 	case UDP_V4_FLOW:
183 		return FBNIC_UDP4_HASH_OPT;
184 	case UDP_V6_FLOW:
185 		return FBNIC_UDP6_HASH_OPT;
186 	case AH_V4_FLOW:
187 	case ESP_V4_FLOW:
188 	case AH_ESP_V4_FLOW:
189 	case SCTP_V4_FLOW:
190 	case IPV4_FLOW:
191 	case IPV4_USER_FLOW:
192 		return FBNIC_IPV4_HASH_OPT;
193 	case AH_V6_FLOW:
194 	case ESP_V6_FLOW:
195 	case AH_ESP_V6_FLOW:
196 	case SCTP_V6_FLOW:
197 	case IPV6_FLOW:
198 	case IPV6_USER_FLOW:
199 		return FBNIC_IPV6_HASH_OPT;
200 	case ETHER_FLOW:
201 		return FBNIC_ETHER_HASH_OPT;
202 	}
203 
204 	return -1;
205 }
206 
207 static int
fbnic_get_rss_hash_opts(struct fbnic_net * fbn,struct ethtool_rxnfc * cmd)208 fbnic_get_rss_hash_opts(struct fbnic_net *fbn, struct ethtool_rxnfc *cmd)
209 {
210 	int hash_opt_idx = fbnic_get_rss_hash_idx(cmd->flow_type);
211 
212 	if (hash_opt_idx < 0)
213 		return -EINVAL;
214 
215 	/* Report options from rss_en table in fbn */
216 	cmd->data = fbn->rss_flow_hash[hash_opt_idx];
217 
218 	return 0;
219 }
220 
fbnic_get_rxnfc(struct net_device * netdev,struct ethtool_rxnfc * cmd,u32 * rule_locs)221 static int fbnic_get_rxnfc(struct net_device *netdev,
222 			   struct ethtool_rxnfc *cmd, u32 *rule_locs)
223 {
224 	struct fbnic_net *fbn = netdev_priv(netdev);
225 	int ret = -EOPNOTSUPP;
226 
227 	switch (cmd->cmd) {
228 	case ETHTOOL_GRXRINGS:
229 		cmd->data = fbn->num_rx_queues;
230 		ret = 0;
231 		break;
232 	case ETHTOOL_GRXFH:
233 		ret = fbnic_get_rss_hash_opts(fbn, cmd);
234 		break;
235 	}
236 
237 	return ret;
238 }
239 
240 #define FBNIC_L2_HASH_OPTIONS \
241 	(RXH_L2DA | RXH_DISCARD)
242 #define FBNIC_L3_HASH_OPTIONS \
243 	(FBNIC_L2_HASH_OPTIONS | RXH_IP_SRC | RXH_IP_DST)
244 #define FBNIC_L4_HASH_OPTIONS \
245 	(FBNIC_L3_HASH_OPTIONS | RXH_L4_B_0_1 | RXH_L4_B_2_3)
246 
247 static int
fbnic_set_rss_hash_opts(struct fbnic_net * fbn,const struct ethtool_rxnfc * cmd)248 fbnic_set_rss_hash_opts(struct fbnic_net *fbn, const struct ethtool_rxnfc *cmd)
249 {
250 	int hash_opt_idx;
251 
252 	/* Verify the type requested is correct */
253 	hash_opt_idx = fbnic_get_rss_hash_idx(cmd->flow_type);
254 	if (hash_opt_idx < 0)
255 		return -EINVAL;
256 
257 	/* Verify the fields asked for can actually be assigned based on type */
258 	if (cmd->data & ~FBNIC_L4_HASH_OPTIONS ||
259 	    (hash_opt_idx > FBNIC_L4_HASH_OPT &&
260 	     cmd->data & ~FBNIC_L3_HASH_OPTIONS) ||
261 	    (hash_opt_idx > FBNIC_IP_HASH_OPT &&
262 	     cmd->data & ~FBNIC_L2_HASH_OPTIONS))
263 		return -EINVAL;
264 
265 	fbn->rss_flow_hash[hash_opt_idx] = cmd->data;
266 
267 	if (netif_running(fbn->netdev)) {
268 		fbnic_rss_reinit(fbn->fbd, fbn);
269 		fbnic_write_rules(fbn->fbd);
270 	}
271 
272 	return 0;
273 }
274 
fbnic_set_rxnfc(struct net_device * netdev,struct ethtool_rxnfc * cmd)275 static int fbnic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
276 {
277 	struct fbnic_net *fbn = netdev_priv(netdev);
278 	int ret = -EOPNOTSUPP;
279 
280 	switch (cmd->cmd) {
281 	case ETHTOOL_SRXFH:
282 		ret = fbnic_set_rss_hash_opts(fbn, cmd);
283 		break;
284 	}
285 
286 	return ret;
287 }
288 
fbnic_get_rxfh_key_size(struct net_device * netdev)289 static u32 fbnic_get_rxfh_key_size(struct net_device *netdev)
290 {
291 	return FBNIC_RPC_RSS_KEY_BYTE_LEN;
292 }
293 
fbnic_get_rxfh_indir_size(struct net_device * netdev)294 static u32 fbnic_get_rxfh_indir_size(struct net_device *netdev)
295 {
296 	return FBNIC_RPC_RSS_TBL_SIZE;
297 }
298 
299 static int
fbnic_get_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh)300 fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
301 {
302 	struct fbnic_net *fbn = netdev_priv(netdev);
303 	unsigned int i;
304 
305 	rxfh->hfunc = ETH_RSS_HASH_TOP;
306 
307 	if (rxfh->key) {
308 		for (i = 0; i < FBNIC_RPC_RSS_KEY_BYTE_LEN; i++) {
309 			u32 rss_key = fbn->rss_key[i / 4] << ((i % 4) * 8);
310 
311 			rxfh->key[i] = rss_key >> 24;
312 		}
313 	}
314 
315 	if (rxfh->indir) {
316 		for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
317 			rxfh->indir[i] = fbn->indir_tbl[0][i];
318 	}
319 
320 	return 0;
321 }
322 
323 static unsigned int
fbnic_set_indir(struct fbnic_net * fbn,unsigned int idx,const u32 * indir)324 fbnic_set_indir(struct fbnic_net *fbn, unsigned int idx, const u32 *indir)
325 {
326 	unsigned int i, changes = 0;
327 
328 	for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
329 		if (fbn->indir_tbl[idx][i] == indir[i])
330 			continue;
331 
332 		fbn->indir_tbl[idx][i] = indir[i];
333 		changes++;
334 	}
335 
336 	return changes;
337 }
338 
339 static int
fbnic_set_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh,struct netlink_ext_ack * extack)340 fbnic_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh,
341 	       struct netlink_ext_ack *extack)
342 {
343 	struct fbnic_net *fbn = netdev_priv(netdev);
344 	unsigned int i, changes = 0;
345 
346 	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
347 	    rxfh->hfunc != ETH_RSS_HASH_TOP)
348 		return -EINVAL;
349 
350 	if (rxfh->key) {
351 		u32 rss_key = 0;
352 
353 		for (i = FBNIC_RPC_RSS_KEY_BYTE_LEN; i--;) {
354 			rss_key >>= 8;
355 			rss_key |= (u32)(rxfh->key[i]) << 24;
356 
357 			if (i % 4)
358 				continue;
359 
360 			if (fbn->rss_key[i / 4] == rss_key)
361 				continue;
362 
363 			fbn->rss_key[i / 4] = rss_key;
364 			changes++;
365 		}
366 	}
367 
368 	if (rxfh->indir)
369 		changes += fbnic_set_indir(fbn, 0, rxfh->indir);
370 
371 	if (changes && netif_running(netdev))
372 		fbnic_rss_reinit_hw(fbn->fbd, fbn);
373 
374 	return 0;
375 }
376 
fbnic_get_channels(struct net_device * netdev,struct ethtool_channels * ch)377 static void fbnic_get_channels(struct net_device *netdev,
378 			       struct ethtool_channels *ch)
379 {
380 	struct fbnic_net *fbn = netdev_priv(netdev);
381 	struct fbnic_dev *fbd = fbn->fbd;
382 
383 	ch->max_rx = fbd->max_num_queues;
384 	ch->max_tx = fbd->max_num_queues;
385 	ch->max_combined = min(ch->max_rx, ch->max_tx);
386 	ch->max_other =	FBNIC_NON_NAPI_VECTORS;
387 
388 	if (fbn->num_rx_queues > fbn->num_napi ||
389 	    fbn->num_tx_queues > fbn->num_napi)
390 		ch->combined_count = min(fbn->num_rx_queues,
391 					 fbn->num_tx_queues);
392 	else
393 		ch->combined_count =
394 			fbn->num_rx_queues + fbn->num_tx_queues - fbn->num_napi;
395 	ch->rx_count = fbn->num_rx_queues - ch->combined_count;
396 	ch->tx_count = fbn->num_tx_queues - ch->combined_count;
397 	ch->other_count = FBNIC_NON_NAPI_VECTORS;
398 }
399 
fbnic_set_queues(struct fbnic_net * fbn,struct ethtool_channels * ch,unsigned int max_napis)400 static void fbnic_set_queues(struct fbnic_net *fbn, struct ethtool_channels *ch,
401 			     unsigned int max_napis)
402 {
403 	fbn->num_rx_queues = ch->rx_count + ch->combined_count;
404 	fbn->num_tx_queues = ch->tx_count + ch->combined_count;
405 	fbn->num_napi = min(ch->rx_count + ch->tx_count + ch->combined_count,
406 			    max_napis);
407 }
408 
fbnic_set_channels(struct net_device * netdev,struct ethtool_channels * ch)409 static int fbnic_set_channels(struct net_device *netdev,
410 			      struct ethtool_channels *ch)
411 {
412 	struct fbnic_net *fbn = netdev_priv(netdev);
413 	unsigned int max_napis, standalone;
414 	struct fbnic_dev *fbd = fbn->fbd;
415 	struct fbnic_net *clone;
416 	int err;
417 
418 	max_napis = fbd->num_irqs - FBNIC_NON_NAPI_VECTORS;
419 	standalone = ch->rx_count + ch->tx_count;
420 
421 	/* Limits for standalone queues:
422 	 *  - each queue has it's own NAPI (num_napi >= rx + tx + combined)
423 	 *  - combining queues (combined not 0, rx or tx must be 0)
424 	 */
425 	if ((ch->rx_count && ch->tx_count && ch->combined_count) ||
426 	    (standalone && standalone + ch->combined_count > max_napis) ||
427 	    ch->rx_count + ch->combined_count > fbd->max_num_queues ||
428 	    ch->tx_count + ch->combined_count > fbd->max_num_queues ||
429 	    ch->other_count != FBNIC_NON_NAPI_VECTORS)
430 		return -EINVAL;
431 
432 	if (!netif_running(netdev)) {
433 		fbnic_set_queues(fbn, ch, max_napis);
434 		fbnic_reset_indir_tbl(fbn);
435 		return 0;
436 	}
437 
438 	clone = fbnic_clone_create(fbn);
439 	if (!clone)
440 		return -ENOMEM;
441 
442 	fbnic_set_queues(clone, ch, max_napis);
443 
444 	err = fbnic_alloc_napi_vectors(clone);
445 	if (err)
446 		goto err_free_clone;
447 
448 	err = fbnic_alloc_resources(clone);
449 	if (err)
450 		goto err_free_napis;
451 
452 	fbnic_down_noidle(fbn);
453 	err = fbnic_wait_all_queues_idle(fbn->fbd, true);
454 	if (err)
455 		goto err_start_stack;
456 
457 	err = fbnic_set_netif_queues(clone);
458 	if (err)
459 		goto err_start_stack;
460 
461 	/* Nothing can fail past this point */
462 	fbnic_flush(fbn);
463 
464 	fbnic_clone_swap(fbn, clone);
465 
466 	/* Reset RSS indirection table */
467 	fbnic_reset_indir_tbl(fbn);
468 
469 	fbnic_up(fbn);
470 
471 	fbnic_free_resources(clone);
472 	fbnic_free_napi_vectors(clone);
473 	fbnic_clone_free(clone);
474 
475 	return 0;
476 
477 err_start_stack:
478 	fbnic_flush(fbn);
479 	fbnic_up(fbn);
480 	fbnic_free_resources(clone);
481 err_free_napis:
482 	fbnic_free_napi_vectors(clone);
483 err_free_clone:
484 	fbnic_clone_free(clone);
485 	return err;
486 }
487 
488 static int
fbnic_get_ts_info(struct net_device * netdev,struct kernel_ethtool_ts_info * tsinfo)489 fbnic_get_ts_info(struct net_device *netdev,
490 		  struct kernel_ethtool_ts_info *tsinfo)
491 {
492 	struct fbnic_net *fbn = netdev_priv(netdev);
493 
494 	tsinfo->phc_index = ptp_clock_index(fbn->fbd->ptp);
495 
496 	tsinfo->so_timestamping =
497 		SOF_TIMESTAMPING_TX_SOFTWARE |
498 		SOF_TIMESTAMPING_TX_HARDWARE |
499 		SOF_TIMESTAMPING_RX_HARDWARE |
500 		SOF_TIMESTAMPING_RAW_HARDWARE;
501 
502 	tsinfo->tx_types =
503 		BIT(HWTSTAMP_TX_OFF) |
504 		BIT(HWTSTAMP_TX_ON);
505 
506 	tsinfo->rx_filters =
507 		BIT(HWTSTAMP_FILTER_NONE) |
508 		BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
509 		BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
510 		BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
511 		BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
512 		BIT(HWTSTAMP_FILTER_ALL);
513 
514 	return 0;
515 }
516 
fbnic_get_ts_stats(struct net_device * netdev,struct ethtool_ts_stats * ts_stats)517 static void fbnic_get_ts_stats(struct net_device *netdev,
518 			       struct ethtool_ts_stats *ts_stats)
519 {
520 	struct fbnic_net *fbn = netdev_priv(netdev);
521 	u64 ts_packets, ts_lost;
522 	struct fbnic_ring *ring;
523 	unsigned int start;
524 	int i;
525 
526 	ts_stats->pkts = fbn->tx_stats.ts_packets;
527 	ts_stats->lost = fbn->tx_stats.ts_lost;
528 	for (i = 0; i < fbn->num_tx_queues; i++) {
529 		ring = fbn->tx[i];
530 		do {
531 			start = u64_stats_fetch_begin(&ring->stats.syncp);
532 			ts_packets = ring->stats.ts_packets;
533 			ts_lost = ring->stats.ts_lost;
534 		} while (u64_stats_fetch_retry(&ring->stats.syncp, start));
535 		ts_stats->pkts += ts_packets;
536 		ts_stats->lost += ts_lost;
537 	}
538 }
539 
fbnic_set_counter(u64 * stat,struct fbnic_stat_counter * counter)540 static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
541 {
542 	if (counter->reported)
543 		*stat = counter->value;
544 }
545 
546 static void
fbnic_get_eth_mac_stats(struct net_device * netdev,struct ethtool_eth_mac_stats * eth_mac_stats)547 fbnic_get_eth_mac_stats(struct net_device *netdev,
548 			struct ethtool_eth_mac_stats *eth_mac_stats)
549 {
550 	struct fbnic_net *fbn = netdev_priv(netdev);
551 	struct fbnic_mac_stats *mac_stats;
552 	struct fbnic_dev *fbd = fbn->fbd;
553 	const struct fbnic_mac *mac;
554 
555 	mac_stats = &fbd->hw_stats.mac;
556 	mac = fbd->mac;
557 
558 	mac->get_eth_mac_stats(fbd, false, &mac_stats->eth_mac);
559 
560 	fbnic_set_counter(&eth_mac_stats->FramesTransmittedOK,
561 			  &mac_stats->eth_mac.FramesTransmittedOK);
562 	fbnic_set_counter(&eth_mac_stats->FramesReceivedOK,
563 			  &mac_stats->eth_mac.FramesReceivedOK);
564 	fbnic_set_counter(&eth_mac_stats->FrameCheckSequenceErrors,
565 			  &mac_stats->eth_mac.FrameCheckSequenceErrors);
566 	fbnic_set_counter(&eth_mac_stats->AlignmentErrors,
567 			  &mac_stats->eth_mac.AlignmentErrors);
568 	fbnic_set_counter(&eth_mac_stats->OctetsTransmittedOK,
569 			  &mac_stats->eth_mac.OctetsTransmittedOK);
570 	fbnic_set_counter(&eth_mac_stats->FramesLostDueToIntMACXmitError,
571 			  &mac_stats->eth_mac.FramesLostDueToIntMACXmitError);
572 	fbnic_set_counter(&eth_mac_stats->OctetsReceivedOK,
573 			  &mac_stats->eth_mac.OctetsReceivedOK);
574 	fbnic_set_counter(&eth_mac_stats->FramesLostDueToIntMACRcvError,
575 			  &mac_stats->eth_mac.FramesLostDueToIntMACRcvError);
576 	fbnic_set_counter(&eth_mac_stats->MulticastFramesXmittedOK,
577 			  &mac_stats->eth_mac.MulticastFramesXmittedOK);
578 	fbnic_set_counter(&eth_mac_stats->BroadcastFramesXmittedOK,
579 			  &mac_stats->eth_mac.BroadcastFramesXmittedOK);
580 	fbnic_set_counter(&eth_mac_stats->MulticastFramesReceivedOK,
581 			  &mac_stats->eth_mac.MulticastFramesReceivedOK);
582 	fbnic_set_counter(&eth_mac_stats->BroadcastFramesReceivedOK,
583 			  &mac_stats->eth_mac.BroadcastFramesReceivedOK);
584 	fbnic_set_counter(&eth_mac_stats->FrameTooLongErrors,
585 			  &mac_stats->eth_mac.FrameTooLongErrors);
586 }
587 
588 static const struct ethtool_ops fbnic_ethtool_ops = {
589 	.get_drvinfo		= fbnic_get_drvinfo,
590 	.get_regs_len		= fbnic_get_regs_len,
591 	.get_regs		= fbnic_get_regs,
592 	.get_strings		= fbnic_get_strings,
593 	.get_ethtool_stats	= fbnic_get_ethtool_stats,
594 	.get_sset_count		= fbnic_get_sset_count,
595 	.get_rxnfc		= fbnic_get_rxnfc,
596 	.set_rxnfc		= fbnic_set_rxnfc,
597 	.get_rxfh_key_size	= fbnic_get_rxfh_key_size,
598 	.get_rxfh_indir_size	= fbnic_get_rxfh_indir_size,
599 	.get_rxfh		= fbnic_get_rxfh,
600 	.set_rxfh		= fbnic_set_rxfh,
601 	.get_channels		= fbnic_get_channels,
602 	.set_channels		= fbnic_set_channels,
603 	.get_ts_info		= fbnic_get_ts_info,
604 	.get_ts_stats		= fbnic_get_ts_stats,
605 	.get_eth_mac_stats	= fbnic_get_eth_mac_stats,
606 };
607 
fbnic_set_ethtool_ops(struct net_device * dev)608 void fbnic_set_ethtool_ops(struct net_device *dev)
609 {
610 	dev->ethtool_ops = &fbnic_ethtool_ops;
611 }
612