1 /*
2 * Copyright (c) 2009-2015 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 "efx.h"
32 #include "efx_impl.h"
33
34 #if EFSYS_OPT_SIENA
35
36 __checkReturn efx_rc_t
siena_mac_poll(__in efx_nic_t * enp,__out efx_link_mode_t * link_modep)37 siena_mac_poll(
38 __in efx_nic_t *enp,
39 __out efx_link_mode_t *link_modep)
40 {
41 efx_port_t *epp = &(enp->en_port);
42 siena_link_state_t sls;
43 efx_rc_t rc;
44
45 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
46 goto fail1;
47
48 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
49 epp->ep_fcntl = sls.sls_fcntl;
50
51 *link_modep = sls.sls_link_mode;
52
53 return (0);
54
55 fail1:
56 EFSYS_PROBE1(fail1, efx_rc_t, rc);
57
58 *link_modep = EFX_LINK_UNKNOWN;
59
60 return (rc);
61 }
62
63 __checkReturn efx_rc_t
siena_mac_up(__in efx_nic_t * enp,__out boolean_t * mac_upp)64 siena_mac_up(
65 __in efx_nic_t *enp,
66 __out boolean_t *mac_upp)
67 {
68 siena_link_state_t sls;
69 efx_rc_t rc;
70
71 /*
72 * Because Siena doesn't *require* polling, we can't rely on
73 * siena_mac_poll() being executed to populate epp->ep_mac_up.
74 */
75 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
76 goto fail1;
77
78 *mac_upp = sls.sls_mac_up;
79
80 return (0);
81
82 fail1:
83 EFSYS_PROBE1(fail1, efx_rc_t, rc);
84
85 return (rc);
86 }
87
88 __checkReturn efx_rc_t
siena_mac_reconfigure(__in efx_nic_t * enp)89 siena_mac_reconfigure(
90 __in efx_nic_t *enp)
91 {
92 efx_port_t *epp = &(enp->en_port);
93 efx_oword_t multicast_hash[2];
94 efx_mcdi_req_t req;
95 uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
96 MC_CMD_SET_MAC_OUT_LEN),
97 MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
98 MC_CMD_SET_MCAST_HASH_OUT_LEN))];
99 unsigned int fcntl;
100 efx_rc_t rc;
101
102 (void) memset(payload, 0, sizeof (payload));
103 req.emr_cmd = MC_CMD_SET_MAC;
104 req.emr_in_buf = payload;
105 req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
106 req.emr_out_buf = payload;
107 req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
108
109 MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
110 MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
111 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
112 epp->ep_mac_addr);
113 MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
114 SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst,
115 SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
116
117 if (epp->ep_fcntl_autoneg)
118 /* efx_fcntl_set() has already set the phy capabilities */
119 fcntl = MC_CMD_FCNTL_AUTO;
120 else if (epp->ep_fcntl & EFX_FCNTL_RESPOND)
121 fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE)
122 ? MC_CMD_FCNTL_BIDIR
123 : MC_CMD_FCNTL_RESPOND;
124 else
125 fcntl = MC_CMD_FCNTL_OFF;
126
127 MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl);
128
129 efx_mcdi_execute(enp, &req);
130
131 if (req.emr_rc != 0) {
132 rc = req.emr_rc;
133 goto fail1;
134 }
135
136 /* Push multicast hash */
137
138 if (epp->ep_all_mulcst) {
139 /* A hash matching all multicast is all 1s */
140 EFX_SET_OWORD(multicast_hash[0]);
141 EFX_SET_OWORD(multicast_hash[1]);
142 } else if (epp->ep_mulcst) {
143 /* Use the hash set by the multicast list */
144 multicast_hash[0] = epp->ep_multicst_hash[0];
145 multicast_hash[1] = epp->ep_multicst_hash[1];
146 } else {
147 /* A hash matching no traffic is simply 0 */
148 EFX_ZERO_OWORD(multicast_hash[0]);
149 EFX_ZERO_OWORD(multicast_hash[1]);
150 }
151
152 /*
153 * Broadcast packets go through the multicast hash filter.
154 * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff
155 * so we always add bit 0xff to the mask (bit 0x7f in the
156 * second octword).
157 */
158 if (epp->ep_brdcst) {
159 /*
160 * NB: due to constant folding, some of this evaluates
161 * to null expressions, giving E_EXPR_NULL_EFFECT during
162 * lint. No good way to fix this without explicit coding
163 * the individual word/bit setting. So just suppress lint
164 * for this one line.
165 */
166 /* LINTED */
167 EFX_SET_OWORD_BIT(multicast_hash[1], 0x7f);
168 }
169
170 (void) memset(payload, 0, sizeof (payload));
171 req.emr_cmd = MC_CMD_SET_MCAST_HASH;
172 req.emr_in_buf = payload;
173 req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
174 req.emr_out_buf = payload;
175 req.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN;
176
177 (void) memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
178 multicast_hash, sizeof (multicast_hash));
179
180 efx_mcdi_execute(enp, &req);
181
182 if (req.emr_rc != 0) {
183 rc = req.emr_rc;
184 goto fail2;
185 }
186
187 return (0);
188
189 fail2:
190 EFSYS_PROBE(fail2);
191 fail1:
192 EFSYS_PROBE1(fail1, efx_rc_t, rc);
193
194 return (rc);
195 }
196
197 #if EFSYS_OPT_LOOPBACK
198
199 __checkReturn efx_rc_t
siena_mac_loopback_set(__in efx_nic_t * enp,__in efx_link_mode_t link_mode,__in efx_loopback_type_t loopback_type)200 siena_mac_loopback_set(
201 __in efx_nic_t *enp,
202 __in efx_link_mode_t link_mode,
203 __in efx_loopback_type_t loopback_type)
204 {
205 efx_port_t *epp = &(enp->en_port);
206 const efx_phy_ops_t *epop = epp->ep_epop;
207 efx_loopback_type_t old_loopback_type;
208 efx_link_mode_t old_loopback_link_mode;
209 efx_rc_t rc;
210
211 /* The PHY object handles this on Siena */
212 old_loopback_type = epp->ep_loopback_type;
213 old_loopback_link_mode = epp->ep_loopback_link_mode;
214 epp->ep_loopback_type = loopback_type;
215 epp->ep_loopback_link_mode = link_mode;
216
217 if ((rc = epop->epo_reconfigure(enp)) != 0)
218 goto fail1;
219
220 return (0);
221
222 fail1:
223 EFSYS_PROBE(fail2);
224
225 epp->ep_loopback_type = old_loopback_type;
226 epp->ep_loopback_link_mode = old_loopback_link_mode;
227
228 return (rc);
229 }
230
231 #endif /* EFSYS_OPT_LOOPBACK */
232
233 #if EFSYS_OPT_MAC_STATS
234
235 #define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \
236 EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
237
238 __checkReturn efx_rc_t
siena_mac_stats_update(__in efx_nic_t * enp,__in efsys_mem_t * esmp,__inout_ecount (EFX_MAC_NSTATS)efsys_stat_t * stat,__inout_opt uint32_t * generationp)239 siena_mac_stats_update(
240 __in efx_nic_t *enp,
241 __in efsys_mem_t *esmp,
242 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
243 __inout_opt uint32_t *generationp)
244 {
245 efx_qword_t value;
246 efx_qword_t generation_start;
247 efx_qword_t generation_end;
248
249 _NOTE(ARGUNUSED(enp))
250
251 /* Read END first so we don't race with the MC */
252 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
253 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
254 &generation_end);
255 EFSYS_MEM_READ_BARRIER();
256
257 /* TX */
258 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
259 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
260 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
261 EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
262
263 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
264 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
265
266 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
267 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
268
269 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
270 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
271
272 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
273 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
274
275 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
276 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
277
278 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
279 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
280 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
281 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
282
283 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
284 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
285
286 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
287 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
288
289 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
290 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
291
292 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
293 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
294
295 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
296 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
297
298 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
299 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
300 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
301 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
302
303 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
304 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
305
306 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
307 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
308
309 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
310 &value);
311 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
312
313 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
314 &value);
315 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
316
317 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
318 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
319
320 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
321 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
322
323 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
324 &value);
325 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
326
327 /* RX */
328 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
329 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
330
331 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
332 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
333
334 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
335 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
336
337 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
338 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
339
340 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
341 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
342
343 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
344 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
345
346 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
347 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
348 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
349 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
350
351 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
352 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
353
354 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
355 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
356
357 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
358 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
359
360 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
361 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
362
363 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
364 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
365
366 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
367 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
368 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
369 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
370
371 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
372 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
373
374 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
375 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
376
377 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
378 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
379
380 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
381 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
382
383 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
384 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
385
386 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
387 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
388
389 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
390 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
391
392 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
393 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
394 &(value.eq_dword[0]));
395 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
396 &(value.eq_dword[1]));
397
398 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
399 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
400 &(value.eq_dword[0]));
401 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
402 &(value.eq_dword[1]));
403
404 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
405 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
406 &(value.eq_dword[0]));
407 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
408 &(value.eq_dword[1]));
409
410 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
411 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
412 &(value.eq_dword[0]));
413 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
414 &(value.eq_dword[1]));
415
416 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
417 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
418
419 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
420 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
421
422 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
423 EFSYS_MEM_READ_BARRIER();
424 SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
425 &generation_start);
426
427 /* Check that we didn't read the stats in the middle of a DMA */
428 /* Not a good enough check ? */
429 if (memcmp(&generation_start, &generation_end,
430 sizeof (generation_start)))
431 return (EAGAIN);
432
433 if (generationp)
434 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
435
436 return (0);
437 }
438
439 #endif /* EFSYS_OPT_MAC_STATS */
440
441 #endif /* EFSYS_OPT_SIENA */
442