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 || EFSYS_OPT_MEDFORD2
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 || EFSYS_OPT_MEDFORD2 */
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 1a45a82fcfb30c1b */
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",
578 "fec_uncorrected_errors",
579 "fec_corrected_errors",
580 "fec_corrected_symbols_lane0",
581 "fec_corrected_symbols_lane1",
582 "fec_corrected_symbols_lane2",
583 "fec_corrected_symbols_lane3",
584 "ctpio_vi_busy_fallback",
585 "ctpio_long_write_success",
586 "ctpio_missing_dbell_fail",
587 "ctpio_overflow_fail",
588 "ctpio_underflow_fail",
589 "ctpio_timeout_fail",
590 "ctpio_noncontig_wr_fail",
591 "ctpio_frm_clobber_fail",
592 "ctpio_invalid_wr_fail",
593 "ctpio_vi_clobber_fallback",
594 "ctpio_unqualified_fallback",
595 "ctpio_runt_fallback",
600 "rxdp_scatter_disabled_trunc",
604 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
606 __checkReturn
const char *
609 __in
unsigned int id
)
611 _NOTE(ARGUNUSED(enp
))
612 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
614 EFSYS_ASSERT3U(id
, <, EFX_MAC_NSTATS
);
615 return (__efx_mac_stat_name
[id
]);
618 #endif /* EFSYS_OPT_NAMES */
621 efx_mac_stats_mask_add_range(
622 __inout_bcount(mask_size
) uint32_t *maskp
,
623 __in
size_t mask_size
,
624 __in
const struct efx_mac_stats_range
*rngp
)
626 unsigned int mask_npages
= mask_size
/ sizeof (*maskp
);
635 if ((mask_npages
* EFX_MAC_STATS_MASK_BITS_PER_PAGE
) <=
636 (unsigned int)rngp
->last
) {
641 EFSYS_ASSERT3U(rngp
->first
, <=, rngp
->last
);
642 EFSYS_ASSERT3U(rngp
->last
, <, EFX_MAC_NSTATS
);
644 for (el
= 0; el
< mask_npages
; ++el
) {
645 el_min
= el
* EFX_MAC_STATS_MASK_BITS_PER_PAGE
;
647 el_min
+ (EFX_MAC_STATS_MASK_BITS_PER_PAGE
- 1);
648 if ((unsigned int)rngp
->first
> el_max
||
649 (unsigned int)rngp
->last
< el_min
)
651 low
= MAX((unsigned int)rngp
->first
, el_min
);
652 high
= MIN((unsigned int)rngp
->last
, el_max
);
653 width
= high
- low
+ 1;
655 (width
== EFX_MAC_STATS_MASK_BITS_PER_PAGE
) ?
656 (~0ULL) : (((1ULL << width
) - 1) << (low
- el_min
));
662 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
668 efx_mac_stats_mask_add_ranges(
669 __inout_bcount(mask_size
) uint32_t *maskp
,
670 __in
size_t mask_size
,
671 __in_ecount(rng_count
) const struct efx_mac_stats_range
*rngp
,
672 __in
unsigned int rng_count
)
677 for (i
= 0; i
< rng_count
; ++i
) {
678 if ((rc
= efx_mac_stats_mask_add_range(maskp
, mask_size
,
686 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
691 __checkReturn efx_rc_t
692 efx_mac_stats_get_mask(
694 __out_bcount(mask_size
) uint32_t *maskp
,
695 __in
size_t mask_size
)
697 efx_port_t
*epp
= &(enp
->en_port
);
698 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
701 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
702 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
703 EFSYS_ASSERT(maskp
!= NULL
);
704 EFSYS_ASSERT(mask_size
% sizeof (maskp
[0]) == 0);
706 (void) memset(maskp
, 0, mask_size
);
708 if ((rc
= emop
->emo_stats_get_mask(enp
, maskp
, mask_size
)) != 0)
714 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
719 __checkReturn efx_rc_t
723 efx_port_t
*epp
= &(enp
->en_port
);
724 const 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
);
729 EFSYS_ASSERT(emop
!= NULL
);
731 if ((rc
= emop
->emo_stats_clear(enp
)) != 0)
737 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
742 __checkReturn efx_rc_t
743 efx_mac_stats_upload(
745 __in efsys_mem_t
*esmp
)
747 efx_port_t
*epp
= &(enp
->en_port
);
748 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
751 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
752 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
753 EFSYS_ASSERT(emop
!= NULL
);
755 if ((rc
= emop
->emo_stats_upload(enp
, esmp
)) != 0)
761 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
766 __checkReturn efx_rc_t
767 efx_mac_stats_periodic(
769 __in efsys_mem_t
*esmp
,
770 __in
uint16_t period_ms
,
771 __in boolean_t events
)
773 efx_port_t
*epp
= &(enp
->en_port
);
774 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
777 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
778 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
780 EFSYS_ASSERT(emop
!= NULL
);
782 if (emop
->emo_stats_periodic
== NULL
) {
787 if ((rc
= emop
->emo_stats_periodic(enp
, esmp
, period_ms
, events
)) != 0)
795 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
801 __checkReturn efx_rc_t
802 efx_mac_stats_update(
804 __in efsys_mem_t
*esmp
,
805 __inout_ecount(EFX_MAC_NSTATS
) efsys_stat_t
*essp
,
806 __inout_opt
uint32_t *generationp
)
808 efx_port_t
*epp
= &(enp
->en_port
);
809 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
812 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
813 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
814 EFSYS_ASSERT(emop
!= NULL
);
816 rc
= emop
->emo_stats_update(enp
, esmp
, essp
, generationp
);
821 #endif /* EFSYS_OPT_MAC_STATS */
823 __checkReturn efx_rc_t
827 efx_port_t
*epp
= &(enp
->en_port
);
828 efx_mac_type_t type
= EFX_MAC_INVALID
;
829 const efx_mac_ops_t
*emop
;
832 switch (enp
->en_family
) {
834 case EFX_FAMILY_SIENA
:
835 emop
= &__efx_mac_siena_ops
;
836 type
= EFX_MAC_SIENA
;
838 #endif /* EFSYS_OPT_SIENA */
840 #if EFSYS_OPT_HUNTINGTON
841 case EFX_FAMILY_HUNTINGTON
:
842 emop
= &__efx_mac_ef10_ops
;
843 type
= EFX_MAC_HUNTINGTON
;
845 #endif /* EFSYS_OPT_HUNTINGTON */
847 #if EFSYS_OPT_MEDFORD
848 case EFX_FAMILY_MEDFORD
:
849 emop
= &__efx_mac_ef10_ops
;
850 type
= EFX_MAC_MEDFORD
;
852 #endif /* EFSYS_OPT_MEDFORD */
854 #if EFSYS_OPT_MEDFORD2
855 case EFX_FAMILY_MEDFORD2
:
856 emop
= &__efx_mac_ef10_ops
;
857 type
= EFX_MAC_MEDFORD2
;
859 #endif /* EFSYS_OPT_MEDFORD2 */
866 EFSYS_ASSERT(type
!= EFX_MAC_INVALID
);
867 EFSYS_ASSERT3U(type
, <, EFX_MAC_NTYPES
);
868 EFSYS_ASSERT(emop
!= NULL
);
871 epp
->ep_mac_type
= type
;
876 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
884 #define EFX_MAC_HASH_BITS (1 << 8)
886 /* Compute the multicast hash as used on Falcon and Siena. */
888 siena_mac_multicast_hash_compute(
889 __in_ecount(6*count
) uint8_t const *addrs
,
891 __out efx_oword_t
*hash_low
,
892 __out efx_oword_t
*hash_high
)
897 EFSYS_ASSERT(hash_low
!= NULL
);
898 EFSYS_ASSERT(hash_high
!= NULL
);
900 EFX_ZERO_OWORD(*hash_low
);
901 EFX_ZERO_OWORD(*hash_high
);
903 for (i
= 0; i
< count
; i
++) {
904 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
905 crc
= efx_crc32_calculate(0xffffffff, addrs
, EFX_MAC_ADDR_LEN
);
906 index
= crc
% EFX_MAC_HASH_BITS
;
908 EFX_SET_OWORD_BIT(*hash_low
, index
);
910 EFX_SET_OWORD_BIT(*hash_high
, index
- 128);
913 addrs
+= EFX_MAC_ADDR_LEN
;
917 static __checkReturn efx_rc_t
918 siena_mac_multicast_list_set(
921 efx_port_t
*epp
= &(enp
->en_port
);
922 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
923 efx_oword_t old_hash
[2];
926 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
927 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
929 memcpy(old_hash
, epp
->ep_multicst_hash
, sizeof (old_hash
));
931 siena_mac_multicast_hash_compute(
932 epp
->ep_mulcst_addr_list
,
933 epp
->ep_mulcst_addr_count
,
934 &epp
->ep_multicst_hash
[0],
935 &epp
->ep_multicst_hash
[1]);
937 if ((rc
= emop
->emo_reconfigure(enp
)) != 0)
943 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
945 memcpy(epp
->ep_multicst_hash
, old_hash
, sizeof (old_hash
));
950 #endif /* EFSYS_OPT_SIENA */