xref: /freebsd/sys/dev/sfxge/common/efx_mac.c (revision 685dc743)
1e948693eSPhilip Paeps /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
4929c7febSAndrew Rybchenko  * Copyright (c) 2007-2016 Solarflare Communications Inc.
53c838a9fSAndrew Rybchenko  * All rights reserved.
6e948693eSPhilip Paeps  *
7e948693eSPhilip Paeps  * Redistribution and use in source and binary forms, with or without
83c838a9fSAndrew Rybchenko  * modification, are permitted provided that the following conditions are met:
9e948693eSPhilip Paeps  *
103c838a9fSAndrew Rybchenko  * 1. Redistributions of source code must retain the above copyright notice,
113c838a9fSAndrew Rybchenko  *    this list of conditions and the following disclaimer.
123c838a9fSAndrew Rybchenko  * 2. Redistributions in binary form must reproduce the above copyright notice,
133c838a9fSAndrew Rybchenko  *    this list of conditions and the following disclaimer in the documentation
143c838a9fSAndrew Rybchenko  *    and/or other materials provided with the distribution.
153c838a9fSAndrew Rybchenko  *
163c838a9fSAndrew Rybchenko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
173c838a9fSAndrew Rybchenko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
183c838a9fSAndrew Rybchenko  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
193c838a9fSAndrew Rybchenko  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
203c838a9fSAndrew Rybchenko  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
213c838a9fSAndrew Rybchenko  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
223c838a9fSAndrew Rybchenko  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
233c838a9fSAndrew Rybchenko  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
243c838a9fSAndrew Rybchenko  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
253c838a9fSAndrew Rybchenko  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
263c838a9fSAndrew Rybchenko  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273c838a9fSAndrew Rybchenko  *
283c838a9fSAndrew Rybchenko  * The views and conclusions contained in the software and documentation are
293c838a9fSAndrew Rybchenko  * those of the authors and should not be interpreted as representing official
303c838a9fSAndrew Rybchenko  * policies, either expressed or implied, of the FreeBSD Project.
31e948693eSPhilip Paeps  */
32e948693eSPhilip Paeps 
335dee87d7SPhilip Paeps #include <sys/cdefs.h>
34e948693eSPhilip Paeps #include "efx.h"
35e948693eSPhilip Paeps #include "efx_impl.h"
36e948693eSPhilip Paeps 
37e75412c9SAndrew Rybchenko #if EFSYS_OPT_SIENA
383c838a9fSAndrew Rybchenko 
39460cb568SAndrew Rybchenko static	__checkReturn	efx_rc_t
405cab4fc7SAndrew Rybchenko siena_mac_multicast_list_set(
413c838a9fSAndrew Rybchenko 	__in		efx_nic_t *enp);
423c838a9fSAndrew Rybchenko 
43e75412c9SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
443c838a9fSAndrew Rybchenko 
45e948693eSPhilip Paeps #if EFSYS_OPT_SIENA
46ae346558SAndrew Rybchenko static const efx_mac_ops_t	__efx_mac_siena_ops = {
47e948693eSPhilip Paeps 	siena_mac_poll,				/* emo_poll */
48e948693eSPhilip Paeps 	siena_mac_up,				/* emo_up */
493c838a9fSAndrew Rybchenko 	siena_mac_reconfigure,			/* emo_addr_set */
5008c5af79SAndrew Rybchenko 	siena_mac_reconfigure,			/* emo_pdu_set */
51d8484af2SAndrew Rybchenko 	siena_mac_pdu_get,			/* emo_pdu_get */
52e948693eSPhilip Paeps 	siena_mac_reconfigure,			/* emo_reconfigure */
535cab4fc7SAndrew Rybchenko 	siena_mac_multicast_list_set,		/* emo_multicast_list_set */
543c838a9fSAndrew Rybchenko 	NULL,					/* emo_filter_set_default_rxq */
553c838a9fSAndrew Rybchenko 	NULL,				/* emo_filter_default_rxq_clear */
56e948693eSPhilip Paeps #if EFSYS_OPT_LOOPBACK
57e948693eSPhilip Paeps 	siena_mac_loopback_set,			/* emo_loopback_set */
58e948693eSPhilip Paeps #endif	/* EFSYS_OPT_LOOPBACK */
59e948693eSPhilip Paeps #if EFSYS_OPT_MAC_STATS
6058a72cb2SAndrew Rybchenko 	siena_mac_stats_get_mask,		/* emo_stats_get_mask */
6131e518b4SAndrew Rybchenko 	efx_mcdi_mac_stats_clear,		/* emo_stats_clear */
623c838a9fSAndrew Rybchenko 	efx_mcdi_mac_stats_upload,		/* emo_stats_upload */
633c838a9fSAndrew Rybchenko 	efx_mcdi_mac_stats_periodic,		/* emo_stats_periodic */
64e948693eSPhilip Paeps 	siena_mac_stats_update			/* emo_stats_update */
65e948693eSPhilip Paeps #endif	/* EFSYS_OPT_MAC_STATS */
66e948693eSPhilip Paeps };
67e948693eSPhilip Paeps #endif	/* EFSYS_OPT_SIENA */
68e948693eSPhilip Paeps 
69cbc3f94fSAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
70ae346558SAndrew Rybchenko static const efx_mac_ops_t	__efx_mac_ef10_ops = {
71c15d6d21SAndrew Rybchenko 	ef10_mac_poll,				/* emo_poll */
72c15d6d21SAndrew Rybchenko 	ef10_mac_up,				/* emo_up */
73c15d6d21SAndrew Rybchenko 	ef10_mac_addr_set,			/* emo_addr_set */
7408c5af79SAndrew Rybchenko 	ef10_mac_pdu_set,			/* emo_pdu_set */
75d8484af2SAndrew Rybchenko 	ef10_mac_pdu_get,			/* emo_pdu_get */
76c15d6d21SAndrew Rybchenko 	ef10_mac_reconfigure,			/* emo_reconfigure */
77c15d6d21SAndrew Rybchenko 	ef10_mac_multicast_list_set,		/* emo_multicast_list_set */
78c15d6d21SAndrew Rybchenko 	ef10_mac_filter_default_rxq_set,	/* emo_filter_default_rxq_set */
79c15d6d21SAndrew Rybchenko 	ef10_mac_filter_default_rxq_clear,
803c838a9fSAndrew Rybchenko 					/* emo_filter_default_rxq_clear */
813c838a9fSAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
82c15d6d21SAndrew Rybchenko 	ef10_mac_loopback_set,			/* emo_loopback_set */
833c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_LOOPBACK */
843c838a9fSAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
8558a72cb2SAndrew Rybchenko 	ef10_mac_stats_get_mask,		/* emo_stats_get_mask */
8631e518b4SAndrew Rybchenko 	efx_mcdi_mac_stats_clear,		/* emo_stats_clear */
873c838a9fSAndrew Rybchenko 	efx_mcdi_mac_stats_upload,		/* emo_stats_upload */
883c838a9fSAndrew Rybchenko 	efx_mcdi_mac_stats_periodic,		/* emo_stats_periodic */
89c15d6d21SAndrew Rybchenko 	ef10_mac_stats_update			/* emo_stats_update */
903c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_MAC_STATS */
913c838a9fSAndrew Rybchenko };
92cbc3f94fSAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
933c838a9fSAndrew Rybchenko 
94460cb568SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_pdu_set(__in efx_nic_t * enp,__in size_t pdu)95e948693eSPhilip Paeps efx_mac_pdu_set(
96e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
97e948693eSPhilip Paeps 	__in				size_t pdu)
98e948693eSPhilip Paeps {
99e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
100ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
101e948693eSPhilip Paeps 	uint32_t old_pdu;
102460cb568SAndrew Rybchenko 	efx_rc_t rc;
103e948693eSPhilip Paeps 
104e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
105e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
106e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
107e948693eSPhilip Paeps 
108e948693eSPhilip Paeps 	if (pdu < EFX_MAC_PDU_MIN) {
109e948693eSPhilip Paeps 		rc = EINVAL;
110e948693eSPhilip Paeps 		goto fail1;
111e948693eSPhilip Paeps 	}
112e948693eSPhilip Paeps 
113e948693eSPhilip Paeps 	if (pdu > EFX_MAC_PDU_MAX) {
114e948693eSPhilip Paeps 		rc = EINVAL;
115e948693eSPhilip Paeps 		goto fail2;
116e948693eSPhilip Paeps 	}
117e948693eSPhilip Paeps 
118e948693eSPhilip Paeps 	old_pdu = epp->ep_mac_pdu;
119e948693eSPhilip Paeps 	epp->ep_mac_pdu = (uint32_t)pdu;
12008c5af79SAndrew Rybchenko 	if ((rc = emop->emo_pdu_set(enp)) != 0)
121e948693eSPhilip Paeps 		goto fail3;
122e948693eSPhilip Paeps 
123e948693eSPhilip Paeps 	return (0);
124e948693eSPhilip Paeps 
125e948693eSPhilip Paeps fail3:
126e948693eSPhilip Paeps 	EFSYS_PROBE(fail3);
127e948693eSPhilip Paeps 
128e948693eSPhilip Paeps 	epp->ep_mac_pdu = old_pdu;
129e948693eSPhilip Paeps 
130e948693eSPhilip Paeps fail2:
131e948693eSPhilip Paeps 	EFSYS_PROBE(fail2);
132e948693eSPhilip Paeps fail1:
133460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
134e948693eSPhilip Paeps 
135e948693eSPhilip Paeps 	return (rc);
136e948693eSPhilip Paeps }
137e948693eSPhilip Paeps 
138460cb568SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_mac_pdu_get(__in efx_nic_t * enp,__out size_t * pdu)139d8484af2SAndrew Rybchenko efx_mac_pdu_get(
140d8484af2SAndrew Rybchenko 	__in		efx_nic_t *enp,
141d8484af2SAndrew Rybchenko 	__out		size_t *pdu)
142d8484af2SAndrew Rybchenko {
143d8484af2SAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
144d8484af2SAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
145d8484af2SAndrew Rybchenko 	efx_rc_t rc;
146d8484af2SAndrew Rybchenko 
147d8484af2SAndrew Rybchenko 	if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
148d8484af2SAndrew Rybchenko 		goto fail1;
149d8484af2SAndrew Rybchenko 
150d8484af2SAndrew Rybchenko 	return (0);
151d8484af2SAndrew Rybchenko 
152d8484af2SAndrew Rybchenko fail1:
153d8484af2SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
154d8484af2SAndrew Rybchenko 
155d8484af2SAndrew Rybchenko 	return (rc);
156d8484af2SAndrew Rybchenko }
157d8484af2SAndrew Rybchenko 
158d8484af2SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_addr_set(__in efx_nic_t * enp,__in uint8_t * addr)159e948693eSPhilip Paeps efx_mac_addr_set(
160e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
161e948693eSPhilip Paeps 	__in				uint8_t *addr)
162e948693eSPhilip Paeps {
163e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
164ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
165e948693eSPhilip Paeps 	uint8_t old_addr[6];
166e948693eSPhilip Paeps 	uint32_t oui;
167460cb568SAndrew Rybchenko 	efx_rc_t rc;
168e948693eSPhilip Paeps 
169e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
170e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
171e948693eSPhilip Paeps 
1723c838a9fSAndrew Rybchenko 	if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
173e948693eSPhilip Paeps 		rc = EINVAL;
174e948693eSPhilip Paeps 		goto fail1;
175e948693eSPhilip Paeps 	}
176e948693eSPhilip Paeps 
177e948693eSPhilip Paeps 	oui = addr[0] << 16 | addr[1] << 8 | addr[2];
178e948693eSPhilip Paeps 	if (oui == 0x000000) {
179e948693eSPhilip Paeps 		rc = EINVAL;
180e948693eSPhilip Paeps 		goto fail2;
181e948693eSPhilip Paeps 	}
182e948693eSPhilip Paeps 
183e948693eSPhilip Paeps 	EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
184e948693eSPhilip Paeps 	EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
1853c838a9fSAndrew Rybchenko 	if ((rc = emop->emo_addr_set(enp)) != 0)
186e948693eSPhilip Paeps 		goto fail3;
187e948693eSPhilip Paeps 
188e948693eSPhilip Paeps 	return (0);
189e948693eSPhilip Paeps 
190e948693eSPhilip Paeps fail3:
191e948693eSPhilip Paeps 	EFSYS_PROBE(fail3);
192e948693eSPhilip Paeps 
193e948693eSPhilip Paeps 	EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
194e948693eSPhilip Paeps 
195e948693eSPhilip Paeps fail2:
196e948693eSPhilip Paeps 	EFSYS_PROBE(fail2);
197e948693eSPhilip Paeps fail1:
198460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
199e948693eSPhilip Paeps 
200e948693eSPhilip Paeps 	return (rc);
201e948693eSPhilip Paeps }
202e948693eSPhilip Paeps 
203460cb568SAndrew 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)204e948693eSPhilip Paeps efx_mac_filter_set(
205e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
2063c838a9fSAndrew Rybchenko 	__in				boolean_t all_unicst,
2073c838a9fSAndrew Rybchenko 	__in				boolean_t mulcst,
2083c838a9fSAndrew Rybchenko 	__in				boolean_t all_mulcst,
209e948693eSPhilip Paeps 	__in				boolean_t brdcst)
210e948693eSPhilip Paeps {
211e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
212ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
2133c838a9fSAndrew Rybchenko 	boolean_t old_all_unicst;
2143c838a9fSAndrew Rybchenko 	boolean_t old_mulcst;
2153c838a9fSAndrew Rybchenko 	boolean_t old_all_mulcst;
216e948693eSPhilip Paeps 	boolean_t old_brdcst;
217460cb568SAndrew Rybchenko 	efx_rc_t rc;
218e948693eSPhilip Paeps 
219e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
220e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
221e948693eSPhilip Paeps 
2223c838a9fSAndrew Rybchenko 	old_all_unicst = epp->ep_all_unicst;
2233c838a9fSAndrew Rybchenko 	old_mulcst = epp->ep_mulcst;
2243c838a9fSAndrew Rybchenko 	old_all_mulcst = epp->ep_all_mulcst;
2253c838a9fSAndrew Rybchenko 	old_brdcst = epp->ep_brdcst;
226e948693eSPhilip Paeps 
2273c838a9fSAndrew Rybchenko 	epp->ep_all_unicst = all_unicst;
2283c838a9fSAndrew Rybchenko 	epp->ep_mulcst = mulcst;
2293c838a9fSAndrew Rybchenko 	epp->ep_all_mulcst = all_mulcst;
230e948693eSPhilip Paeps 	epp->ep_brdcst = brdcst;
231e948693eSPhilip Paeps 
232e948693eSPhilip Paeps 	if ((rc = emop->emo_reconfigure(enp)) != 0)
233e948693eSPhilip Paeps 		goto fail1;
234e948693eSPhilip Paeps 
235e948693eSPhilip Paeps 	return (0);
236e948693eSPhilip Paeps 
237e948693eSPhilip Paeps fail1:
238460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
239e948693eSPhilip Paeps 
2403c838a9fSAndrew Rybchenko 	epp->ep_all_unicst = old_all_unicst;
2413c838a9fSAndrew Rybchenko 	epp->ep_mulcst = old_mulcst;
2423c838a9fSAndrew Rybchenko 	epp->ep_all_mulcst = old_all_mulcst;
243e948693eSPhilip Paeps 	epp->ep_brdcst = old_brdcst;
244e948693eSPhilip Paeps 
245e948693eSPhilip Paeps 	return (rc);
246e948693eSPhilip Paeps }
247e948693eSPhilip Paeps 
248460cb568SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_drain(__in efx_nic_t * enp,__in boolean_t enabled)249e948693eSPhilip Paeps efx_mac_drain(
250e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
251e948693eSPhilip Paeps 	__in				boolean_t enabled)
252e948693eSPhilip Paeps {
253e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
254ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
255460cb568SAndrew Rybchenko 	efx_rc_t rc;
256e948693eSPhilip Paeps 
257e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
258e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
259e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
260e948693eSPhilip Paeps 
261e948693eSPhilip Paeps 	if (epp->ep_mac_drain == enabled)
262e948693eSPhilip Paeps 		return (0);
263e948693eSPhilip Paeps 
264e948693eSPhilip Paeps 	epp->ep_mac_drain = enabled;
265e948693eSPhilip Paeps 
266e948693eSPhilip Paeps 	if ((rc = emop->emo_reconfigure(enp)) != 0)
2670c909247SAndrew Rybchenko 		goto fail1;
268e948693eSPhilip Paeps 
269e948693eSPhilip Paeps 	return (0);
270e948693eSPhilip Paeps 
271e948693eSPhilip Paeps fail1:
272460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
273e948693eSPhilip Paeps 
274e948693eSPhilip Paeps 	return (rc);
275e948693eSPhilip Paeps }
276e948693eSPhilip Paeps 
277460cb568SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_mac_up(__in efx_nic_t * enp,__out boolean_t * mac_upp)278e948693eSPhilip Paeps efx_mac_up(
279e948693eSPhilip Paeps 	__in		efx_nic_t *enp,
280e948693eSPhilip Paeps 	__out		boolean_t *mac_upp)
281e948693eSPhilip Paeps {
282e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
283ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
284460cb568SAndrew Rybchenko 	efx_rc_t rc;
285e948693eSPhilip Paeps 
286e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
287e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
288e948693eSPhilip Paeps 
289e948693eSPhilip Paeps 	if ((rc = emop->emo_up(enp, mac_upp)) != 0)
290e948693eSPhilip Paeps 		goto fail1;
291e948693eSPhilip Paeps 
292e948693eSPhilip Paeps 	return (0);
293e948693eSPhilip Paeps 
294e948693eSPhilip Paeps fail1:
295460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
296e948693eSPhilip Paeps 
297e948693eSPhilip Paeps 	return (rc);
298e948693eSPhilip Paeps }
299e948693eSPhilip Paeps 
300460cb568SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_fcntl_set(__in efx_nic_t * enp,__in unsigned int fcntl,__in boolean_t autoneg)301e948693eSPhilip Paeps efx_mac_fcntl_set(
302e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
303e948693eSPhilip Paeps 	__in				unsigned int fcntl,
304e948693eSPhilip Paeps 	__in				boolean_t autoneg)
305e948693eSPhilip Paeps {
306e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
307ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
308ec831f7fSAndrew Rybchenko 	const efx_phy_ops_t *epop = epp->ep_epop;
309e948693eSPhilip Paeps 	unsigned int old_fcntl;
310e948693eSPhilip Paeps 	boolean_t old_autoneg;
311e948693eSPhilip Paeps 	unsigned int old_adv_cap;
312460cb568SAndrew Rybchenko 	efx_rc_t rc;
313e948693eSPhilip Paeps 
314e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
315e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
316e948693eSPhilip Paeps 
317e948693eSPhilip Paeps 	if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
318e948693eSPhilip Paeps 		rc = EINVAL;
319e948693eSPhilip Paeps 		goto fail1;
320e948693eSPhilip Paeps 	}
321e948693eSPhilip Paeps 
322e948693eSPhilip Paeps 	/*
3233c838a9fSAndrew Rybchenko 	 * Ignore a request to set flow control auto-negotiation
324e948693eSPhilip Paeps 	 * if the PHY doesn't support it.
325e948693eSPhilip Paeps 	 */
326e948693eSPhilip Paeps 	if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
327e948693eSPhilip Paeps 		autoneg = B_FALSE;
328e948693eSPhilip Paeps 
329e948693eSPhilip Paeps 	old_fcntl = epp->ep_fcntl;
3303c838a9fSAndrew Rybchenko 	old_autoneg = epp->ep_fcntl_autoneg;
331e948693eSPhilip Paeps 	old_adv_cap = epp->ep_adv_cap_mask;
332e948693eSPhilip Paeps 
333e948693eSPhilip Paeps 	epp->ep_fcntl = fcntl;
334e948693eSPhilip Paeps 	epp->ep_fcntl_autoneg = autoneg;
335e948693eSPhilip Paeps 
336e948693eSPhilip Paeps 	/*
3373c838a9fSAndrew Rybchenko 	 * Always encode the flow control settings in the advertised
3383c838a9fSAndrew Rybchenko 	 * capabilities even if we are not trying to auto-negotiate
3393c838a9fSAndrew Rybchenko 	 * them and reconfigure both the PHY and the MAC.
340e948693eSPhilip Paeps 	 */
341e948693eSPhilip Paeps 	if (fcntl & EFX_FCNTL_RESPOND)
342e948693eSPhilip Paeps 		epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
343e948693eSPhilip Paeps 					    1 << EFX_PHY_CAP_ASYM);
344e948693eSPhilip Paeps 	else
345e948693eSPhilip Paeps 		epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
346e948693eSPhilip Paeps 					    1 << EFX_PHY_CAP_ASYM);
347e948693eSPhilip Paeps 
348e948693eSPhilip Paeps 	if (fcntl & EFX_FCNTL_GENERATE)
349e948693eSPhilip Paeps 		epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
350e948693eSPhilip Paeps 
351e948693eSPhilip Paeps 	if ((rc = epop->epo_reconfigure(enp)) != 0)
352e948693eSPhilip Paeps 		goto fail2;
353e948693eSPhilip Paeps 
354e948693eSPhilip Paeps 	if ((rc = emop->emo_reconfigure(enp)) != 0)
3553c838a9fSAndrew Rybchenko 		goto fail3;
356e948693eSPhilip Paeps 
357e948693eSPhilip Paeps 	return (0);
358e948693eSPhilip Paeps 
3593c838a9fSAndrew Rybchenko fail3:
3603c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail3);
3613c838a9fSAndrew Rybchenko 
362e948693eSPhilip Paeps fail2:
363e948693eSPhilip Paeps 	EFSYS_PROBE(fail2);
364e948693eSPhilip Paeps 
365e948693eSPhilip Paeps 	epp->ep_fcntl = old_fcntl;
366e948693eSPhilip Paeps 	epp->ep_fcntl_autoneg = old_autoneg;
367e948693eSPhilip Paeps 	epp->ep_adv_cap_mask = old_adv_cap;
368e948693eSPhilip Paeps 
369e948693eSPhilip Paeps fail1:
370460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
371e948693eSPhilip Paeps 
372e948693eSPhilip Paeps 	return (rc);
373e948693eSPhilip Paeps }
374e948693eSPhilip Paeps 
375e948693eSPhilip Paeps 			void
efx_mac_fcntl_get(__in efx_nic_t * enp,__out unsigned int * fcntl_wantedp,__out unsigned int * fcntl_linkp)376e948693eSPhilip Paeps efx_mac_fcntl_get(
377e948693eSPhilip Paeps 	__in		efx_nic_t *enp,
378e948693eSPhilip Paeps 	__out		unsigned int *fcntl_wantedp,
379e948693eSPhilip Paeps 	__out		unsigned int *fcntl_linkp)
380e948693eSPhilip Paeps {
381e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
3823c838a9fSAndrew Rybchenko 	unsigned int wanted = 0;
383e948693eSPhilip Paeps 
384e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
385e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
386e948693eSPhilip Paeps 
387e948693eSPhilip Paeps 	/*
3883c838a9fSAndrew Rybchenko 	 * Decode the requested flow control settings from the PHY
3893c838a9fSAndrew Rybchenko 	 * advertised capabilities.
390e948693eSPhilip Paeps 	 */
391e948693eSPhilip Paeps 	if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
392e948693eSPhilip Paeps 		wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
393e948693eSPhilip Paeps 	if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
394e948693eSPhilip Paeps 		wanted ^= EFX_FCNTL_GENERATE;
395e948693eSPhilip Paeps 
396e948693eSPhilip Paeps 	*fcntl_linkp = epp->ep_fcntl;
397e948693eSPhilip Paeps 	*fcntl_wantedp = wanted;
398e948693eSPhilip Paeps }
399e948693eSPhilip Paeps 
400460cb568SAndrew Rybchenko 	__checkReturn	efx_rc_t
4013c838a9fSAndrew Rybchenko efx_mac_multicast_list_set(
4023c838a9fSAndrew Rybchenko 	__in				efx_nic_t *enp,
4033c838a9fSAndrew Rybchenko 	__in_ecount(6*count)		uint8_t const *addrs,
4043c838a9fSAndrew Rybchenko 	__in				int count)
4053c838a9fSAndrew Rybchenko {
4063c838a9fSAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
407ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
4083c838a9fSAndrew Rybchenko 	uint8_t	*old_mulcst_addr_list = NULL;
4093c838a9fSAndrew Rybchenko 	uint32_t old_mulcst_addr_count;
410460cb568SAndrew Rybchenko 	efx_rc_t rc;
4113c838a9fSAndrew Rybchenko 
4123c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
4133c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
4143c838a9fSAndrew Rybchenko 
4153c838a9fSAndrew Rybchenko 	if (count > EFX_MAC_MULTICAST_LIST_MAX) {
4163c838a9fSAndrew Rybchenko 		rc = EINVAL;
4173c838a9fSAndrew Rybchenko 		goto fail1;
4183c838a9fSAndrew Rybchenko 	}
4193c838a9fSAndrew Rybchenko 
4203c838a9fSAndrew Rybchenko 	old_mulcst_addr_count = epp->ep_mulcst_addr_count;
4213c838a9fSAndrew Rybchenko 	if (old_mulcst_addr_count > 0) {
4223c838a9fSAndrew Rybchenko 		/* Allocate memory to store old list (instead of using stack) */
4233c838a9fSAndrew Rybchenko 		EFSYS_KMEM_ALLOC(enp->en_esip,
4243c838a9fSAndrew Rybchenko 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4253c838a9fSAndrew Rybchenko 				old_mulcst_addr_list);
4263c838a9fSAndrew Rybchenko 		if (old_mulcst_addr_list == NULL) {
4273c838a9fSAndrew Rybchenko 			rc = ENOMEM;
4283c838a9fSAndrew Rybchenko 			goto fail2;
4293c838a9fSAndrew Rybchenko 		}
4303c838a9fSAndrew Rybchenko 
4313c838a9fSAndrew Rybchenko 		/* Save the old list in case we need to rollback */
4323c838a9fSAndrew Rybchenko 		memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
4333c838a9fSAndrew Rybchenko 			old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
4343c838a9fSAndrew Rybchenko 	}
4353c838a9fSAndrew Rybchenko 
4363c838a9fSAndrew Rybchenko 	/* Store the new list */
4373c838a9fSAndrew Rybchenko 	memcpy(epp->ep_mulcst_addr_list, addrs,
4383c838a9fSAndrew Rybchenko 		count * EFX_MAC_ADDR_LEN);
4393c838a9fSAndrew Rybchenko 	epp->ep_mulcst_addr_count = count;
4403c838a9fSAndrew Rybchenko 
4413c838a9fSAndrew Rybchenko 	if ((rc = emop->emo_multicast_list_set(enp)) != 0)
4423c838a9fSAndrew Rybchenko 		goto fail3;
4433c838a9fSAndrew Rybchenko 
4443c838a9fSAndrew Rybchenko 	if (old_mulcst_addr_count > 0) {
4453c838a9fSAndrew Rybchenko 		EFSYS_KMEM_FREE(enp->en_esip,
4463c838a9fSAndrew Rybchenko 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4473c838a9fSAndrew Rybchenko 				old_mulcst_addr_list);
4483c838a9fSAndrew Rybchenko 	}
4493c838a9fSAndrew Rybchenko 
4503c838a9fSAndrew Rybchenko 	return (0);
4513c838a9fSAndrew Rybchenko 
4523c838a9fSAndrew Rybchenko fail3:
4533c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail3);
4543c838a9fSAndrew Rybchenko 
4553c838a9fSAndrew Rybchenko 	/* Restore original list on failure */
4563c838a9fSAndrew Rybchenko 	epp->ep_mulcst_addr_count = old_mulcst_addr_count;
4573c838a9fSAndrew Rybchenko 	if (old_mulcst_addr_count > 0) {
4583c838a9fSAndrew Rybchenko 		memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
4593c838a9fSAndrew Rybchenko 			old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
4603c838a9fSAndrew Rybchenko 
4613c838a9fSAndrew Rybchenko 		EFSYS_KMEM_FREE(enp->en_esip,
4623c838a9fSAndrew Rybchenko 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
4633c838a9fSAndrew Rybchenko 				old_mulcst_addr_list);
4643c838a9fSAndrew Rybchenko 	}
4653c838a9fSAndrew Rybchenko 
4663c838a9fSAndrew Rybchenko fail2:
4673c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
4683c838a9fSAndrew Rybchenko 
4693c838a9fSAndrew Rybchenko fail1:
470460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4713c838a9fSAndrew Rybchenko 
4723c838a9fSAndrew Rybchenko 	return (rc);
4733c838a9fSAndrew Rybchenko 
4743c838a9fSAndrew Rybchenko }
4753c838a9fSAndrew Rybchenko 
476460cb568SAndrew 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)4773c838a9fSAndrew Rybchenko efx_mac_filter_default_rxq_set(
4783c838a9fSAndrew Rybchenko 	__in		efx_nic_t *enp,
4793c838a9fSAndrew Rybchenko 	__in		efx_rxq_t *erp,
4803c838a9fSAndrew Rybchenko 	__in		boolean_t using_rss)
4813c838a9fSAndrew Rybchenko {
4823c838a9fSAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
483ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
484460cb568SAndrew Rybchenko 	efx_rc_t rc;
4853c838a9fSAndrew Rybchenko 
4863c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
4873c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
4883c838a9fSAndrew Rybchenko 
4893c838a9fSAndrew Rybchenko 	if (emop->emo_filter_default_rxq_set != NULL) {
4903c838a9fSAndrew Rybchenko 		rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
4913c838a9fSAndrew Rybchenko 		if (rc != 0)
4923c838a9fSAndrew Rybchenko 			goto fail1;
4933c838a9fSAndrew Rybchenko 	}
4943c838a9fSAndrew Rybchenko 
4953c838a9fSAndrew Rybchenko 	return (0);
4963c838a9fSAndrew Rybchenko 
4973c838a9fSAndrew Rybchenko fail1:
498460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4993c838a9fSAndrew Rybchenko 
5003c838a9fSAndrew Rybchenko 	return (rc);
5013c838a9fSAndrew Rybchenko }
5023c838a9fSAndrew Rybchenko 
5033c838a9fSAndrew Rybchenko 			void
efx_mac_filter_default_rxq_clear(__in efx_nic_t * enp)5043c838a9fSAndrew Rybchenko efx_mac_filter_default_rxq_clear(
5053c838a9fSAndrew Rybchenko 	__in		efx_nic_t *enp)
5063c838a9fSAndrew Rybchenko {
5073c838a9fSAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
508ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
5093c838a9fSAndrew Rybchenko 
5103c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
5113c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
5123c838a9fSAndrew Rybchenko 
5133c838a9fSAndrew Rybchenko 	if (emop->emo_filter_default_rxq_clear != NULL)
5143c838a9fSAndrew Rybchenko 		emop->emo_filter_default_rxq_clear(enp);
5153c838a9fSAndrew Rybchenko }
5163c838a9fSAndrew Rybchenko 
517e948693eSPhilip Paeps #if EFSYS_OPT_MAC_STATS
518e948693eSPhilip Paeps 
519e948693eSPhilip Paeps #if EFSYS_OPT_NAMES
520e948693eSPhilip Paeps 
521c27e7228SAndrew Rybchenko /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
522a260bd77SAndrew Rybchenko static const char * const __efx_mac_stat_name[] = {
523e948693eSPhilip Paeps 	"rx_octets",
524e948693eSPhilip Paeps 	"rx_pkts",
525e948693eSPhilip Paeps 	"rx_unicst_pkts",
526e948693eSPhilip Paeps 	"rx_multicst_pkts",
527e948693eSPhilip Paeps 	"rx_brdcst_pkts",
528e948693eSPhilip Paeps 	"rx_pause_pkts",
529e948693eSPhilip Paeps 	"rx_le_64_pkts",
530e948693eSPhilip Paeps 	"rx_65_to_127_pkts",
531e948693eSPhilip Paeps 	"rx_128_to_255_pkts",
532e948693eSPhilip Paeps 	"rx_256_to_511_pkts",
533e948693eSPhilip Paeps 	"rx_512_to_1023_pkts",
534e948693eSPhilip Paeps 	"rx_1024_to_15xx_pkts",
535e948693eSPhilip Paeps 	"rx_ge_15xx_pkts",
536e948693eSPhilip Paeps 	"rx_errors",
537e948693eSPhilip Paeps 	"rx_fcs_errors",
538e948693eSPhilip Paeps 	"rx_drop_events",
539e948693eSPhilip Paeps 	"rx_false_carrier_errors",
540e948693eSPhilip Paeps 	"rx_symbol_errors",
541e948693eSPhilip Paeps 	"rx_align_errors",
542e948693eSPhilip Paeps 	"rx_internal_errors",
543e948693eSPhilip Paeps 	"rx_jabber_pkts",
544e948693eSPhilip Paeps 	"rx_lane0_char_err",
545e948693eSPhilip Paeps 	"rx_lane1_char_err",
546e948693eSPhilip Paeps 	"rx_lane2_char_err",
547e948693eSPhilip Paeps 	"rx_lane3_char_err",
548e948693eSPhilip Paeps 	"rx_lane0_disp_err",
549e948693eSPhilip Paeps 	"rx_lane1_disp_err",
550e948693eSPhilip Paeps 	"rx_lane2_disp_err",
551e948693eSPhilip Paeps 	"rx_lane3_disp_err",
552e948693eSPhilip Paeps 	"rx_match_fault",
553e948693eSPhilip Paeps 	"rx_nodesc_drop_cnt",
554e948693eSPhilip Paeps 	"tx_octets",
555e948693eSPhilip Paeps 	"tx_pkts",
556e948693eSPhilip Paeps 	"tx_unicst_pkts",
557e948693eSPhilip Paeps 	"tx_multicst_pkts",
558e948693eSPhilip Paeps 	"tx_brdcst_pkts",
559e948693eSPhilip Paeps 	"tx_pause_pkts",
560e948693eSPhilip Paeps 	"tx_le_64_pkts",
561e948693eSPhilip Paeps 	"tx_65_to_127_pkts",
562e948693eSPhilip Paeps 	"tx_128_to_255_pkts",
563e948693eSPhilip Paeps 	"tx_256_to_511_pkts",
564e948693eSPhilip Paeps 	"tx_512_to_1023_pkts",
565e948693eSPhilip Paeps 	"tx_1024_to_15xx_pkts",
566e948693eSPhilip Paeps 	"tx_ge_15xx_pkts",
567e948693eSPhilip Paeps 	"tx_errors",
568e948693eSPhilip Paeps 	"tx_sgl_col_pkts",
569e948693eSPhilip Paeps 	"tx_mult_col_pkts",
570e948693eSPhilip Paeps 	"tx_ex_col_pkts",
571e948693eSPhilip Paeps 	"tx_late_col_pkts",
572e948693eSPhilip Paeps 	"tx_def_pkts",
573e948693eSPhilip Paeps 	"tx_ex_def_pkts",
5743c838a9fSAndrew Rybchenko 	"pm_trunc_bb_overflow",
5753c838a9fSAndrew Rybchenko 	"pm_discard_bb_overflow",
5763c838a9fSAndrew Rybchenko 	"pm_trunc_vfifo_full",
5773c838a9fSAndrew Rybchenko 	"pm_discard_vfifo_full",
5783c838a9fSAndrew Rybchenko 	"pm_trunc_qbb",
5793c838a9fSAndrew Rybchenko 	"pm_discard_qbb",
5803c838a9fSAndrew Rybchenko 	"pm_discard_mapping",
5813c838a9fSAndrew Rybchenko 	"rxdp_q_disabled_pkts",
5823c838a9fSAndrew Rybchenko 	"rxdp_di_dropped_pkts",
5833c838a9fSAndrew Rybchenko 	"rxdp_streaming_pkts",
5843c838a9fSAndrew Rybchenko 	"rxdp_hlb_fetch",
5853c838a9fSAndrew Rybchenko 	"rxdp_hlb_wait",
5863c838a9fSAndrew Rybchenko 	"vadapter_rx_unicast_packets",
5873c838a9fSAndrew Rybchenko 	"vadapter_rx_unicast_bytes",
5883c838a9fSAndrew Rybchenko 	"vadapter_rx_multicast_packets",
5893c838a9fSAndrew Rybchenko 	"vadapter_rx_multicast_bytes",
5903c838a9fSAndrew Rybchenko 	"vadapter_rx_broadcast_packets",
5913c838a9fSAndrew Rybchenko 	"vadapter_rx_broadcast_bytes",
5923c838a9fSAndrew Rybchenko 	"vadapter_rx_bad_packets",
5933c838a9fSAndrew Rybchenko 	"vadapter_rx_bad_bytes",
5943c838a9fSAndrew Rybchenko 	"vadapter_rx_overflow",
5953c838a9fSAndrew Rybchenko 	"vadapter_tx_unicast_packets",
5963c838a9fSAndrew Rybchenko 	"vadapter_tx_unicast_bytes",
5973c838a9fSAndrew Rybchenko 	"vadapter_tx_multicast_packets",
5983c838a9fSAndrew Rybchenko 	"vadapter_tx_multicast_bytes",
5993c838a9fSAndrew Rybchenko 	"vadapter_tx_broadcast_packets",
6003c838a9fSAndrew Rybchenko 	"vadapter_tx_broadcast_bytes",
6013c838a9fSAndrew Rybchenko 	"vadapter_tx_bad_packets",
6023c838a9fSAndrew Rybchenko 	"vadapter_tx_bad_bytes",
6033c838a9fSAndrew Rybchenko 	"vadapter_tx_overflow",
60479300430SAndrew Rybchenko 	"fec_uncorrected_errors",
60579300430SAndrew Rybchenko 	"fec_corrected_errors",
60679300430SAndrew Rybchenko 	"fec_corrected_symbols_lane0",
60779300430SAndrew Rybchenko 	"fec_corrected_symbols_lane1",
60879300430SAndrew Rybchenko 	"fec_corrected_symbols_lane2",
60979300430SAndrew Rybchenko 	"fec_corrected_symbols_lane3",
6102fdc432cSAndrew Rybchenko 	"ctpio_vi_busy_fallback",
6112fdc432cSAndrew Rybchenko 	"ctpio_long_write_success",
6122fdc432cSAndrew Rybchenko 	"ctpio_missing_dbell_fail",
6132fdc432cSAndrew Rybchenko 	"ctpio_overflow_fail",
6142fdc432cSAndrew Rybchenko 	"ctpio_underflow_fail",
6152fdc432cSAndrew Rybchenko 	"ctpio_timeout_fail",
6162fdc432cSAndrew Rybchenko 	"ctpio_noncontig_wr_fail",
6172fdc432cSAndrew Rybchenko 	"ctpio_frm_clobber_fail",
6182fdc432cSAndrew Rybchenko 	"ctpio_invalid_wr_fail",
6192fdc432cSAndrew Rybchenko 	"ctpio_vi_clobber_fallback",
6202fdc432cSAndrew Rybchenko 	"ctpio_unqualified_fallback",
6212fdc432cSAndrew Rybchenko 	"ctpio_runt_fallback",
6222fdc432cSAndrew Rybchenko 	"ctpio_success",
6232fdc432cSAndrew Rybchenko 	"ctpio_fallback",
6242fdc432cSAndrew Rybchenko 	"ctpio_poison",
6252fdc432cSAndrew Rybchenko 	"ctpio_erase",
626c27e7228SAndrew Rybchenko 	"rxdp_scatter_disabled_trunc",
627c27e7228SAndrew Rybchenko 	"rxdp_hlb_idle",
628c27e7228SAndrew Rybchenko 	"rxdp_hlb_timeout",
629e948693eSPhilip Paeps };
630e948693eSPhilip Paeps /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
631e948693eSPhilip Paeps 
6323c838a9fSAndrew Rybchenko 	__checkReturn			const char *
efx_mac_stat_name(__in efx_nic_t * enp,__in unsigned int id)633e948693eSPhilip Paeps efx_mac_stat_name(
634e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
635e948693eSPhilip Paeps 	__in				unsigned int id)
636e948693eSPhilip Paeps {
637e948693eSPhilip Paeps 	_NOTE(ARGUNUSED(enp))
638e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
639e948693eSPhilip Paeps 
640e948693eSPhilip Paeps 	EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
641e948693eSPhilip Paeps 	return (__efx_mac_stat_name[id]);
642e948693eSPhilip Paeps }
643e948693eSPhilip Paeps 
6443c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_NAMES */
645e948693eSPhilip Paeps 
64658a72cb2SAndrew 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)64758a72cb2SAndrew Rybchenko efx_mac_stats_mask_add_range(
64858a72cb2SAndrew Rybchenko 	__inout_bcount(mask_size)	uint32_t *maskp,
64958a72cb2SAndrew Rybchenko 	__in				size_t mask_size,
65058a72cb2SAndrew Rybchenko 	__in				const struct efx_mac_stats_range *rngp)
65158a72cb2SAndrew Rybchenko {
65258a72cb2SAndrew Rybchenko 	unsigned int mask_npages = mask_size / sizeof (*maskp);
65358a72cb2SAndrew Rybchenko 	unsigned int el;
65458a72cb2SAndrew Rybchenko 	unsigned int el_min;
65558a72cb2SAndrew Rybchenko 	unsigned int el_max;
65658a72cb2SAndrew Rybchenko 	unsigned int low;
65758a72cb2SAndrew Rybchenko 	unsigned int high;
65858a72cb2SAndrew Rybchenko 	unsigned int width;
65958a72cb2SAndrew Rybchenko 	efx_rc_t rc;
66058a72cb2SAndrew Rybchenko 
66158a72cb2SAndrew Rybchenko 	if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
66258a72cb2SAndrew Rybchenko 	    (unsigned int)rngp->last) {
66358a72cb2SAndrew Rybchenko 		rc = EINVAL;
66458a72cb2SAndrew Rybchenko 		goto fail1;
66558a72cb2SAndrew Rybchenko 	}
66658a72cb2SAndrew Rybchenko 
66758a72cb2SAndrew Rybchenko 	EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
66858a72cb2SAndrew Rybchenko 	EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
66958a72cb2SAndrew Rybchenko 
67058a72cb2SAndrew Rybchenko 	for (el = 0; el < mask_npages; ++el) {
67158a72cb2SAndrew Rybchenko 		el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
67258a72cb2SAndrew Rybchenko 		el_max =
67358a72cb2SAndrew Rybchenko 		    el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
67458a72cb2SAndrew Rybchenko 		if ((unsigned int)rngp->first > el_max ||
67558a72cb2SAndrew Rybchenko 		    (unsigned int)rngp->last < el_min)
67658a72cb2SAndrew Rybchenko 			continue;
67758a72cb2SAndrew Rybchenko 		low = MAX((unsigned int)rngp->first, el_min);
67858a72cb2SAndrew Rybchenko 		high = MIN((unsigned int)rngp->last, el_max);
67958a72cb2SAndrew Rybchenko 		width = high - low + 1;
68058a72cb2SAndrew Rybchenko 		maskp[el] |=
68158a72cb2SAndrew Rybchenko 		    (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
68258a72cb2SAndrew Rybchenko 		    (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
68358a72cb2SAndrew Rybchenko 	}
68458a72cb2SAndrew Rybchenko 
68558a72cb2SAndrew Rybchenko 	return (0);
68658a72cb2SAndrew Rybchenko 
68758a72cb2SAndrew Rybchenko fail1:
68858a72cb2SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
68958a72cb2SAndrew Rybchenko 
69058a72cb2SAndrew Rybchenko 	return (rc);
69158a72cb2SAndrew Rybchenko }
69258a72cb2SAndrew Rybchenko 
69358a72cb2SAndrew 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)69458a72cb2SAndrew Rybchenko efx_mac_stats_mask_add_ranges(
69558a72cb2SAndrew Rybchenko 	__inout_bcount(mask_size)	uint32_t *maskp,
69658a72cb2SAndrew Rybchenko 	__in				size_t mask_size,
69758a72cb2SAndrew Rybchenko 	__in_ecount(rng_count)		const struct efx_mac_stats_range *rngp,
69858a72cb2SAndrew Rybchenko 	__in				unsigned int rng_count)
69958a72cb2SAndrew Rybchenko {
70058a72cb2SAndrew Rybchenko 	unsigned int i;
70158a72cb2SAndrew Rybchenko 	efx_rc_t rc;
70258a72cb2SAndrew Rybchenko 
70358a72cb2SAndrew Rybchenko 	for (i = 0; i < rng_count; ++i) {
70458a72cb2SAndrew Rybchenko 		if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
70558a72cb2SAndrew Rybchenko 		    &rngp[i])) != 0)
70658a72cb2SAndrew Rybchenko 			goto fail1;
70758a72cb2SAndrew Rybchenko 	}
70858a72cb2SAndrew Rybchenko 
70958a72cb2SAndrew Rybchenko 	return (0);
71058a72cb2SAndrew Rybchenko 
71158a72cb2SAndrew Rybchenko fail1:
71258a72cb2SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
71358a72cb2SAndrew Rybchenko 
71458a72cb2SAndrew Rybchenko 	return (rc);
71558a72cb2SAndrew Rybchenko }
71658a72cb2SAndrew Rybchenko 
71758a72cb2SAndrew 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)71858a72cb2SAndrew Rybchenko efx_mac_stats_get_mask(
71958a72cb2SAndrew Rybchenko 	__in				efx_nic_t *enp,
72058a72cb2SAndrew Rybchenko 	__out_bcount(mask_size)		uint32_t *maskp,
72158a72cb2SAndrew Rybchenko 	__in				size_t mask_size)
72258a72cb2SAndrew Rybchenko {
72358a72cb2SAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
72458a72cb2SAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
72558a72cb2SAndrew Rybchenko 	efx_rc_t rc;
72658a72cb2SAndrew Rybchenko 
72758a72cb2SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
72858a72cb2SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
72958a72cb2SAndrew Rybchenko 	EFSYS_ASSERT(maskp != NULL);
73058a72cb2SAndrew Rybchenko 	EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
73158a72cb2SAndrew Rybchenko 
73258a72cb2SAndrew Rybchenko 	(void) memset(maskp, 0, mask_size);
73358a72cb2SAndrew Rybchenko 
73458a72cb2SAndrew Rybchenko 	if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
73558a72cb2SAndrew Rybchenko 		goto fail1;
73658a72cb2SAndrew Rybchenko 
73758a72cb2SAndrew Rybchenko 	return (0);
73858a72cb2SAndrew Rybchenko 
73958a72cb2SAndrew Rybchenko fail1:
74058a72cb2SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
74158a72cb2SAndrew Rybchenko 
74258a72cb2SAndrew Rybchenko 	return (rc);
74358a72cb2SAndrew Rybchenko }
74458a72cb2SAndrew Rybchenko 
745460cb568SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_stats_clear(__in efx_nic_t * enp)74631e518b4SAndrew Rybchenko efx_mac_stats_clear(
74731e518b4SAndrew Rybchenko 	__in				efx_nic_t *enp)
74831e518b4SAndrew Rybchenko {
74931e518b4SAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
75031e518b4SAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
75131e518b4SAndrew Rybchenko 	efx_rc_t rc;
75231e518b4SAndrew Rybchenko 
75331e518b4SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
75431e518b4SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
75531e518b4SAndrew Rybchenko 	EFSYS_ASSERT(emop != NULL);
75631e518b4SAndrew Rybchenko 
75731e518b4SAndrew Rybchenko 	if ((rc = emop->emo_stats_clear(enp)) != 0)
75831e518b4SAndrew Rybchenko 		goto fail1;
75931e518b4SAndrew Rybchenko 
76031e518b4SAndrew Rybchenko 	return (0);
76131e518b4SAndrew Rybchenko 
76231e518b4SAndrew Rybchenko fail1:
76331e518b4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
76431e518b4SAndrew Rybchenko 
76531e518b4SAndrew Rybchenko 	return (rc);
76631e518b4SAndrew Rybchenko }
76731e518b4SAndrew Rybchenko 
76831e518b4SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_stats_upload(__in efx_nic_t * enp,__in efsys_mem_t * esmp)769e948693eSPhilip Paeps efx_mac_stats_upload(
770e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
771e948693eSPhilip Paeps 	__in				efsys_mem_t *esmp)
772e948693eSPhilip Paeps {
773e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
774ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
775460cb568SAndrew Rybchenko 	efx_rc_t rc;
776e948693eSPhilip Paeps 
777e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
778e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
779e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
780e948693eSPhilip Paeps 
781e948693eSPhilip Paeps 	if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
782e948693eSPhilip Paeps 		goto fail1;
783e948693eSPhilip Paeps 
784e948693eSPhilip Paeps 	return (0);
785e948693eSPhilip Paeps 
786e948693eSPhilip Paeps fail1:
787460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
788e948693eSPhilip Paeps 
789e948693eSPhilip Paeps 	return (rc);
790e948693eSPhilip Paeps }
791e948693eSPhilip Paeps 
792460cb568SAndrew 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)793e948693eSPhilip Paeps efx_mac_stats_periodic(
794e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
795e948693eSPhilip Paeps 	__in				efsys_mem_t *esmp,
796e948693eSPhilip Paeps 	__in				uint16_t period_ms,
797e948693eSPhilip Paeps 	__in				boolean_t events)
798e948693eSPhilip Paeps {
799e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
800ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
801460cb568SAndrew Rybchenko 	efx_rc_t rc;
802e948693eSPhilip Paeps 
803e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
804e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
805e948693eSPhilip Paeps 
806e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
807e948693eSPhilip Paeps 
808e948693eSPhilip Paeps 	if (emop->emo_stats_periodic == NULL) {
809e948693eSPhilip Paeps 		rc = EINVAL;
810e948693eSPhilip Paeps 		goto fail1;
811e948693eSPhilip Paeps 	}
812e948693eSPhilip Paeps 
813e948693eSPhilip Paeps 	if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
814e948693eSPhilip Paeps 		goto fail2;
815e948693eSPhilip Paeps 
816e948693eSPhilip Paeps 	return (0);
817e948693eSPhilip Paeps 
818e948693eSPhilip Paeps fail2:
819e948693eSPhilip Paeps 	EFSYS_PROBE(fail2);
820e948693eSPhilip Paeps fail1:
821460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
822e948693eSPhilip Paeps 
823e948693eSPhilip Paeps 	return (rc);
824e948693eSPhilip Paeps }
825e948693eSPhilip Paeps 
826460cb568SAndrew 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)827e948693eSPhilip Paeps efx_mac_stats_update(
828e948693eSPhilip Paeps 	__in				efx_nic_t *enp,
829e948693eSPhilip Paeps 	__in				efsys_mem_t *esmp,
830e948693eSPhilip Paeps 	__inout_ecount(EFX_MAC_NSTATS)	efsys_stat_t *essp,
83114c3e490SAndrew Rybchenko 	__inout_opt			uint32_t *generationp)
832e948693eSPhilip Paeps {
833e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
834ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
835460cb568SAndrew Rybchenko 	efx_rc_t rc;
836e948693eSPhilip Paeps 
837e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
838e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
839e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
840e948693eSPhilip Paeps 
841e948693eSPhilip Paeps 	rc = emop->emo_stats_update(enp, esmp, essp, generationp);
842e948693eSPhilip Paeps 
843e948693eSPhilip Paeps 	return (rc);
844e948693eSPhilip Paeps }
845e948693eSPhilip Paeps 
846e948693eSPhilip Paeps #endif	/* EFSYS_OPT_MAC_STATS */
847e948693eSPhilip Paeps 
848460cb568SAndrew Rybchenko 	__checkReturn			efx_rc_t
efx_mac_select(__in efx_nic_t * enp)849e948693eSPhilip Paeps efx_mac_select(
850e948693eSPhilip Paeps 	__in				efx_nic_t *enp)
851e948693eSPhilip Paeps {
852e948693eSPhilip Paeps 	efx_port_t *epp = &(enp->en_port);
853e948693eSPhilip Paeps 	efx_mac_type_t type = EFX_MAC_INVALID;
854ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop;
855e948693eSPhilip Paeps 	int rc = EINVAL;
856e948693eSPhilip Paeps 
85795812f27SAndrew Rybchenko 	switch (enp->en_family) {
858c15d6d21SAndrew Rybchenko #if EFSYS_OPT_SIENA
85995812f27SAndrew Rybchenko 	case EFX_FAMILY_SIENA:
860ae346558SAndrew Rybchenko 		emop = &__efx_mac_siena_ops;
861c15d6d21SAndrew Rybchenko 		type = EFX_MAC_SIENA;
86295812f27SAndrew Rybchenko 		break;
86395812f27SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
864c15d6d21SAndrew Rybchenko 
8653c838a9fSAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
86695812f27SAndrew Rybchenko 	case EFX_FAMILY_HUNTINGTON:
867ae346558SAndrew Rybchenko 		emop = &__efx_mac_ef10_ops;
8683c838a9fSAndrew Rybchenko 		type = EFX_MAC_HUNTINGTON;
86995812f27SAndrew Rybchenko 		break;
87095812f27SAndrew Rybchenko #endif /* EFSYS_OPT_HUNTINGTON */
8713c838a9fSAndrew Rybchenko 
872c15d6d21SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
87395812f27SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD:
874ae346558SAndrew Rybchenko 		emop = &__efx_mac_ef10_ops;
875c15d6d21SAndrew Rybchenko 		type = EFX_MAC_MEDFORD;
87695812f27SAndrew Rybchenko 		break;
87795812f27SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD */
878e948693eSPhilip Paeps 
879cbc3f94fSAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
880cbc3f94fSAndrew Rybchenko 	case EFX_FAMILY_MEDFORD2:
881cbc3f94fSAndrew Rybchenko 		emop = &__efx_mac_ef10_ops;
882cbc3f94fSAndrew Rybchenko 		type = EFX_MAC_MEDFORD2;
883cbc3f94fSAndrew Rybchenko 		break;
884cbc3f94fSAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD2 */
885cbc3f94fSAndrew Rybchenko 
88695812f27SAndrew Rybchenko 	default:
88795812f27SAndrew Rybchenko 		rc = EINVAL;
88895812f27SAndrew Rybchenko 		goto fail1;
88995812f27SAndrew Rybchenko 	}
89095812f27SAndrew Rybchenko 
891e948693eSPhilip Paeps 	EFSYS_ASSERT(type != EFX_MAC_INVALID);
892e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
893e948693eSPhilip Paeps 	EFSYS_ASSERT(emop != NULL);
894e948693eSPhilip Paeps 
89595812f27SAndrew Rybchenko 	epp->ep_emop = emop;
896e948693eSPhilip Paeps 	epp->ep_mac_type = type;
897e948693eSPhilip Paeps 
898e948693eSPhilip Paeps 	return (0);
899e948693eSPhilip Paeps 
900e948693eSPhilip Paeps fail1:
901460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
902e948693eSPhilip Paeps 
903e948693eSPhilip Paeps 	return (rc);
904e948693eSPhilip Paeps }
9053c838a9fSAndrew Rybchenko 
906e75412c9SAndrew Rybchenko #if EFSYS_OPT_SIENA
9073c838a9fSAndrew Rybchenko 
90874bb0ed8SAndrew Rybchenko #define	EFX_MAC_HASH_BITS	(1 << 8)
90974bb0ed8SAndrew Rybchenko 
9103c838a9fSAndrew Rybchenko /* Compute the multicast hash as used on Falcon and Siena. */
9113c838a9fSAndrew Rybchenko static	void
9125cab4fc7SAndrew Rybchenko siena_mac_multicast_hash_compute(
9133c838a9fSAndrew Rybchenko 	__in_ecount(6*count)		uint8_t const *addrs,
9143c838a9fSAndrew Rybchenko 	__in				int count,
9153c838a9fSAndrew Rybchenko 	__out				efx_oword_t *hash_low,
9163c838a9fSAndrew Rybchenko 	__out				efx_oword_t *hash_high)
9173c838a9fSAndrew Rybchenko {
9183c838a9fSAndrew Rybchenko 	uint32_t crc, index;
9193c838a9fSAndrew Rybchenko 	int i;
9203c838a9fSAndrew Rybchenko 
9213c838a9fSAndrew Rybchenko 	EFSYS_ASSERT(hash_low != NULL);
9223c838a9fSAndrew Rybchenko 	EFSYS_ASSERT(hash_high != NULL);
9233c838a9fSAndrew Rybchenko 
9243c838a9fSAndrew Rybchenko 	EFX_ZERO_OWORD(*hash_low);
9253c838a9fSAndrew Rybchenko 	EFX_ZERO_OWORD(*hash_high);
9263c838a9fSAndrew Rybchenko 
9273c838a9fSAndrew Rybchenko 	for (i = 0; i < count; i++) {
9283c838a9fSAndrew Rybchenko 		/* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
9293c838a9fSAndrew Rybchenko 		crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
9303c838a9fSAndrew Rybchenko 		index = crc % EFX_MAC_HASH_BITS;
9313c838a9fSAndrew Rybchenko 		if (index < 128) {
9323c838a9fSAndrew Rybchenko 			EFX_SET_OWORD_BIT(*hash_low, index);
9333c838a9fSAndrew Rybchenko 		} else {
9343c838a9fSAndrew Rybchenko 			EFX_SET_OWORD_BIT(*hash_high, index - 128);
9353c838a9fSAndrew Rybchenko 		}
9363c838a9fSAndrew Rybchenko 
9373c838a9fSAndrew Rybchenko 		addrs += EFX_MAC_ADDR_LEN;
9383c838a9fSAndrew Rybchenko 	}
9393c838a9fSAndrew Rybchenko }
9403c838a9fSAndrew Rybchenko 
941460cb568SAndrew Rybchenko static	__checkReturn	efx_rc_t
siena_mac_multicast_list_set(__in efx_nic_t * enp)9425cab4fc7SAndrew Rybchenko siena_mac_multicast_list_set(
9433c838a9fSAndrew Rybchenko 	__in		efx_nic_t *enp)
9443c838a9fSAndrew Rybchenko {
9453c838a9fSAndrew Rybchenko 	efx_port_t *epp = &(enp->en_port);
946ec831f7fSAndrew Rybchenko 	const efx_mac_ops_t *emop = epp->ep_emop;
9473c838a9fSAndrew Rybchenko 	efx_oword_t old_hash[2];
948460cb568SAndrew Rybchenko 	efx_rc_t rc;
9493c838a9fSAndrew Rybchenko 
9503c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
9513c838a9fSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
9523c838a9fSAndrew Rybchenko 
9533c838a9fSAndrew Rybchenko 	memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
9543c838a9fSAndrew Rybchenko 
9555cab4fc7SAndrew Rybchenko 	siena_mac_multicast_hash_compute(
9565cab4fc7SAndrew Rybchenko 	    epp->ep_mulcst_addr_list,
9573c838a9fSAndrew Rybchenko 	    epp->ep_mulcst_addr_count,
9583c838a9fSAndrew Rybchenko 	    &epp->ep_multicst_hash[0],
9593c838a9fSAndrew Rybchenko 	    &epp->ep_multicst_hash[1]);
9603c838a9fSAndrew Rybchenko 
9613c838a9fSAndrew Rybchenko 	if ((rc = emop->emo_reconfigure(enp)) != 0)
9623c838a9fSAndrew Rybchenko 		goto fail1;
9633c838a9fSAndrew Rybchenko 
9643c838a9fSAndrew Rybchenko 	return (0);
9653c838a9fSAndrew Rybchenko 
9663c838a9fSAndrew Rybchenko fail1:
967460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9683c838a9fSAndrew Rybchenko 
9693c838a9fSAndrew Rybchenko 	memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
9703c838a9fSAndrew Rybchenko 
9713c838a9fSAndrew Rybchenko 	return (rc);
9723c838a9fSAndrew Rybchenko }
9733c838a9fSAndrew Rybchenko 
974e75412c9SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
975