1/*-
2 * Copyright (c) 2012-2016 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 *    this list of conditions and the following disclaimer in the documentation
12 *    and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/ef10_mac.c 342519 2018-12-26 10:26:58Z arybchik $");
33
34#include "efx.h"
35#include "efx_impl.h"
36
37
38#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
39
40	__checkReturn	efx_rc_t
41ef10_mac_poll(
42	__in		efx_nic_t *enp,
43	__out		efx_link_mode_t *link_modep)
44{
45	efx_port_t *epp = &(enp->en_port);
46	ef10_link_state_t els;
47	efx_rc_t rc;
48
49	if ((rc = ef10_phy_get_link(enp, &els)) != 0)
50		goto fail1;
51
52	epp->ep_adv_cap_mask = els.els_adv_cap_mask;
53	epp->ep_fcntl = els.els_fcntl;
54
55	*link_modep = els.els_link_mode;
56
57	return (0);
58
59fail1:
60	EFSYS_PROBE1(fail1, efx_rc_t, rc);
61
62	*link_modep = EFX_LINK_UNKNOWN;
63
64	return (rc);
65}
66
67	__checkReturn	efx_rc_t
68ef10_mac_up(
69	__in		efx_nic_t *enp,
70	__out		boolean_t *mac_upp)
71{
72	ef10_link_state_t els;
73	efx_rc_t rc;
74
75	/*
76	 * Because EF10 doesn't *require* polling, we can't rely on
77	 * ef10_mac_poll() being executed to populate epp->ep_mac_up.
78	 */
79	if ((rc = ef10_phy_get_link(enp, &els)) != 0)
80		goto fail1;
81
82	*mac_upp = els.els_mac_up;
83
84	return (0);
85
86fail1:
87	EFSYS_PROBE1(fail1, efx_rc_t, rc);
88
89	return (rc);
90}
91
92/*
93 * EF10 adapters use MC_CMD_VADAPTOR_SET_MAC to set the
94 * MAC address; the address field in MC_CMD_SET_MAC has no
95 * effect.
96 * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and
97 * the port to have no filters or queues active.
98 */
99static	__checkReturn	efx_rc_t
100efx_mcdi_vadapter_set_mac(
101	__in		efx_nic_t *enp)
102{
103	efx_port_t *epp = &(enp->en_port);
104	efx_mcdi_req_t req;
105	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
106		MC_CMD_VADAPTOR_SET_MAC_OUT_LEN);
107	efx_rc_t rc;
108
109	req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
110	req.emr_in_buf = payload;
111	req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
112	req.emr_out_buf = payload;
113	req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN;
114
115	MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
116	    enp->en_vport_id);
117	EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR),
118	    epp->ep_mac_addr);
119
120	efx_mcdi_execute(enp, &req);
121
122	if (req.emr_rc != 0) {
123		rc = req.emr_rc;
124		goto fail1;
125	}
126
127	return (0);
128
129fail1:
130	EFSYS_PROBE1(fail1, efx_rc_t, rc);
131
132	return (rc);
133}
134
135	__checkReturn	efx_rc_t
136ef10_mac_addr_set(
137	__in		efx_nic_t *enp)
138{
139	efx_rc_t rc;
140
141	if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0) {
142		if (rc != ENOTSUP)
143			goto fail1;
144
145		/*
146		 * Fallback for older Huntington firmware without Vadapter
147		 * support.
148		 */
149		if ((rc = ef10_mac_reconfigure(enp)) != 0)
150			goto fail2;
151	}
152
153	return (0);
154
155fail2:
156	EFSYS_PROBE(fail2);
157
158fail1:
159	EFSYS_PROBE1(fail1, efx_rc_t, rc);
160
161	return (rc);
162}
163
164static	__checkReturn	efx_rc_t
165efx_mcdi_mtu_set(
166	__in		efx_nic_t *enp,
167	__in		uint32_t mtu)
168{
169	efx_mcdi_req_t req;
170	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN,
171		MC_CMD_SET_MAC_OUT_LEN);
172	efx_rc_t rc;
173
174	req.emr_cmd = MC_CMD_SET_MAC;
175	req.emr_in_buf = payload;
176	req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN;
177	req.emr_out_buf = payload;
178	req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
179
180	/* Only configure the MTU in this call to MC_CMD_SET_MAC */
181	MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_MTU, mtu);
182	MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_EXT_IN_CONTROL,
183			    SET_MAC_EXT_IN_CFG_MTU, 1);
184
185	efx_mcdi_execute(enp, &req);
186
187	if (req.emr_rc != 0) {
188		rc = req.emr_rc;
189		goto fail1;
190	}
191
192	return (0);
193
194fail1:
195	EFSYS_PROBE1(fail1, efx_rc_t, rc);
196
197	return (rc);
198}
199
200static	__checkReturn		efx_rc_t
201efx_mcdi_mtu_get(
202	__in		efx_nic_t *enp,
203	__out		size_t *mtu)
204{
205	efx_mcdi_req_t req;
206	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN,
207		MC_CMD_SET_MAC_V2_OUT_LEN);
208	efx_rc_t rc;
209
210	req.emr_cmd = MC_CMD_SET_MAC;
211	req.emr_in_buf = payload;
212	req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN;
213	req.emr_out_buf = payload;
214	req.emr_out_length = MC_CMD_SET_MAC_V2_OUT_LEN;
215
216	/*
217	 * With MC_CMD_SET_MAC_EXT_IN_CONTROL set to 0, this just queries the
218	 * MTU.  This should always be supported on Medford, but it is not
219	 * supported on older Huntington firmware.
220	 */
221	MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_CONTROL, 0);
222
223	efx_mcdi_execute(enp, &req);
224
225	if (req.emr_rc != 0) {
226		rc = req.emr_rc;
227		goto fail1;
228	}
229	if (req.emr_out_length_used < MC_CMD_SET_MAC_V2_OUT_MTU_OFST + 4) {
230		rc = EMSGSIZE;
231		goto fail2;
232	}
233
234	*mtu = MCDI_OUT_DWORD(req, SET_MAC_V2_OUT_MTU);
235
236	return (0);
237
238fail2:
239	EFSYS_PROBE(fail2);
240fail1:
241	EFSYS_PROBE1(fail1, efx_rc_t, rc);
242
243	return (rc);
244}
245
246	__checkReturn	efx_rc_t
247ef10_mac_pdu_set(
248	__in		efx_nic_t *enp)
249{
250	efx_port_t *epp = &(enp->en_port);
251	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
252	efx_rc_t rc;
253
254	if (encp->enc_enhanced_set_mac_supported) {
255		if ((rc = efx_mcdi_mtu_set(enp, epp->ep_mac_pdu)) != 0)
256			goto fail1;
257	} else {
258		/*
259		 * Fallback for older Huntington firmware, which always
260		 * configure all of the parameters to MC_CMD_SET_MAC. This isn't
261		 * suitable for setting the MTU on unpriviliged functions.
262		 */
263		if ((rc = ef10_mac_reconfigure(enp)) != 0)
264			goto fail2;
265	}
266
267	return (0);
268
269fail2:
270	EFSYS_PROBE(fail2);
271fail1:
272	EFSYS_PROBE1(fail1, efx_rc_t, rc);
273
274	return (rc);
275}
276
277	__checkReturn		efx_rc_t
278ef10_mac_pdu_get(
279	__in		efx_nic_t *enp,
280	__out		size_t *pdu)
281{
282	efx_rc_t rc;
283
284	if ((rc = efx_mcdi_mtu_get(enp, pdu)) != 0)
285		goto fail1;
286
287	return (0);
288
289fail1:
290	EFSYS_PROBE1(fail1, efx_rc_t, rc);
291
292	return (rc);
293}
294
295__checkReturn	efx_rc_t
296ef10_mac_reconfigure(
297	__in		efx_nic_t *enp)
298{
299	efx_port_t *epp = &(enp->en_port);
300	efx_mcdi_req_t req;
301	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_IN_LEN,
302		MC_CMD_SET_MAC_OUT_LEN);
303	efx_rc_t rc;
304
305	req.emr_cmd = MC_CMD_SET_MAC;
306	req.emr_in_buf = payload;
307	req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
308	req.emr_out_buf = payload;
309	req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
310
311	MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
312	MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
313	EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
314			    epp->ep_mac_addr);
315
316	/*
317	 * Note: The Huntington MAC does not support REJECT_BRDCST.
318	 * The REJECT_UNCST flag will also prevent multicast traffic
319	 * from reaching the filters. As Huntington filters drop any
320	 * traffic that does not match a filter it is ok to leave the
321	 * MAC running in promiscuous mode. See bug41141.
322	 *
323	 * FIXME: Does REJECT_UNCST behave the same way on Medford?
324	 */
325	MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
326				    SET_MAC_IN_REJECT_UNCST, 0,
327				    SET_MAC_IN_REJECT_BRDCST, 0);
328
329	/*
330	 * Flow control, whether it is auto-negotiated or not,
331	 * is set via the PHY advertised capabilities.  When set to
332	 * automatic the MAC will use the PHY settings to determine
333	 * the flow control settings.
334	 */
335	MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO);
336
337	/* Do not include the Ethernet frame checksum in RX packets */
338	MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS,
339				    SET_MAC_IN_FLAG_INCLUDE_FCS, 0);
340
341	efx_mcdi_execute_quiet(enp, &req);
342
343	if (req.emr_rc != 0) {
344		/*
345		 * Unprivileged functions cannot control link state,
346		 * but still need to configure filters.
347		 */
348		if (req.emr_rc != EACCES) {
349			rc = req.emr_rc;
350			goto fail1;
351		}
352	}
353
354	/*
355	 * Apply the filters for the MAC configuration.
356	 * If the NIC isn't ready to accept filters this may
357	 * return success without setting anything.
358	 */
359	rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
360				    epp->ep_all_unicst, epp->ep_mulcst,
361				    epp->ep_all_mulcst, epp->ep_brdcst,
362				    epp->ep_mulcst_addr_list,
363				    epp->ep_mulcst_addr_count);
364
365	return (0);
366
367fail1:
368	EFSYS_PROBE1(fail1, efx_rc_t, rc);
369
370	return (rc);
371}
372
373	__checkReturn			efx_rc_t
374ef10_mac_multicast_list_set(
375	__in				efx_nic_t *enp)
376{
377	efx_port_t *epp = &(enp->en_port);
378	const efx_mac_ops_t *emop = epp->ep_emop;
379	efx_rc_t rc;
380
381	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
382		    enp->en_family == EFX_FAMILY_MEDFORD);
383
384	if ((rc = emop->emo_reconfigure(enp)) != 0)
385		goto fail1;
386
387	return (0);
388
389fail1:
390	EFSYS_PROBE1(fail1, efx_rc_t, rc);
391
392	return (rc);
393}
394
395	__checkReturn	efx_rc_t
396ef10_mac_filter_default_rxq_set(
397	__in		efx_nic_t *enp,
398	__in		efx_rxq_t *erp,
399	__in		boolean_t using_rss)
400{
401	efx_port_t *epp = &(enp->en_port);
402	efx_rxq_t *old_rxq;
403	boolean_t old_using_rss;
404	efx_rc_t rc;
405
406	ef10_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
407
408	ef10_filter_default_rxq_set(enp, erp, using_rss);
409
410	rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
411				    epp->ep_all_unicst, epp->ep_mulcst,
412				    epp->ep_all_mulcst, epp->ep_brdcst,
413				    epp->ep_mulcst_addr_list,
414				    epp->ep_mulcst_addr_count);
415
416	if (rc != 0)
417		goto fail1;
418
419	return (0);
420
421fail1:
422	EFSYS_PROBE1(fail1, efx_rc_t, rc);
423
424	ef10_filter_default_rxq_set(enp, old_rxq, old_using_rss);
425
426	return (rc);
427}
428
429			void
430ef10_mac_filter_default_rxq_clear(
431	__in		efx_nic_t *enp)
432{
433	efx_port_t *epp = &(enp->en_port);
434
435	ef10_filter_default_rxq_clear(enp);
436
437	(void) efx_filter_reconfigure(enp, epp->ep_mac_addr,
438				    epp->ep_all_unicst, epp->ep_mulcst,
439				    epp->ep_all_mulcst, epp->ep_brdcst,
440				    epp->ep_mulcst_addr_list,
441				    epp->ep_mulcst_addr_count);
442}
443
444
445#if EFSYS_OPT_LOOPBACK
446
447	__checkReturn	efx_rc_t
448ef10_mac_loopback_set(
449	__in		efx_nic_t *enp,
450	__in		efx_link_mode_t link_mode,
451	__in		efx_loopback_type_t loopback_type)
452{
453	efx_port_t *epp = &(enp->en_port);
454	const efx_phy_ops_t *epop = epp->ep_epop;
455	efx_loopback_type_t old_loopback_type;
456	efx_link_mode_t old_loopback_link_mode;
457	efx_rc_t rc;
458
459	/* The PHY object handles this on EF10 */
460	old_loopback_type = epp->ep_loopback_type;
461	old_loopback_link_mode = epp->ep_loopback_link_mode;
462	epp->ep_loopback_type = loopback_type;
463	epp->ep_loopback_link_mode = link_mode;
464
465	if ((rc = epop->epo_reconfigure(enp)) != 0)
466		goto fail1;
467
468	return (0);
469
470fail1:
471	EFSYS_PROBE1(fail1, efx_rc_t, rc);
472
473	epp->ep_loopback_type = old_loopback_type;
474	epp->ep_loopback_link_mode = old_loopback_link_mode;
475
476	return (rc);
477}
478
479#endif	/* EFSYS_OPT_LOOPBACK */
480
481#if EFSYS_OPT_MAC_STATS
482
483	__checkReturn			efx_rc_t
484ef10_mac_stats_get_mask(
485	__in				efx_nic_t *enp,
486	__inout_bcount(mask_size)	uint32_t *maskp,
487	__in				size_t mask_size)
488{
489	const struct efx_mac_stats_range ef10_common[] = {
490		{ EFX_MAC_RX_OCTETS, EFX_MAC_RX_GE_15XX_PKTS },
491		{ EFX_MAC_RX_FCS_ERRORS, EFX_MAC_RX_DROP_EVENTS },
492		{ EFX_MAC_RX_JABBER_PKTS, EFX_MAC_RX_JABBER_PKTS },
493		{ EFX_MAC_RX_NODESC_DROP_CNT, EFX_MAC_TX_PAUSE_PKTS },
494	};
495	const struct efx_mac_stats_range ef10_tx_size_bins[] = {
496		{ EFX_MAC_TX_LE_64_PKTS, EFX_MAC_TX_GE_15XX_PKTS },
497	};
498	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
499	efx_port_t *epp = &(enp->en_port);
500	efx_rc_t rc;
501
502	if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size,
503	    ef10_common, EFX_ARRAY_SIZE(ef10_common))) != 0)
504		goto fail1;
505
506	if (epp->ep_phy_cap_mask & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) {
507		const struct efx_mac_stats_range ef10_40g_extra[] = {
508			{ EFX_MAC_RX_ALIGN_ERRORS, EFX_MAC_RX_ALIGN_ERRORS },
509		};
510
511		if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size,
512		    ef10_40g_extra, EFX_ARRAY_SIZE(ef10_40g_extra))) != 0)
513			goto fail2;
514
515		if (encp->enc_mac_stats_40g_tx_size_bins) {
516			if ((rc = efx_mac_stats_mask_add_ranges(maskp,
517			    mask_size, ef10_tx_size_bins,
518			    EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0)
519				goto fail3;
520		}
521	} else {
522		if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size,
523		    ef10_tx_size_bins, EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0)
524			goto fail4;
525	}
526
527	if (encp->enc_pm_and_rxdp_counters) {
528		const struct efx_mac_stats_range ef10_pm_and_rxdp[] = {
529			{ EFX_MAC_PM_TRUNC_BB_OVERFLOW, EFX_MAC_RXDP_HLB_WAIT },
530		};
531
532		if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size,
533		    ef10_pm_and_rxdp, EFX_ARRAY_SIZE(ef10_pm_and_rxdp))) != 0)
534			goto fail5;
535	}
536
537	if (encp->enc_datapath_cap_evb) {
538		const struct efx_mac_stats_range ef10_vadaptor[] = {
539			{ EFX_MAC_VADAPTER_RX_UNICAST_PACKETS,
540			    EFX_MAC_VADAPTER_TX_OVERFLOW },
541		};
542
543		if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size,
544		    ef10_vadaptor, EFX_ARRAY_SIZE(ef10_vadaptor))) != 0)
545			goto fail6;
546	}
547
548	return (0);
549
550fail6:
551	EFSYS_PROBE(fail6);
552fail5:
553	EFSYS_PROBE(fail5);
554fail4:
555	EFSYS_PROBE(fail4);
556fail3:
557	EFSYS_PROBE(fail3);
558fail2:
559	EFSYS_PROBE(fail2);
560fail1:
561	EFSYS_PROBE1(fail1, efx_rc_t, rc);
562
563	return (rc);
564}
565
566#define	EF10_MAC_STAT_READ(_esmp, _field, _eqp)			\
567	EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
568
569
570	__checkReturn			efx_rc_t
571ef10_mac_stats_update(
572	__in				efx_nic_t *enp,
573	__in				efsys_mem_t *esmp,
574	__inout_ecount(EFX_MAC_NSTATS)	efsys_stat_t *stat,
575	__inout_opt			uint32_t *generationp)
576{
577	efx_qword_t value;
578	efx_qword_t generation_start;
579	efx_qword_t generation_end;
580
581	_NOTE(ARGUNUSED(enp))
582
583	/* Read END first so we don't race with the MC */
584	EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
585	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
586			    &generation_end);
587	EFSYS_MEM_READ_BARRIER();
588
589	/* TX */
590	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
591	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
592
593	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
594	EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
595
596	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
597	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
598
599	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
600	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
601
602	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
603	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
604
605	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
606	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
607
608	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
609	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
610
611	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
612	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
613	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
614	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
615
616	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
617	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
618
619	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
620	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
621
622	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
623	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
624
625	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
626	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
627
628	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
629	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
630
631	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
632	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
633	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
634	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
635
636	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
637	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
638
639	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
640	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
641
642	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
643			    &value);
644	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
645
646	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
647			    &value);
648	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
649
650	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
651	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
652
653	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
654	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
655
656	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
657	    &value);
658	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
659
660	/* RX */
661	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
662	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
663
664	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
665	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
666
667	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
668	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
669
670	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
671	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
672
673	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
674	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
675
676	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
677	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
678
679	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
680	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
681	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
682	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
683
684	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
685	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
686
687	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
688	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
689
690	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
691	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
692
693	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
694	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
695
696	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
697	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
698
699	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
700	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
701	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
702	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
703
704	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
705	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
706
707	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
708	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
709
710	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
711	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
712
713	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
714	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
715
716	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
717	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
718
719	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
720	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
721
722	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
723	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
724
725	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
726	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
727			    &(value.eq_dword[0]));
728	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
729			    &(value.eq_dword[1]));
730
731	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
732	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
733			    &(value.eq_dword[0]));
734	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
735			    &(value.eq_dword[1]));
736
737	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
738	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
739			    &(value.eq_dword[0]));
740	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
741			    &(value.eq_dword[1]));
742
743	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
744	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
745			    &(value.eq_dword[0]));
746	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
747			    &(value.eq_dword[1]));
748
749	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
750	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
751
752	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
753	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
754
755	/* Packet memory (EF10 only) */
756	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value);
757	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value);
758
759	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value);
760	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value);
761
762	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value);
763	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value);
764
765	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value);
766	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value);
767
768	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value);
769	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value);
770
771	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value);
772	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value);
773
774	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value);
775	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value);
776
777	/* RX datapath */
778	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value);
779	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value);
780
781	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value);
782	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value);
783
784	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value);
785	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value);
786
787	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value);
788	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value);
789
790	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value);
791	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value);
792
793
794	/* VADAPTER RX */
795	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS,
796	    &value);
797	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]),
798	    &value);
799
800	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES,
801	    &value);
802	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]),
803	    &value);
804
805	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS,
806	    &value);
807	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]),
808	    &value);
809
810	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES,
811	    &value);
812	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]),
813	    &value);
814
815	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS,
816	    &value);
817	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]),
818	    &value);
819
820	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES,
821	    &value);
822	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]),
823	    &value);
824
825	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS,
826	    &value);
827	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]),
828	    &value);
829
830	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value);
831	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value);
832
833	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value);
834	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value);
835
836	/* VADAPTER TX */
837	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS,
838	    &value);
839	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]),
840	    &value);
841
842	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES,
843	    &value);
844	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]),
845	    &value);
846
847	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS,
848	    &value);
849	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]),
850	    &value);
851
852	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES,
853	    &value);
854	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]),
855	    &value);
856
857	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS,
858	    &value);
859	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]),
860	    &value);
861
862	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES,
863	    &value);
864	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]),
865	    &value);
866
867	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value);
868	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value);
869
870	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value);
871	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value);
872
873	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value);
874	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value);
875
876
877	EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
878	EFSYS_MEM_READ_BARRIER();
879	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
880			    &generation_start);
881
882	/* Check that we didn't read the stats in the middle of a DMA */
883	/* Not a good enough check ? */
884	if (memcmp(&generation_start, &generation_end,
885	    sizeof (generation_start)))
886		return (EAGAIN);
887
888	if (generationp)
889		*generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
890
891	return (0);
892}
893
894#endif	/* EFSYS_OPT_MAC_STATS */
895
896#endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
897