15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko *
3672386c1SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko * Copyright(c) 2007-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko */
65e111ed8SAndrew Rybchenko
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko
105e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
115e111ed8SAndrew Rybchenko
125e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
135e111ed8SAndrew Rybchenko siena_mac_multicast_list_set(
145e111ed8SAndrew Rybchenko __in efx_nic_t *enp);
155e111ed8SAndrew Rybchenko
165e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
175e111ed8SAndrew Rybchenko
185e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
195e111ed8SAndrew Rybchenko static const efx_mac_ops_t __efx_mac_siena_ops = {
205e111ed8SAndrew Rybchenko siena_mac_poll, /* emo_poll */
215e111ed8SAndrew Rybchenko siena_mac_up, /* emo_up */
225e111ed8SAndrew Rybchenko siena_mac_reconfigure, /* emo_addr_set */
235e111ed8SAndrew Rybchenko siena_mac_reconfigure, /* emo_pdu_set */
245e111ed8SAndrew Rybchenko siena_mac_pdu_get, /* emo_pdu_get */
255e111ed8SAndrew Rybchenko siena_mac_reconfigure, /* emo_reconfigure */
265e111ed8SAndrew Rybchenko siena_mac_multicast_list_set, /* emo_multicast_list_set */
275e111ed8SAndrew Rybchenko NULL, /* emo_filter_set_default_rxq */
285e111ed8SAndrew Rybchenko NULL, /* emo_filter_default_rxq_clear */
295e111ed8SAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
305e111ed8SAndrew Rybchenko siena_mac_loopback_set, /* emo_loopback_set */
315e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_LOOPBACK */
325e111ed8SAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
335e111ed8SAndrew Rybchenko siena_mac_stats_get_mask, /* emo_stats_get_mask */
345e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_clear, /* emo_stats_clear */
355e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_upload, /* emo_stats_upload */
365e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
375e111ed8SAndrew Rybchenko siena_mac_stats_update /* emo_stats_update */
385e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MAC_STATS */
395e111ed8SAndrew Rybchenko };
405e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
415e111ed8SAndrew Rybchenko
425e111ed8SAndrew Rybchenko #if EFX_OPTS_EF10()
435e111ed8SAndrew Rybchenko static const efx_mac_ops_t __efx_mac_ef10_ops = {
445e111ed8SAndrew Rybchenko ef10_mac_poll, /* emo_poll */
455e111ed8SAndrew Rybchenko ef10_mac_up, /* emo_up */
465e111ed8SAndrew Rybchenko ef10_mac_addr_set, /* emo_addr_set */
475e111ed8SAndrew Rybchenko ef10_mac_pdu_set, /* emo_pdu_set */
485e111ed8SAndrew Rybchenko ef10_mac_pdu_get, /* emo_pdu_get */
495e111ed8SAndrew Rybchenko ef10_mac_reconfigure, /* emo_reconfigure */
505e111ed8SAndrew Rybchenko ef10_mac_multicast_list_set, /* emo_multicast_list_set */
515e111ed8SAndrew Rybchenko ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
525e111ed8SAndrew Rybchenko ef10_mac_filter_default_rxq_clear,
535e111ed8SAndrew Rybchenko /* emo_filter_default_rxq_clear */
545e111ed8SAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
555e111ed8SAndrew Rybchenko ef10_mac_loopback_set, /* emo_loopback_set */
565e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_LOOPBACK */
575e111ed8SAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
585e111ed8SAndrew Rybchenko ef10_mac_stats_get_mask, /* emo_stats_get_mask */
595e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_clear, /* emo_stats_clear */
605e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_upload, /* emo_stats_upload */
615e111ed8SAndrew Rybchenko efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
625e111ed8SAndrew Rybchenko ef10_mac_stats_update /* emo_stats_update */
635e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MAC_STATS */
645e111ed8SAndrew Rybchenko };
655e111ed8SAndrew Rybchenko #endif /* EFX_OPTS_EF10() */
665e111ed8SAndrew Rybchenko
67de0d268fSAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
68de0d268fSAndrew Rybchenko static const efx_mac_ops_t __efx_mac_rhead_ops = {
69de0d268fSAndrew Rybchenko ef10_mac_poll, /* emo_poll */
70de0d268fSAndrew Rybchenko ef10_mac_up, /* emo_up */
71de0d268fSAndrew Rybchenko ef10_mac_addr_set, /* emo_addr_set */
72de0d268fSAndrew Rybchenko ef10_mac_pdu_set, /* emo_pdu_set */
73de0d268fSAndrew Rybchenko ef10_mac_pdu_get, /* emo_pdu_get */
74de0d268fSAndrew Rybchenko ef10_mac_reconfigure, /* emo_reconfigure */
75de0d268fSAndrew Rybchenko ef10_mac_multicast_list_set, /* emo_multicast_list_set */
76de0d268fSAndrew Rybchenko ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
77de0d268fSAndrew Rybchenko ef10_mac_filter_default_rxq_clear,
78de0d268fSAndrew Rybchenko /* emo_filter_default_rxq_clear */
79de0d268fSAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
80de0d268fSAndrew Rybchenko ef10_mac_loopback_set, /* emo_loopback_set */
81de0d268fSAndrew Rybchenko #endif /* EFSYS_OPT_LOOPBACK */
82de0d268fSAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
83de0d268fSAndrew Rybchenko ef10_mac_stats_get_mask, /* emo_stats_get_mask */
84de0d268fSAndrew Rybchenko efx_mcdi_mac_stats_clear, /* emo_stats_clear */
85de0d268fSAndrew Rybchenko efx_mcdi_mac_stats_upload, /* emo_stats_upload */
86de0d268fSAndrew Rybchenko efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
87de0d268fSAndrew Rybchenko ef10_mac_stats_update /* emo_stats_update */
88de0d268fSAndrew Rybchenko #endif /* EFSYS_OPT_MAC_STATS */
89de0d268fSAndrew Rybchenko };
90de0d268fSAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD */
91de0d268fSAndrew Rybchenko
925e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_pdu_set(__in efx_nic_t * enp,__in size_t pdu)935e111ed8SAndrew Rybchenko efx_mac_pdu_set(
945e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
955e111ed8SAndrew Rybchenko __in size_t pdu)
965e111ed8SAndrew Rybchenko {
975e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
985e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
995e111ed8SAndrew Rybchenko uint32_t old_pdu;
1005e111ed8SAndrew Rybchenko efx_rc_t rc;
1015e111ed8SAndrew Rybchenko
1025e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1035e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
1045e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
1055e111ed8SAndrew Rybchenko
1065e111ed8SAndrew Rybchenko if (pdu < EFX_MAC_PDU_MIN) {
1075e111ed8SAndrew Rybchenko rc = EINVAL;
1085e111ed8SAndrew Rybchenko goto fail1;
1095e111ed8SAndrew Rybchenko }
1105e111ed8SAndrew Rybchenko
1115e111ed8SAndrew Rybchenko if (pdu > EFX_MAC_PDU_MAX) {
1125e111ed8SAndrew Rybchenko rc = EINVAL;
1135e111ed8SAndrew Rybchenko goto fail2;
1145e111ed8SAndrew Rybchenko }
1155e111ed8SAndrew Rybchenko
1165e111ed8SAndrew Rybchenko old_pdu = epp->ep_mac_pdu;
1175e111ed8SAndrew Rybchenko epp->ep_mac_pdu = (uint32_t)pdu;
1185e111ed8SAndrew Rybchenko if ((rc = emop->emo_pdu_set(enp)) != 0)
1195e111ed8SAndrew Rybchenko goto fail3;
1205e111ed8SAndrew Rybchenko
1215e111ed8SAndrew Rybchenko return (0);
1225e111ed8SAndrew Rybchenko
1235e111ed8SAndrew Rybchenko fail3:
1245e111ed8SAndrew Rybchenko EFSYS_PROBE(fail3);
1255e111ed8SAndrew Rybchenko
1265e111ed8SAndrew Rybchenko epp->ep_mac_pdu = old_pdu;
1275e111ed8SAndrew Rybchenko
1285e111ed8SAndrew Rybchenko fail2:
1295e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
1305e111ed8SAndrew Rybchenko fail1:
1315e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1325e111ed8SAndrew Rybchenko
1335e111ed8SAndrew Rybchenko return (rc);
1345e111ed8SAndrew Rybchenko }
1355e111ed8SAndrew Rybchenko
1365e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_pdu_get(__in efx_nic_t * enp,__out size_t * pdu)1375e111ed8SAndrew Rybchenko efx_mac_pdu_get(
1385e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1395e111ed8SAndrew Rybchenko __out size_t *pdu)
1405e111ed8SAndrew Rybchenko {
1415e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
1425e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
1435e111ed8SAndrew Rybchenko efx_rc_t rc;
1445e111ed8SAndrew Rybchenko
1455e111ed8SAndrew Rybchenko if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
1465e111ed8SAndrew Rybchenko goto fail1;
1475e111ed8SAndrew Rybchenko
1485e111ed8SAndrew Rybchenko return (0);
1495e111ed8SAndrew Rybchenko
1505e111ed8SAndrew Rybchenko fail1:
1515e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1525e111ed8SAndrew Rybchenko
1535e111ed8SAndrew Rybchenko return (rc);
1545e111ed8SAndrew Rybchenko }
1555e111ed8SAndrew Rybchenko
1565e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_addr_set(__in efx_nic_t * enp,__in uint8_t * addr)1575e111ed8SAndrew Rybchenko efx_mac_addr_set(
1585e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1595e111ed8SAndrew Rybchenko __in uint8_t *addr)
1605e111ed8SAndrew Rybchenko {
1615e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
1625e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
1635e111ed8SAndrew Rybchenko uint8_t old_addr[6];
1645e111ed8SAndrew Rybchenko uint32_t oui;
1655e111ed8SAndrew Rybchenko efx_rc_t rc;
1665e111ed8SAndrew Rybchenko
1675e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1685e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
1695e111ed8SAndrew Rybchenko
1705e111ed8SAndrew Rybchenko if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
1715e111ed8SAndrew Rybchenko rc = EINVAL;
1725e111ed8SAndrew Rybchenko goto fail1;
1735e111ed8SAndrew Rybchenko }
1745e111ed8SAndrew Rybchenko
1755e111ed8SAndrew Rybchenko oui = addr[0] << 16 | addr[1] << 8 | addr[2];
1765e111ed8SAndrew Rybchenko if (oui == 0x000000) {
1775e111ed8SAndrew Rybchenko rc = EINVAL;
1785e111ed8SAndrew Rybchenko goto fail2;
1795e111ed8SAndrew Rybchenko }
1805e111ed8SAndrew Rybchenko
1815e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
1825e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
1835e111ed8SAndrew Rybchenko if ((rc = emop->emo_addr_set(enp)) != 0)
1845e111ed8SAndrew Rybchenko goto fail3;
1855e111ed8SAndrew Rybchenko
1865e111ed8SAndrew Rybchenko return (0);
1875e111ed8SAndrew Rybchenko
1885e111ed8SAndrew Rybchenko fail3:
1895e111ed8SAndrew Rybchenko EFSYS_PROBE(fail3);
1905e111ed8SAndrew Rybchenko
1915e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
1925e111ed8SAndrew Rybchenko
1935e111ed8SAndrew Rybchenko fail2:
1945e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
1955e111ed8SAndrew Rybchenko fail1:
1965e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1975e111ed8SAndrew Rybchenko
1985e111ed8SAndrew Rybchenko return (rc);
1995e111ed8SAndrew Rybchenko }
2005e111ed8SAndrew Rybchenko
2015e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_filter_set(__in efx_nic_t * enp,__in boolean_t all_unicst,__in boolean_t mulcst,__in boolean_t all_mulcst,__in boolean_t brdcst)2025e111ed8SAndrew Rybchenko efx_mac_filter_set(
2035e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2045e111ed8SAndrew Rybchenko __in boolean_t all_unicst,
2055e111ed8SAndrew Rybchenko __in boolean_t mulcst,
2065e111ed8SAndrew Rybchenko __in boolean_t all_mulcst,
2075e111ed8SAndrew Rybchenko __in boolean_t brdcst)
2085e111ed8SAndrew Rybchenko {
2095e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
2105e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
2115e111ed8SAndrew Rybchenko boolean_t old_all_unicst;
2125e111ed8SAndrew Rybchenko boolean_t old_mulcst;
2135e111ed8SAndrew Rybchenko boolean_t old_all_mulcst;
2145e111ed8SAndrew Rybchenko boolean_t old_brdcst;
2155e111ed8SAndrew Rybchenko efx_rc_t rc;
2165e111ed8SAndrew Rybchenko
2175e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
2185e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
2195e111ed8SAndrew Rybchenko
2205e111ed8SAndrew Rybchenko old_all_unicst = epp->ep_all_unicst;
2215e111ed8SAndrew Rybchenko old_mulcst = epp->ep_mulcst;
2225e111ed8SAndrew Rybchenko old_all_mulcst = epp->ep_all_mulcst;
2235e111ed8SAndrew Rybchenko old_brdcst = epp->ep_brdcst;
2245e111ed8SAndrew Rybchenko
2255e111ed8SAndrew Rybchenko epp->ep_all_unicst = all_unicst;
2265e111ed8SAndrew Rybchenko epp->ep_mulcst = mulcst;
2275e111ed8SAndrew Rybchenko epp->ep_all_mulcst = all_mulcst;
2285e111ed8SAndrew Rybchenko epp->ep_brdcst = brdcst;
2295e111ed8SAndrew Rybchenko
2305e111ed8SAndrew Rybchenko if ((rc = emop->emo_reconfigure(enp)) != 0)
2315e111ed8SAndrew Rybchenko goto fail1;
2325e111ed8SAndrew Rybchenko
2335e111ed8SAndrew Rybchenko return (0);
2345e111ed8SAndrew Rybchenko
2355e111ed8SAndrew Rybchenko fail1:
2365e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2375e111ed8SAndrew Rybchenko
2385e111ed8SAndrew Rybchenko epp->ep_all_unicst = old_all_unicst;
2395e111ed8SAndrew Rybchenko epp->ep_mulcst = old_mulcst;
2405e111ed8SAndrew Rybchenko epp->ep_all_mulcst = old_all_mulcst;
2415e111ed8SAndrew Rybchenko epp->ep_brdcst = old_brdcst;
2425e111ed8SAndrew Rybchenko
2435e111ed8SAndrew Rybchenko return (rc);
2445e111ed8SAndrew Rybchenko }
2455e111ed8SAndrew Rybchenko
2465e111ed8SAndrew Rybchenko void
efx_mac_filter_get_all_ucast_mcast(__in efx_nic_t * enp,__out boolean_t * all_unicst,__out boolean_t * all_mulcst)2475e111ed8SAndrew Rybchenko efx_mac_filter_get_all_ucast_mcast(
2485e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2495e111ed8SAndrew Rybchenko __out boolean_t *all_unicst,
2505e111ed8SAndrew Rybchenko __out boolean_t *all_mulcst)
2515e111ed8SAndrew Rybchenko {
2525e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
2535e111ed8SAndrew Rybchenko
2545e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
2555e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
2565e111ed8SAndrew Rybchenko
2575e111ed8SAndrew Rybchenko *all_unicst = epp->ep_all_unicst_inserted;
2585e111ed8SAndrew Rybchenko *all_mulcst = epp->ep_all_mulcst_inserted;
2595e111ed8SAndrew Rybchenko }
2605e111ed8SAndrew Rybchenko
2615e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_drain(__in efx_nic_t * enp,__in boolean_t enabled)2625e111ed8SAndrew Rybchenko efx_mac_drain(
2635e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2645e111ed8SAndrew Rybchenko __in boolean_t enabled)
2655e111ed8SAndrew Rybchenko {
2665e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
2675e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
2685e111ed8SAndrew Rybchenko efx_rc_t rc;
2695e111ed8SAndrew Rybchenko
2705e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
2715e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
2725e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
2735e111ed8SAndrew Rybchenko
2745e111ed8SAndrew Rybchenko if (epp->ep_mac_drain == enabled)
2755e111ed8SAndrew Rybchenko return (0);
2765e111ed8SAndrew Rybchenko
2775e111ed8SAndrew Rybchenko epp->ep_mac_drain = enabled;
2785e111ed8SAndrew Rybchenko
2795e111ed8SAndrew Rybchenko if ((rc = emop->emo_reconfigure(enp)) != 0)
2805e111ed8SAndrew Rybchenko goto fail1;
2815e111ed8SAndrew Rybchenko
2825e111ed8SAndrew Rybchenko return (0);
2835e111ed8SAndrew Rybchenko
2845e111ed8SAndrew Rybchenko fail1:
2855e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2865e111ed8SAndrew Rybchenko
2875e111ed8SAndrew Rybchenko return (rc);
2885e111ed8SAndrew Rybchenko }
2895e111ed8SAndrew Rybchenko
2905e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_up(__in efx_nic_t * enp,__out boolean_t * mac_upp)2915e111ed8SAndrew Rybchenko efx_mac_up(
2925e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2935e111ed8SAndrew Rybchenko __out boolean_t *mac_upp)
2945e111ed8SAndrew Rybchenko {
2955e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
2965e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
2975e111ed8SAndrew Rybchenko efx_rc_t rc;
2985e111ed8SAndrew Rybchenko
2995e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
3005e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
3015e111ed8SAndrew Rybchenko
3025e111ed8SAndrew Rybchenko if ((rc = emop->emo_up(enp, mac_upp)) != 0)
3035e111ed8SAndrew Rybchenko goto fail1;
3045e111ed8SAndrew Rybchenko
3055e111ed8SAndrew Rybchenko return (0);
3065e111ed8SAndrew Rybchenko
3075e111ed8SAndrew Rybchenko fail1:
3085e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
3095e111ed8SAndrew Rybchenko
3105e111ed8SAndrew Rybchenko return (rc);
3115e111ed8SAndrew Rybchenko }
3125e111ed8SAndrew Rybchenko
3135e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_fcntl_set(__in efx_nic_t * enp,__in unsigned int fcntl,__in boolean_t autoneg)3145e111ed8SAndrew Rybchenko efx_mac_fcntl_set(
3155e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
3165e111ed8SAndrew Rybchenko __in unsigned int fcntl,
3175e111ed8SAndrew Rybchenko __in boolean_t autoneg)
3185e111ed8SAndrew Rybchenko {
3195e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
3205e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
3215e111ed8SAndrew Rybchenko const efx_phy_ops_t *epop = epp->ep_epop;
3225e111ed8SAndrew Rybchenko unsigned int old_fcntl;
3235e111ed8SAndrew Rybchenko boolean_t old_autoneg;
3245e111ed8SAndrew Rybchenko unsigned int old_adv_cap;
3255e111ed8SAndrew Rybchenko efx_rc_t rc;
3265e111ed8SAndrew Rybchenko
3275e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
3285e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
3295e111ed8SAndrew Rybchenko
3305e111ed8SAndrew Rybchenko if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
3315e111ed8SAndrew Rybchenko rc = EINVAL;
3325e111ed8SAndrew Rybchenko goto fail1;
3335e111ed8SAndrew Rybchenko }
3345e111ed8SAndrew Rybchenko
3355e111ed8SAndrew Rybchenko /*
3365e111ed8SAndrew Rybchenko * Ignore a request to set flow control auto-negotiation
3375e111ed8SAndrew Rybchenko * if the PHY doesn't support it.
3385e111ed8SAndrew Rybchenko */
3395e111ed8SAndrew Rybchenko if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
3405e111ed8SAndrew Rybchenko autoneg = B_FALSE;
3415e111ed8SAndrew Rybchenko
3425e111ed8SAndrew Rybchenko old_fcntl = epp->ep_fcntl;
3435e111ed8SAndrew Rybchenko old_autoneg = epp->ep_fcntl_autoneg;
3445e111ed8SAndrew Rybchenko old_adv_cap = epp->ep_adv_cap_mask;
3455e111ed8SAndrew Rybchenko
3465e111ed8SAndrew Rybchenko epp->ep_fcntl = fcntl;
3475e111ed8SAndrew Rybchenko epp->ep_fcntl_autoneg = autoneg;
3485e111ed8SAndrew Rybchenko
3495e111ed8SAndrew Rybchenko /*
3505e111ed8SAndrew Rybchenko * Always encode the flow control settings in the advertised
3515e111ed8SAndrew Rybchenko * capabilities even if we are not trying to auto-negotiate
3525e111ed8SAndrew Rybchenko * them and reconfigure both the PHY and the MAC.
3535e111ed8SAndrew Rybchenko */
3545e111ed8SAndrew Rybchenko if (fcntl & EFX_FCNTL_RESPOND)
3555e111ed8SAndrew Rybchenko epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
3565e111ed8SAndrew Rybchenko 1 << EFX_PHY_CAP_ASYM);
3575e111ed8SAndrew Rybchenko else
3585e111ed8SAndrew Rybchenko epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
3595e111ed8SAndrew Rybchenko 1 << EFX_PHY_CAP_ASYM);
3605e111ed8SAndrew Rybchenko
3615e111ed8SAndrew Rybchenko if (fcntl & EFX_FCNTL_GENERATE)
3625e111ed8SAndrew Rybchenko epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
3635e111ed8SAndrew Rybchenko
3645e111ed8SAndrew Rybchenko if ((rc = epop->epo_reconfigure(enp)) != 0)
3655e111ed8SAndrew Rybchenko goto fail2;
3665e111ed8SAndrew Rybchenko
3675e111ed8SAndrew Rybchenko if ((rc = emop->emo_reconfigure(enp)) != 0)
3685e111ed8SAndrew Rybchenko goto fail3;
3695e111ed8SAndrew Rybchenko
3705e111ed8SAndrew Rybchenko return (0);
3715e111ed8SAndrew Rybchenko
3725e111ed8SAndrew Rybchenko fail3:
3735e111ed8SAndrew Rybchenko EFSYS_PROBE(fail3);
3745e111ed8SAndrew Rybchenko
3755e111ed8SAndrew Rybchenko fail2:
3765e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
3775e111ed8SAndrew Rybchenko
3785e111ed8SAndrew Rybchenko epp->ep_fcntl = old_fcntl;
3795e111ed8SAndrew Rybchenko epp->ep_fcntl_autoneg = old_autoneg;
3805e111ed8SAndrew Rybchenko epp->ep_adv_cap_mask = old_adv_cap;
3815e111ed8SAndrew Rybchenko
3825e111ed8SAndrew Rybchenko fail1:
3835e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
3845e111ed8SAndrew Rybchenko
3855e111ed8SAndrew Rybchenko return (rc);
3865e111ed8SAndrew Rybchenko }
3875e111ed8SAndrew Rybchenko
3885e111ed8SAndrew Rybchenko void
efx_mac_fcntl_get(__in efx_nic_t * enp,__out unsigned int * fcntl_wantedp,__out unsigned int * fcntl_linkp)3895e111ed8SAndrew Rybchenko efx_mac_fcntl_get(
3905e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
3915e111ed8SAndrew Rybchenko __out unsigned int *fcntl_wantedp,
3925e111ed8SAndrew Rybchenko __out unsigned int *fcntl_linkp)
3935e111ed8SAndrew Rybchenko {
3945e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
3955e111ed8SAndrew Rybchenko unsigned int wanted = 0;
3965e111ed8SAndrew Rybchenko
3975e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
3985e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
3995e111ed8SAndrew Rybchenko
4005e111ed8SAndrew Rybchenko /*
4015e111ed8SAndrew Rybchenko * Decode the requested flow control settings from the PHY
4025e111ed8SAndrew Rybchenko * advertised capabilities.
4035e111ed8SAndrew Rybchenko */
4045e111ed8SAndrew Rybchenko if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
4055e111ed8SAndrew Rybchenko wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
4065e111ed8SAndrew Rybchenko if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
4075e111ed8SAndrew Rybchenko wanted ^= EFX_FCNTL_GENERATE;
4085e111ed8SAndrew Rybchenko
4095e111ed8SAndrew Rybchenko *fcntl_linkp = epp->ep_fcntl;
4105e111ed8SAndrew Rybchenko *fcntl_wantedp = wanted;
4115e111ed8SAndrew Rybchenko }
4125e111ed8SAndrew Rybchenko
4135e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
4145e111ed8SAndrew Rybchenko efx_mac_multicast_list_set(
4155e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4165e111ed8SAndrew Rybchenko __in_ecount(6*count) uint8_t const *addrs,
4175e111ed8SAndrew Rybchenko __in int count)
4185e111ed8SAndrew Rybchenko {
4195e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
4205e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
4215e111ed8SAndrew Rybchenko uint8_t *old_mulcst_addr_list = NULL;
4225e111ed8SAndrew Rybchenko uint32_t old_mulcst_addr_count;
4235e111ed8SAndrew Rybchenko efx_rc_t rc;
4245e111ed8SAndrew Rybchenko
4255e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
4265e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
4275e111ed8SAndrew Rybchenko
4285e111ed8SAndrew Rybchenko if (count > EFX_MAC_MULTICAST_LIST_MAX) {
4295e111ed8SAndrew Rybchenko rc = EINVAL;
4305e111ed8SAndrew Rybchenko goto fail1;
4315e111ed8SAndrew Rybchenko }
4325e111ed8SAndrew Rybchenko
4335e111ed8SAndrew Rybchenko old_mulcst_addr_count = epp->ep_mulcst_addr_count;
4345e111ed8SAndrew Rybchenko if (old_mulcst_addr_count > 0) {
4355e111ed8SAndrew Rybchenko /* Allocate memory to store old list (instead of using stack) */
4365e111ed8SAndrew Rybchenko EFSYS_KMEM_ALLOC(enp->en_esip,
4375e111ed8SAndrew Rybchenko old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4385e111ed8SAndrew Rybchenko old_mulcst_addr_list);
4395e111ed8SAndrew Rybchenko if (old_mulcst_addr_list == NULL) {
4405e111ed8SAndrew Rybchenko rc = ENOMEM;
4415e111ed8SAndrew Rybchenko goto fail2;
4425e111ed8SAndrew Rybchenko }
4435e111ed8SAndrew Rybchenko
4445e111ed8SAndrew Rybchenko /* Save the old list in case we need to rollback */
4455e111ed8SAndrew Rybchenko memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
4465e111ed8SAndrew Rybchenko old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
4475e111ed8SAndrew Rybchenko }
4485e111ed8SAndrew Rybchenko
4495e111ed8SAndrew Rybchenko /* Store the new list */
4505e111ed8SAndrew Rybchenko memcpy(epp->ep_mulcst_addr_list, addrs,
4515e111ed8SAndrew Rybchenko count * EFX_MAC_ADDR_LEN);
4525e111ed8SAndrew Rybchenko epp->ep_mulcst_addr_count = count;
4535e111ed8SAndrew Rybchenko
4545e111ed8SAndrew Rybchenko if ((rc = emop->emo_multicast_list_set(enp)) != 0)
4555e111ed8SAndrew Rybchenko goto fail3;
4565e111ed8SAndrew Rybchenko
4575e111ed8SAndrew Rybchenko if (old_mulcst_addr_count > 0) {
4585e111ed8SAndrew Rybchenko EFSYS_KMEM_FREE(enp->en_esip,
4595e111ed8SAndrew Rybchenko old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4605e111ed8SAndrew Rybchenko old_mulcst_addr_list);
4615e111ed8SAndrew Rybchenko }
4625e111ed8SAndrew Rybchenko
4635e111ed8SAndrew Rybchenko return (0);
4645e111ed8SAndrew Rybchenko
4655e111ed8SAndrew Rybchenko fail3:
4665e111ed8SAndrew Rybchenko EFSYS_PROBE(fail3);
4675e111ed8SAndrew Rybchenko
4685e111ed8SAndrew Rybchenko /* Restore original list on failure */
4695e111ed8SAndrew Rybchenko epp->ep_mulcst_addr_count = old_mulcst_addr_count;
4705e111ed8SAndrew Rybchenko if (old_mulcst_addr_count > 0) {
4715e111ed8SAndrew Rybchenko memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
4725e111ed8SAndrew Rybchenko old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
4735e111ed8SAndrew Rybchenko
4745e111ed8SAndrew Rybchenko EFSYS_KMEM_FREE(enp->en_esip,
4755e111ed8SAndrew Rybchenko old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4765e111ed8SAndrew Rybchenko old_mulcst_addr_list);
4775e111ed8SAndrew Rybchenko }
4785e111ed8SAndrew Rybchenko
4795e111ed8SAndrew Rybchenko fail2:
4805e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
4815e111ed8SAndrew Rybchenko
4825e111ed8SAndrew Rybchenko fail1:
4835e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
4845e111ed8SAndrew Rybchenko
4855e111ed8SAndrew Rybchenko return (rc);
4865e111ed8SAndrew Rybchenko
4875e111ed8SAndrew Rybchenko }
4885e111ed8SAndrew Rybchenko
4895e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_filter_default_rxq_set(__in efx_nic_t * enp,__in efx_rxq_t * erp,__in boolean_t using_rss)4905e111ed8SAndrew Rybchenko efx_mac_filter_default_rxq_set(
4915e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4925e111ed8SAndrew Rybchenko __in efx_rxq_t *erp,
4935e111ed8SAndrew Rybchenko __in boolean_t using_rss)
4945e111ed8SAndrew Rybchenko {
4955e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
4965e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
4975e111ed8SAndrew Rybchenko efx_rc_t rc;
4985e111ed8SAndrew Rybchenko
4995e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
5005e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
5015e111ed8SAndrew Rybchenko
5025e111ed8SAndrew Rybchenko if (emop->emo_filter_default_rxq_set != NULL) {
5035e111ed8SAndrew Rybchenko rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
5045e111ed8SAndrew Rybchenko if (rc != 0)
5055e111ed8SAndrew Rybchenko goto fail1;
5065e111ed8SAndrew Rybchenko }
5075e111ed8SAndrew Rybchenko
5085e111ed8SAndrew Rybchenko return (0);
5095e111ed8SAndrew Rybchenko
5105e111ed8SAndrew Rybchenko fail1:
5115e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
5125e111ed8SAndrew Rybchenko
5135e111ed8SAndrew Rybchenko return (rc);
5145e111ed8SAndrew Rybchenko }
5155e111ed8SAndrew Rybchenko
5165e111ed8SAndrew Rybchenko void
efx_mac_filter_default_rxq_clear(__in efx_nic_t * enp)5175e111ed8SAndrew Rybchenko efx_mac_filter_default_rxq_clear(
5185e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
5195e111ed8SAndrew Rybchenko {
5205e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
5215e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
5225e111ed8SAndrew Rybchenko
5235e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
5245e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
5255e111ed8SAndrew Rybchenko
5265e111ed8SAndrew Rybchenko if (emop->emo_filter_default_rxq_clear != NULL)
5275e111ed8SAndrew Rybchenko emop->emo_filter_default_rxq_clear(enp);
5285e111ed8SAndrew Rybchenko }
5295e111ed8SAndrew Rybchenko
530*718263c4SRoman Zhukov __checkReturn efx_rc_t
efx_mac_include_fcs_set(__in efx_nic_t * enp,__in boolean_t enabled)531*718263c4SRoman Zhukov efx_mac_include_fcs_set(
532*718263c4SRoman Zhukov __in efx_nic_t *enp,
533*718263c4SRoman Zhukov __in boolean_t enabled)
534*718263c4SRoman Zhukov {
535*718263c4SRoman Zhukov efx_port_t *epp = &(enp->en_port);
536*718263c4SRoman Zhukov efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
537*718263c4SRoman Zhukov const efx_mac_ops_t *emop = epp->ep_emop;
538*718263c4SRoman Zhukov efx_rc_t rc;
539*718263c4SRoman Zhukov
540*718263c4SRoman Zhukov EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
541*718263c4SRoman Zhukov EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
542*718263c4SRoman Zhukov EFSYS_ASSERT(emop != NULL);
543*718263c4SRoman Zhukov
544*718263c4SRoman Zhukov if (enabled && !encp->enc_rx_include_fcs_supported) {
545*718263c4SRoman Zhukov rc = ENOTSUP;
546*718263c4SRoman Zhukov goto fail1;
547*718263c4SRoman Zhukov }
548*718263c4SRoman Zhukov
549*718263c4SRoman Zhukov /*
550*718263c4SRoman Zhukov * Enabling 'include FCS' changes link control state and affects
551*718263c4SRoman Zhukov * behaviour for all PCI functions on the port, so to avoid this it
552*718263c4SRoman Zhukov * can be enabled only if the PCI function is exclusive port user
553*718263c4SRoman Zhukov */
554*718263c4SRoman Zhukov if (enabled && encp->enc_port_usage != EFX_PORT_USAGE_EXCLUSIVE) {
555*718263c4SRoman Zhukov rc = EACCES;
556*718263c4SRoman Zhukov goto fail2;
557*718263c4SRoman Zhukov }
558*718263c4SRoman Zhukov
559*718263c4SRoman Zhukov if (epp->ep_include_fcs != enabled) {
560*718263c4SRoman Zhukov epp->ep_include_fcs = enabled;
561*718263c4SRoman Zhukov
562*718263c4SRoman Zhukov rc = emop->emo_reconfigure(enp);
563*718263c4SRoman Zhukov if (rc != 0)
564*718263c4SRoman Zhukov goto fail3;
565*718263c4SRoman Zhukov }
566*718263c4SRoman Zhukov
567*718263c4SRoman Zhukov return 0;
568*718263c4SRoman Zhukov
569*718263c4SRoman Zhukov fail3:
570*718263c4SRoman Zhukov EFSYS_PROBE(fail3);
571*718263c4SRoman Zhukov fail2:
572*718263c4SRoman Zhukov EFSYS_PROBE(fail2);
573*718263c4SRoman Zhukov fail1:
574*718263c4SRoman Zhukov EFSYS_PROBE1(fail1, efx_rc_t, rc);
575*718263c4SRoman Zhukov
576*718263c4SRoman Zhukov return rc;
577*718263c4SRoman Zhukov }
5785e111ed8SAndrew Rybchenko
5795e111ed8SAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
5805e111ed8SAndrew Rybchenko
5815e111ed8SAndrew Rybchenko #if EFSYS_OPT_NAMES
5825e111ed8SAndrew Rybchenko
5835e111ed8SAndrew Rybchenko /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
5845e111ed8SAndrew Rybchenko static const char * const __efx_mac_stat_name[] = {
5855e111ed8SAndrew Rybchenko "rx_octets",
5865e111ed8SAndrew Rybchenko "rx_pkts",
5875e111ed8SAndrew Rybchenko "rx_unicst_pkts",
5885e111ed8SAndrew Rybchenko "rx_multicst_pkts",
5895e111ed8SAndrew Rybchenko "rx_brdcst_pkts",
5905e111ed8SAndrew Rybchenko "rx_pause_pkts",
5915e111ed8SAndrew Rybchenko "rx_le_64_pkts",
5925e111ed8SAndrew Rybchenko "rx_65_to_127_pkts",
5935e111ed8SAndrew Rybchenko "rx_128_to_255_pkts",
5945e111ed8SAndrew Rybchenko "rx_256_to_511_pkts",
5955e111ed8SAndrew Rybchenko "rx_512_to_1023_pkts",
5965e111ed8SAndrew Rybchenko "rx_1024_to_15xx_pkts",
5975e111ed8SAndrew Rybchenko "rx_ge_15xx_pkts",
5985e111ed8SAndrew Rybchenko "rx_errors",
5995e111ed8SAndrew Rybchenko "rx_fcs_errors",
6005e111ed8SAndrew Rybchenko "rx_drop_events",
6015e111ed8SAndrew Rybchenko "rx_false_carrier_errors",
6025e111ed8SAndrew Rybchenko "rx_symbol_errors",
6035e111ed8SAndrew Rybchenko "rx_align_errors",
6045e111ed8SAndrew Rybchenko "rx_internal_errors",
6055e111ed8SAndrew Rybchenko "rx_jabber_pkts",
6065e111ed8SAndrew Rybchenko "rx_lane0_char_err",
6075e111ed8SAndrew Rybchenko "rx_lane1_char_err",
6085e111ed8SAndrew Rybchenko "rx_lane2_char_err",
6095e111ed8SAndrew Rybchenko "rx_lane3_char_err",
6105e111ed8SAndrew Rybchenko "rx_lane0_disp_err",
6115e111ed8SAndrew Rybchenko "rx_lane1_disp_err",
6125e111ed8SAndrew Rybchenko "rx_lane2_disp_err",
6135e111ed8SAndrew Rybchenko "rx_lane3_disp_err",
6145e111ed8SAndrew Rybchenko "rx_match_fault",
6155e111ed8SAndrew Rybchenko "rx_nodesc_drop_cnt",
6165e111ed8SAndrew Rybchenko "tx_octets",
6175e111ed8SAndrew Rybchenko "tx_pkts",
6185e111ed8SAndrew Rybchenko "tx_unicst_pkts",
6195e111ed8SAndrew Rybchenko "tx_multicst_pkts",
6205e111ed8SAndrew Rybchenko "tx_brdcst_pkts",
6215e111ed8SAndrew Rybchenko "tx_pause_pkts",
6225e111ed8SAndrew Rybchenko "tx_le_64_pkts",
6235e111ed8SAndrew Rybchenko "tx_65_to_127_pkts",
6245e111ed8SAndrew Rybchenko "tx_128_to_255_pkts",
6255e111ed8SAndrew Rybchenko "tx_256_to_511_pkts",
6265e111ed8SAndrew Rybchenko "tx_512_to_1023_pkts",
6275e111ed8SAndrew Rybchenko "tx_1024_to_15xx_pkts",
6285e111ed8SAndrew Rybchenko "tx_ge_15xx_pkts",
6295e111ed8SAndrew Rybchenko "tx_errors",
6305e111ed8SAndrew Rybchenko "tx_sgl_col_pkts",
6315e111ed8SAndrew Rybchenko "tx_mult_col_pkts",
6325e111ed8SAndrew Rybchenko "tx_ex_col_pkts",
6335e111ed8SAndrew Rybchenko "tx_late_col_pkts",
6345e111ed8SAndrew Rybchenko "tx_def_pkts",
6355e111ed8SAndrew Rybchenko "tx_ex_def_pkts",
6365e111ed8SAndrew Rybchenko "pm_trunc_bb_overflow",
6375e111ed8SAndrew Rybchenko "pm_discard_bb_overflow",
6385e111ed8SAndrew Rybchenko "pm_trunc_vfifo_full",
6395e111ed8SAndrew Rybchenko "pm_discard_vfifo_full",
6405e111ed8SAndrew Rybchenko "pm_trunc_qbb",
6415e111ed8SAndrew Rybchenko "pm_discard_qbb",
6425e111ed8SAndrew Rybchenko "pm_discard_mapping",
6435e111ed8SAndrew Rybchenko "rxdp_q_disabled_pkts",
6445e111ed8SAndrew Rybchenko "rxdp_di_dropped_pkts",
6455e111ed8SAndrew Rybchenko "rxdp_streaming_pkts",
6465e111ed8SAndrew Rybchenko "rxdp_hlb_fetch",
6475e111ed8SAndrew Rybchenko "rxdp_hlb_wait",
6485e111ed8SAndrew Rybchenko "vadapter_rx_unicast_packets",
6495e111ed8SAndrew Rybchenko "vadapter_rx_unicast_bytes",
6505e111ed8SAndrew Rybchenko "vadapter_rx_multicast_packets",
6515e111ed8SAndrew Rybchenko "vadapter_rx_multicast_bytes",
6525e111ed8SAndrew Rybchenko "vadapter_rx_broadcast_packets",
6535e111ed8SAndrew Rybchenko "vadapter_rx_broadcast_bytes",
6545e111ed8SAndrew Rybchenko "vadapter_rx_bad_packets",
6555e111ed8SAndrew Rybchenko "vadapter_rx_bad_bytes",
6565e111ed8SAndrew Rybchenko "vadapter_rx_overflow",
6575e111ed8SAndrew Rybchenko "vadapter_tx_unicast_packets",
6585e111ed8SAndrew Rybchenko "vadapter_tx_unicast_bytes",
6595e111ed8SAndrew Rybchenko "vadapter_tx_multicast_packets",
6605e111ed8SAndrew Rybchenko "vadapter_tx_multicast_bytes",
6615e111ed8SAndrew Rybchenko "vadapter_tx_broadcast_packets",
6625e111ed8SAndrew Rybchenko "vadapter_tx_broadcast_bytes",
6635e111ed8SAndrew Rybchenko "vadapter_tx_bad_packets",
6645e111ed8SAndrew Rybchenko "vadapter_tx_bad_bytes",
6655e111ed8SAndrew Rybchenko "vadapter_tx_overflow",
6665e111ed8SAndrew Rybchenko "fec_uncorrected_errors",
6675e111ed8SAndrew Rybchenko "fec_corrected_errors",
6685e111ed8SAndrew Rybchenko "fec_corrected_symbols_lane0",
6695e111ed8SAndrew Rybchenko "fec_corrected_symbols_lane1",
6705e111ed8SAndrew Rybchenko "fec_corrected_symbols_lane2",
6715e111ed8SAndrew Rybchenko "fec_corrected_symbols_lane3",
6725e111ed8SAndrew Rybchenko "ctpio_vi_busy_fallback",
6735e111ed8SAndrew Rybchenko "ctpio_long_write_success",
6745e111ed8SAndrew Rybchenko "ctpio_missing_dbell_fail",
6755e111ed8SAndrew Rybchenko "ctpio_overflow_fail",
6765e111ed8SAndrew Rybchenko "ctpio_underflow_fail",
6775e111ed8SAndrew Rybchenko "ctpio_timeout_fail",
6785e111ed8SAndrew Rybchenko "ctpio_noncontig_wr_fail",
6795e111ed8SAndrew Rybchenko "ctpio_frm_clobber_fail",
6805e111ed8SAndrew Rybchenko "ctpio_invalid_wr_fail",
6815e111ed8SAndrew Rybchenko "ctpio_vi_clobber_fallback",
6825e111ed8SAndrew Rybchenko "ctpio_unqualified_fallback",
6835e111ed8SAndrew Rybchenko "ctpio_runt_fallback",
6845e111ed8SAndrew Rybchenko "ctpio_success",
6855e111ed8SAndrew Rybchenko "ctpio_fallback",
6865e111ed8SAndrew Rybchenko "ctpio_poison",
6875e111ed8SAndrew Rybchenko "ctpio_erase",
6885e111ed8SAndrew Rybchenko "rxdp_scatter_disabled_trunc",
6895e111ed8SAndrew Rybchenko "rxdp_hlb_idle",
6905e111ed8SAndrew Rybchenko "rxdp_hlb_timeout",
6915e111ed8SAndrew Rybchenko };
6925e111ed8SAndrew Rybchenko /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
6935e111ed8SAndrew Rybchenko
6945e111ed8SAndrew Rybchenko __checkReturn const char *
efx_mac_stat_name(__in efx_nic_t * enp,__in unsigned int id)6955e111ed8SAndrew Rybchenko efx_mac_stat_name(
6965e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
6975e111ed8SAndrew Rybchenko __in unsigned int id)
6985e111ed8SAndrew Rybchenko {
6995e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
7005e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
7015e111ed8SAndrew Rybchenko
7025e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
7035e111ed8SAndrew Rybchenko return (__efx_mac_stat_name[id]);
7045e111ed8SAndrew Rybchenko }
7055e111ed8SAndrew Rybchenko
7065e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_NAMES */
7075e111ed8SAndrew Rybchenko
7085e111ed8SAndrew Rybchenko static efx_rc_t
efx_mac_stats_mask_add_range(__inout_bcount (mask_size)uint32_t * maskp,__in size_t mask_size,__in const struct efx_mac_stats_range * rngp)7095e111ed8SAndrew Rybchenko efx_mac_stats_mask_add_range(
7105e111ed8SAndrew Rybchenko __inout_bcount(mask_size) uint32_t *maskp,
7115e111ed8SAndrew Rybchenko __in size_t mask_size,
7125e111ed8SAndrew Rybchenko __in const struct efx_mac_stats_range *rngp)
7135e111ed8SAndrew Rybchenko {
7145e111ed8SAndrew Rybchenko unsigned int mask_npages = mask_size / sizeof (*maskp);
7155e111ed8SAndrew Rybchenko unsigned int el;
7165e111ed8SAndrew Rybchenko unsigned int el_min;
7175e111ed8SAndrew Rybchenko unsigned int el_max;
7185e111ed8SAndrew Rybchenko unsigned int low;
7195e111ed8SAndrew Rybchenko unsigned int high;
7205e111ed8SAndrew Rybchenko unsigned int width;
7215e111ed8SAndrew Rybchenko efx_rc_t rc;
7225e111ed8SAndrew Rybchenko
7235e111ed8SAndrew Rybchenko if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
7245e111ed8SAndrew Rybchenko (unsigned int)rngp->last) {
7255e111ed8SAndrew Rybchenko rc = EINVAL;
7265e111ed8SAndrew Rybchenko goto fail1;
7275e111ed8SAndrew Rybchenko }
7285e111ed8SAndrew Rybchenko
7295e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
7305e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
7315e111ed8SAndrew Rybchenko
7325e111ed8SAndrew Rybchenko for (el = 0; el < mask_npages; ++el) {
7335e111ed8SAndrew Rybchenko el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
7345e111ed8SAndrew Rybchenko el_max =
7355e111ed8SAndrew Rybchenko el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
7365e111ed8SAndrew Rybchenko if ((unsigned int)rngp->first > el_max ||
7375e111ed8SAndrew Rybchenko (unsigned int)rngp->last < el_min)
7385e111ed8SAndrew Rybchenko continue;
7395e111ed8SAndrew Rybchenko low = MAX((unsigned int)rngp->first, el_min);
7405e111ed8SAndrew Rybchenko high = MIN((unsigned int)rngp->last, el_max);
7415e111ed8SAndrew Rybchenko width = high - low + 1;
7425e111ed8SAndrew Rybchenko maskp[el] |=
7435e111ed8SAndrew Rybchenko (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
7445e111ed8SAndrew Rybchenko (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
7455e111ed8SAndrew Rybchenko }
7465e111ed8SAndrew Rybchenko
7475e111ed8SAndrew Rybchenko return (0);
7485e111ed8SAndrew Rybchenko
7495e111ed8SAndrew Rybchenko fail1:
7505e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
7515e111ed8SAndrew Rybchenko
7525e111ed8SAndrew Rybchenko return (rc);
7535e111ed8SAndrew Rybchenko }
7545e111ed8SAndrew Rybchenko
7555e111ed8SAndrew Rybchenko efx_rc_t
efx_mac_stats_mask_add_ranges(__inout_bcount (mask_size)uint32_t * maskp,__in size_t mask_size,__in_ecount (rng_count)const struct efx_mac_stats_range * rngp,__in unsigned int rng_count)7565e111ed8SAndrew Rybchenko efx_mac_stats_mask_add_ranges(
7575e111ed8SAndrew Rybchenko __inout_bcount(mask_size) uint32_t *maskp,
7585e111ed8SAndrew Rybchenko __in size_t mask_size,
7595e111ed8SAndrew Rybchenko __in_ecount(rng_count) const struct efx_mac_stats_range *rngp,
7605e111ed8SAndrew Rybchenko __in unsigned int rng_count)
7615e111ed8SAndrew Rybchenko {
7625e111ed8SAndrew Rybchenko unsigned int i;
7635e111ed8SAndrew Rybchenko efx_rc_t rc;
7645e111ed8SAndrew Rybchenko
7655e111ed8SAndrew Rybchenko for (i = 0; i < rng_count; ++i) {
7665e111ed8SAndrew Rybchenko if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
7675e111ed8SAndrew Rybchenko &rngp[i])) != 0)
7685e111ed8SAndrew Rybchenko goto fail1;
7695e111ed8SAndrew Rybchenko }
7705e111ed8SAndrew Rybchenko
7715e111ed8SAndrew Rybchenko return (0);
7725e111ed8SAndrew Rybchenko
7735e111ed8SAndrew Rybchenko fail1:
7745e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
7755e111ed8SAndrew Rybchenko
7765e111ed8SAndrew Rybchenko return (rc);
7775e111ed8SAndrew Rybchenko }
7785e111ed8SAndrew Rybchenko
7795e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_stats_get_mask(__in efx_nic_t * enp,__out_bcount (mask_size)uint32_t * maskp,__in size_t mask_size)7805e111ed8SAndrew Rybchenko efx_mac_stats_get_mask(
7815e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
7825e111ed8SAndrew Rybchenko __out_bcount(mask_size) uint32_t *maskp,
7835e111ed8SAndrew Rybchenko __in size_t mask_size)
7845e111ed8SAndrew Rybchenko {
7855e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
7865e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
7875e111ed8SAndrew Rybchenko efx_rc_t rc;
7885e111ed8SAndrew Rybchenko
7895e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
7905e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
7915e111ed8SAndrew Rybchenko EFSYS_ASSERT(maskp != NULL);
7925e111ed8SAndrew Rybchenko EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
7935e111ed8SAndrew Rybchenko
7945e111ed8SAndrew Rybchenko (void) memset(maskp, 0, mask_size);
7955e111ed8SAndrew Rybchenko
7965e111ed8SAndrew Rybchenko if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
7975e111ed8SAndrew Rybchenko goto fail1;
7985e111ed8SAndrew Rybchenko
7995e111ed8SAndrew Rybchenko return (0);
8005e111ed8SAndrew Rybchenko
8015e111ed8SAndrew Rybchenko fail1:
8025e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
8035e111ed8SAndrew Rybchenko
8045e111ed8SAndrew Rybchenko return (rc);
8055e111ed8SAndrew Rybchenko }
8065e111ed8SAndrew Rybchenko
8075e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_stats_clear(__in efx_nic_t * enp)8085e111ed8SAndrew Rybchenko efx_mac_stats_clear(
8095e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
8105e111ed8SAndrew Rybchenko {
8115e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
8125e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
8135e111ed8SAndrew Rybchenko efx_rc_t rc;
8145e111ed8SAndrew Rybchenko
8155e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
8165e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
8175e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
8185e111ed8SAndrew Rybchenko
8195e111ed8SAndrew Rybchenko if ((rc = emop->emo_stats_clear(enp)) != 0)
8205e111ed8SAndrew Rybchenko goto fail1;
8215e111ed8SAndrew Rybchenko
8225e111ed8SAndrew Rybchenko return (0);
8235e111ed8SAndrew Rybchenko
8245e111ed8SAndrew Rybchenko fail1:
8255e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
8265e111ed8SAndrew Rybchenko
8275e111ed8SAndrew Rybchenko return (rc);
8285e111ed8SAndrew Rybchenko }
8295e111ed8SAndrew Rybchenko
8305e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_stats_upload(__in efx_nic_t * enp,__in efsys_mem_t * esmp)8315e111ed8SAndrew Rybchenko efx_mac_stats_upload(
8325e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
8335e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp)
8345e111ed8SAndrew Rybchenko {
8355e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
8365e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
8375e111ed8SAndrew Rybchenko efx_rc_t rc;
8385e111ed8SAndrew Rybchenko
8395e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
8405e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
8415e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
8425e111ed8SAndrew Rybchenko
8435e111ed8SAndrew Rybchenko if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
8445e111ed8SAndrew Rybchenko goto fail1;
8455e111ed8SAndrew Rybchenko
8465e111ed8SAndrew Rybchenko return (0);
8475e111ed8SAndrew Rybchenko
8485e111ed8SAndrew Rybchenko fail1:
8495e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
8505e111ed8SAndrew Rybchenko
8515e111ed8SAndrew Rybchenko return (rc);
8525e111ed8SAndrew Rybchenko }
8535e111ed8SAndrew Rybchenko
8545e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_stats_periodic(__in efx_nic_t * enp,__in efsys_mem_t * esmp,__in uint16_t period_ms,__in boolean_t events)8555e111ed8SAndrew Rybchenko efx_mac_stats_periodic(
8565e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
8575e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp,
8585e111ed8SAndrew Rybchenko __in uint16_t period_ms,
8595e111ed8SAndrew Rybchenko __in boolean_t events)
8605e111ed8SAndrew Rybchenko {
8615e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
8625e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
8635e111ed8SAndrew Rybchenko efx_rc_t rc;
8645e111ed8SAndrew Rybchenko
8655e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
8665e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
8675e111ed8SAndrew Rybchenko
8685e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
8695e111ed8SAndrew Rybchenko
8705e111ed8SAndrew Rybchenko if (emop->emo_stats_periodic == NULL) {
8715e111ed8SAndrew Rybchenko rc = EINVAL;
8725e111ed8SAndrew Rybchenko goto fail1;
8735e111ed8SAndrew Rybchenko }
8745e111ed8SAndrew Rybchenko
8755e111ed8SAndrew Rybchenko if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
8765e111ed8SAndrew Rybchenko goto fail2;
8775e111ed8SAndrew Rybchenko
8785e111ed8SAndrew Rybchenko return (0);
8795e111ed8SAndrew Rybchenko
8805e111ed8SAndrew Rybchenko fail2:
8815e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
8825e111ed8SAndrew Rybchenko fail1:
8835e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
8845e111ed8SAndrew Rybchenko
8855e111ed8SAndrew Rybchenko return (rc);
8865e111ed8SAndrew Rybchenko }
8875e111ed8SAndrew Rybchenko
8885e111ed8SAndrew Rybchenko
8895e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_stats_update(__in efx_nic_t * enp,__in efsys_mem_t * esmp,__inout_ecount (EFX_MAC_NSTATS)efsys_stat_t * essp,__inout_opt uint32_t * generationp)8905e111ed8SAndrew Rybchenko efx_mac_stats_update(
8915e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
8925e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp,
8935e111ed8SAndrew Rybchenko __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
8945e111ed8SAndrew Rybchenko __inout_opt uint32_t *generationp)
8955e111ed8SAndrew Rybchenko {
8965e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
8975e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
8985e111ed8SAndrew Rybchenko efx_rc_t rc;
8995e111ed8SAndrew Rybchenko
9005e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
9015e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
9025e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
9035e111ed8SAndrew Rybchenko
9045e111ed8SAndrew Rybchenko rc = emop->emo_stats_update(enp, esmp, essp, generationp);
9055e111ed8SAndrew Rybchenko
9065e111ed8SAndrew Rybchenko return (rc);
9075e111ed8SAndrew Rybchenko }
9085e111ed8SAndrew Rybchenko
9095e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MAC_STATS */
9105e111ed8SAndrew Rybchenko
9115e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
efx_mac_select(__in efx_nic_t * enp)9125e111ed8SAndrew Rybchenko efx_mac_select(
9135e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
9145e111ed8SAndrew Rybchenko {
9155e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
9165e111ed8SAndrew Rybchenko efx_mac_type_t type = EFX_MAC_INVALID;
9175e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop;
9185e111ed8SAndrew Rybchenko int rc = EINVAL;
9195e111ed8SAndrew Rybchenko
9205e111ed8SAndrew Rybchenko switch (enp->en_family) {
9215e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
9225e111ed8SAndrew Rybchenko case EFX_FAMILY_SIENA:
9235e111ed8SAndrew Rybchenko emop = &__efx_mac_siena_ops;
9245e111ed8SAndrew Rybchenko type = EFX_MAC_SIENA;
9255e111ed8SAndrew Rybchenko break;
9265e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
9275e111ed8SAndrew Rybchenko
9285e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
9295e111ed8SAndrew Rybchenko case EFX_FAMILY_HUNTINGTON:
9305e111ed8SAndrew Rybchenko emop = &__efx_mac_ef10_ops;
9315e111ed8SAndrew Rybchenko type = EFX_MAC_HUNTINGTON;
9325e111ed8SAndrew Rybchenko break;
9335e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_HUNTINGTON */
9345e111ed8SAndrew Rybchenko
9355e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
9365e111ed8SAndrew Rybchenko case EFX_FAMILY_MEDFORD:
9375e111ed8SAndrew Rybchenko emop = &__efx_mac_ef10_ops;
9385e111ed8SAndrew Rybchenko type = EFX_MAC_MEDFORD;
9395e111ed8SAndrew Rybchenko break;
9405e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD */
9415e111ed8SAndrew Rybchenko
9425e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
9435e111ed8SAndrew Rybchenko case EFX_FAMILY_MEDFORD2:
9445e111ed8SAndrew Rybchenko emop = &__efx_mac_ef10_ops;
9455e111ed8SAndrew Rybchenko type = EFX_MAC_MEDFORD2;
9465e111ed8SAndrew Rybchenko break;
9475e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD2 */
9485e111ed8SAndrew Rybchenko
949de0d268fSAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
950de0d268fSAndrew Rybchenko case EFX_FAMILY_RIVERHEAD:
951de0d268fSAndrew Rybchenko emop = &__efx_mac_rhead_ops;
952de0d268fSAndrew Rybchenko type = EFX_MAC_RIVERHEAD;
953de0d268fSAndrew Rybchenko break;
954de0d268fSAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD */
955de0d268fSAndrew Rybchenko
9565e111ed8SAndrew Rybchenko default:
9575e111ed8SAndrew Rybchenko rc = EINVAL;
9585e111ed8SAndrew Rybchenko goto fail1;
9595e111ed8SAndrew Rybchenko }
9605e111ed8SAndrew Rybchenko
9615e111ed8SAndrew Rybchenko EFSYS_ASSERT(type != EFX_MAC_INVALID);
9625e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
9635e111ed8SAndrew Rybchenko EFSYS_ASSERT(emop != NULL);
9645e111ed8SAndrew Rybchenko
9655e111ed8SAndrew Rybchenko epp->ep_emop = emop;
9665e111ed8SAndrew Rybchenko epp->ep_mac_type = type;
9675e111ed8SAndrew Rybchenko
9685e111ed8SAndrew Rybchenko return (0);
9695e111ed8SAndrew Rybchenko
9705e111ed8SAndrew Rybchenko fail1:
9715e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
9725e111ed8SAndrew Rybchenko
9735e111ed8SAndrew Rybchenko return (rc);
9745e111ed8SAndrew Rybchenko }
9755e111ed8SAndrew Rybchenko
9765e111ed8SAndrew Rybchenko
9775e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
9785e111ed8SAndrew Rybchenko
9795e111ed8SAndrew Rybchenko #define EFX_MAC_HASH_BITS (1 << 8)
9805e111ed8SAndrew Rybchenko
9815e111ed8SAndrew Rybchenko /* Compute the multicast hash as used on Falcon and Siena. */
9825e111ed8SAndrew Rybchenko static void
9835e111ed8SAndrew Rybchenko siena_mac_multicast_hash_compute(
9845e111ed8SAndrew Rybchenko __in_ecount(6*count) uint8_t const *addrs,
9855e111ed8SAndrew Rybchenko __in int count,
9865e111ed8SAndrew Rybchenko __out efx_oword_t *hash_low,
9875e111ed8SAndrew Rybchenko __out efx_oword_t *hash_high)
9885e111ed8SAndrew Rybchenko {
9895e111ed8SAndrew Rybchenko uint32_t crc, index;
9905e111ed8SAndrew Rybchenko int i;
9915e111ed8SAndrew Rybchenko
9925e111ed8SAndrew Rybchenko EFSYS_ASSERT(hash_low != NULL);
9935e111ed8SAndrew Rybchenko EFSYS_ASSERT(hash_high != NULL);
9945e111ed8SAndrew Rybchenko
9955e111ed8SAndrew Rybchenko EFX_ZERO_OWORD(*hash_low);
9965e111ed8SAndrew Rybchenko EFX_ZERO_OWORD(*hash_high);
9975e111ed8SAndrew Rybchenko
9985e111ed8SAndrew Rybchenko for (i = 0; i < count; i++) {
9995e111ed8SAndrew Rybchenko /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
10005e111ed8SAndrew Rybchenko crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
10015e111ed8SAndrew Rybchenko index = crc % EFX_MAC_HASH_BITS;
10025e111ed8SAndrew Rybchenko if (index < 128) {
10035e111ed8SAndrew Rybchenko EFX_SET_OWORD_BIT(*hash_low, index);
10045e111ed8SAndrew Rybchenko } else {
10055e111ed8SAndrew Rybchenko EFX_SET_OWORD_BIT(*hash_high, index - 128);
10065e111ed8SAndrew Rybchenko }
10075e111ed8SAndrew Rybchenko
10085e111ed8SAndrew Rybchenko addrs += EFX_MAC_ADDR_LEN;
10095e111ed8SAndrew Rybchenko }
10105e111ed8SAndrew Rybchenko }
10115e111ed8SAndrew Rybchenko
10125e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
siena_mac_multicast_list_set(__in efx_nic_t * enp)10135e111ed8SAndrew Rybchenko siena_mac_multicast_list_set(
10145e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
10155e111ed8SAndrew Rybchenko {
10165e111ed8SAndrew Rybchenko efx_port_t *epp = &(enp->en_port);
10175e111ed8SAndrew Rybchenko const efx_mac_ops_t *emop = epp->ep_emop;
10185e111ed8SAndrew Rybchenko efx_oword_t old_hash[2];
10195e111ed8SAndrew Rybchenko efx_rc_t rc;
10205e111ed8SAndrew Rybchenko
10215e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
10225e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
10235e111ed8SAndrew Rybchenko
10245e111ed8SAndrew Rybchenko memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
10255e111ed8SAndrew Rybchenko
10265e111ed8SAndrew Rybchenko siena_mac_multicast_hash_compute(
10275e111ed8SAndrew Rybchenko epp->ep_mulcst_addr_list,
10285e111ed8SAndrew Rybchenko epp->ep_mulcst_addr_count,
10295e111ed8SAndrew Rybchenko &epp->ep_multicst_hash[0],
10305e111ed8SAndrew Rybchenko &epp->ep_multicst_hash[1]);
10315e111ed8SAndrew Rybchenko
10325e111ed8SAndrew Rybchenko if ((rc = emop->emo_reconfigure(enp)) != 0)
10335e111ed8SAndrew Rybchenko goto fail1;
10345e111ed8SAndrew Rybchenko
10355e111ed8SAndrew Rybchenko return (0);
10365e111ed8SAndrew Rybchenko
10375e111ed8SAndrew Rybchenko fail1:
10385e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
10395e111ed8SAndrew Rybchenko
10405e111ed8SAndrew Rybchenko memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
10415e111ed8SAndrew Rybchenko
10425e111ed8SAndrew Rybchenko return (rc);
10435e111ed8SAndrew Rybchenko }
10445e111ed8SAndrew Rybchenko
10455e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
1046