1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2007-2018 Solarflare Communications Inc.
12 static __checkReturn efx_rc_t
13 siena_mac_multicast_list_set(
16 #endif /* EFSYS_OPT_SIENA */
19 static const efx_mac_ops_t __efx_mac_siena_ops = {
20 siena_mac_poll, /* emo_poll */
21 siena_mac_up, /* emo_up */
22 siena_mac_reconfigure, /* emo_addr_set */
23 siena_mac_reconfigure, /* emo_pdu_set */
24 siena_mac_pdu_get, /* emo_pdu_get */
25 siena_mac_reconfigure, /* emo_reconfigure */
26 siena_mac_multicast_list_set, /* emo_multicast_list_set */
27 NULL, /* emo_filter_set_default_rxq */
28 NULL, /* emo_filter_default_rxq_clear */
29 #if EFSYS_OPT_LOOPBACK
30 siena_mac_loopback_set, /* emo_loopback_set */
31 #endif /* EFSYS_OPT_LOOPBACK */
32 #if EFSYS_OPT_MAC_STATS
33 siena_mac_stats_get_mask, /* emo_stats_get_mask */
34 efx_mcdi_mac_stats_clear, /* emo_stats_clear */
35 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
36 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
37 siena_mac_stats_update /* emo_stats_update */
38 #endif /* EFSYS_OPT_MAC_STATS */
40 #endif /* EFSYS_OPT_SIENA */
42 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
43 static const efx_mac_ops_t __efx_mac_ef10_ops = {
44 ef10_mac_poll, /* emo_poll */
45 ef10_mac_up, /* emo_up */
46 ef10_mac_addr_set, /* emo_addr_set */
47 ef10_mac_pdu_set, /* emo_pdu_set */
48 ef10_mac_pdu_get, /* emo_pdu_get */
49 ef10_mac_reconfigure, /* emo_reconfigure */
50 ef10_mac_multicast_list_set, /* emo_multicast_list_set */
51 ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
52 ef10_mac_filter_default_rxq_clear,
53 /* emo_filter_default_rxq_clear */
54 #if EFSYS_OPT_LOOPBACK
55 ef10_mac_loopback_set, /* emo_loopback_set */
56 #endif /* EFSYS_OPT_LOOPBACK */
57 #if EFSYS_OPT_MAC_STATS
58 ef10_mac_stats_get_mask, /* emo_stats_get_mask */
59 efx_mcdi_mac_stats_clear, /* emo_stats_clear */
60 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
61 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
62 ef10_mac_stats_update /* emo_stats_update */
63 #endif /* EFSYS_OPT_MAC_STATS */
65 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
67 __checkReturn efx_rc_t
72 efx_port_t *epp = &(enp->en_port);
73 const efx_mac_ops_t *emop = epp->ep_emop;
77 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
78 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
79 EFSYS_ASSERT(emop != NULL);
81 if (pdu < EFX_MAC_PDU_MIN) {
86 if (pdu > EFX_MAC_PDU_MAX) {
91 old_pdu = epp->ep_mac_pdu;
92 epp->ep_mac_pdu = (uint32_t)pdu;
93 if ((rc = emop->emo_pdu_set(enp)) != 0)
101 epp->ep_mac_pdu = old_pdu;
106 EFSYS_PROBE1(fail1, efx_rc_t, rc);
111 __checkReturn efx_rc_t
116 efx_port_t *epp = &(enp->en_port);
117 const efx_mac_ops_t *emop = epp->ep_emop;
120 if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
126 EFSYS_PROBE1(fail1, efx_rc_t, rc);
131 __checkReturn efx_rc_t
136 efx_port_t *epp = &(enp->en_port);
137 const efx_mac_ops_t *emop = epp->ep_emop;
142 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
143 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
145 if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
150 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
151 if (oui == 0x000000) {
156 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
157 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
158 if ((rc = emop->emo_addr_set(enp)) != 0)
166 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
171 EFSYS_PROBE1(fail1, efx_rc_t, rc);
176 __checkReturn efx_rc_t
179 __in boolean_t all_unicst,
180 __in boolean_t mulcst,
181 __in boolean_t all_mulcst,
182 __in boolean_t brdcst)
184 efx_port_t *epp = &(enp->en_port);
185 const efx_mac_ops_t *emop = epp->ep_emop;
186 boolean_t old_all_unicst;
187 boolean_t old_mulcst;
188 boolean_t old_all_mulcst;
189 boolean_t old_brdcst;
192 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
193 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
195 old_all_unicst = epp->ep_all_unicst;
196 old_mulcst = epp->ep_mulcst;
197 old_all_mulcst = epp->ep_all_mulcst;
198 old_brdcst = epp->ep_brdcst;
200 epp->ep_all_unicst = all_unicst;
201 epp->ep_mulcst = mulcst;
202 epp->ep_all_mulcst = all_mulcst;
203 epp->ep_brdcst = brdcst;
205 if ((rc = emop->emo_reconfigure(enp)) != 0)
211 EFSYS_PROBE1(fail1, efx_rc_t, rc);
213 epp->ep_all_unicst = old_all_unicst;
214 epp->ep_mulcst = old_mulcst;
215 epp->ep_all_mulcst = old_all_mulcst;
216 epp->ep_brdcst = old_brdcst;
221 __checkReturn efx_rc_t
224 __in boolean_t enabled)
226 efx_port_t *epp = &(enp->en_port);
227 const efx_mac_ops_t *emop = epp->ep_emop;
230 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
231 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
232 EFSYS_ASSERT(emop != NULL);
234 if (epp->ep_mac_drain == enabled)
237 epp->ep_mac_drain = enabled;
239 if ((rc = emop->emo_reconfigure(enp)) != 0)
245 EFSYS_PROBE1(fail1, efx_rc_t, rc);
250 __checkReturn efx_rc_t
253 __out boolean_t *mac_upp)
255 efx_port_t *epp = &(enp->en_port);
256 const efx_mac_ops_t *emop = epp->ep_emop;
259 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
260 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
262 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
268 EFSYS_PROBE1(fail1, efx_rc_t, rc);
273 __checkReturn efx_rc_t
276 __in unsigned int fcntl,
277 __in boolean_t autoneg)
279 efx_port_t *epp = &(enp->en_port);
280 const efx_mac_ops_t *emop = epp->ep_emop;
281 const efx_phy_ops_t *epop = epp->ep_epop;
282 unsigned int old_fcntl;
283 boolean_t old_autoneg;
284 unsigned int old_adv_cap;
287 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
288 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
290 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
296 * Ignore a request to set flow control auto-negotiation
297 * if the PHY doesn't support it.
299 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
302 old_fcntl = epp->ep_fcntl;
303 old_autoneg = epp->ep_fcntl_autoneg;
304 old_adv_cap = epp->ep_adv_cap_mask;
306 epp->ep_fcntl = fcntl;
307 epp->ep_fcntl_autoneg = autoneg;
310 * Always encode the flow control settings in the advertised
311 * capabilities even if we are not trying to auto-negotiate
312 * them and reconfigure both the PHY and the MAC.
314 if (fcntl & EFX_FCNTL_RESPOND)
315 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
316 1 << EFX_PHY_CAP_ASYM);
318 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
319 1 << EFX_PHY_CAP_ASYM);
321 if (fcntl & EFX_FCNTL_GENERATE)
322 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
324 if ((rc = epop->epo_reconfigure(enp)) != 0)
327 if ((rc = emop->emo_reconfigure(enp)) != 0)
338 epp->ep_fcntl = old_fcntl;
339 epp->ep_fcntl_autoneg = old_autoneg;
340 epp->ep_adv_cap_mask = old_adv_cap;
343 EFSYS_PROBE1(fail1, efx_rc_t, rc);
351 __out unsigned int *fcntl_wantedp,
352 __out unsigned int *fcntl_linkp)
354 efx_port_t *epp = &(enp->en_port);
355 unsigned int wanted = 0;
357 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
358 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
361 * Decode the requested flow control settings from the PHY
362 * advertised capabilities.
364 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
365 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
366 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
367 wanted ^= EFX_FCNTL_GENERATE;
369 *fcntl_linkp = epp->ep_fcntl;
370 *fcntl_wantedp = wanted;
373 __checkReturn efx_rc_t
374 efx_mac_multicast_list_set(
376 __in_ecount(6*count) uint8_t const *addrs,
379 efx_port_t *epp = &(enp->en_port);
380 const efx_mac_ops_t *emop = epp->ep_emop;
381 uint8_t *old_mulcst_addr_list = NULL;
382 uint32_t old_mulcst_addr_count;
385 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
386 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
388 if (count > EFX_MAC_MULTICAST_LIST_MAX) {
393 old_mulcst_addr_count = epp->ep_mulcst_addr_count;
394 if (old_mulcst_addr_count > 0) {
395 /* Allocate memory to store old list (instead of using stack) */
396 EFSYS_KMEM_ALLOC(enp->en_esip,
397 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
398 old_mulcst_addr_list);
399 if (old_mulcst_addr_list == NULL) {
404 /* Save the old list in case we need to rollback */
405 memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
406 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
409 /* Store the new list */
410 memcpy(epp->ep_mulcst_addr_list, addrs,
411 count * EFX_MAC_ADDR_LEN);
412 epp->ep_mulcst_addr_count = count;
414 if ((rc = emop->emo_multicast_list_set(enp)) != 0)
417 if (old_mulcst_addr_count > 0) {
418 EFSYS_KMEM_FREE(enp->en_esip,
419 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
420 old_mulcst_addr_list);
428 /* Restore original list on failure */
429 epp->ep_mulcst_addr_count = old_mulcst_addr_count;
430 if (old_mulcst_addr_count > 0) {
431 memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
432 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
434 EFSYS_KMEM_FREE(enp->en_esip,
435 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
436 old_mulcst_addr_list);
443 EFSYS_PROBE1(fail1, efx_rc_t, rc);
449 __checkReturn efx_rc_t
450 efx_mac_filter_default_rxq_set(
453 __in boolean_t using_rss)
455 efx_port_t *epp = &(enp->en_port);
456 const efx_mac_ops_t *emop = epp->ep_emop;
459 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
460 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
462 if (emop->emo_filter_default_rxq_set != NULL) {
463 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
471 EFSYS_PROBE1(fail1, efx_rc_t, rc);
477 efx_mac_filter_default_rxq_clear(
480 efx_port_t *epp = &(enp->en_port);
481 const efx_mac_ops_t *emop = epp->ep_emop;
483 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
484 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
486 if (emop->emo_filter_default_rxq_clear != NULL)
487 emop->emo_filter_default_rxq_clear(enp);
491 #if EFSYS_OPT_MAC_STATS
495 /* START MKCONFIG GENERATED EfxMacStatNamesBlock c11b91b42f922516 */
496 static const char * const __efx_mac_stat_name[] = {
505 "rx_128_to_255_pkts",
506 "rx_256_to_511_pkts",
507 "rx_512_to_1023_pkts",
508 "rx_1024_to_15xx_pkts",
513 "rx_false_carrier_errors",
516 "rx_internal_errors",
527 "rx_nodesc_drop_cnt",
536 "tx_128_to_255_pkts",
537 "tx_256_to_511_pkts",
538 "tx_512_to_1023_pkts",
539 "tx_1024_to_15xx_pkts",
548 "pm_trunc_bb_overflow",
549 "pm_discard_bb_overflow",
550 "pm_trunc_vfifo_full",
551 "pm_discard_vfifo_full",
554 "pm_discard_mapping",
555 "rxdp_q_disabled_pkts",
556 "rxdp_di_dropped_pkts",
557 "rxdp_streaming_pkts",
560 "vadapter_rx_unicast_packets",
561 "vadapter_rx_unicast_bytes",
562 "vadapter_rx_multicast_packets",
563 "vadapter_rx_multicast_bytes",
564 "vadapter_rx_broadcast_packets",
565 "vadapter_rx_broadcast_bytes",
566 "vadapter_rx_bad_packets",
567 "vadapter_rx_bad_bytes",
568 "vadapter_rx_overflow",
569 "vadapter_tx_unicast_packets",
570 "vadapter_tx_unicast_bytes",
571 "vadapter_tx_multicast_packets",
572 "vadapter_tx_multicast_bytes",
573 "vadapter_tx_broadcast_packets",
574 "vadapter_tx_broadcast_bytes",
575 "vadapter_tx_bad_packets",
576 "vadapter_tx_bad_bytes",
577 "vadapter_tx_overflow",
579 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
581 __checkReturn const char *
584 __in unsigned int id)
586 _NOTE(ARGUNUSED(enp))
587 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
589 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
590 return (__efx_mac_stat_name[id]);
593 #endif /* EFSYS_OPT_NAMES */
596 efx_mac_stats_mask_add_range(
597 __inout_bcount(mask_size) uint32_t *maskp,
598 __in size_t mask_size,
599 __in const struct efx_mac_stats_range *rngp)
601 unsigned int mask_npages = mask_size / sizeof (*maskp);
610 if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
611 (unsigned int)rngp->last) {
616 EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
617 EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
619 for (el = 0; el < mask_npages; ++el) {
620 el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
622 el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
623 if ((unsigned int)rngp->first > el_max ||
624 (unsigned int)rngp->last < el_min)
626 low = MAX((unsigned int)rngp->first, el_min);
627 high = MIN((unsigned int)rngp->last, el_max);
628 width = high - low + 1;
630 (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
631 (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
637 EFSYS_PROBE1(fail1, efx_rc_t, rc);
643 efx_mac_stats_mask_add_ranges(
644 __inout_bcount(mask_size) uint32_t *maskp,
645 __in size_t mask_size,
646 __in_ecount(rng_count) const struct efx_mac_stats_range *rngp,
647 __in unsigned int rng_count)
652 for (i = 0; i < rng_count; ++i) {
653 if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
661 EFSYS_PROBE1(fail1, efx_rc_t, rc);
666 __checkReturn efx_rc_t
667 efx_mac_stats_get_mask(
669 __out_bcount(mask_size) uint32_t *maskp,
670 __in size_t mask_size)
672 efx_port_t *epp = &(enp->en_port);
673 const efx_mac_ops_t *emop = epp->ep_emop;
676 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
677 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
678 EFSYS_ASSERT(maskp != NULL);
679 EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
681 (void) memset(maskp, 0, mask_size);
683 if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
689 EFSYS_PROBE1(fail1, efx_rc_t, rc);
694 __checkReturn efx_rc_t
698 efx_port_t *epp = &(enp->en_port);
699 const efx_mac_ops_t *emop = epp->ep_emop;
702 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
703 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
704 EFSYS_ASSERT(emop != NULL);
706 if ((rc = emop->emo_stats_clear(enp)) != 0)
712 EFSYS_PROBE1(fail1, efx_rc_t, rc);
717 __checkReturn efx_rc_t
718 efx_mac_stats_upload(
720 __in efsys_mem_t *esmp)
722 efx_port_t *epp = &(enp->en_port);
723 const efx_mac_ops_t *emop = epp->ep_emop;
726 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
727 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
728 EFSYS_ASSERT(emop != NULL);
730 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
736 EFSYS_PROBE1(fail1, efx_rc_t, rc);
741 __checkReturn efx_rc_t
742 efx_mac_stats_periodic(
744 __in efsys_mem_t *esmp,
745 __in uint16_t period_ms,
746 __in boolean_t events)
748 efx_port_t *epp = &(enp->en_port);
749 const efx_mac_ops_t *emop = epp->ep_emop;
752 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
753 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
755 EFSYS_ASSERT(emop != NULL);
757 if (emop->emo_stats_periodic == NULL) {
762 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
770 EFSYS_PROBE1(fail1, efx_rc_t, rc);
776 __checkReturn efx_rc_t
777 efx_mac_stats_update(
779 __in efsys_mem_t *esmp,
780 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
781 __inout_opt uint32_t *generationp)
783 efx_port_t *epp = &(enp->en_port);
784 const efx_mac_ops_t *emop = epp->ep_emop;
787 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
788 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
789 EFSYS_ASSERT(emop != NULL);
791 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
796 #endif /* EFSYS_OPT_MAC_STATS */
798 __checkReturn efx_rc_t
802 efx_port_t *epp = &(enp->en_port);
803 efx_mac_type_t type = EFX_MAC_INVALID;
804 const efx_mac_ops_t *emop;
807 switch (enp->en_family) {
809 case EFX_FAMILY_SIENA:
810 emop = &__efx_mac_siena_ops;
811 type = EFX_MAC_SIENA;
813 #endif /* EFSYS_OPT_SIENA */
815 #if EFSYS_OPT_HUNTINGTON
816 case EFX_FAMILY_HUNTINGTON:
817 emop = &__efx_mac_ef10_ops;
818 type = EFX_MAC_HUNTINGTON;
820 #endif /* EFSYS_OPT_HUNTINGTON */
822 #if EFSYS_OPT_MEDFORD
823 case EFX_FAMILY_MEDFORD:
824 emop = &__efx_mac_ef10_ops;
825 type = EFX_MAC_MEDFORD;
827 #endif /* EFSYS_OPT_MEDFORD */
834 EFSYS_ASSERT(type != EFX_MAC_INVALID);
835 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
836 EFSYS_ASSERT(emop != NULL);
839 epp->ep_mac_type = type;
844 EFSYS_PROBE1(fail1, efx_rc_t, rc);
852 #define EFX_MAC_HASH_BITS (1 << 8)
854 /* Compute the multicast hash as used on Falcon and Siena. */
856 siena_mac_multicast_hash_compute(
857 __in_ecount(6*count) uint8_t const *addrs,
859 __out efx_oword_t *hash_low,
860 __out efx_oword_t *hash_high)
865 EFSYS_ASSERT(hash_low != NULL);
866 EFSYS_ASSERT(hash_high != NULL);
868 EFX_ZERO_OWORD(*hash_low);
869 EFX_ZERO_OWORD(*hash_high);
871 for (i = 0; i < count; i++) {
872 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
873 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
874 index = crc % EFX_MAC_HASH_BITS;
876 EFX_SET_OWORD_BIT(*hash_low, index);
878 EFX_SET_OWORD_BIT(*hash_high, index - 128);
881 addrs += EFX_MAC_ADDR_LEN;
885 static __checkReturn efx_rc_t
886 siena_mac_multicast_list_set(
889 efx_port_t *epp = &(enp->en_port);
890 const efx_mac_ops_t *emop = epp->ep_emop;
891 efx_oword_t old_hash[2];
894 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
895 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
897 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
899 siena_mac_multicast_hash_compute(
900 epp->ep_mulcst_addr_list,
901 epp->ep_mulcst_addr_count,
902 &epp->ep_multicst_hash[0],
903 &epp->ep_multicst_hash[1]);
905 if ((rc = emop->emo_reconfigure(enp)) != 0)
911 EFSYS_PROBE1(fail1, efx_rc_t, rc);
913 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
918 #endif /* EFSYS_OPT_SIENA */