xref: /freebsd/sys/dev/sfxge/common/siena_mac.c (revision 8d20be1e22095c27faf8fe8b2f0d089739cc742e)
1 /*-
2  * Copyright 2009 Solarflare Communications Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28 
29 #include "efsys.h"
30 #include "efx.h"
31 #include "efx_impl.h"
32 
33 #if EFSYS_OPT_SIENA
34 
35 	__checkReturn	int
36 siena_mac_poll(
37 	__in		efx_nic_t *enp,
38 	__out		efx_link_mode_t *link_modep)
39 {
40 	efx_port_t *epp = &(enp->en_port);
41 	siena_link_state_t sls;
42 	int rc;
43 
44 	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
45 		goto fail1;
46 
47 	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
48 	epp->ep_fcntl = sls.sls_fcntl;
49 
50 	*link_modep = sls.sls_link_mode;
51 
52 	return (0);
53 
54 fail1:
55 	EFSYS_PROBE1(fail1, int, rc);
56 
57 	*link_modep = EFX_LINK_UNKNOWN;
58 
59 	return (rc);
60 }
61 
62 	__checkReturn	int
63 siena_mac_up(
64 	__in		efx_nic_t *enp,
65 	__out		boolean_t *mac_upp)
66 {
67 	siena_link_state_t sls;
68 	int rc;
69 
70 	/*
71 	 * Because Siena doesn't *require* polling, we can't rely on
72 	 * siena_mac_poll() being executed to populate epp->ep_mac_up.
73 	 */
74 	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
75 		goto fail1;
76 
77 	*mac_upp = sls.sls_mac_up;
78 
79 	return (0);
80 
81 fail1:
82 	EFSYS_PROBE1(fail1, int, rc);
83 
84 	return (rc);
85 }
86 
87 	__checkReturn	int
88 siena_mac_reconfigure(
89 	__in		efx_nic_t *enp)
90 {
91 	efx_port_t *epp = &(enp->en_port);
92 	uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
93 			    MC_CMD_SET_MCAST_HASH_IN_LEN)];
94 	efx_mcdi_req_t req;
95 	unsigned int fcntl;
96 	int rc;
97 
98 	req.emr_cmd = MC_CMD_SET_MAC;
99 	req.emr_in_buf = payload;
100 	req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
101 	EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0);
102 	req.emr_out_buf = NULL;
103 	req.emr_out_length = 0;
104 
105 	MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
106 	MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
107 	EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
108 			    epp->ep_mac_addr);
109 	MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
110 				    SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst,
111 				    SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
112 
113 	if (epp->ep_fcntl_autoneg)
114 		/* efx_fcntl_set() has already set the phy capabilities */
115 		fcntl = MC_CMD_FCNTL_AUTO;
116 	else if (epp->ep_fcntl & EFX_FCNTL_RESPOND)
117 		fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE)
118 			? MC_CMD_FCNTL_BIDIR
119 			: MC_CMD_FCNTL_RESPOND;
120 	else
121 		fcntl = MC_CMD_FCNTL_OFF;
122 
123 	MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl);
124 
125 	efx_mcdi_execute(enp, &req);
126 
127 	if (req.emr_rc != 0) {
128 		rc = req.emr_rc;
129 		goto fail1;
130 	}
131 
132 	/* Push multicast hash. Set the broadcast bit (0xff) appropriately */
133 	req.emr_cmd = MC_CMD_SET_MCAST_HASH;
134 	req.emr_in_buf = payload;
135 	req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
136 	EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0);
137 	req.emr_out_buf = NULL;
138 	req.emr_out_length = 0;
139 
140 	memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
141 	    epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash));
142 	if (epp->ep_brdcst)
143 		EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t,
144 		    SET_MCAST_HASH_IN_HASH1), 0x7f);
145 
146 	efx_mcdi_execute(enp, &req);
147 
148 	if (req.emr_rc != 0) {
149 		rc = req.emr_rc;
150 		goto fail2;
151 	}
152 
153 	return (0);
154 
155 fail2:
156 	EFSYS_PROBE(fail2);
157 fail1:
158 	EFSYS_PROBE1(fail1, int, rc);
159 
160 	return (rc);
161 }
162 
163 #if EFSYS_OPT_LOOPBACK
164 
165 	__checkReturn	int
166 siena_mac_loopback_set(
167 	__in		efx_nic_t *enp,
168 	__in		efx_link_mode_t link_mode,
169 	__in		efx_loopback_type_t loopback_type)
170 {
171 	efx_port_t *epp = &(enp->en_port);
172 	efx_phy_ops_t *epop = epp->ep_epop;
173 	efx_loopback_type_t old_loopback_type;
174 	efx_link_mode_t old_loopback_link_mode;
175 	int rc;
176 
177 	/* The PHY object handles this on Siena */
178 	old_loopback_type = epp->ep_loopback_type;
179 	old_loopback_link_mode = epp->ep_loopback_link_mode;
180 	epp->ep_loopback_type = loopback_type;
181 	epp->ep_loopback_link_mode = link_mode;
182 
183 	if ((rc = epop->epo_reconfigure(enp)) != 0)
184 		goto fail1;
185 
186 	return (0);
187 
188 fail1:
189 	EFSYS_PROBE(fail2);
190 
191 	epp->ep_loopback_type = old_loopback_type;
192 	epp->ep_loopback_link_mode = old_loopback_link_mode;
193 
194 	return (rc);
195 }
196 
197 #endif	/* EFSYS_OPT_LOOPBACK */
198 
199 #if EFSYS_OPT_MAC_STATS
200 
201 	__checkReturn			int
202 siena_mac_stats_clear(
203 	__in				efx_nic_t *enp)
204 {
205 	uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
206 	efx_mcdi_req_t req;
207 	int rc;
208 
209 	req.emr_cmd = MC_CMD_MAC_STATS;
210 	req.emr_in_buf = payload;
211 	req.emr_in_length = sizeof (payload);
212 	EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
213 	req.emr_out_buf = NULL;
214 	req.emr_out_length = 0;
215 
216 	MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
217 				    MAC_STATS_IN_DMA, 0,
218 				    MAC_STATS_IN_CLEAR, 1,
219 				    MAC_STATS_IN_PERIODIC_CHANGE, 0);
220 
221 	efx_mcdi_execute(enp, &req);
222 
223 	if (req.emr_rc != 0) {
224 		rc = req.emr_rc;
225 		goto fail1;
226 	}
227 
228 	return (0);
229 
230 fail1:
231 	EFSYS_PROBE1(fail1, int, rc);
232 
233 	return (rc);
234 }
235 
236 	__checkReturn			int
237 siena_mac_stats_upload(
238 	__in				efx_nic_t *enp,
239 	__in				efsys_mem_t *esmp)
240 {
241 	uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
242 	efx_mcdi_req_t req;
243 	size_t bytes;
244 	int rc;
245 
246 	EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
247 	    EFX_MAC_STATS_SIZE);
248 
249 	bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
250 
251 	req.emr_cmd = MC_CMD_MAC_STATS;
252 	req.emr_in_buf = payload;
253 	req.emr_in_length = sizeof (payload);
254 	EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
255 	req.emr_out_buf = NULL;
256 	req.emr_out_length = 0;
257 
258 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
259 			    EFSYS_MEM_ADDR(esmp) & 0xffffffff);
260 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
261 			    EFSYS_MEM_ADDR(esmp) >> 32);
262 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
263 
264 	/*
265 	 * The MC DMAs aggregate statistics for our convinience, so we can
266 	 * avoid having to pull the statistics buffer into the cache to
267 	 * maintain cumulative statistics.
268 	 */
269 	MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
270 				    MAC_STATS_IN_DMA, 1,
271 				    MAC_STATS_IN_CLEAR, 0,
272 				    MAC_STATS_IN_PERIODIC_CHANGE, 0);
273 
274 	efx_mcdi_execute(enp, &req);
275 
276 	if (req.emr_rc != 0) {
277 		rc = req.emr_rc;
278 		goto fail1;
279 	}
280 
281 	return (0);
282 
283 fail1:
284 	EFSYS_PROBE1(fail1, int, rc);
285 
286 	return (rc);
287 }
288 
289 	__checkReturn			int
290 siena_mac_stats_periodic(
291 	__in				efx_nic_t *enp,
292 	__in				efsys_mem_t *esmp,
293 	__in				uint16_t period,
294 	__in				boolean_t events)
295 {
296 	uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
297 	efx_mcdi_req_t req;
298 	size_t bytes;
299 	int rc;
300 
301 	bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
302 
303 	req.emr_cmd = MC_CMD_MAC_STATS;
304 	req.emr_in_buf = payload;
305 	req.emr_in_length = sizeof (payload);
306 	EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
307 	req.emr_out_buf = NULL;
308 	req.emr_out_length = 0;
309 
310 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
311 			    EFSYS_MEM_ADDR(esmp) & 0xffffffff);
312 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
313 			    EFSYS_MEM_ADDR(esmp) >> 32);
314 	MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
315 
316 	/*
317 	 * The MC DMAs aggregate statistics for our convinience, so we can
318 	 * avoid having to pull the statistics buffer into the cache to
319 	 * maintain cumulative statistics.
320 	 */
321 	MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
322 			    MAC_STATS_IN_DMA, 0,
323 			    MAC_STATS_IN_CLEAR, 0,
324 			    MAC_STATS_IN_PERIODIC_CHANGE, 1,
325 			    MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0,
326 			    MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1,
327 			    MAC_STATS_IN_PERIOD_MS, period);
328 
329 	efx_mcdi_execute(enp, &req);
330 
331 	if (req.emr_rc != 0) {
332 		rc = req.emr_rc;
333 		goto fail1;
334 	}
335 
336 	return (0);
337 
338 fail1:
339 	EFSYS_PROBE1(fail1, int, rc);
340 
341 	return (rc);
342 }
343 
344 
345 #define	SIENA_MAC_STAT_READ(_esmp, _field, _eqp)			\
346 	EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
347 
348 	__checkReturn			int
349 siena_mac_stats_update(
350 	__in				efx_nic_t *enp,
351 	__in				efsys_mem_t *esmp,
352 	__out_ecount(EFX_MAC_NSTATS)	efsys_stat_t *stat,
353 	__out_opt			uint32_t *generationp)
354 {
355 	efx_qword_t rx_pkts;
356 	efx_qword_t value;
357 	efx_qword_t generation_start;
358 	efx_qword_t generation_end;
359 
360 	_NOTE(ARGUNUSED(enp))
361 
362 	/* Read END first so we don't race with the MC */
363 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
364 			    &generation_end);
365 	EFSYS_MEM_READ_BARRIER();
366 
367 	/* TX */
368 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
369 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
370 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
371 	EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
372 
373 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
374 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
375 
376 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
377 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
378 
379 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
380 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
381 
382 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
383 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
384 
385 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
386 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
387 
388 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
389 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
390 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
391 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
392 
393 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
394 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
395 
396 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
397 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
398 
399 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
400 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
401 
402 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
403 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
404 
405 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
406 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
407 
408 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
409 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
410 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
411 	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
412 
413 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
414 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
415 
416 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
417 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
418 
419 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
420 			    &value);
421 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
422 
423 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
424 			    &value);
425 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
426 
427 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
428 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
429 
430 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
431 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
432 
433 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
434 	    &value);
435 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
436 
437 	/* RX */
438 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts);
439 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts);
440 
441 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
442 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
443 
444 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
445 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
446 
447 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
448 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
449 
450 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
451 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
452 
453 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
454 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
455 
456 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
457 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
458 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
459 	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
460 
461 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
462 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
463 
464 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
465 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
466 
467 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
468 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
469 
470 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
471 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
472 
473 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
474 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
475 
476 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
477 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
478 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
479 	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
480 
481 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
482 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
483 
484 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
485 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
486 
487 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
488 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
489 
490 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
491 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
492 
493 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
494 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
495 
496 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
497 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
498 
499 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
500 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
501 
502 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
503 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
504 			    &(value.eq_dword[0]));
505 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
506 			    &(value.eq_dword[1]));
507 
508 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
509 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
510 			    &(value.eq_dword[0]));
511 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
512 			    &(value.eq_dword[1]));
513 
514 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
515 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
516 			    &(value.eq_dword[0]));
517 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
518 			    &(value.eq_dword[1]));
519 
520 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
521 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
522 			    &(value.eq_dword[0]));
523 	EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
524 			    &(value.eq_dword[1]));
525 
526 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
527 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
528 
529 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
530 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
531 
532 	EFSYS_MEM_READ_BARRIER();
533 	SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
534 			    &generation_start);
535 
536 	/* Check that we didn't read the stats in the middle of a DMA */
537 	if (memcmp(&generation_start, &generation_end,
538 	    sizeof (generation_start)))
539 		return (EAGAIN);
540 
541 	if (generationp)
542 		*generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
543 
544 	return (0);
545 }
546 
547 #endif	/* EFSYS_OPT_MAC_STATS */
548 
549 #endif	/* EFSYS_OPT_SIENA */
550