1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2020 Xilinx, Inc.
4 * Copyright(c) 2007-2019 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 */
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 /* EFX_OPTS_EF10() */
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
;
222 efx_mac_filter_get_all_ucast_mcast(
224 __out boolean_t
*all_unicst
,
225 __out boolean_t
*all_mulcst
)
227 efx_port_t
*epp
= &(enp
->en_port
);
229 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
230 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
232 *all_unicst
= epp
->ep_all_unicst_inserted
;
233 *all_mulcst
= epp
->ep_all_mulcst_inserted
;
236 __checkReturn efx_rc_t
239 __in boolean_t enabled
)
241 efx_port_t
*epp
= &(enp
->en_port
);
242 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
245 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
246 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
247 EFSYS_ASSERT(emop
!= NULL
);
249 if (epp
->ep_mac_drain
== enabled
)
252 epp
->ep_mac_drain
= enabled
;
254 if ((rc
= emop
->emo_reconfigure(enp
)) != 0)
260 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
265 __checkReturn efx_rc_t
268 __out boolean_t
*mac_upp
)
270 efx_port_t
*epp
= &(enp
->en_port
);
271 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
274 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
275 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
277 if ((rc
= emop
->emo_up(enp
, mac_upp
)) != 0)
283 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
288 __checkReturn efx_rc_t
291 __in
unsigned int fcntl
,
292 __in boolean_t autoneg
)
294 efx_port_t
*epp
= &(enp
->en_port
);
295 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
296 const efx_phy_ops_t
*epop
= epp
->ep_epop
;
297 unsigned int old_fcntl
;
298 boolean_t old_autoneg
;
299 unsigned int old_adv_cap
;
302 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
303 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
305 if ((fcntl
& ~(EFX_FCNTL_RESPOND
| EFX_FCNTL_GENERATE
)) != 0) {
311 * Ignore a request to set flow control auto-negotiation
312 * if the PHY doesn't support it.
314 if (~epp
->ep_phy_cap_mask
& (1 << EFX_PHY_CAP_AN
))
317 old_fcntl
= epp
->ep_fcntl
;
318 old_autoneg
= epp
->ep_fcntl_autoneg
;
319 old_adv_cap
= epp
->ep_adv_cap_mask
;
321 epp
->ep_fcntl
= fcntl
;
322 epp
->ep_fcntl_autoneg
= autoneg
;
325 * Always encode the flow control settings in the advertised
326 * capabilities even if we are not trying to auto-negotiate
327 * them and reconfigure both the PHY and the MAC.
329 if (fcntl
& EFX_FCNTL_RESPOND
)
330 epp
->ep_adv_cap_mask
|= (1 << EFX_PHY_CAP_PAUSE
|
331 1 << EFX_PHY_CAP_ASYM
);
333 epp
->ep_adv_cap_mask
&= ~(1 << EFX_PHY_CAP_PAUSE
|
334 1 << EFX_PHY_CAP_ASYM
);
336 if (fcntl
& EFX_FCNTL_GENERATE
)
337 epp
->ep_adv_cap_mask
^= (1 << EFX_PHY_CAP_ASYM
);
339 if ((rc
= epop
->epo_reconfigure(enp
)) != 0)
342 if ((rc
= emop
->emo_reconfigure(enp
)) != 0)
353 epp
->ep_fcntl
= old_fcntl
;
354 epp
->ep_fcntl_autoneg
= old_autoneg
;
355 epp
->ep_adv_cap_mask
= old_adv_cap
;
358 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
366 __out
unsigned int *fcntl_wantedp
,
367 __out
unsigned int *fcntl_linkp
)
369 efx_port_t
*epp
= &(enp
->en_port
);
370 unsigned int wanted
= 0;
372 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
373 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
376 * Decode the requested flow control settings from the PHY
377 * advertised capabilities.
379 if (epp
->ep_adv_cap_mask
& (1 << EFX_PHY_CAP_PAUSE
))
380 wanted
= EFX_FCNTL_RESPOND
| EFX_FCNTL_GENERATE
;
381 if (epp
->ep_adv_cap_mask
& (1 << EFX_PHY_CAP_ASYM
))
382 wanted
^= EFX_FCNTL_GENERATE
;
384 *fcntl_linkp
= epp
->ep_fcntl
;
385 *fcntl_wantedp
= wanted
;
388 __checkReturn efx_rc_t
389 efx_mac_multicast_list_set(
391 __in_ecount(6*count
) uint8_t const *addrs
,
394 efx_port_t
*epp
= &(enp
->en_port
);
395 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
396 uint8_t *old_mulcst_addr_list
= NULL
;
397 uint32_t old_mulcst_addr_count
;
400 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
401 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
403 if (count
> EFX_MAC_MULTICAST_LIST_MAX
) {
408 old_mulcst_addr_count
= epp
->ep_mulcst_addr_count
;
409 if (old_mulcst_addr_count
> 0) {
410 /* Allocate memory to store old list (instead of using stack) */
411 EFSYS_KMEM_ALLOC(enp
->en_esip
,
412 old_mulcst_addr_count
* EFX_MAC_ADDR_LEN
,
413 old_mulcst_addr_list
);
414 if (old_mulcst_addr_list
== NULL
) {
419 /* Save the old list in case we need to rollback */
420 memcpy(old_mulcst_addr_list
, epp
->ep_mulcst_addr_list
,
421 old_mulcst_addr_count
* EFX_MAC_ADDR_LEN
);
424 /* Store the new list */
425 memcpy(epp
->ep_mulcst_addr_list
, addrs
,
426 count
* EFX_MAC_ADDR_LEN
);
427 epp
->ep_mulcst_addr_count
= count
;
429 if ((rc
= emop
->emo_multicast_list_set(enp
)) != 0)
432 if (old_mulcst_addr_count
> 0) {
433 EFSYS_KMEM_FREE(enp
->en_esip
,
434 old_mulcst_addr_count
* EFX_MAC_ADDR_LEN
,
435 old_mulcst_addr_list
);
443 /* Restore original list on failure */
444 epp
->ep_mulcst_addr_count
= old_mulcst_addr_count
;
445 if (old_mulcst_addr_count
> 0) {
446 memcpy(epp
->ep_mulcst_addr_list
, old_mulcst_addr_list
,
447 old_mulcst_addr_count
* EFX_MAC_ADDR_LEN
);
449 EFSYS_KMEM_FREE(enp
->en_esip
,
450 old_mulcst_addr_count
* EFX_MAC_ADDR_LEN
,
451 old_mulcst_addr_list
);
458 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
464 __checkReturn efx_rc_t
465 efx_mac_filter_default_rxq_set(
468 __in boolean_t using_rss
)
470 efx_port_t
*epp
= &(enp
->en_port
);
471 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
474 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
475 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
477 if (emop
->emo_filter_default_rxq_set
!= NULL
) {
478 rc
= emop
->emo_filter_default_rxq_set(enp
, erp
, using_rss
);
486 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
492 efx_mac_filter_default_rxq_clear(
495 efx_port_t
*epp
= &(enp
->en_port
);
496 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
498 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
499 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
501 if (emop
->emo_filter_default_rxq_clear
!= NULL
)
502 emop
->emo_filter_default_rxq_clear(enp
);
506 #if EFSYS_OPT_MAC_STATS
510 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
511 static const char * const __efx_mac_stat_name
[] = {
520 "rx_128_to_255_pkts",
521 "rx_256_to_511_pkts",
522 "rx_512_to_1023_pkts",
523 "rx_1024_to_15xx_pkts",
528 "rx_false_carrier_errors",
531 "rx_internal_errors",
542 "rx_nodesc_drop_cnt",
551 "tx_128_to_255_pkts",
552 "tx_256_to_511_pkts",
553 "tx_512_to_1023_pkts",
554 "tx_1024_to_15xx_pkts",
563 "pm_trunc_bb_overflow",
564 "pm_discard_bb_overflow",
565 "pm_trunc_vfifo_full",
566 "pm_discard_vfifo_full",
569 "pm_discard_mapping",
570 "rxdp_q_disabled_pkts",
571 "rxdp_di_dropped_pkts",
572 "rxdp_streaming_pkts",
575 "vadapter_rx_unicast_packets",
576 "vadapter_rx_unicast_bytes",
577 "vadapter_rx_multicast_packets",
578 "vadapter_rx_multicast_bytes",
579 "vadapter_rx_broadcast_packets",
580 "vadapter_rx_broadcast_bytes",
581 "vadapter_rx_bad_packets",
582 "vadapter_rx_bad_bytes",
583 "vadapter_rx_overflow",
584 "vadapter_tx_unicast_packets",
585 "vadapter_tx_unicast_bytes",
586 "vadapter_tx_multicast_packets",
587 "vadapter_tx_multicast_bytes",
588 "vadapter_tx_broadcast_packets",
589 "vadapter_tx_broadcast_bytes",
590 "vadapter_tx_bad_packets",
591 "vadapter_tx_bad_bytes",
592 "vadapter_tx_overflow",
593 "fec_uncorrected_errors",
594 "fec_corrected_errors",
595 "fec_corrected_symbols_lane0",
596 "fec_corrected_symbols_lane1",
597 "fec_corrected_symbols_lane2",
598 "fec_corrected_symbols_lane3",
599 "ctpio_vi_busy_fallback",
600 "ctpio_long_write_success",
601 "ctpio_missing_dbell_fail",
602 "ctpio_overflow_fail",
603 "ctpio_underflow_fail",
604 "ctpio_timeout_fail",
605 "ctpio_noncontig_wr_fail",
606 "ctpio_frm_clobber_fail",
607 "ctpio_invalid_wr_fail",
608 "ctpio_vi_clobber_fallback",
609 "ctpio_unqualified_fallback",
610 "ctpio_runt_fallback",
615 "rxdp_scatter_disabled_trunc",
619 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
621 __checkReturn
const char *
624 __in
unsigned int id
)
626 _NOTE(ARGUNUSED(enp
))
627 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
629 EFSYS_ASSERT3U(id
, <, EFX_MAC_NSTATS
);
630 return (__efx_mac_stat_name
[id
]);
633 #endif /* EFSYS_OPT_NAMES */
636 efx_mac_stats_mask_add_range(
637 __inout_bcount(mask_size
) uint32_t *maskp
,
638 __in
size_t mask_size
,
639 __in
const struct efx_mac_stats_range
*rngp
)
641 unsigned int mask_npages
= mask_size
/ sizeof (*maskp
);
650 if ((mask_npages
* EFX_MAC_STATS_MASK_BITS_PER_PAGE
) <=
651 (unsigned int)rngp
->last
) {
656 EFSYS_ASSERT3U(rngp
->first
, <=, rngp
->last
);
657 EFSYS_ASSERT3U(rngp
->last
, <, EFX_MAC_NSTATS
);
659 for (el
= 0; el
< mask_npages
; ++el
) {
660 el_min
= el
* EFX_MAC_STATS_MASK_BITS_PER_PAGE
;
662 el_min
+ (EFX_MAC_STATS_MASK_BITS_PER_PAGE
- 1);
663 if ((unsigned int)rngp
->first
> el_max
||
664 (unsigned int)rngp
->last
< el_min
)
666 low
= MAX((unsigned int)rngp
->first
, el_min
);
667 high
= MIN((unsigned int)rngp
->last
, el_max
);
668 width
= high
- low
+ 1;
670 (width
== EFX_MAC_STATS_MASK_BITS_PER_PAGE
) ?
671 (~0ULL) : (((1ULL << width
) - 1) << (low
- el_min
));
677 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
683 efx_mac_stats_mask_add_ranges(
684 __inout_bcount(mask_size
) uint32_t *maskp
,
685 __in
size_t mask_size
,
686 __in_ecount(rng_count
) const struct efx_mac_stats_range
*rngp
,
687 __in
unsigned int rng_count
)
692 for (i
= 0; i
< rng_count
; ++i
) {
693 if ((rc
= efx_mac_stats_mask_add_range(maskp
, mask_size
,
701 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
706 __checkReturn efx_rc_t
707 efx_mac_stats_get_mask(
709 __out_bcount(mask_size
) uint32_t *maskp
,
710 __in
size_t mask_size
)
712 efx_port_t
*epp
= &(enp
->en_port
);
713 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
716 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
717 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
718 EFSYS_ASSERT(maskp
!= NULL
);
719 EFSYS_ASSERT(mask_size
% sizeof (maskp
[0]) == 0);
721 (void) memset(maskp
, 0, mask_size
);
723 if ((rc
= emop
->emo_stats_get_mask(enp
, maskp
, mask_size
)) != 0)
729 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
734 __checkReturn efx_rc_t
738 efx_port_t
*epp
= &(enp
->en_port
);
739 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
742 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
743 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
744 EFSYS_ASSERT(emop
!= NULL
);
746 if ((rc
= emop
->emo_stats_clear(enp
)) != 0)
752 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
757 __checkReturn efx_rc_t
758 efx_mac_stats_upload(
760 __in efsys_mem_t
*esmp
)
762 efx_port_t
*epp
= &(enp
->en_port
);
763 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
766 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
767 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
768 EFSYS_ASSERT(emop
!= NULL
);
770 if ((rc
= emop
->emo_stats_upload(enp
, esmp
)) != 0)
776 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
781 __checkReturn efx_rc_t
782 efx_mac_stats_periodic(
784 __in efsys_mem_t
*esmp
,
785 __in
uint16_t period_ms
,
786 __in boolean_t events
)
788 efx_port_t
*epp
= &(enp
->en_port
);
789 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
792 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
793 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
795 EFSYS_ASSERT(emop
!= NULL
);
797 if (emop
->emo_stats_periodic
== NULL
) {
802 if ((rc
= emop
->emo_stats_periodic(enp
, esmp
, period_ms
, events
)) != 0)
810 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
816 __checkReturn efx_rc_t
817 efx_mac_stats_update(
819 __in efsys_mem_t
*esmp
,
820 __inout_ecount(EFX_MAC_NSTATS
) efsys_stat_t
*essp
,
821 __inout_opt
uint32_t *generationp
)
823 efx_port_t
*epp
= &(enp
->en_port
);
824 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
827 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
828 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
829 EFSYS_ASSERT(emop
!= NULL
);
831 rc
= emop
->emo_stats_update(enp
, esmp
, essp
, generationp
);
836 #endif /* EFSYS_OPT_MAC_STATS */
838 __checkReturn efx_rc_t
842 efx_port_t
*epp
= &(enp
->en_port
);
843 efx_mac_type_t type
= EFX_MAC_INVALID
;
844 const efx_mac_ops_t
*emop
;
847 switch (enp
->en_family
) {
849 case EFX_FAMILY_SIENA
:
850 emop
= &__efx_mac_siena_ops
;
851 type
= EFX_MAC_SIENA
;
853 #endif /* EFSYS_OPT_SIENA */
855 #if EFSYS_OPT_HUNTINGTON
856 case EFX_FAMILY_HUNTINGTON
:
857 emop
= &__efx_mac_ef10_ops
;
858 type
= EFX_MAC_HUNTINGTON
;
860 #endif /* EFSYS_OPT_HUNTINGTON */
862 #if EFSYS_OPT_MEDFORD
863 case EFX_FAMILY_MEDFORD
:
864 emop
= &__efx_mac_ef10_ops
;
865 type
= EFX_MAC_MEDFORD
;
867 #endif /* EFSYS_OPT_MEDFORD */
869 #if EFSYS_OPT_MEDFORD2
870 case EFX_FAMILY_MEDFORD2
:
871 emop
= &__efx_mac_ef10_ops
;
872 type
= EFX_MAC_MEDFORD2
;
874 #endif /* EFSYS_OPT_MEDFORD2 */
881 EFSYS_ASSERT(type
!= EFX_MAC_INVALID
);
882 EFSYS_ASSERT3U(type
, <, EFX_MAC_NTYPES
);
883 EFSYS_ASSERT(emop
!= NULL
);
886 epp
->ep_mac_type
= type
;
891 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
899 #define EFX_MAC_HASH_BITS (1 << 8)
901 /* Compute the multicast hash as used on Falcon and Siena. */
903 siena_mac_multicast_hash_compute(
904 __in_ecount(6*count
) uint8_t const *addrs
,
906 __out efx_oword_t
*hash_low
,
907 __out efx_oword_t
*hash_high
)
912 EFSYS_ASSERT(hash_low
!= NULL
);
913 EFSYS_ASSERT(hash_high
!= NULL
);
915 EFX_ZERO_OWORD(*hash_low
);
916 EFX_ZERO_OWORD(*hash_high
);
918 for (i
= 0; i
< count
; i
++) {
919 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
920 crc
= efx_crc32_calculate(0xffffffff, addrs
, EFX_MAC_ADDR_LEN
);
921 index
= crc
% EFX_MAC_HASH_BITS
;
923 EFX_SET_OWORD_BIT(*hash_low
, index
);
925 EFX_SET_OWORD_BIT(*hash_high
, index
- 128);
928 addrs
+= EFX_MAC_ADDR_LEN
;
932 static __checkReturn efx_rc_t
933 siena_mac_multicast_list_set(
936 efx_port_t
*epp
= &(enp
->en_port
);
937 const efx_mac_ops_t
*emop
= epp
->ep_emop
;
938 efx_oword_t old_hash
[2];
941 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
942 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PORT
);
944 memcpy(old_hash
, epp
->ep_multicst_hash
, sizeof (old_hash
));
946 siena_mac_multicast_hash_compute(
947 epp
->ep_mulcst_addr_list
,
948 epp
->ep_mulcst_addr_count
,
949 &epp
->ep_multicst_hash
[0],
950 &epp
->ep_multicst_hash
[1]);
952 if ((rc
= emop
->emo_reconfigure(enp
)) != 0)
958 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
960 memcpy(epp
->ep_multicst_hash
, old_hash
, sizeof (old_hash
));
965 #endif /* EFSYS_OPT_SIENA */