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