]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/common/hunt_mac.c
MFH
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / common / hunt_mac.c
1 /*-
2  * Copyright (c) 2012-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 <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "efx.h"
35 #include "efx_impl.h"
36
37
38 #if EFSYS_OPT_HUNTINGTON
39
40         __checkReturn   efx_rc_t
41 hunt_mac_poll(
42         __in            efx_nic_t *enp,
43         __out           efx_link_mode_t *link_modep)
44 {
45         /*
46          * TBD: Consider a common Siena/Huntington function.  The code is
47          * essentially identical.
48          */
49
50         efx_port_t *epp = &(enp->en_port);
51         hunt_link_state_t hls;
52         efx_rc_t rc;
53
54         if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
55                 goto fail1;
56
57         epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
58         epp->ep_fcntl = hls.hls_fcntl;
59
60         *link_modep = hls.hls_link_mode;
61
62         return (0);
63
64 fail1:
65         EFSYS_PROBE1(fail1, efx_rc_t, rc);
66
67         *link_modep = EFX_LINK_UNKNOWN;
68
69         return (rc);
70 }
71
72         __checkReturn   efx_rc_t
73 hunt_mac_up(
74         __in            efx_nic_t *enp,
75         __out           boolean_t *mac_upp)
76 {
77         /*
78          * TBD: Consider a common Siena/Huntington function.  The code is
79          * essentially identical.
80          */
81
82         hunt_link_state_t hls;
83         efx_rc_t rc;
84
85         /*
86          * Because Huntington doesn't *require* polling, we can't rely on
87          * hunt_mac_poll() being executed to populate epp->ep_mac_up.
88          */
89         if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
90                 goto fail1;
91
92         *mac_upp = hls.hls_mac_up;
93
94         return (0);
95
96 fail1:
97         EFSYS_PROBE1(fail1, efx_rc_t, rc);
98
99         return (rc);
100 }
101
102 /*
103  * Huntington uses MC_CMD_VADAPTOR_SET_MAC to set the
104  * MAC address; the address field in MC_CMD_SET_MAC has no
105  * effect.
106  * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and
107  * the port to have no filters or queues active.
108  */
109 static  __checkReturn   efx_rc_t
110 efx_mcdi_vadapter_set_mac(
111         __in            efx_nic_t *enp)
112 {
113         efx_port_t *epp = &(enp->en_port);
114         efx_mcdi_req_t req;
115         uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
116                             MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)];
117         efx_rc_t rc;
118
119         (void) memset(payload, 0, sizeof (payload));
120         req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
121         req.emr_in_buf = payload;
122         req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
123         req.emr_out_buf = payload;
124         req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN;
125
126         MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
127             enp->en_vport_id);
128         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR),
129             epp->ep_mac_addr);
130
131         efx_mcdi_execute(enp, &req);
132
133         if (req.emr_rc != 0) {
134                 rc = req.emr_rc;
135                 goto fail1;
136         }
137
138         return (0);
139
140 fail1:
141         EFSYS_PROBE1(fail1, efx_rc_t, rc);
142
143         return (rc);
144 }
145
146         __checkReturn   efx_rc_t
147 hunt_mac_addr_set(
148         __in            efx_nic_t *enp)
149 {
150         efx_rc_t rc;
151
152         if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0) {
153                 if (rc != ENOTSUP)
154                         goto fail1;
155
156                 /* Fallback for older firmware without Vadapter support */
157                 if ((rc = hunt_mac_reconfigure(enp)) != 0)
158                         goto fail2;
159         }
160
161         return (0);
162
163 fail2:
164         EFSYS_PROBE(fail2);
165
166 fail1:
167         EFSYS_PROBE1(fail1, efx_rc_t, rc);
168
169         return (rc);
170 }
171
172 __checkReturn   efx_rc_t
173 hunt_mac_reconfigure(
174         __in            efx_nic_t *enp)
175 {
176         efx_port_t *epp = &(enp->en_port);
177         efx_mcdi_req_t req;
178         uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
179                             MC_CMD_SET_MAC_OUT_LEN)];
180         efx_rc_t rc;
181
182         (void) memset(payload, 0, sizeof (payload));
183         req.emr_cmd = MC_CMD_SET_MAC;
184         req.emr_in_buf = payload;
185         req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
186         req.emr_out_buf = payload;
187         req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
188
189         MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
190         MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
191         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
192                             epp->ep_mac_addr);
193
194         /*
195          * Note: The Huntington MAC does not support REJECT_BRDCST.
196          * The REJECT_UNCST flag will also prevent multicast traffic
197          * from reaching the filters. As Huntington filters drop any
198          * traffic that does not match a filter it is ok to leave the
199          * MAC running in promiscuous mode. See bug41141.
200          */
201         MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
202                                     SET_MAC_IN_REJECT_UNCST, 0,
203                                     SET_MAC_IN_REJECT_BRDCST, 0);
204
205         /*
206          * Flow control, whether it is auto-negotiated or not,
207          * is set via the PHY advertised capabilities.  When set to
208          * automatic the MAC will use the PHY settings to determine
209          * the flow control settings.
210          */
211         MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO);
212
213         /* Do not include the Ethernet frame checksum in RX packets */
214         MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS,
215                                     SET_MAC_IN_FLAG_INCLUDE_FCS, 0);
216
217         efx_mcdi_execute_quiet(enp, &req);
218
219         if (req.emr_rc != 0) {
220                 /*
221                  * Unprivileged functions cannot control link state,
222                  * but still need to configure filters.
223                  */
224                 if (req.emr_rc != EACCES) {
225                         rc = req.emr_rc;
226                         goto fail1;
227                 }
228         }
229
230         /*
231          * Apply the filters for the MAC configuration.
232          * If the NIC isn't ready to accept filters this may
233          * return success without setting anything.
234          */
235         rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
236                                     epp->ep_all_unicst, epp->ep_mulcst,
237                                     epp->ep_all_mulcst, epp->ep_brdcst,
238                                     epp->ep_mulcst_addr_list,
239                                     epp->ep_mulcst_addr_count);
240
241         return (0);
242
243 fail1:
244         EFSYS_PROBE1(fail1, efx_rc_t, rc);
245
246         return (rc);
247 }
248
249         __checkReturn                   efx_rc_t
250 hunt_mac_multicast_list_set(
251         __in                            efx_nic_t *enp)
252 {
253         efx_port_t *epp = &(enp->en_port);
254         efx_mac_ops_t *emop = epp->ep_emop;
255         efx_rc_t rc;
256
257         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
258
259         /* FIXME: Insert filters for multicast list */
260
261         if ((rc = emop->emo_reconfigure(enp)) != 0)
262                 goto fail1;
263
264         return (0);
265
266 fail1:
267         EFSYS_PROBE1(fail1, efx_rc_t, rc);
268
269         return (rc);
270 }
271
272         __checkReturn   efx_rc_t
273 hunt_mac_filter_default_rxq_set(
274         __in            efx_nic_t *enp,
275         __in            efx_rxq_t *erp,
276         __in            boolean_t using_rss)
277 {
278         efx_port_t *epp = &(enp->en_port);
279         efx_rxq_t *old_rxq;
280         boolean_t old_using_rss;
281         efx_rc_t rc;
282
283         ef10_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
284
285         ef10_filter_default_rxq_set(enp, erp, using_rss);
286
287         rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
288                                     epp->ep_all_unicst, epp->ep_mulcst,
289                                     epp->ep_all_mulcst, epp->ep_brdcst,
290                                     epp->ep_mulcst_addr_list,
291                                     epp->ep_mulcst_addr_count);
292
293         if (rc != 0)
294                 goto fail1;
295
296         return (0);
297
298 fail1:
299         EFSYS_PROBE1(fail1, efx_rc_t, rc);
300
301         ef10_filter_default_rxq_set(enp, old_rxq, old_using_rss);
302
303         return (rc);
304 }
305
306                         void
307 hunt_mac_filter_default_rxq_clear(
308         __in            efx_nic_t *enp)
309 {
310         efx_port_t *epp = &(enp->en_port);
311
312         ef10_filter_default_rxq_clear(enp);
313
314         efx_filter_reconfigure(enp, epp->ep_mac_addr,
315                                     epp->ep_all_unicst, epp->ep_mulcst,
316                                     epp->ep_all_mulcst, epp->ep_brdcst,
317                                     epp->ep_mulcst_addr_list,
318                                     epp->ep_mulcst_addr_count);
319 }
320
321
322 #if EFSYS_OPT_LOOPBACK
323
324         __checkReturn   efx_rc_t
325 hunt_mac_loopback_set(
326         __in            efx_nic_t *enp,
327         __in            efx_link_mode_t link_mode,
328         __in            efx_loopback_type_t loopback_type)
329 {
330         /*
331          * TBD: Consider a common Siena/Huntington function.  The code is
332          * essentially identical.
333          */
334
335         efx_port_t *epp = &(enp->en_port);
336         efx_phy_ops_t *epop = epp->ep_epop;
337         efx_loopback_type_t old_loopback_type;
338         efx_link_mode_t old_loopback_link_mode;
339         efx_rc_t rc;
340
341         /* The PHY object handles this on Huntington */
342         old_loopback_type = epp->ep_loopback_type;
343         old_loopback_link_mode = epp->ep_loopback_link_mode;
344         epp->ep_loopback_type = loopback_type;
345         epp->ep_loopback_link_mode = link_mode;
346
347         if ((rc = epop->epo_reconfigure(enp)) != 0)
348                 goto fail1;
349
350         return (0);
351
352 fail1:
353         EFSYS_PROBE1(fail1, efx_rc_t, rc);
354
355         epp->ep_loopback_type = old_loopback_type;
356         epp->ep_loopback_link_mode = old_loopback_link_mode;
357
358         return (rc);
359 }
360
361 #endif  /* EFSYS_OPT_LOOPBACK */
362
363 #if EFSYS_OPT_MAC_STATS
364
365 #define HUNT_MAC_STAT_READ(_esmp, _field, _eqp)                 \
366         EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
367
368
369         __checkReturn                   efx_rc_t
370 hunt_mac_stats_update(
371         __in                            efx_nic_t *enp,
372         __in                            efsys_mem_t *esmp,
373         __inout_ecount(EFX_MAC_NSTATS)  efsys_stat_t *stat,
374         __inout_opt                     uint32_t *generationp)
375 {
376         efx_qword_t value;
377         efx_qword_t generation_start;
378         efx_qword_t generation_end;
379
380         _NOTE(ARGUNUSED(enp))
381
382         /* Read END first so we don't race with the MC */
383         EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
384         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
385                             &generation_end);
386         EFSYS_MEM_READ_BARRIER();
387
388         /* TX */
389         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
390         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
391
392         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
393         EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
394
395         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
396         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
397
398         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
399         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
400
401         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
402         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
403
404         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
405         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
406
407         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
408         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
409
410         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
411         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
412         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
413         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
414
415         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
416         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
417
418         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
419         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
420
421         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
422         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
423
424         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
425         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
426
427         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
428         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
429
430         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
431         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
432         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
433         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
434
435         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
436         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
437
438         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
439         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
440
441         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
442                             &value);
443         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
444
445         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
446                             &value);
447         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
448
449         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
450         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
451
452         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
453         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
454
455         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
456             &value);
457         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
458
459         /* RX */
460         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
461         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
462
463         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
464         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
465
466         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
467         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
468
469         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
470         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
471
472         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
473         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
474
475         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
476         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
477
478         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
479         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
480         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
481         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
482
483         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
484         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
485
486         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
487         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
488
489         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
490         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
491
492         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
493         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
494
495         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
496         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
497
498         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
499         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
500         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
501         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
502
503         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
504         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
505
506         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
507         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
508
509         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
510         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
511
512         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
513         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
514
515         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
516         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
517
518         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
519         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
520
521         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
522         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
523
524         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
525         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
526                             &(value.eq_dword[0]));
527         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
528                             &(value.eq_dword[1]));
529
530         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
531         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
532                             &(value.eq_dword[0]));
533         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
534                             &(value.eq_dword[1]));
535
536         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
537         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
538                             &(value.eq_dword[0]));
539         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
540                             &(value.eq_dword[1]));
541
542         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
543         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
544                             &(value.eq_dword[0]));
545         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
546                             &(value.eq_dword[1]));
547
548         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
549         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
550
551         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
552         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
553
554         /* Packet memory (EF10 only) */
555         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value);
556         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value);
557
558         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value);
559         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value);
560
561         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value);
562         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value);
563
564         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value);
565         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value);
566
567         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value);
568         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value);
569
570         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value);
571         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value);
572
573         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value);
574         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value);
575
576         /* RX datapath */
577         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value);
578         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value);
579
580         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value);
581         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value);
582
583         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value);
584         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value);
585
586         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value);
587         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value);
588
589         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value);
590         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value);
591
592
593         /* VADAPTER RX */
594         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS,
595             &value);
596         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]),
597             &value);
598
599         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES,
600             &value);
601         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]),
602             &value);
603
604         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS,
605             &value);
606         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]),
607             &value);
608
609         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES,
610             &value);
611         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]),
612             &value);
613
614         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS,
615             &value);
616         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]),
617             &value);
618
619         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES,
620             &value);
621         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]),
622             &value);
623
624         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS,
625             &value);
626         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]),
627             &value);
628
629         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value);
630         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value);
631
632         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value);
633         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value);
634
635         /* VADAPTER TX */
636         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS,
637             &value);
638         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]),
639             &value);
640
641         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES,
642             &value);
643         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]),
644             &value);
645
646         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS,
647             &value);
648         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]),
649             &value);
650
651         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES,
652             &value);
653         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]),
654             &value);
655
656         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS,
657             &value);
658         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]),
659             &value);
660
661         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES,
662             &value);
663         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]),
664             &value);
665
666         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value);
667         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value);
668
669         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value);
670         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value);
671
672         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value);
673         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value);
674
675
676         EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
677         EFSYS_MEM_READ_BARRIER();
678         HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
679                             &generation_start);
680
681         /* Check that we didn't read the stats in the middle of a DMA */
682         /* Not a good enough check ? */
683         if (memcmp(&generation_start, &generation_end,
684             sizeof (generation_start)))
685                 return (EAGAIN);
686
687         if (generationp)
688                 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
689
690         return (0);
691 }
692
693 #endif  /* EFSYS_OPT_MAC_STATS */
694
695 #endif  /* EFSYS_OPT_HUNTINGTON */