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_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 */
72 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */
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 */
93 #endif /* EFSYS_OPT_MAC_FALCON_XMAC */
96 static efx_mac_ops_t __efx_siena_mac_ops = {
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 */
114 #endif /* EFSYS_OPT_SIENA */
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 */
136 #endif /* EFSYS_OPT_HUNTINGTON */
138 static efx_mac_ops_t *__efx_mac_ops[] = {
139 /* [EFX_MAC_INVALID] */
141 /* [EFX_MAC_FALCON_GMAC] */
142 #if EFSYS_OPT_MAC_FALCON_GMAC
143 &__efx_falcon_gmac_ops,
147 /* [EFX_MAC_FALCON_XMAC] */
148 #if EFSYS_OPT_MAC_FALCON_XMAC
149 &__efx_falcon_xmac_ops,
153 /* [EFX_MAC_SIENA] */
155 &__efx_siena_mac_ops,
159 /* [EFX_MAC_HUNTINGTON] */
160 #if EFSYS_OPT_HUNTINGTON
167 __checkReturn efx_rc_t
172 efx_port_t *epp = &(enp->en_port);
173 efx_mac_ops_t *emop = epp->ep_emop;
177 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
178 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
179 EFSYS_ASSERT(emop != NULL);
181 if (pdu < EFX_MAC_PDU_MIN) {
186 if (pdu > EFX_MAC_PDU_MAX) {
191 old_pdu = epp->ep_mac_pdu;
192 epp->ep_mac_pdu = (uint32_t)pdu;
193 if ((rc = emop->emo_reconfigure(enp)) != 0)
201 epp->ep_mac_pdu = old_pdu;
206 EFSYS_PROBE1(fail1, efx_rc_t, rc);
211 __checkReturn efx_rc_t
216 efx_port_t *epp = &(enp->en_port);
217 efx_mac_ops_t *emop = epp->ep_emop;
222 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
223 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
225 if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
230 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
231 if (oui == 0x000000) {
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)
246 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
251 EFSYS_PROBE1(fail1, efx_rc_t, rc);
256 __checkReturn efx_rc_t
259 __in boolean_t all_unicst,
260 __in boolean_t mulcst,
261 __in boolean_t all_mulcst,
262 __in boolean_t brdcst)
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;
272 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
273 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
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;
280 epp->ep_all_unicst = all_unicst;
281 epp->ep_mulcst = mulcst;
282 epp->ep_all_mulcst = all_mulcst;
283 epp->ep_brdcst = brdcst;
285 if ((rc = emop->emo_reconfigure(enp)) != 0)
291 EFSYS_PROBE1(fail1, efx_rc_t, rc);
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;
301 __checkReturn efx_rc_t
304 __in boolean_t enabled)
306 efx_port_t *epp = &(enp->en_port);
307 efx_mac_ops_t *emop = epp->ep_emop;
310 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
311 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
312 EFSYS_ASSERT(emop != NULL);
314 if (epp->ep_mac_drain == enabled)
317 epp->ep_mac_drain = enabled;
319 if (enabled && emop->emo_reset != NULL) {
320 if ((rc = emop->emo_reset(enp)) != 0)
323 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
324 enp->en_reset_flags &= ~EFX_RESET_PHY;
327 if ((rc = emop->emo_reconfigure(enp)) != 0)
335 EFSYS_PROBE1(fail1, efx_rc_t, rc);
340 __checkReturn efx_rc_t
343 __out boolean_t *mac_upp)
345 efx_port_t *epp = &(enp->en_port);
346 efx_mac_ops_t *emop = epp->ep_emop;
349 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
350 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
352 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
358 EFSYS_PROBE1(fail1, efx_rc_t, rc);
363 __checkReturn efx_rc_t
366 __in unsigned int fcntl,
367 __in boolean_t autoneg)
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;
377 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
378 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
380 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
386 * Ignore a request to set flow control auto-negotiation
387 * if the PHY doesn't support it.
389 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
392 old_fcntl = epp->ep_fcntl;
393 old_autoneg = epp->ep_fcntl_autoneg;
394 old_adv_cap = epp->ep_adv_cap_mask;
396 epp->ep_fcntl = fcntl;
397 epp->ep_fcntl_autoneg = autoneg;
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.
404 if (fcntl & EFX_FCNTL_RESPOND)
405 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
406 1 << EFX_PHY_CAP_ASYM);
408 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
409 1 << EFX_PHY_CAP_ASYM);
411 if (fcntl & EFX_FCNTL_GENERATE)
412 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
414 if ((rc = epop->epo_reconfigure(enp)) != 0)
417 if ((rc = emop->emo_reconfigure(enp)) != 0)
428 epp->ep_fcntl = old_fcntl;
429 epp->ep_fcntl_autoneg = old_autoneg;
430 epp->ep_adv_cap_mask = old_adv_cap;
433 EFSYS_PROBE1(fail1, efx_rc_t, rc);
441 __out unsigned int *fcntl_wantedp,
442 __out unsigned int *fcntl_linkp)
444 efx_port_t *epp = &(enp->en_port);
445 unsigned int wanted = 0;
447 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
448 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
451 * Decode the requested flow control settings from the PHY
452 * advertised capabilities.
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;
459 *fcntl_linkp = epp->ep_fcntl;
460 *fcntl_wantedp = wanted;
463 __checkReturn efx_rc_t
464 efx_mac_multicast_list_set(
466 __in_ecount(6*count) uint8_t const *addrs,
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;
475 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
476 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
478 if (count > EFX_MAC_MULTICAST_LIST_MAX) {
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) {
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);
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;
504 if ((rc = emop->emo_multicast_list_set(enp)) != 0)
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);
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);
524 EFSYS_KMEM_FREE(enp->en_esip,
525 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
526 old_mulcst_addr_list);
533 EFSYS_PROBE1(fail1, efx_rc_t, rc);
539 __checkReturn efx_rc_t
540 efx_mac_filter_default_rxq_set(
543 __in boolean_t using_rss)
545 efx_port_t *epp = &(enp->en_port);
546 efx_mac_ops_t *emop = epp->ep_emop;
549 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
550 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
552 if (emop->emo_filter_default_rxq_set != NULL) {
553 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
561 EFSYS_PROBE1(fail1, efx_rc_t, rc);
567 efx_mac_filter_default_rxq_clear(
570 efx_port_t *epp = &(enp->en_port);
571 efx_mac_ops_t *emop = epp->ep_emop;
573 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
574 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
576 if (emop->emo_filter_default_rxq_clear != NULL)
577 emop->emo_filter_default_rxq_clear(enp);
581 #if EFSYS_OPT_MAC_STATS
585 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 054d43a31d2d7a45 */
586 static const char *__efx_mac_stat_name[] = {
595 "rx_128_to_255_pkts",
596 "rx_256_to_511_pkts",
597 "rx_512_to_1023_pkts",
598 "rx_1024_to_15xx_pkts",
603 "rx_false_carrier_errors",
606 "rx_internal_errors",
617 "rx_nodesc_drop_cnt",
626 "tx_128_to_255_pkts",
627 "tx_256_to_511_pkts",
628 "tx_512_to_1023_pkts",
629 "tx_1024_to_15xx_pkts",
638 "pm_trunc_bb_overflow",
639 "pm_discard_bb_overflow",
640 "pm_trunc_vfifo_full",
641 "pm_discard_vfifo_full",
644 "pm_discard_mapping",
645 "rxdp_q_disabled_pkts",
646 "rxdp_di_dropped_pkts",
647 "rxdp_streaming_pkts",
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",
669 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
671 __checkReturn const char *
674 __in unsigned int id)
676 _NOTE(ARGUNUSED(enp))
677 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
679 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
680 return (__efx_mac_stat_name[id]);
683 #endif /* EFSYS_OPT_NAMES */
685 __checkReturn efx_rc_t
686 efx_mac_stats_upload(
688 __in efsys_mem_t *esmp)
690 efx_port_t *epp = &(enp->en_port);
691 efx_mac_ops_t *emop = epp->ep_emop;
694 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
695 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
696 EFSYS_ASSERT(emop != NULL);
699 * Don't assert !ep_mac_stats_pending, because the client might
700 * have failed to finalise statistics when previously stopping
703 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
706 epp->ep_mac_stats_pending = B_TRUE;
711 EFSYS_PROBE1(fail1, efx_rc_t, rc);
716 __checkReturn efx_rc_t
717 efx_mac_stats_periodic(
719 __in efsys_mem_t *esmp,
720 __in uint16_t period_ms,
721 __in boolean_t events)
723 efx_port_t *epp = &(enp->en_port);
724 efx_mac_ops_t *emop = epp->ep_emop;
727 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
728 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
730 EFSYS_ASSERT(emop != NULL);
732 if (emop->emo_stats_periodic == NULL) {
737 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
745 EFSYS_PROBE1(fail1, efx_rc_t, rc);
751 __checkReturn efx_rc_t
752 efx_mac_stats_update(
754 __in efsys_mem_t *esmp,
755 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
756 __inout_opt uint32_t *generationp)
758 efx_port_t *epp = &(enp->en_port);
759 efx_mac_ops_t *emop = epp->ep_emop;
762 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
763 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
764 EFSYS_ASSERT(emop != NULL);
766 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
768 epp->ep_mac_stats_pending = B_FALSE;
773 #endif /* EFSYS_OPT_MAC_STATS */
775 __checkReturn efx_rc_t
779 efx_port_t *epp = &(enp->en_port);
780 efx_mac_type_t type = EFX_MAC_INVALID;
784 #if EFSYS_OPT_HUNTINGTON
785 if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
786 type = EFX_MAC_HUNTINGTON;
792 if (enp->en_family == EFX_FAMILY_SIENA) {
793 type = EFX_MAC_SIENA;
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;
807 #endif /* EFSYS_OPT_FALCON_GMAC */
809 #if EFSYS_OPT_MAC_FALCON_XMAC
810 case EFX_LINK_10000FDX:
811 type = EFX_MAC_FALCON_XMAC;
813 #endif /* EFSYS_OPT_FALCON_XMAC */
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;
827 type = EFX_MAC_FALCON_XMAC;
828 #elif EFSYS_OPT_MAC_FALCON_GMAC
829 type = EFX_MAC_FALCON_GMAC;
831 type = EFX_MAC_FALCON_XMAC;
835 #endif /* EFSYS_OPT_FALCON */
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);
843 epp->ep_mac_type = type;
845 if (emop->emo_reset != NULL) {
846 if ((rc = emop->emo_reset(enp)) != 0)
849 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
850 enp->en_reset_flags &= ~EFX_RESET_MAC;
856 EFSYS_PROBE1(fail1, efx_rc_t, rc);
862 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
864 #define EFX_MAC_HASH_BITS (1 << 8)
866 /* Compute the multicast hash as used on Falcon and Siena. */
868 falconsiena_mac_multicast_hash_compute(
869 __in_ecount(6*count) uint8_t const *addrs,
871 __out efx_oword_t *hash_low,
872 __out efx_oword_t *hash_high)
877 EFSYS_ASSERT(hash_low != NULL);
878 EFSYS_ASSERT(hash_high != NULL);
880 EFX_ZERO_OWORD(*hash_low);
881 EFX_ZERO_OWORD(*hash_high);
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;
888 EFX_SET_OWORD_BIT(*hash_low, index);
890 EFX_SET_OWORD_BIT(*hash_high, index - 128);
893 addrs += EFX_MAC_ADDR_LEN;
897 static __checkReturn efx_rc_t
898 falconsiena_mac_multicast_list_set(
901 efx_port_t *epp = &(enp->en_port);
902 efx_mac_ops_t *emop = epp->ep_emop;
903 efx_oword_t old_hash[2];
906 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
907 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
909 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
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]);
916 if ((rc = emop->emo_reconfigure(enp)) != 0)
922 EFSYS_PROBE1(fail1, efx_rc_t, rc);
924 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
929 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */