]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/common/efx_mac.c
sfxge: add table entries for License NVRAM partition
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / common / efx_mac.c
1 /*-
2  * Copyright (c) 2007-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 #if EFSYS_OPT_MAC_FALCON_GMAC
38 #include "falcon_gmac.h"
39 #endif
40
41 #if EFSYS_OPT_MAC_FALCON_XMAC
42 #include "falcon_xmac.h"
43 #endif
44
45 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
46
47 static  __checkReturn   efx_rc_t
48 falconsiena_mac_multicast_list_set(
49         __in            efx_nic_t *enp);
50
51 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
52
53 #if EFSYS_OPT_MAC_FALCON_GMAC
54 static efx_mac_ops_t    __efx_falcon_gmac_ops = {
55         falcon_gmac_reset,                      /* emo_reset */
56         falcon_mac_poll,                        /* emo_poll */
57         falcon_mac_up,                          /* emo_up */
58         falcon_gmac_reconfigure,                /* emo_addr_set */
59         falcon_gmac_reconfigure,                /* emo_reconfigure */
60         falconsiena_mac_multicast_list_set,     /* emo_multicast_list_set */
61         NULL,                                   /* emo_filter_set_default_rxq */
62         NULL,                           /* emo_filter_default_rxq_clear */
63 #if EFSYS_OPT_LOOPBACK
64         falcon_mac_loopback_set,                /* emo_loopback_set */
65 #endif  /* EFSYS_OPT_LOOPBACK */
66 #if EFSYS_OPT_MAC_STATS
67         falcon_mac_stats_upload,                /* emo_stats_upload */
68         NULL,                                   /* emo_stats_periodic */
69         falcon_gmac_stats_update                /* emo_stats_update */
70 #endif  /* EFSYS_OPT_MAC_STATS */
71 };
72 #endif  /* EFSYS_OPT_MAC_FALCON_GMAC */
73
74 #if EFSYS_OPT_MAC_FALCON_XMAC
75 static efx_mac_ops_t    __efx_falcon_xmac_ops = {
76         falcon_xmac_reset,                      /* emo_reset */
77         falcon_mac_poll,                        /* emo_poll */
78         falcon_mac_up,                          /* emo_up */
79         falcon_xmac_reconfigure,                /* emo_addr_set */
80         falcon_xmac_reconfigure,                /* emo_reconfigure */
81         falconsiena_mac_multicast_list_set,     /* emo_multicast_list_set */
82         NULL,                                   /* emo_filter_set_default_rxq */
83         NULL,                           /* emo_filter_default_rxq_clear */
84 #if EFSYS_OPT_LOOPBACK
85         falcon_mac_loopback_set,                /* emo_loopback_set */
86 #endif  /* EFSYS_OPT_LOOPBACK */
87 #if EFSYS_OPT_MAC_STATS
88         falcon_mac_stats_upload,                /* emo_stats_upload */
89         NULL,                                   /* emo_stats_periodic */
90         falcon_xmac_stats_update                /* emo_stats_update */
91 #endif  /* EFSYS_OPT_MAC_STATS */
92 };
93 #endif  /* EFSYS_OPT_MAC_FALCON_XMAC */
94
95 #if EFSYS_OPT_SIENA
96 static efx_mac_ops_t    __efx_siena_mac_ops = {
97         NULL,                                   /* emo_reset */
98         siena_mac_poll,                         /* emo_poll */
99         siena_mac_up,                           /* emo_up */
100         siena_mac_reconfigure,                  /* emo_addr_set */
101         siena_mac_reconfigure,                  /* emo_reconfigure */
102         falconsiena_mac_multicast_list_set,     /* emo_multicast_list_set */
103         NULL,                                   /* emo_filter_set_default_rxq */
104         NULL,                           /* emo_filter_default_rxq_clear */
105 #if EFSYS_OPT_LOOPBACK
106         siena_mac_loopback_set,                 /* emo_loopback_set */
107 #endif  /* EFSYS_OPT_LOOPBACK */
108 #if EFSYS_OPT_MAC_STATS
109         efx_mcdi_mac_stats_upload,              /* emo_stats_upload */
110         efx_mcdi_mac_stats_periodic,            /* emo_stats_periodic */
111         siena_mac_stats_update                  /* emo_stats_update */
112 #endif  /* EFSYS_OPT_MAC_STATS */
113 };
114 #endif  /* EFSYS_OPT_SIENA */
115
116 #if EFSYS_OPT_HUNTINGTON
117 static efx_mac_ops_t    __efx_hunt_mac_ops = {
118         NULL,                                   /* emo_reset */
119         hunt_mac_poll,                          /* emo_poll */
120         hunt_mac_up,                            /* emo_up */
121         hunt_mac_addr_set,                      /* emo_addr_set */
122         hunt_mac_reconfigure,                   /* emo_reconfigure */
123         hunt_mac_multicast_list_set,            /* emo_multicast_list_set */
124         hunt_mac_filter_default_rxq_set,        /* emo_filter_default_rxq_set */
125         hunt_mac_filter_default_rxq_clear,
126                                         /* emo_filter_default_rxq_clear */
127 #if EFSYS_OPT_LOOPBACK
128         hunt_mac_loopback_set,                  /* emo_loopback_set */
129 #endif  /* EFSYS_OPT_LOOPBACK */
130 #if EFSYS_OPT_MAC_STATS
131         efx_mcdi_mac_stats_upload,              /* emo_stats_upload */
132         efx_mcdi_mac_stats_periodic,            /* emo_stats_periodic */
133         hunt_mac_stats_update                   /* emo_stats_update */
134 #endif  /* EFSYS_OPT_MAC_STATS */
135 };
136 #endif  /* EFSYS_OPT_HUNTINGTON */
137
138 static efx_mac_ops_t    *__efx_mac_ops[] = {
139         /* [EFX_MAC_INVALID] */
140         NULL,
141         /* [EFX_MAC_FALCON_GMAC] */
142 #if EFSYS_OPT_MAC_FALCON_GMAC
143         &__efx_falcon_gmac_ops,
144 #else
145         NULL,
146 #endif
147         /* [EFX_MAC_FALCON_XMAC] */
148 #if EFSYS_OPT_MAC_FALCON_XMAC
149         &__efx_falcon_xmac_ops,
150 #else
151         NULL,
152 #endif
153         /* [EFX_MAC_SIENA] */
154 #if EFSYS_OPT_SIENA
155         &__efx_siena_mac_ops,
156 #else
157         NULL,
158 #endif
159         /* [EFX_MAC_HUNTINGTON] */
160 #if EFSYS_OPT_HUNTINGTON
161         &__efx_hunt_mac_ops,
162 #else
163         NULL,
164 #endif
165 };
166
167         __checkReturn                   efx_rc_t
168 efx_mac_pdu_set(
169         __in                            efx_nic_t *enp,
170         __in                            size_t pdu)
171 {
172         efx_port_t *epp = &(enp->en_port);
173         efx_mac_ops_t *emop = epp->ep_emop;
174         uint32_t old_pdu;
175         efx_rc_t rc;
176
177         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
178         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
179         EFSYS_ASSERT(emop != NULL);
180
181         if (pdu < EFX_MAC_PDU_MIN) {
182                 rc = EINVAL;
183                 goto fail1;
184         }
185
186         if (pdu > EFX_MAC_PDU_MAX) {
187                 rc = EINVAL;
188                 goto fail2;
189         }
190
191         old_pdu = epp->ep_mac_pdu;
192         epp->ep_mac_pdu = (uint32_t)pdu;
193         if ((rc = emop->emo_reconfigure(enp)) != 0)
194                 goto fail3;
195
196         return (0);
197
198 fail3:
199         EFSYS_PROBE(fail3);
200
201         epp->ep_mac_pdu = old_pdu;
202
203 fail2:
204         EFSYS_PROBE(fail2);
205 fail1:
206         EFSYS_PROBE1(fail1, efx_rc_t, rc);
207
208         return (rc);
209 }
210
211         __checkReturn                   efx_rc_t
212 efx_mac_addr_set(
213         __in                            efx_nic_t *enp,
214         __in                            uint8_t *addr)
215 {
216         efx_port_t *epp = &(enp->en_port);
217         efx_mac_ops_t *emop = epp->ep_emop;
218         uint8_t old_addr[6];
219         uint32_t oui;
220         efx_rc_t rc;
221
222         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
223         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
224
225         if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
226                 rc = EINVAL;
227                 goto fail1;
228         }
229
230         oui = addr[0] << 16 | addr[1] << 8 | addr[2];
231         if (oui == 0x000000) {
232                 rc = EINVAL;
233                 goto fail2;
234         }
235
236         EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
237         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
238         if ((rc = emop->emo_addr_set(enp)) != 0)
239                 goto fail3;
240
241         return (0);
242
243 fail3:
244         EFSYS_PROBE(fail3);
245
246         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
247
248 fail2:
249         EFSYS_PROBE(fail2);
250 fail1:
251         EFSYS_PROBE1(fail1, efx_rc_t, rc);
252
253         return (rc);
254 }
255
256         __checkReturn                   efx_rc_t
257 efx_mac_filter_set(
258         __in                            efx_nic_t *enp,
259         __in                            boolean_t all_unicst,
260         __in                            boolean_t mulcst,
261         __in                            boolean_t all_mulcst,
262         __in                            boolean_t brdcst)
263 {
264         efx_port_t *epp = &(enp->en_port);
265         efx_mac_ops_t *emop = epp->ep_emop;
266         boolean_t old_all_unicst;
267         boolean_t old_mulcst;
268         boolean_t old_all_mulcst;
269         boolean_t old_brdcst;
270         efx_rc_t rc;
271
272         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
273         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
274
275         old_all_unicst = epp->ep_all_unicst;
276         old_mulcst = epp->ep_mulcst;
277         old_all_mulcst = epp->ep_all_mulcst;
278         old_brdcst = epp->ep_brdcst;
279
280         epp->ep_all_unicst = all_unicst;
281         epp->ep_mulcst = mulcst;
282         epp->ep_all_mulcst = all_mulcst;
283         epp->ep_brdcst = brdcst;
284
285         if ((rc = emop->emo_reconfigure(enp)) != 0)
286                 goto fail1;
287
288         return (0);
289
290 fail1:
291         EFSYS_PROBE1(fail1, efx_rc_t, rc);
292
293         epp->ep_all_unicst = old_all_unicst;
294         epp->ep_mulcst = old_mulcst;
295         epp->ep_all_mulcst = old_all_mulcst;
296         epp->ep_brdcst = old_brdcst;
297
298         return (rc);
299 }
300
301         __checkReturn                   efx_rc_t
302 efx_mac_drain(
303         __in                            efx_nic_t *enp,
304         __in                            boolean_t enabled)
305 {
306         efx_port_t *epp = &(enp->en_port);
307         efx_mac_ops_t *emop = epp->ep_emop;
308         efx_rc_t rc;
309
310         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
311         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
312         EFSYS_ASSERT(emop != NULL);
313
314         if (epp->ep_mac_drain == enabled)
315                 return (0);
316
317         epp->ep_mac_drain = enabled;
318
319         if (enabled && emop->emo_reset != NULL) {
320                 if ((rc = emop->emo_reset(enp)) != 0)
321                         goto fail1;
322
323                 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
324                 enp->en_reset_flags &= ~EFX_RESET_PHY;
325         }
326
327         if ((rc = emop->emo_reconfigure(enp)) != 0)
328                 goto fail2;
329
330         return (0);
331
332 fail2:
333         EFSYS_PROBE(fail2);
334 fail1:
335         EFSYS_PROBE1(fail1, efx_rc_t, rc);
336
337         return (rc);
338 }
339
340         __checkReturn   efx_rc_t
341 efx_mac_up(
342         __in            efx_nic_t *enp,
343         __out           boolean_t *mac_upp)
344 {
345         efx_port_t *epp = &(enp->en_port);
346         efx_mac_ops_t *emop = epp->ep_emop;
347         efx_rc_t rc;
348
349         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
350         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
351
352         if ((rc = emop->emo_up(enp, mac_upp)) != 0)
353                 goto fail1;
354
355         return (0);
356
357 fail1:
358         EFSYS_PROBE1(fail1, efx_rc_t, rc);
359
360         return (rc);
361 }
362
363         __checkReturn                   efx_rc_t
364 efx_mac_fcntl_set(
365         __in                            efx_nic_t *enp,
366         __in                            unsigned int fcntl,
367         __in                            boolean_t autoneg)
368 {
369         efx_port_t *epp = &(enp->en_port);
370         efx_mac_ops_t *emop = epp->ep_emop;
371         efx_phy_ops_t *epop = epp->ep_epop;
372         unsigned int old_fcntl;
373         boolean_t old_autoneg;
374         unsigned int old_adv_cap;
375         efx_rc_t rc;
376
377         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
378         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
379
380         if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
381                 rc = EINVAL;
382                 goto fail1;
383         }
384
385         /*
386          * Ignore a request to set flow control auto-negotiation
387          * if the PHY doesn't support it.
388          */
389         if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
390                 autoneg = B_FALSE;
391
392         old_fcntl = epp->ep_fcntl;
393         old_autoneg = epp->ep_fcntl_autoneg;
394         old_adv_cap = epp->ep_adv_cap_mask;
395
396         epp->ep_fcntl = fcntl;
397         epp->ep_fcntl_autoneg = autoneg;
398
399         /*
400          * Always encode the flow control settings in the advertised
401          * capabilities even if we are not trying to auto-negotiate
402          * them and reconfigure both the PHY and the MAC.
403          */
404         if (fcntl & EFX_FCNTL_RESPOND)
405                 epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
406                                             1 << EFX_PHY_CAP_ASYM);
407         else
408                 epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
409                                             1 << EFX_PHY_CAP_ASYM);
410
411         if (fcntl & EFX_FCNTL_GENERATE)
412                 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
413
414         if ((rc = epop->epo_reconfigure(enp)) != 0)
415                 goto fail2;
416
417         if ((rc = emop->emo_reconfigure(enp)) != 0)
418                 goto fail3;
419
420         return (0);
421
422 fail3:
423         EFSYS_PROBE(fail3);
424
425 fail2:
426         EFSYS_PROBE(fail2);
427
428         epp->ep_fcntl = old_fcntl;
429         epp->ep_fcntl_autoneg = old_autoneg;
430         epp->ep_adv_cap_mask = old_adv_cap;
431
432 fail1:
433         EFSYS_PROBE1(fail1, efx_rc_t, rc);
434
435         return (rc);
436 }
437
438                         void
439 efx_mac_fcntl_get(
440         __in            efx_nic_t *enp,
441         __out           unsigned int *fcntl_wantedp,
442         __out           unsigned int *fcntl_linkp)
443 {
444         efx_port_t *epp = &(enp->en_port);
445         unsigned int wanted = 0;
446
447         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
448         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
449
450         /*
451          * Decode the requested flow control settings from the PHY
452          * advertised capabilities.
453          */
454         if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
455                 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
456         if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
457                 wanted ^= EFX_FCNTL_GENERATE;
458
459         *fcntl_linkp = epp->ep_fcntl;
460         *fcntl_wantedp = wanted;
461 }
462
463         __checkReturn   efx_rc_t
464 efx_mac_multicast_list_set(
465         __in                            efx_nic_t *enp,
466         __in_ecount(6*count)            uint8_t const *addrs,
467         __in                            int count)
468 {
469         efx_port_t *epp = &(enp->en_port);
470         efx_mac_ops_t *emop = epp->ep_emop;
471         uint8_t *old_mulcst_addr_list = NULL;
472         uint32_t old_mulcst_addr_count;
473         efx_rc_t rc;
474
475         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
476         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
477
478         if (count > EFX_MAC_MULTICAST_LIST_MAX) {
479                 rc = EINVAL;
480                 goto fail1;
481         }
482
483         old_mulcst_addr_count = epp->ep_mulcst_addr_count;
484         if (old_mulcst_addr_count > 0) {
485                 /* Allocate memory to store old list (instead of using stack) */
486                 EFSYS_KMEM_ALLOC(enp->en_esip,
487                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
488                                 old_mulcst_addr_list);
489                 if (old_mulcst_addr_list == NULL) {
490                         rc = ENOMEM;
491                         goto fail2;
492                 }
493
494                 /* Save the old list in case we need to rollback */
495                 memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
496                         old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
497         }
498
499         /* Store the new list */
500         memcpy(epp->ep_mulcst_addr_list, addrs,
501                 count * EFX_MAC_ADDR_LEN);
502         epp->ep_mulcst_addr_count = count;
503
504         if ((rc = emop->emo_multicast_list_set(enp)) != 0)
505                 goto fail3;
506
507         if (old_mulcst_addr_count > 0) {
508                 EFSYS_KMEM_FREE(enp->en_esip,
509                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
510                                 old_mulcst_addr_list);
511         }
512
513         return (0);
514
515 fail3:
516         EFSYS_PROBE(fail3);
517
518         /* Restore original list on failure */
519         epp->ep_mulcst_addr_count = old_mulcst_addr_count;
520         if (old_mulcst_addr_count > 0) {
521                 memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
522                         old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
523
524                 EFSYS_KMEM_FREE(enp->en_esip,
525                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
526                                 old_mulcst_addr_list);
527         }
528
529 fail2:
530         EFSYS_PROBE(fail2);
531
532 fail1:
533         EFSYS_PROBE1(fail1, efx_rc_t, rc);
534
535         return (rc);
536
537 }
538
539         __checkReturn   efx_rc_t
540 efx_mac_filter_default_rxq_set(
541         __in            efx_nic_t *enp,
542         __in            efx_rxq_t *erp,
543         __in            boolean_t using_rss)
544 {
545         efx_port_t *epp = &(enp->en_port);
546         efx_mac_ops_t *emop = epp->ep_emop;
547         efx_rc_t rc;
548
549         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
550         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
551
552         if (emop->emo_filter_default_rxq_set != NULL) {
553                 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
554                 if (rc != 0)
555                         goto fail1;
556         }
557
558         return (0);
559
560 fail1:
561         EFSYS_PROBE1(fail1, efx_rc_t, rc);
562
563         return (rc);
564 }
565
566                         void
567 efx_mac_filter_default_rxq_clear(
568         __in            efx_nic_t *enp)
569 {
570         efx_port_t *epp = &(enp->en_port);
571         efx_mac_ops_t *emop = epp->ep_emop;
572
573         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
574         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
575
576         if (emop->emo_filter_default_rxq_clear != NULL)
577                 emop->emo_filter_default_rxq_clear(enp);
578 }
579
580
581 #if EFSYS_OPT_MAC_STATS
582
583 #if EFSYS_OPT_NAMES
584
585 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 054d43a31d2d7a45 */
586 static const char       *__efx_mac_stat_name[] = {
587         "rx_octets",
588         "rx_pkts",
589         "rx_unicst_pkts",
590         "rx_multicst_pkts",
591         "rx_brdcst_pkts",
592         "rx_pause_pkts",
593         "rx_le_64_pkts",
594         "rx_65_to_127_pkts",
595         "rx_128_to_255_pkts",
596         "rx_256_to_511_pkts",
597         "rx_512_to_1023_pkts",
598         "rx_1024_to_15xx_pkts",
599         "rx_ge_15xx_pkts",
600         "rx_errors",
601         "rx_fcs_errors",
602         "rx_drop_events",
603         "rx_false_carrier_errors",
604         "rx_symbol_errors",
605         "rx_align_errors",
606         "rx_internal_errors",
607         "rx_jabber_pkts",
608         "rx_lane0_char_err",
609         "rx_lane1_char_err",
610         "rx_lane2_char_err",
611         "rx_lane3_char_err",
612         "rx_lane0_disp_err",
613         "rx_lane1_disp_err",
614         "rx_lane2_disp_err",
615         "rx_lane3_disp_err",
616         "rx_match_fault",
617         "rx_nodesc_drop_cnt",
618         "tx_octets",
619         "tx_pkts",
620         "tx_unicst_pkts",
621         "tx_multicst_pkts",
622         "tx_brdcst_pkts",
623         "tx_pause_pkts",
624         "tx_le_64_pkts",
625         "tx_65_to_127_pkts",
626         "tx_128_to_255_pkts",
627         "tx_256_to_511_pkts",
628         "tx_512_to_1023_pkts",
629         "tx_1024_to_15xx_pkts",
630         "tx_ge_15xx_pkts",
631         "tx_errors",
632         "tx_sgl_col_pkts",
633         "tx_mult_col_pkts",
634         "tx_ex_col_pkts",
635         "tx_late_col_pkts",
636         "tx_def_pkts",
637         "tx_ex_def_pkts",
638         "pm_trunc_bb_overflow",
639         "pm_discard_bb_overflow",
640         "pm_trunc_vfifo_full",
641         "pm_discard_vfifo_full",
642         "pm_trunc_qbb",
643         "pm_discard_qbb",
644         "pm_discard_mapping",
645         "rxdp_q_disabled_pkts",
646         "rxdp_di_dropped_pkts",
647         "rxdp_streaming_pkts",
648         "rxdp_hlb_fetch",
649         "rxdp_hlb_wait",
650         "vadapter_rx_unicast_packets",
651         "vadapter_rx_unicast_bytes",
652         "vadapter_rx_multicast_packets",
653         "vadapter_rx_multicast_bytes",
654         "vadapter_rx_broadcast_packets",
655         "vadapter_rx_broadcast_bytes",
656         "vadapter_rx_bad_packets",
657         "vadapter_rx_bad_bytes",
658         "vadapter_rx_overflow",
659         "vadapter_tx_unicast_packets",
660         "vadapter_tx_unicast_bytes",
661         "vadapter_tx_multicast_packets",
662         "vadapter_tx_multicast_bytes",
663         "vadapter_tx_broadcast_packets",
664         "vadapter_tx_broadcast_bytes",
665         "vadapter_tx_bad_packets",
666         "vadapter_tx_bad_bytes",
667         "vadapter_tx_overflow",
668 };
669 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
670
671         __checkReturn                   const char *
672 efx_mac_stat_name(
673         __in                            efx_nic_t *enp,
674         __in                            unsigned int id)
675 {
676         _NOTE(ARGUNUSED(enp))
677         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
678
679         EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
680         return (__efx_mac_stat_name[id]);
681 }
682
683 #endif  /* EFSYS_OPT_NAMES */
684
685         __checkReturn                   efx_rc_t
686 efx_mac_stats_upload(
687         __in                            efx_nic_t *enp,
688         __in                            efsys_mem_t *esmp)
689 {
690         efx_port_t *epp = &(enp->en_port);
691         efx_mac_ops_t *emop = epp->ep_emop;
692         efx_rc_t rc;
693
694         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
695         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
696         EFSYS_ASSERT(emop != NULL);
697
698         /*
699          * Don't assert !ep_mac_stats_pending, because the client might
700          * have failed to finalise statistics when previously stopping
701          * the port.
702          */
703         if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
704                 goto fail1;
705
706         epp->ep_mac_stats_pending = B_TRUE;
707
708         return (0);
709
710 fail1:
711         EFSYS_PROBE1(fail1, efx_rc_t, rc);
712
713         return (rc);
714 }
715
716         __checkReturn                   efx_rc_t
717 efx_mac_stats_periodic(
718         __in                            efx_nic_t *enp,
719         __in                            efsys_mem_t *esmp,
720         __in                            uint16_t period_ms,
721         __in                            boolean_t events)
722 {
723         efx_port_t *epp = &(enp->en_port);
724         efx_mac_ops_t *emop = epp->ep_emop;
725         efx_rc_t rc;
726
727         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
728         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
729
730         EFSYS_ASSERT(emop != NULL);
731
732         if (emop->emo_stats_periodic == NULL) {
733                 rc = EINVAL;
734                 goto fail1;
735         }
736
737         if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
738                 goto fail2;
739
740         return (0);
741
742 fail2:
743         EFSYS_PROBE(fail2);
744 fail1:
745         EFSYS_PROBE1(fail1, efx_rc_t, rc);
746
747         return (rc);
748 }
749
750
751         __checkReturn                   efx_rc_t
752 efx_mac_stats_update(
753         __in                            efx_nic_t *enp,
754         __in                            efsys_mem_t *esmp,
755         __inout_ecount(EFX_MAC_NSTATS)  efsys_stat_t *essp,
756         __inout_opt                     uint32_t *generationp)
757 {
758         efx_port_t *epp = &(enp->en_port);
759         efx_mac_ops_t *emop = epp->ep_emop;
760         efx_rc_t rc;
761
762         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
763         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
764         EFSYS_ASSERT(emop != NULL);
765
766         rc = emop->emo_stats_update(enp, esmp, essp, generationp);
767         if (rc == 0)
768                 epp->ep_mac_stats_pending = B_FALSE;
769
770         return (rc);
771 }
772
773 #endif  /* EFSYS_OPT_MAC_STATS */
774
775         __checkReturn                   efx_rc_t
776 efx_mac_select(
777         __in                            efx_nic_t *enp)
778 {
779         efx_port_t *epp = &(enp->en_port);
780         efx_mac_type_t type = EFX_MAC_INVALID;
781         efx_mac_ops_t *emop;
782         int rc = EINVAL;
783
784 #if EFSYS_OPT_HUNTINGTON
785         if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
786                 type = EFX_MAC_HUNTINGTON;
787                 goto chosen;
788         }
789 #endif
790
791 #if EFSYS_OPT_SIENA
792         if (enp->en_family == EFX_FAMILY_SIENA) {
793                 type = EFX_MAC_SIENA;
794                 goto chosen;
795         }
796 #endif
797
798 #if EFSYS_OPT_FALCON
799         switch (epp->ep_link_mode) {
800 #if EFSYS_OPT_MAC_FALCON_GMAC
801         case EFX_LINK_100HDX:
802         case EFX_LINK_100FDX:
803         case EFX_LINK_1000HDX:
804         case EFX_LINK_1000FDX:
805                 type = EFX_MAC_FALCON_GMAC;
806                 goto chosen;
807 #endif  /* EFSYS_OPT_FALCON_GMAC */
808
809 #if EFSYS_OPT_MAC_FALCON_XMAC
810         case EFX_LINK_10000FDX:
811                 type = EFX_MAC_FALCON_XMAC;
812                 goto chosen;
813 #endif  /* EFSYS_OPT_FALCON_XMAC */
814
815         default:
816 #if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC
817                 /* Only initialise a MAC supported by the PHY */
818                 if (epp->ep_phy_cap_mask &
819                     ((1 << EFX_PHY_CAP_1000FDX) |
820                     (1 << EFX_PHY_CAP_1000HDX) |
821                     (1 << EFX_PHY_CAP_100FDX) |
822                     (1 << EFX_PHY_CAP_100HDX) |
823                     (1 << EFX_PHY_CAP_10FDX) |
824                     (1 << EFX_PHY_CAP_10FDX)))
825                         type = EFX_MAC_FALCON_GMAC;
826                 else
827                         type = EFX_MAC_FALCON_XMAC;
828 #elif EFSYS_OPT_MAC_FALCON_GMAC
829                 type = EFX_MAC_FALCON_GMAC;
830 #else
831                 type = EFX_MAC_FALCON_XMAC;
832 #endif
833                 goto chosen;
834         }
835 #endif  /* EFSYS_OPT_FALCON */
836
837 chosen:
838         EFSYS_ASSERT(type != EFX_MAC_INVALID);
839         EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
840         emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type];
841         EFSYS_ASSERT(emop != NULL);
842
843         epp->ep_mac_type = type;
844
845         if (emop->emo_reset != NULL) {
846                 if ((rc = emop->emo_reset(enp)) != 0)
847                         goto fail1;
848
849                 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
850                 enp->en_reset_flags &= ~EFX_RESET_MAC;
851         }
852
853         return (0);
854
855 fail1:
856         EFSYS_PROBE1(fail1, efx_rc_t, rc);
857
858         return (rc);
859 }
860
861
862 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
863
864 #define EFX_MAC_HASH_BITS       (1 << 8)
865
866 /* Compute the multicast hash as used on Falcon and Siena. */
867 static  void
868 falconsiena_mac_multicast_hash_compute(
869         __in_ecount(6*count)            uint8_t const *addrs,
870         __in                            int count,
871         __out                           efx_oword_t *hash_low,
872         __out                           efx_oword_t *hash_high)
873 {
874         uint32_t crc, index;
875         int i;
876
877         EFSYS_ASSERT(hash_low != NULL);
878         EFSYS_ASSERT(hash_high != NULL);
879
880         EFX_ZERO_OWORD(*hash_low);
881         EFX_ZERO_OWORD(*hash_high);
882
883         for (i = 0; i < count; i++) {
884                 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
885                 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
886                 index = crc % EFX_MAC_HASH_BITS;
887                 if (index < 128) {
888                         EFX_SET_OWORD_BIT(*hash_low, index);
889                 } else {
890                         EFX_SET_OWORD_BIT(*hash_high, index - 128);
891                 }
892
893                 addrs += EFX_MAC_ADDR_LEN;
894         }
895 }
896
897 static  __checkReturn   efx_rc_t
898 falconsiena_mac_multicast_list_set(
899         __in            efx_nic_t *enp)
900 {
901         efx_port_t *epp = &(enp->en_port);
902         efx_mac_ops_t *emop = epp->ep_emop;
903         efx_oword_t old_hash[2];
904         efx_rc_t rc;
905
906         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
907         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
908
909         memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
910
911         falconsiena_mac_multicast_hash_compute(epp->ep_mulcst_addr_list,
912                                 epp->ep_mulcst_addr_count,
913                                 &epp->ep_multicst_hash[0],
914                                 &epp->ep_multicst_hash[1]);
915
916         if ((rc = emop->emo_reconfigure(enp)) != 0)
917                 goto fail1;
918
919         return (0);
920
921 fail1:
922         EFSYS_PROBE1(fail1, efx_rc_t, rc);
923
924         memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
925
926         return (rc);
927 }
928
929 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */