2 * Copyright (c) 2007-2015 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
37 #if EFSYS_OPT_MAC_FALCON_GMAC
38 #include "falcon_gmac.h"
41 #if EFSYS_OPT_MAC_FALCON_XMAC
42 #include "falcon_xmac.h"
45 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
47 static __checkReturn efx_rc_t
48 falconsiena_mac_multicast_list_set(
51 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
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_pdu_set */
60 falcon_gmac_reconfigure, /* emo_reconfigure */
61 falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
62 NULL, /* emo_filter_set_default_rxq */
63 NULL, /* emo_filter_default_rxq_clear */
64 #if EFSYS_OPT_LOOPBACK
65 falcon_mac_loopback_set, /* emo_loopback_set */
66 #endif /* EFSYS_OPT_LOOPBACK */
67 #if EFSYS_OPT_MAC_STATS
68 falcon_mac_stats_upload, /* emo_stats_upload */
69 NULL, /* emo_stats_periodic */
70 falcon_gmac_stats_update /* emo_stats_update */
71 #endif /* EFSYS_OPT_MAC_STATS */
73 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */
75 #if EFSYS_OPT_MAC_FALCON_XMAC
76 static efx_mac_ops_t __efx_falcon_xmac_ops = {
77 falcon_xmac_reset, /* emo_reset */
78 falcon_mac_poll, /* emo_poll */
79 falcon_mac_up, /* emo_up */
80 falcon_xmac_reconfigure, /* emo_addr_set */
81 falcon_xmac_reconfigure, /* emo_pdu_set */
82 falcon_xmac_reconfigure, /* emo_reconfigure */
83 falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
84 NULL, /* emo_filter_set_default_rxq */
85 NULL, /* emo_filter_default_rxq_clear */
86 #if EFSYS_OPT_LOOPBACK
87 falcon_mac_loopback_set, /* emo_loopback_set */
88 #endif /* EFSYS_OPT_LOOPBACK */
89 #if EFSYS_OPT_MAC_STATS
90 falcon_mac_stats_upload, /* emo_stats_upload */
91 NULL, /* emo_stats_periodic */
92 falcon_xmac_stats_update /* emo_stats_update */
93 #endif /* EFSYS_OPT_MAC_STATS */
95 #endif /* EFSYS_OPT_MAC_FALCON_XMAC */
98 static efx_mac_ops_t __efx_siena_mac_ops = {
100 siena_mac_poll, /* emo_poll */
101 siena_mac_up, /* emo_up */
102 siena_mac_reconfigure, /* emo_addr_set */
103 siena_mac_reconfigure, /* emo_pdu_set */
104 siena_mac_reconfigure, /* emo_reconfigure */
105 falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
106 NULL, /* emo_filter_set_default_rxq */
107 NULL, /* emo_filter_default_rxq_clear */
108 #if EFSYS_OPT_LOOPBACK
109 siena_mac_loopback_set, /* emo_loopback_set */
110 #endif /* EFSYS_OPT_LOOPBACK */
111 #if EFSYS_OPT_MAC_STATS
112 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
113 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
114 siena_mac_stats_update /* emo_stats_update */
115 #endif /* EFSYS_OPT_MAC_STATS */
117 #endif /* EFSYS_OPT_SIENA */
119 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
120 static efx_mac_ops_t __efx_ef10_mac_ops = {
121 NULL, /* emo_reset */
122 ef10_mac_poll, /* emo_poll */
123 ef10_mac_up, /* emo_up */
124 ef10_mac_addr_set, /* emo_addr_set */
125 ef10_mac_pdu_set, /* emo_pdu_set */
126 ef10_mac_reconfigure, /* emo_reconfigure */
127 ef10_mac_multicast_list_set, /* emo_multicast_list_set */
128 ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
129 ef10_mac_filter_default_rxq_clear,
130 /* emo_filter_default_rxq_clear */
131 #if EFSYS_OPT_LOOPBACK
132 ef10_mac_loopback_set, /* emo_loopback_set */
133 #endif /* EFSYS_OPT_LOOPBACK */
134 #if EFSYS_OPT_MAC_STATS
135 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
136 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
137 ef10_mac_stats_update /* emo_stats_update */
138 #endif /* EFSYS_OPT_MAC_STATS */
140 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
142 static efx_mac_ops_t *__efx_mac_ops[] = {
143 /* [EFX_MAC_INVALID] */
145 /* [EFX_MAC_FALCON_GMAC] */
146 #if EFSYS_OPT_MAC_FALCON_GMAC
147 &__efx_falcon_gmac_ops,
151 /* [EFX_MAC_FALCON_XMAC] */
152 #if EFSYS_OPT_MAC_FALCON_XMAC
153 &__efx_falcon_xmac_ops,
157 /* [EFX_MAC_SIENA] */
159 &__efx_siena_mac_ops,
163 /* [EFX_MAC_HUNTINGTON] */
164 #if EFSYS_OPT_HUNTINGTON
169 /* [EFX_MAC_MEDFORD] */
170 #if EFSYS_OPT_MEDFORD
177 __checkReturn efx_rc_t
182 efx_port_t *epp = &(enp->en_port);
183 efx_mac_ops_t *emop = epp->ep_emop;
187 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
188 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
189 EFSYS_ASSERT(emop != NULL);
191 if (pdu < EFX_MAC_PDU_MIN) {
196 if (pdu > EFX_MAC_PDU_MAX) {
201 old_pdu = epp->ep_mac_pdu;
202 epp->ep_mac_pdu = (uint32_t)pdu;
203 if ((rc = emop->emo_pdu_set(enp)) != 0)
211 epp->ep_mac_pdu = old_pdu;
216 EFSYS_PROBE1(fail1, efx_rc_t, rc);
221 __checkReturn efx_rc_t
226 efx_port_t *epp = &(enp->en_port);
227 efx_mac_ops_t *emop = epp->ep_emop;
232 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
233 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
235 if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
240 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
241 if (oui == 0x000000) {
246 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
247 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
248 if ((rc = emop->emo_addr_set(enp)) != 0)
256 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
261 EFSYS_PROBE1(fail1, efx_rc_t, rc);
266 __checkReturn efx_rc_t
269 __in boolean_t all_unicst,
270 __in boolean_t mulcst,
271 __in boolean_t all_mulcst,
272 __in boolean_t brdcst)
274 efx_port_t *epp = &(enp->en_port);
275 efx_mac_ops_t *emop = epp->ep_emop;
276 boolean_t old_all_unicst;
277 boolean_t old_mulcst;
278 boolean_t old_all_mulcst;
279 boolean_t old_brdcst;
282 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
283 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
285 old_all_unicst = epp->ep_all_unicst;
286 old_mulcst = epp->ep_mulcst;
287 old_all_mulcst = epp->ep_all_mulcst;
288 old_brdcst = epp->ep_brdcst;
290 epp->ep_all_unicst = all_unicst;
291 epp->ep_mulcst = mulcst;
292 epp->ep_all_mulcst = all_mulcst;
293 epp->ep_brdcst = brdcst;
295 if ((rc = emop->emo_reconfigure(enp)) != 0)
301 EFSYS_PROBE1(fail1, efx_rc_t, rc);
303 epp->ep_all_unicst = old_all_unicst;
304 epp->ep_mulcst = old_mulcst;
305 epp->ep_all_mulcst = old_all_mulcst;
306 epp->ep_brdcst = old_brdcst;
311 __checkReturn efx_rc_t
314 __in boolean_t enabled)
316 efx_port_t *epp = &(enp->en_port);
317 efx_mac_ops_t *emop = epp->ep_emop;
320 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
321 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
322 EFSYS_ASSERT(emop != NULL);
324 if (epp->ep_mac_drain == enabled)
327 epp->ep_mac_drain = enabled;
329 if (enabled && emop->emo_reset != NULL) {
330 if ((rc = emop->emo_reset(enp)) != 0)
333 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
334 enp->en_reset_flags &= ~EFX_RESET_PHY;
337 if ((rc = emop->emo_reconfigure(enp)) != 0)
345 EFSYS_PROBE1(fail1, efx_rc_t, rc);
350 __checkReturn efx_rc_t
353 __out boolean_t *mac_upp)
355 efx_port_t *epp = &(enp->en_port);
356 efx_mac_ops_t *emop = epp->ep_emop;
359 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
360 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
362 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
368 EFSYS_PROBE1(fail1, efx_rc_t, rc);
373 __checkReturn efx_rc_t
376 __in unsigned int fcntl,
377 __in boolean_t autoneg)
379 efx_port_t *epp = &(enp->en_port);
380 efx_mac_ops_t *emop = epp->ep_emop;
381 efx_phy_ops_t *epop = epp->ep_epop;
382 unsigned int old_fcntl;
383 boolean_t old_autoneg;
384 unsigned int old_adv_cap;
387 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
388 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
390 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
396 * Ignore a request to set flow control auto-negotiation
397 * if the PHY doesn't support it.
399 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
402 old_fcntl = epp->ep_fcntl;
403 old_autoneg = epp->ep_fcntl_autoneg;
404 old_adv_cap = epp->ep_adv_cap_mask;
406 epp->ep_fcntl = fcntl;
407 epp->ep_fcntl_autoneg = autoneg;
410 * Always encode the flow control settings in the advertised
411 * capabilities even if we are not trying to auto-negotiate
412 * them and reconfigure both the PHY and the MAC.
414 if (fcntl & EFX_FCNTL_RESPOND)
415 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
416 1 << EFX_PHY_CAP_ASYM);
418 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
419 1 << EFX_PHY_CAP_ASYM);
421 if (fcntl & EFX_FCNTL_GENERATE)
422 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
424 if ((rc = epop->epo_reconfigure(enp)) != 0)
427 if ((rc = emop->emo_reconfigure(enp)) != 0)
438 epp->ep_fcntl = old_fcntl;
439 epp->ep_fcntl_autoneg = old_autoneg;
440 epp->ep_adv_cap_mask = old_adv_cap;
443 EFSYS_PROBE1(fail1, efx_rc_t, rc);
451 __out unsigned int *fcntl_wantedp,
452 __out unsigned int *fcntl_linkp)
454 efx_port_t *epp = &(enp->en_port);
455 unsigned int wanted = 0;
457 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
458 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
461 * Decode the requested flow control settings from the PHY
462 * advertised capabilities.
464 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
465 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
466 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
467 wanted ^= EFX_FCNTL_GENERATE;
469 *fcntl_linkp = epp->ep_fcntl;
470 *fcntl_wantedp = wanted;
473 __checkReturn efx_rc_t
474 efx_mac_multicast_list_set(
476 __in_ecount(6*count) uint8_t const *addrs,
479 efx_port_t *epp = &(enp->en_port);
480 efx_mac_ops_t *emop = epp->ep_emop;
481 uint8_t *old_mulcst_addr_list = NULL;
482 uint32_t old_mulcst_addr_count;
485 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
486 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
488 if (count > EFX_MAC_MULTICAST_LIST_MAX) {
493 old_mulcst_addr_count = epp->ep_mulcst_addr_count;
494 if (old_mulcst_addr_count > 0) {
495 /* Allocate memory to store old list (instead of using stack) */
496 EFSYS_KMEM_ALLOC(enp->en_esip,
497 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
498 old_mulcst_addr_list);
499 if (old_mulcst_addr_list == NULL) {
504 /* Save the old list in case we need to rollback */
505 memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
506 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
509 /* Store the new list */
510 memcpy(epp->ep_mulcst_addr_list, addrs,
511 count * EFX_MAC_ADDR_LEN);
512 epp->ep_mulcst_addr_count = count;
514 if ((rc = emop->emo_multicast_list_set(enp)) != 0)
517 if (old_mulcst_addr_count > 0) {
518 EFSYS_KMEM_FREE(enp->en_esip,
519 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
520 old_mulcst_addr_list);
528 /* Restore original list on failure */
529 epp->ep_mulcst_addr_count = old_mulcst_addr_count;
530 if (old_mulcst_addr_count > 0) {
531 memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
532 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
534 EFSYS_KMEM_FREE(enp->en_esip,
535 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
536 old_mulcst_addr_list);
543 EFSYS_PROBE1(fail1, efx_rc_t, rc);
549 __checkReturn efx_rc_t
550 efx_mac_filter_default_rxq_set(
553 __in boolean_t using_rss)
555 efx_port_t *epp = &(enp->en_port);
556 efx_mac_ops_t *emop = epp->ep_emop;
559 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
560 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
562 if (emop->emo_filter_default_rxq_set != NULL) {
563 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
571 EFSYS_PROBE1(fail1, efx_rc_t, rc);
577 efx_mac_filter_default_rxq_clear(
580 efx_port_t *epp = &(enp->en_port);
581 efx_mac_ops_t *emop = epp->ep_emop;
583 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
584 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
586 if (emop->emo_filter_default_rxq_clear != NULL)
587 emop->emo_filter_default_rxq_clear(enp);
591 #if EFSYS_OPT_MAC_STATS
595 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 054d43a31d2d7a45 */
596 static const char *__efx_mac_stat_name[] = {
605 "rx_128_to_255_pkts",
606 "rx_256_to_511_pkts",
607 "rx_512_to_1023_pkts",
608 "rx_1024_to_15xx_pkts",
613 "rx_false_carrier_errors",
616 "rx_internal_errors",
627 "rx_nodesc_drop_cnt",
636 "tx_128_to_255_pkts",
637 "tx_256_to_511_pkts",
638 "tx_512_to_1023_pkts",
639 "tx_1024_to_15xx_pkts",
648 "pm_trunc_bb_overflow",
649 "pm_discard_bb_overflow",
650 "pm_trunc_vfifo_full",
651 "pm_discard_vfifo_full",
654 "pm_discard_mapping",
655 "rxdp_q_disabled_pkts",
656 "rxdp_di_dropped_pkts",
657 "rxdp_streaming_pkts",
660 "vadapter_rx_unicast_packets",
661 "vadapter_rx_unicast_bytes",
662 "vadapter_rx_multicast_packets",
663 "vadapter_rx_multicast_bytes",
664 "vadapter_rx_broadcast_packets",
665 "vadapter_rx_broadcast_bytes",
666 "vadapter_rx_bad_packets",
667 "vadapter_rx_bad_bytes",
668 "vadapter_rx_overflow",
669 "vadapter_tx_unicast_packets",
670 "vadapter_tx_unicast_bytes",
671 "vadapter_tx_multicast_packets",
672 "vadapter_tx_multicast_bytes",
673 "vadapter_tx_broadcast_packets",
674 "vadapter_tx_broadcast_bytes",
675 "vadapter_tx_bad_packets",
676 "vadapter_tx_bad_bytes",
677 "vadapter_tx_overflow",
679 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
681 __checkReturn const char *
684 __in unsigned int id)
686 _NOTE(ARGUNUSED(enp))
687 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
689 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
690 return (__efx_mac_stat_name[id]);
693 #endif /* EFSYS_OPT_NAMES */
695 __checkReturn efx_rc_t
696 efx_mac_stats_upload(
698 __in efsys_mem_t *esmp)
700 efx_port_t *epp = &(enp->en_port);
701 efx_mac_ops_t *emop = epp->ep_emop;
704 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
705 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
706 EFSYS_ASSERT(emop != NULL);
709 * Don't assert !ep_mac_stats_pending, because the client might
710 * have failed to finalise statistics when previously stopping
713 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
716 epp->ep_mac_stats_pending = B_TRUE;
721 EFSYS_PROBE1(fail1, efx_rc_t, rc);
726 __checkReturn efx_rc_t
727 efx_mac_stats_periodic(
729 __in efsys_mem_t *esmp,
730 __in uint16_t period_ms,
731 __in boolean_t events)
733 efx_port_t *epp = &(enp->en_port);
734 efx_mac_ops_t *emop = epp->ep_emop;
737 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
738 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
740 EFSYS_ASSERT(emop != NULL);
742 if (emop->emo_stats_periodic == NULL) {
747 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
755 EFSYS_PROBE1(fail1, efx_rc_t, rc);
761 __checkReturn efx_rc_t
762 efx_mac_stats_update(
764 __in efsys_mem_t *esmp,
765 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
766 __inout_opt uint32_t *generationp)
768 efx_port_t *epp = &(enp->en_port);
769 efx_mac_ops_t *emop = epp->ep_emop;
772 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
773 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
774 EFSYS_ASSERT(emop != NULL);
776 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
778 epp->ep_mac_stats_pending = B_FALSE;
783 #endif /* EFSYS_OPT_MAC_STATS */
785 __checkReturn efx_rc_t
789 efx_port_t *epp = &(enp->en_port);
790 efx_mac_type_t type = EFX_MAC_INVALID;
795 if (enp->en_family == EFX_FAMILY_SIENA) {
796 type = EFX_MAC_SIENA;
801 #if EFSYS_OPT_HUNTINGTON
802 if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
803 type = EFX_MAC_HUNTINGTON;
808 #if EFSYS_OPT_MEDFORD
809 if (enp->en_family == EFX_FAMILY_MEDFORD) {
810 type = EFX_MAC_MEDFORD;
816 switch (epp->ep_link_mode) {
817 #if EFSYS_OPT_MAC_FALCON_GMAC
818 case EFX_LINK_100HDX:
819 case EFX_LINK_100FDX:
820 case EFX_LINK_1000HDX:
821 case EFX_LINK_1000FDX:
822 type = EFX_MAC_FALCON_GMAC;
824 #endif /* EFSYS_OPT_FALCON_GMAC */
826 #if EFSYS_OPT_MAC_FALCON_XMAC
827 case EFX_LINK_10000FDX:
828 type = EFX_MAC_FALCON_XMAC;
830 #endif /* EFSYS_OPT_FALCON_XMAC */
833 #if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC
834 /* Only initialise a MAC supported by the PHY */
835 if (epp->ep_phy_cap_mask &
836 ((1 << EFX_PHY_CAP_1000FDX) |
837 (1 << EFX_PHY_CAP_1000HDX) |
838 (1 << EFX_PHY_CAP_100FDX) |
839 (1 << EFX_PHY_CAP_100HDX) |
840 (1 << EFX_PHY_CAP_10FDX) |
841 (1 << EFX_PHY_CAP_10FDX)))
842 type = EFX_MAC_FALCON_GMAC;
844 type = EFX_MAC_FALCON_XMAC;
845 #elif EFSYS_OPT_MAC_FALCON_GMAC
846 type = EFX_MAC_FALCON_GMAC;
848 type = EFX_MAC_FALCON_XMAC;
852 #endif /* EFSYS_OPT_FALCON */
855 EFSYS_ASSERT(type != EFX_MAC_INVALID);
856 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
857 emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type];
858 EFSYS_ASSERT(emop != NULL);
860 epp->ep_mac_type = type;
862 if (emop->emo_reset != NULL) {
863 if ((rc = emop->emo_reset(enp)) != 0)
866 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
867 enp->en_reset_flags &= ~EFX_RESET_MAC;
873 EFSYS_PROBE1(fail1, efx_rc_t, rc);
879 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
881 #define EFX_MAC_HASH_BITS (1 << 8)
883 /* Compute the multicast hash as used on Falcon and Siena. */
885 falconsiena_mac_multicast_hash_compute(
886 __in_ecount(6*count) uint8_t const *addrs,
888 __out efx_oword_t *hash_low,
889 __out efx_oword_t *hash_high)
894 EFSYS_ASSERT(hash_low != NULL);
895 EFSYS_ASSERT(hash_high != NULL);
897 EFX_ZERO_OWORD(*hash_low);
898 EFX_ZERO_OWORD(*hash_high);
900 for (i = 0; i < count; i++) {
901 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
902 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
903 index = crc % EFX_MAC_HASH_BITS;
905 EFX_SET_OWORD_BIT(*hash_low, index);
907 EFX_SET_OWORD_BIT(*hash_high, index - 128);
910 addrs += EFX_MAC_ADDR_LEN;
914 static __checkReturn efx_rc_t
915 falconsiena_mac_multicast_list_set(
918 efx_port_t *epp = &(enp->en_port);
919 efx_mac_ops_t *emop = epp->ep_emop;
920 efx_oword_t old_hash[2];
923 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
924 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
926 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
928 falconsiena_mac_multicast_hash_compute(epp->ep_mulcst_addr_list,
929 epp->ep_mulcst_addr_count,
930 &epp->ep_multicst_hash[0],
931 &epp->ep_multicst_hash[1]);
933 if ((rc = emop->emo_reconfigure(enp)) != 0)
939 EFSYS_PROBE1(fail1, efx_rc_t, rc);
941 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
946 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */