1*49ef7e06SGarrett D'Amore /*
2*49ef7e06SGarrett D'Amore  * Copyright (c) 2007-2015 Solarflare Communications Inc.
3*49ef7e06SGarrett D'Amore  * All rights reserved.
4*49ef7e06SGarrett D'Amore  *
5*49ef7e06SGarrett D'Amore  * Redistribution and use in source and binary forms, with or without
6*49ef7e06SGarrett D'Amore  * modification, are permitted provided that the following conditions are met:
7*49ef7e06SGarrett D'Amore  *
8*49ef7e06SGarrett D'Amore  * 1. Redistributions of source code must retain the above copyright notice,
9*49ef7e06SGarrett D'Amore  *    this list of conditions and the following disclaimer.
10*49ef7e06SGarrett D'Amore  * 2. Redistributions in binary form must reproduce the above copyright notice,
11*49ef7e06SGarrett D'Amore  *    this list of conditions and the following disclaimer in the documentation
12*49ef7e06SGarrett D'Amore  *    and/or other materials provided with the distribution.
13*49ef7e06SGarrett D'Amore  *
14*49ef7e06SGarrett D'Amore  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15*49ef7e06SGarrett D'Amore  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16*49ef7e06SGarrett D'Amore  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17*49ef7e06SGarrett D'Amore  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18*49ef7e06SGarrett D'Amore  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19*49ef7e06SGarrett D'Amore  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20*49ef7e06SGarrett D'Amore  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21*49ef7e06SGarrett D'Amore  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22*49ef7e06SGarrett D'Amore  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23*49ef7e06SGarrett D'Amore  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24*49ef7e06SGarrett D'Amore  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*49ef7e06SGarrett D'Amore  *
26*49ef7e06SGarrett D'Amore  * The views and conclusions contained in the software and documentation are
27*49ef7e06SGarrett D'Amore  * those of the authors and should not be interpreted as representing official
28*49ef7e06SGarrett D'Amore  * policies, either expressed or implied, of the FreeBSD Project.
29*49ef7e06SGarrett D'Amore  */
30*49ef7e06SGarrett D'Amore 
31*49ef7e06SGarrett D'Amore #include "efx.h"
32*49ef7e06SGarrett D'Amore #include "efx_impl.h"
33*49ef7e06SGarrett D'Amore 
34*49ef7e06SGarrett D'Amore 
35*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
36*49ef7e06SGarrett D'Amore 
37*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
38*49ef7e06SGarrett D'Amore siena_rx_init(
39*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp);
40*49ef7e06SGarrett D'Amore 
41*49ef7e06SGarrett D'Amore static			void
42*49ef7e06SGarrett D'Amore siena_rx_fini(
43*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp);
44*49ef7e06SGarrett D'Amore 
45*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
46*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
47*49ef7e06SGarrett D'Amore siena_rx_scatter_enable(
48*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
49*49ef7e06SGarrett D'Amore 	__in		unsigned int buf_size);
50*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_RX_SCATTER */
51*49ef7e06SGarrett D'Amore 
52*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
53*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
54*49ef7e06SGarrett D'Amore siena_rx_scale_mode_set(
55*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
56*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t alg,
57*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_type_t type,
58*49ef7e06SGarrett D'Amore 	__in		boolean_t insert);
59*49ef7e06SGarrett D'Amore 
60*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
61*49ef7e06SGarrett D'Amore siena_rx_scale_key_set(
62*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
63*49ef7e06SGarrett D'Amore 	__in_ecount(n)	uint8_t *key,
64*49ef7e06SGarrett D'Amore 	__in		size_t n);
65*49ef7e06SGarrett D'Amore 
66*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
67*49ef7e06SGarrett D'Amore siena_rx_scale_tbl_set(
68*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
69*49ef7e06SGarrett D'Amore 	__in_ecount(n)	unsigned int *table,
70*49ef7e06SGarrett D'Amore 	__in		size_t n);
71*49ef7e06SGarrett D'Amore 
72*49ef7e06SGarrett D'Amore static	__checkReturn	uint32_t
73*49ef7e06SGarrett D'Amore siena_rx_prefix_hash(
74*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
75*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t func,
76*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer);
77*49ef7e06SGarrett D'Amore 
78*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_RX_SCALE */
79*49ef7e06SGarrett D'Amore 
80*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
81*49ef7e06SGarrett D'Amore siena_rx_prefix_pktlen(
82*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
83*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer,
84*49ef7e06SGarrett D'Amore 	__out		uint16_t *lengthp);
85*49ef7e06SGarrett D'Amore 
86*49ef7e06SGarrett D'Amore static			void
87*49ef7e06SGarrett D'Amore siena_rx_qpost(
88*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp,
89*49ef7e06SGarrett D'Amore 	__in_ecount(n)	efsys_dma_addr_t *addrp,
90*49ef7e06SGarrett D'Amore 	__in		size_t size,
91*49ef7e06SGarrett D'Amore 	__in		unsigned int n,
92*49ef7e06SGarrett D'Amore 	__in		unsigned int completed,
93*49ef7e06SGarrett D'Amore 	__in		unsigned int added);
94*49ef7e06SGarrett D'Amore 
95*49ef7e06SGarrett D'Amore static			void
96*49ef7e06SGarrett D'Amore siena_rx_qpush(
97*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp,
98*49ef7e06SGarrett D'Amore 	__in		unsigned int added,
99*49ef7e06SGarrett D'Amore 	__inout		unsigned int *pushedp);
100*49ef7e06SGarrett D'Amore 
101*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
102*49ef7e06SGarrett D'Amore siena_rx_qflush(
103*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp);
104*49ef7e06SGarrett D'Amore 
105*49ef7e06SGarrett D'Amore static			void
106*49ef7e06SGarrett D'Amore siena_rx_qenable(
107*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp);
108*49ef7e06SGarrett D'Amore 
109*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
110*49ef7e06SGarrett D'Amore siena_rx_qcreate(
111*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
112*49ef7e06SGarrett D'Amore 	__in		unsigned int index,
113*49ef7e06SGarrett D'Amore 	__in		unsigned int label,
114*49ef7e06SGarrett D'Amore 	__in		efx_rxq_type_t type,
115*49ef7e06SGarrett D'Amore 	__in		efsys_mem_t *esmp,
116*49ef7e06SGarrett D'Amore 	__in		size_t n,
117*49ef7e06SGarrett D'Amore 	__in		uint32_t id,
118*49ef7e06SGarrett D'Amore 	__in		efx_evq_t *eep,
119*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp);
120*49ef7e06SGarrett D'Amore 
121*49ef7e06SGarrett D'Amore static			void
122*49ef7e06SGarrett D'Amore siena_rx_qdestroy(
123*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp);
124*49ef7e06SGarrett D'Amore 
125*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_SIENA */
126*49ef7e06SGarrett D'Amore 
127*49ef7e06SGarrett D'Amore 
128*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
129*49ef7e06SGarrett D'Amore static const efx_rx_ops_t __efx_rx_siena_ops = {
130*49ef7e06SGarrett D'Amore 	siena_rx_init,				/* erxo_init */
131*49ef7e06SGarrett D'Amore 	siena_rx_fini,				/* erxo_fini */
132*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
133*49ef7e06SGarrett D'Amore 	siena_rx_scatter_enable,		/* erxo_scatter_enable */
134*49ef7e06SGarrett D'Amore #endif
135*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
136*49ef7e06SGarrett D'Amore 	siena_rx_scale_mode_set,		/* erxo_scale_mode_set */
137*49ef7e06SGarrett D'Amore 	siena_rx_scale_key_set,			/* erxo_scale_key_set */
138*49ef7e06SGarrett D'Amore 	siena_rx_scale_tbl_set,			/* erxo_scale_tbl_set */
139*49ef7e06SGarrett D'Amore 	siena_rx_prefix_hash,			/* erxo_prefix_hash */
140*49ef7e06SGarrett D'Amore #endif
141*49ef7e06SGarrett D'Amore 	siena_rx_prefix_pktlen,			/* erxo_prefix_pktlen */
142*49ef7e06SGarrett D'Amore 	siena_rx_qpost,				/* erxo_qpost */
143*49ef7e06SGarrett D'Amore 	siena_rx_qpush,				/* erxo_qpush */
144*49ef7e06SGarrett D'Amore 	siena_rx_qflush,			/* erxo_qflush */
145*49ef7e06SGarrett D'Amore 	siena_rx_qenable,			/* erxo_qenable */
146*49ef7e06SGarrett D'Amore 	siena_rx_qcreate,			/* erxo_qcreate */
147*49ef7e06SGarrett D'Amore 	siena_rx_qdestroy,			/* erxo_qdestroy */
148*49ef7e06SGarrett D'Amore };
149*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_SIENA */
150*49ef7e06SGarrett D'Amore 
151*49ef7e06SGarrett D'Amore #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
152*49ef7e06SGarrett D'Amore static const efx_rx_ops_t __efx_rx_ef10_ops = {
153*49ef7e06SGarrett D'Amore 	ef10_rx_init,				/* erxo_init */
154*49ef7e06SGarrett D'Amore 	ef10_rx_fini,				/* erxo_fini */
155*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
156*49ef7e06SGarrett D'Amore 	ef10_rx_scatter_enable,			/* erxo_scatter_enable */
157*49ef7e06SGarrett D'Amore #endif
158*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
159*49ef7e06SGarrett D'Amore 	ef10_rx_scale_mode_set,			/* erxo_scale_mode_set */
160*49ef7e06SGarrett D'Amore 	ef10_rx_scale_key_set,			/* erxo_scale_key_set */
161*49ef7e06SGarrett D'Amore 	ef10_rx_scale_tbl_set,			/* erxo_scale_tbl_set */
162*49ef7e06SGarrett D'Amore 	ef10_rx_prefix_hash,			/* erxo_prefix_hash */
163*49ef7e06SGarrett D'Amore #endif
164*49ef7e06SGarrett D'Amore 	ef10_rx_prefix_pktlen,			/* erxo_prefix_pktlen */
165*49ef7e06SGarrett D'Amore 	ef10_rx_qpost,				/* erxo_qpost */
166*49ef7e06SGarrett D'Amore 	ef10_rx_qpush,				/* erxo_qpush */
167*49ef7e06SGarrett D'Amore 	ef10_rx_qflush,				/* erxo_qflush */
168*49ef7e06SGarrett D'Amore 	ef10_rx_qenable,			/* erxo_qenable */
169*49ef7e06SGarrett D'Amore 	ef10_rx_qcreate,			/* erxo_qcreate */
170*49ef7e06SGarrett D'Amore 	ef10_rx_qdestroy,			/* erxo_qdestroy */
171*49ef7e06SGarrett D'Amore };
172*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
173*49ef7e06SGarrett D'Amore 
174*49ef7e06SGarrett D'Amore 
175*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_init(__inout efx_nic_t * enp)176*49ef7e06SGarrett D'Amore efx_rx_init(
177*49ef7e06SGarrett D'Amore 	__inout		efx_nic_t *enp)
178*49ef7e06SGarrett D'Amore {
179*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop;
180*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
181*49ef7e06SGarrett D'Amore 
182*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
183*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
184*49ef7e06SGarrett D'Amore 
185*49ef7e06SGarrett D'Amore 	if (!(enp->en_mod_flags & EFX_MOD_EV)) {
186*49ef7e06SGarrett D'Amore 		rc = EINVAL;
187*49ef7e06SGarrett D'Amore 		goto fail1;
188*49ef7e06SGarrett D'Amore 	}
189*49ef7e06SGarrett D'Amore 
190*49ef7e06SGarrett D'Amore 	if (enp->en_mod_flags & EFX_MOD_RX) {
191*49ef7e06SGarrett D'Amore 		rc = EINVAL;
192*49ef7e06SGarrett D'Amore 		goto fail2;
193*49ef7e06SGarrett D'Amore 	}
194*49ef7e06SGarrett D'Amore 
195*49ef7e06SGarrett D'Amore 	switch (enp->en_family) {
196*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
197*49ef7e06SGarrett D'Amore 	case EFX_FAMILY_SIENA:
198*49ef7e06SGarrett D'Amore 		erxop = &__efx_rx_siena_ops;
199*49ef7e06SGarrett D'Amore 		break;
200*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_SIENA */
201*49ef7e06SGarrett D'Amore 
202*49ef7e06SGarrett D'Amore #if EFSYS_OPT_HUNTINGTON
203*49ef7e06SGarrett D'Amore 	case EFX_FAMILY_HUNTINGTON:
204*49ef7e06SGarrett D'Amore 		erxop = &__efx_rx_ef10_ops;
205*49ef7e06SGarrett D'Amore 		break;
206*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_HUNTINGTON */
207*49ef7e06SGarrett D'Amore 
208*49ef7e06SGarrett D'Amore #if EFSYS_OPT_MEDFORD
209*49ef7e06SGarrett D'Amore 	case EFX_FAMILY_MEDFORD:
210*49ef7e06SGarrett D'Amore 		erxop = &__efx_rx_ef10_ops;
211*49ef7e06SGarrett D'Amore 		break;
212*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_MEDFORD */
213*49ef7e06SGarrett D'Amore 
214*49ef7e06SGarrett D'Amore 	default:
215*49ef7e06SGarrett D'Amore 		EFSYS_ASSERT(0);
216*49ef7e06SGarrett D'Amore 		rc = ENOTSUP;
217*49ef7e06SGarrett D'Amore 		goto fail3;
218*49ef7e06SGarrett D'Amore 	}
219*49ef7e06SGarrett D'Amore 
220*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_init(enp)) != 0)
221*49ef7e06SGarrett D'Amore 		goto fail4;
222*49ef7e06SGarrett D'Amore 
223*49ef7e06SGarrett D'Amore 	enp->en_erxop = erxop;
224*49ef7e06SGarrett D'Amore 	enp->en_mod_flags |= EFX_MOD_RX;
225*49ef7e06SGarrett D'Amore 	return (0);
226*49ef7e06SGarrett D'Amore 
227*49ef7e06SGarrett D'Amore fail4:
228*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail4);
229*49ef7e06SGarrett D'Amore fail3:
230*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail3);
231*49ef7e06SGarrett D'Amore fail2:
232*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
233*49ef7e06SGarrett D'Amore fail1:
234*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
235*49ef7e06SGarrett D'Amore 
236*49ef7e06SGarrett D'Amore 	enp->en_erxop = NULL;
237*49ef7e06SGarrett D'Amore 	enp->en_mod_flags &= ~EFX_MOD_RX;
238*49ef7e06SGarrett D'Amore 	return (rc);
239*49ef7e06SGarrett D'Amore }
240*49ef7e06SGarrett D'Amore 
241*49ef7e06SGarrett D'Amore 			void
efx_rx_fini(__in efx_nic_t * enp)242*49ef7e06SGarrett D'Amore efx_rx_fini(
243*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp)
244*49ef7e06SGarrett D'Amore {
245*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
246*49ef7e06SGarrett D'Amore 
247*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
248*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
249*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
250*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
251*49ef7e06SGarrett D'Amore 
252*49ef7e06SGarrett D'Amore 	erxop->erxo_fini(enp);
253*49ef7e06SGarrett D'Amore 
254*49ef7e06SGarrett D'Amore 	enp->en_erxop = NULL;
255*49ef7e06SGarrett D'Amore 	enp->en_mod_flags &= ~EFX_MOD_RX;
256*49ef7e06SGarrett D'Amore }
257*49ef7e06SGarrett D'Amore 
258*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
259*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_scatter_enable(__in efx_nic_t * enp,__in unsigned int buf_size)260*49ef7e06SGarrett D'Amore efx_rx_scatter_enable(
261*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
262*49ef7e06SGarrett D'Amore 	__in		unsigned int buf_size)
263*49ef7e06SGarrett D'Amore {
264*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
265*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
266*49ef7e06SGarrett D'Amore 
267*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
268*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
269*49ef7e06SGarrett D'Amore 
270*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
271*49ef7e06SGarrett D'Amore 		goto fail1;
272*49ef7e06SGarrett D'Amore 
273*49ef7e06SGarrett D'Amore 	return (0);
274*49ef7e06SGarrett D'Amore 
275*49ef7e06SGarrett D'Amore fail1:
276*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
277*49ef7e06SGarrett D'Amore 	return (rc);
278*49ef7e06SGarrett D'Amore }
279*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCATTER */
280*49ef7e06SGarrett D'Amore 
281*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
282*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_hash_support_get(__in efx_nic_t * enp,__out efx_rx_hash_support_t * supportp)283*49ef7e06SGarrett D'Amore efx_rx_hash_support_get(
284*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
285*49ef7e06SGarrett D'Amore 	__out		efx_rx_hash_support_t *supportp)
286*49ef7e06SGarrett D'Amore {
287*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
288*49ef7e06SGarrett D'Amore 
289*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
290*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
291*49ef7e06SGarrett D'Amore 
292*49ef7e06SGarrett D'Amore 	if (supportp == NULL) {
293*49ef7e06SGarrett D'Amore 		rc = EINVAL;
294*49ef7e06SGarrett D'Amore 		goto fail1;
295*49ef7e06SGarrett D'Amore 	}
296*49ef7e06SGarrett D'Amore 
297*49ef7e06SGarrett D'Amore 	/* Report if resources are available to insert RX hash value */
298*49ef7e06SGarrett D'Amore 	*supportp = enp->en_hash_support;
299*49ef7e06SGarrett D'Amore 
300*49ef7e06SGarrett D'Amore 	return (0);
301*49ef7e06SGarrett D'Amore 
302*49ef7e06SGarrett D'Amore fail1:
303*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
304*49ef7e06SGarrett D'Amore 
305*49ef7e06SGarrett D'Amore 	return (rc);
306*49ef7e06SGarrett D'Amore }
307*49ef7e06SGarrett D'Amore 
308*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_scale_support_get(__in efx_nic_t * enp,__out efx_rx_scale_support_t * supportp)309*49ef7e06SGarrett D'Amore efx_rx_scale_support_get(
310*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
311*49ef7e06SGarrett D'Amore 	__out		efx_rx_scale_support_t *supportp)
312*49ef7e06SGarrett D'Amore {
313*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
314*49ef7e06SGarrett D'Amore 
315*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
316*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
317*49ef7e06SGarrett D'Amore 
318*49ef7e06SGarrett D'Amore 	if (supportp == NULL) {
319*49ef7e06SGarrett D'Amore 		rc = EINVAL;
320*49ef7e06SGarrett D'Amore 		goto fail1;
321*49ef7e06SGarrett D'Amore 	}
322*49ef7e06SGarrett D'Amore 
323*49ef7e06SGarrett D'Amore 	/* Report if resources are available to support RSS */
324*49ef7e06SGarrett D'Amore 	*supportp = enp->en_rss_support;
325*49ef7e06SGarrett D'Amore 
326*49ef7e06SGarrett D'Amore 	return (0);
327*49ef7e06SGarrett D'Amore 
328*49ef7e06SGarrett D'Amore fail1:
329*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
330*49ef7e06SGarrett D'Amore 
331*49ef7e06SGarrett D'Amore 	return (rc);
332*49ef7e06SGarrett D'Amore }
333*49ef7e06SGarrett D'Amore 
334*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_scale_mode_set(__in efx_nic_t * enp,__in efx_rx_hash_alg_t alg,__in efx_rx_hash_type_t type,__in boolean_t insert)335*49ef7e06SGarrett D'Amore efx_rx_scale_mode_set(
336*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
337*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t alg,
338*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_type_t type,
339*49ef7e06SGarrett D'Amore 	__in		boolean_t insert)
340*49ef7e06SGarrett D'Amore {
341*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
342*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
343*49ef7e06SGarrett D'Amore 
344*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
345*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
346*49ef7e06SGarrett D'Amore 
347*49ef7e06SGarrett D'Amore 	if (erxop->erxo_scale_mode_set != NULL) {
348*49ef7e06SGarrett D'Amore 		if ((rc = erxop->erxo_scale_mode_set(enp, alg,
349*49ef7e06SGarrett D'Amore 			    type, insert)) != 0)
350*49ef7e06SGarrett D'Amore 			goto fail1;
351*49ef7e06SGarrett D'Amore 	}
352*49ef7e06SGarrett D'Amore 
353*49ef7e06SGarrett D'Amore 	return (0);
354*49ef7e06SGarrett D'Amore 
355*49ef7e06SGarrett D'Amore fail1:
356*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
357*49ef7e06SGarrett D'Amore 	return (rc);
358*49ef7e06SGarrett D'Amore }
359*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCALE */
360*49ef7e06SGarrett D'Amore 
361*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
362*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_scale_key_set(__in efx_nic_t * enp,__in_ecount (n)uint8_t * key,__in size_t n)363*49ef7e06SGarrett D'Amore efx_rx_scale_key_set(
364*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
365*49ef7e06SGarrett D'Amore 	__in_ecount(n)	uint8_t *key,
366*49ef7e06SGarrett D'Amore 	__in		size_t n)
367*49ef7e06SGarrett D'Amore {
368*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
369*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
370*49ef7e06SGarrett D'Amore 
371*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
372*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
373*49ef7e06SGarrett D'Amore 
374*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0)
375*49ef7e06SGarrett D'Amore 		goto fail1;
376*49ef7e06SGarrett D'Amore 
377*49ef7e06SGarrett D'Amore 	return (0);
378*49ef7e06SGarrett D'Amore 
379*49ef7e06SGarrett D'Amore fail1:
380*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
381*49ef7e06SGarrett D'Amore 
382*49ef7e06SGarrett D'Amore 	return (rc);
383*49ef7e06SGarrett D'Amore }
384*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCALE */
385*49ef7e06SGarrett D'Amore 
386*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
387*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_scale_tbl_set(__in efx_nic_t * enp,__in_ecount (n)unsigned int * table,__in size_t n)388*49ef7e06SGarrett D'Amore efx_rx_scale_tbl_set(
389*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
390*49ef7e06SGarrett D'Amore 	__in_ecount(n)	unsigned int *table,
391*49ef7e06SGarrett D'Amore 	__in		size_t n)
392*49ef7e06SGarrett D'Amore {
393*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
394*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
395*49ef7e06SGarrett D'Amore 
396*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
397*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
398*49ef7e06SGarrett D'Amore 
399*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0)
400*49ef7e06SGarrett D'Amore 		goto fail1;
401*49ef7e06SGarrett D'Amore 
402*49ef7e06SGarrett D'Amore 	return (0);
403*49ef7e06SGarrett D'Amore 
404*49ef7e06SGarrett D'Amore fail1:
405*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
406*49ef7e06SGarrett D'Amore 
407*49ef7e06SGarrett D'Amore 	return (rc);
408*49ef7e06SGarrett D'Amore }
409*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCALE */
410*49ef7e06SGarrett D'Amore 
411*49ef7e06SGarrett D'Amore 			void
efx_rx_qpost(__in efx_rxq_t * erp,__in_ecount (n)efsys_dma_addr_t * addrp,__in size_t size,__in unsigned int n,__in unsigned int completed,__in unsigned int added)412*49ef7e06SGarrett D'Amore efx_rx_qpost(
413*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp,
414*49ef7e06SGarrett D'Amore 	__in_ecount(n)	efsys_dma_addr_t *addrp,
415*49ef7e06SGarrett D'Amore 	__in		size_t size,
416*49ef7e06SGarrett D'Amore 	__in		unsigned int n,
417*49ef7e06SGarrett D'Amore 	__in		unsigned int completed,
418*49ef7e06SGarrett D'Amore 	__in		unsigned int added)
419*49ef7e06SGarrett D'Amore {
420*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
421*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
422*49ef7e06SGarrett D'Amore 
423*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
424*49ef7e06SGarrett D'Amore 
425*49ef7e06SGarrett D'Amore 	erxop->erxo_qpost(erp, addrp, size, n, completed, added);
426*49ef7e06SGarrett D'Amore }
427*49ef7e06SGarrett D'Amore 
428*49ef7e06SGarrett D'Amore 			void
efx_rx_qpush(__in efx_rxq_t * erp,__in unsigned int added,__inout unsigned int * pushedp)429*49ef7e06SGarrett D'Amore efx_rx_qpush(
430*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp,
431*49ef7e06SGarrett D'Amore 	__in		unsigned int added,
432*49ef7e06SGarrett D'Amore 	__inout		unsigned int *pushedp)
433*49ef7e06SGarrett D'Amore {
434*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
435*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
436*49ef7e06SGarrett D'Amore 
437*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
438*49ef7e06SGarrett D'Amore 
439*49ef7e06SGarrett D'Amore 	erxop->erxo_qpush(erp, added, pushedp);
440*49ef7e06SGarrett D'Amore }
441*49ef7e06SGarrett D'Amore 
442*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_qflush(__in efx_rxq_t * erp)443*49ef7e06SGarrett D'Amore efx_rx_qflush(
444*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp)
445*49ef7e06SGarrett D'Amore {
446*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
447*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
448*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
449*49ef7e06SGarrett D'Amore 
450*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
451*49ef7e06SGarrett D'Amore 
452*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_qflush(erp)) != 0)
453*49ef7e06SGarrett D'Amore 		goto fail1;
454*49ef7e06SGarrett D'Amore 
455*49ef7e06SGarrett D'Amore 	return (0);
456*49ef7e06SGarrett D'Amore 
457*49ef7e06SGarrett D'Amore fail1:
458*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
459*49ef7e06SGarrett D'Amore 
460*49ef7e06SGarrett D'Amore 	return (rc);
461*49ef7e06SGarrett D'Amore }
462*49ef7e06SGarrett D'Amore 
463*49ef7e06SGarrett D'Amore 			void
efx_rx_qenable(__in efx_rxq_t * erp)464*49ef7e06SGarrett D'Amore efx_rx_qenable(
465*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp)
466*49ef7e06SGarrett D'Amore {
467*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
468*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
469*49ef7e06SGarrett D'Amore 
470*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
471*49ef7e06SGarrett D'Amore 
472*49ef7e06SGarrett D'Amore 	erxop->erxo_qenable(erp);
473*49ef7e06SGarrett D'Amore }
474*49ef7e06SGarrett D'Amore 
475*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_rx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efx_rxq_type_t type,__in efsys_mem_t * esmp,__in size_t n,__in uint32_t id,__in efx_evq_t * eep,__deref_out efx_rxq_t ** erpp)476*49ef7e06SGarrett D'Amore efx_rx_qcreate(
477*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
478*49ef7e06SGarrett D'Amore 	__in		unsigned int index,
479*49ef7e06SGarrett D'Amore 	__in		unsigned int label,
480*49ef7e06SGarrett D'Amore 	__in		efx_rxq_type_t type,
481*49ef7e06SGarrett D'Amore 	__in		efsys_mem_t *esmp,
482*49ef7e06SGarrett D'Amore 	__in		size_t n,
483*49ef7e06SGarrett D'Amore 	__in		uint32_t id,
484*49ef7e06SGarrett D'Amore 	__in		efx_evq_t *eep,
485*49ef7e06SGarrett D'Amore 	__deref_out	efx_rxq_t **erpp)
486*49ef7e06SGarrett D'Amore {
487*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
488*49ef7e06SGarrett D'Amore 	efx_rxq_t *erp;
489*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
490*49ef7e06SGarrett D'Amore 
491*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
492*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
493*49ef7e06SGarrett D'Amore 
494*49ef7e06SGarrett D'Amore 	/* Allocate an RXQ object */
495*49ef7e06SGarrett D'Amore 	EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
496*49ef7e06SGarrett D'Amore 
497*49ef7e06SGarrett D'Amore 	if (erp == NULL) {
498*49ef7e06SGarrett D'Amore 		rc = ENOMEM;
499*49ef7e06SGarrett D'Amore 		goto fail1;
500*49ef7e06SGarrett D'Amore 	}
501*49ef7e06SGarrett D'Amore 
502*49ef7e06SGarrett D'Amore 	erp->er_magic = EFX_RXQ_MAGIC;
503*49ef7e06SGarrett D'Amore 	erp->er_enp = enp;
504*49ef7e06SGarrett D'Amore 	erp->er_index = index;
505*49ef7e06SGarrett D'Amore 	erp->er_mask = n - 1;
506*49ef7e06SGarrett D'Amore 	erp->er_esmp = esmp;
507*49ef7e06SGarrett D'Amore 
508*49ef7e06SGarrett D'Amore 	if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id,
509*49ef7e06SGarrett D'Amore 	    eep, erp)) != 0)
510*49ef7e06SGarrett D'Amore 		goto fail2;
511*49ef7e06SGarrett D'Amore 
512*49ef7e06SGarrett D'Amore 	enp->en_rx_qcount++;
513*49ef7e06SGarrett D'Amore 	*erpp = erp;
514*49ef7e06SGarrett D'Amore 
515*49ef7e06SGarrett D'Amore 	return (0);
516*49ef7e06SGarrett D'Amore 
517*49ef7e06SGarrett D'Amore fail2:
518*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
519*49ef7e06SGarrett D'Amore 
520*49ef7e06SGarrett D'Amore 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
521*49ef7e06SGarrett D'Amore fail1:
522*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
523*49ef7e06SGarrett D'Amore 
524*49ef7e06SGarrett D'Amore 	return (rc);
525*49ef7e06SGarrett D'Amore }
526*49ef7e06SGarrett D'Amore 
527*49ef7e06SGarrett D'Amore 			void
efx_rx_qdestroy(__in efx_rxq_t * erp)528*49ef7e06SGarrett D'Amore efx_rx_qdestroy(
529*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp)
530*49ef7e06SGarrett D'Amore {
531*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
532*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
533*49ef7e06SGarrett D'Amore 
534*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
535*49ef7e06SGarrett D'Amore 
536*49ef7e06SGarrett D'Amore 	erxop->erxo_qdestroy(erp);
537*49ef7e06SGarrett D'Amore }
538*49ef7e06SGarrett D'Amore 
539*49ef7e06SGarrett D'Amore 	__checkReturn	efx_rc_t
efx_psuedo_hdr_pkt_length_get(__in efx_nic_t * enp,__in uint8_t * buffer,__out uint16_t * lengthp)540*49ef7e06SGarrett D'Amore efx_psuedo_hdr_pkt_length_get(
541*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
542*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer,
543*49ef7e06SGarrett D'Amore 	__out		uint16_t *lengthp)
544*49ef7e06SGarrett D'Amore {
545*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
546*49ef7e06SGarrett D'Amore 
547*49ef7e06SGarrett D'Amore 	return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
548*49ef7e06SGarrett D'Amore }
549*49ef7e06SGarrett D'Amore 
550*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
551*49ef7e06SGarrett D'Amore 	__checkReturn	uint32_t
efx_psuedo_hdr_hash_get(__in efx_nic_t * enp,__in efx_rx_hash_alg_t func,__in uint8_t * buffer)552*49ef7e06SGarrett D'Amore efx_psuedo_hdr_hash_get(
553*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
554*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t func,
555*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer)
556*49ef7e06SGarrett D'Amore {
557*49ef7e06SGarrett D'Amore 	const efx_rx_ops_t *erxop = enp->en_erxop;
558*49ef7e06SGarrett D'Amore 
559*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
560*49ef7e06SGarrett D'Amore 	return (erxop->erxo_prefix_hash(enp, func, buffer));
561*49ef7e06SGarrett D'Amore }
562*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCALE */
563*49ef7e06SGarrett D'Amore 
564*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
565*49ef7e06SGarrett D'Amore 
566*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_init(__in efx_nic_t * enp)567*49ef7e06SGarrett D'Amore siena_rx_init(
568*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp)
569*49ef7e06SGarrett D'Amore {
570*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
571*49ef7e06SGarrett D'Amore 	unsigned int index;
572*49ef7e06SGarrett D'Amore 
573*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
574*49ef7e06SGarrett D'Amore 
575*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
576*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
577*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
578*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
579*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
580*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
581*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
582*49ef7e06SGarrett D'Amore 
583*49ef7e06SGarrett D'Amore 	/* Zero the RSS table */
584*49ef7e06SGarrett D'Amore 	for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
585*49ef7e06SGarrett D'Amore 	    index++) {
586*49ef7e06SGarrett D'Amore 		EFX_ZERO_OWORD(oword);
587*49ef7e06SGarrett D'Amore 		EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
588*49ef7e06SGarrett D'Amore 				    index, &oword, B_TRUE);
589*49ef7e06SGarrett D'Amore 	}
590*49ef7e06SGarrett D'Amore 
591*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
592*49ef7e06SGarrett D'Amore 	/* The RSS key and indirection table are writable. */
593*49ef7e06SGarrett D'Amore 	enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
594*49ef7e06SGarrett D'Amore 
595*49ef7e06SGarrett D'Amore 	/* Hardware can insert RX hash with/without RSS */
596*49ef7e06SGarrett D'Amore 	enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
597*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCALE */
598*49ef7e06SGarrett D'Amore 
599*49ef7e06SGarrett D'Amore 	return (0);
600*49ef7e06SGarrett D'Amore }
601*49ef7e06SGarrett D'Amore 
602*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
603*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_scatter_enable(__in efx_nic_t * enp,__in unsigned int buf_size)604*49ef7e06SGarrett D'Amore siena_rx_scatter_enable(
605*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
606*49ef7e06SGarrett D'Amore 	__in		unsigned int buf_size)
607*49ef7e06SGarrett D'Amore {
608*49ef7e06SGarrett D'Amore 	unsigned int nbuf32;
609*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
610*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
611*49ef7e06SGarrett D'Amore 
612*49ef7e06SGarrett D'Amore 	nbuf32 = buf_size / 32;
613*49ef7e06SGarrett D'Amore 	if ((nbuf32 == 0) ||
614*49ef7e06SGarrett D'Amore 	    (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
615*49ef7e06SGarrett D'Amore 	    ((buf_size % 32) != 0)) {
616*49ef7e06SGarrett D'Amore 		rc = EINVAL;
617*49ef7e06SGarrett D'Amore 		goto fail1;
618*49ef7e06SGarrett D'Amore 	}
619*49ef7e06SGarrett D'Amore 
620*49ef7e06SGarrett D'Amore 	if (enp->en_rx_qcount > 0) {
621*49ef7e06SGarrett D'Amore 		rc = EBUSY;
622*49ef7e06SGarrett D'Amore 		goto fail2;
623*49ef7e06SGarrett D'Amore 	}
624*49ef7e06SGarrett D'Amore 
625*49ef7e06SGarrett D'Amore 	/* Set scatter buffer size */
626*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
627*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
628*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
629*49ef7e06SGarrett D'Amore 
630*49ef7e06SGarrett D'Amore 	/* Enable scatter for packets not matching a filter */
631*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
632*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
633*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
634*49ef7e06SGarrett D'Amore 
635*49ef7e06SGarrett D'Amore 	return (0);
636*49ef7e06SGarrett D'Amore 
637*49ef7e06SGarrett D'Amore fail2:
638*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
639*49ef7e06SGarrett D'Amore fail1:
640*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
641*49ef7e06SGarrett D'Amore 
642*49ef7e06SGarrett D'Amore 	return (rc);
643*49ef7e06SGarrett D'Amore }
644*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCATTER */
645*49ef7e06SGarrett D'Amore 
646*49ef7e06SGarrett D'Amore 
647*49ef7e06SGarrett D'Amore #define	EFX_RX_LFSR_HASH(_enp, _insert)					\
648*49ef7e06SGarrett D'Amore 	do {								\
649*49ef7e06SGarrett D'Amore 		efx_oword_t oword;					\
650*49ef7e06SGarrett D'Amore 									\
651*49ef7e06SGarrett D'Amore 		EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);	\
652*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);	\
653*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);	\
654*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);	\
655*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,	\
656*49ef7e06SGarrett D'Amore 		    (_insert) ? 1 : 0);					\
657*49ef7e06SGarrett D'Amore 		EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);	\
658*49ef7e06SGarrett D'Amore 									\
659*49ef7e06SGarrett D'Amore 		if ((_enp)->en_family == EFX_FAMILY_SIENA) {		\
660*49ef7e06SGarrett D'Amore 			EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3,	\
661*49ef7e06SGarrett D'Amore 			    &oword);					\
662*49ef7e06SGarrett D'Amore 			EFX_SET_OWORD_FIELD(oword,			\
663*49ef7e06SGarrett D'Amore 			    FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0);	\
664*49ef7e06SGarrett D'Amore 			EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3,	\
665*49ef7e06SGarrett D'Amore 			    &oword);					\
666*49ef7e06SGarrett D'Amore 		}							\
667*49ef7e06SGarrett D'Amore 									\
668*49ef7e06SGarrett D'Amore 		_NOTE(CONSTANTCONDITION)				\
669*49ef7e06SGarrett D'Amore 	} while (B_FALSE)
670*49ef7e06SGarrett D'Amore 
671*49ef7e06SGarrett D'Amore #define	EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp)		\
672*49ef7e06SGarrett D'Amore 	do {								\
673*49ef7e06SGarrett D'Amore 		efx_oword_t oword;					\
674*49ef7e06SGarrett D'Amore 									\
675*49ef7e06SGarrett D'Amore 		EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG,	&oword);	\
676*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1);	\
677*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH,		\
678*49ef7e06SGarrett D'Amore 		    (_ip) ? 1 : 0);					\
679*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP,		\
680*49ef7e06SGarrett D'Amore 		    (_tcp) ? 0 : 1);					\
681*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,	\
682*49ef7e06SGarrett D'Amore 		    (_insert) ? 1 : 0);					\
683*49ef7e06SGarrett D'Amore 		EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);	\
684*49ef7e06SGarrett D'Amore 									\
685*49ef7e06SGarrett D'Amore 		_NOTE(CONSTANTCONDITION)				\
686*49ef7e06SGarrett D'Amore 	} while (B_FALSE)
687*49ef7e06SGarrett D'Amore 
688*49ef7e06SGarrett D'Amore #define	EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc)			\
689*49ef7e06SGarrett D'Amore 	do {								\
690*49ef7e06SGarrett D'Amore 		efx_oword_t oword;					\
691*49ef7e06SGarrett D'Amore 									\
692*49ef7e06SGarrett D'Amore 		EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);	\
693*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword,				\
694*49ef7e06SGarrett D'Amore 		    FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1);		\
695*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword,				\
696*49ef7e06SGarrett D'Amore 		    FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0);	\
697*49ef7e06SGarrett D'Amore 		EFX_SET_OWORD_FIELD(oword,				\
698*49ef7e06SGarrett D'Amore 		    FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1);	\
699*49ef7e06SGarrett D'Amore 		EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);	\
700*49ef7e06SGarrett D'Amore 									\
701*49ef7e06SGarrett D'Amore 		(_rc) = 0;						\
702*49ef7e06SGarrett D'Amore 									\
703*49ef7e06SGarrett D'Amore 		_NOTE(CONSTANTCONDITION)				\
704*49ef7e06SGarrett D'Amore 	} while (B_FALSE)
705*49ef7e06SGarrett D'Amore 
706*49ef7e06SGarrett D'Amore 
707*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
708*49ef7e06SGarrett D'Amore 
709*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_scale_mode_set(__in efx_nic_t * enp,__in efx_rx_hash_alg_t alg,__in efx_rx_hash_type_t type,__in boolean_t insert)710*49ef7e06SGarrett D'Amore siena_rx_scale_mode_set(
711*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
712*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t alg,
713*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_type_t type,
714*49ef7e06SGarrett D'Amore 	__in		boolean_t insert)
715*49ef7e06SGarrett D'Amore {
716*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
717*49ef7e06SGarrett D'Amore 
718*49ef7e06SGarrett D'Amore 	switch (alg) {
719*49ef7e06SGarrett D'Amore 	case EFX_RX_HASHALG_LFSR:
720*49ef7e06SGarrett D'Amore 		EFX_RX_LFSR_HASH(enp, insert);
721*49ef7e06SGarrett D'Amore 		break;
722*49ef7e06SGarrett D'Amore 
723*49ef7e06SGarrett D'Amore 	case EFX_RX_HASHALG_TOEPLITZ:
724*49ef7e06SGarrett D'Amore 		EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
725*49ef7e06SGarrett D'Amore 		    type & (1 << EFX_RX_HASH_IPV4),
726*49ef7e06SGarrett D'Amore 		    type & (1 << EFX_RX_HASH_TCPIPV4));
727*49ef7e06SGarrett D'Amore 
728*49ef7e06SGarrett D'Amore 		EFX_RX_TOEPLITZ_IPV6_HASH(enp,
729*49ef7e06SGarrett D'Amore 		    type & (1 << EFX_RX_HASH_IPV6),
730*49ef7e06SGarrett D'Amore 		    type & (1 << EFX_RX_HASH_TCPIPV6),
731*49ef7e06SGarrett D'Amore 		    rc);
732*49ef7e06SGarrett D'Amore 		if (rc != 0)
733*49ef7e06SGarrett D'Amore 			goto fail1;
734*49ef7e06SGarrett D'Amore 
735*49ef7e06SGarrett D'Amore 		break;
736*49ef7e06SGarrett D'Amore 
737*49ef7e06SGarrett D'Amore 	default:
738*49ef7e06SGarrett D'Amore 		rc = EINVAL;
739*49ef7e06SGarrett D'Amore 		goto fail2;
740*49ef7e06SGarrett D'Amore 	}
741*49ef7e06SGarrett D'Amore 
742*49ef7e06SGarrett D'Amore 	return (0);
743*49ef7e06SGarrett D'Amore 
744*49ef7e06SGarrett D'Amore fail2:
745*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
746*49ef7e06SGarrett D'Amore fail1:
747*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
748*49ef7e06SGarrett D'Amore 
749*49ef7e06SGarrett D'Amore 	EFX_RX_LFSR_HASH(enp, B_FALSE);
750*49ef7e06SGarrett D'Amore 
751*49ef7e06SGarrett D'Amore 	return (rc);
752*49ef7e06SGarrett D'Amore }
753*49ef7e06SGarrett D'Amore #endif
754*49ef7e06SGarrett D'Amore 
755*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
756*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_scale_key_set(__in efx_nic_t * enp,__in_ecount (n)uint8_t * key,__in size_t n)757*49ef7e06SGarrett D'Amore siena_rx_scale_key_set(
758*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
759*49ef7e06SGarrett D'Amore 	__in_ecount(n)	uint8_t *key,
760*49ef7e06SGarrett D'Amore 	__in		size_t n)
761*49ef7e06SGarrett D'Amore {
762*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
763*49ef7e06SGarrett D'Amore 	unsigned int byte;
764*49ef7e06SGarrett D'Amore 	unsigned int offset;
765*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
766*49ef7e06SGarrett D'Amore 
767*49ef7e06SGarrett D'Amore 	byte = 0;
768*49ef7e06SGarrett D'Amore 
769*49ef7e06SGarrett D'Amore 	/* Write Toeplitz IPv4 hash key */
770*49ef7e06SGarrett D'Amore 	EFX_ZERO_OWORD(oword);
771*49ef7e06SGarrett D'Amore 	for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
772*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
773*49ef7e06SGarrett D'Amore 	    --offset)
774*49ef7e06SGarrett D'Amore 		oword.eo_u8[offset - 1] = key[byte++];
775*49ef7e06SGarrett D'Amore 
776*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
777*49ef7e06SGarrett D'Amore 
778*49ef7e06SGarrett D'Amore 	byte = 0;
779*49ef7e06SGarrett D'Amore 
780*49ef7e06SGarrett D'Amore 	/* Verify Toeplitz IPv4 hash key */
781*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
782*49ef7e06SGarrett D'Amore 	for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
783*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
784*49ef7e06SGarrett D'Amore 	    --offset) {
785*49ef7e06SGarrett D'Amore 		if (oword.eo_u8[offset - 1] != key[byte++]) {
786*49ef7e06SGarrett D'Amore 			rc = EFAULT;
787*49ef7e06SGarrett D'Amore 			goto fail1;
788*49ef7e06SGarrett D'Amore 		}
789*49ef7e06SGarrett D'Amore 	}
790*49ef7e06SGarrett D'Amore 
791*49ef7e06SGarrett D'Amore 	if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
792*49ef7e06SGarrett D'Amore 		goto done;
793*49ef7e06SGarrett D'Amore 
794*49ef7e06SGarrett D'Amore 	byte = 0;
795*49ef7e06SGarrett D'Amore 
796*49ef7e06SGarrett D'Amore 	/* Write Toeplitz IPv6 hash key 3 */
797*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
798*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
799*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
800*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
801*49ef7e06SGarrett D'Amore 	    --offset)
802*49ef7e06SGarrett D'Amore 		oword.eo_u8[offset - 1] = key[byte++];
803*49ef7e06SGarrett D'Amore 
804*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
805*49ef7e06SGarrett D'Amore 
806*49ef7e06SGarrett D'Amore 	/* Write Toeplitz IPv6 hash key 2 */
807*49ef7e06SGarrett D'Amore 	EFX_ZERO_OWORD(oword);
808*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
809*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
810*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
811*49ef7e06SGarrett D'Amore 	    --offset)
812*49ef7e06SGarrett D'Amore 		oword.eo_u8[offset - 1] = key[byte++];
813*49ef7e06SGarrett D'Amore 
814*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
815*49ef7e06SGarrett D'Amore 
816*49ef7e06SGarrett D'Amore 	/* Write Toeplitz IPv6 hash key 1 */
817*49ef7e06SGarrett D'Amore 	EFX_ZERO_OWORD(oword);
818*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
819*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
820*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
821*49ef7e06SGarrett D'Amore 	    --offset)
822*49ef7e06SGarrett D'Amore 		oword.eo_u8[offset - 1] = key[byte++];
823*49ef7e06SGarrett D'Amore 
824*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
825*49ef7e06SGarrett D'Amore 
826*49ef7e06SGarrett D'Amore 	byte = 0;
827*49ef7e06SGarrett D'Amore 
828*49ef7e06SGarrett D'Amore 	/* Verify Toeplitz IPv6 hash key 3 */
829*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
830*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
831*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
832*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
833*49ef7e06SGarrett D'Amore 	    --offset) {
834*49ef7e06SGarrett D'Amore 		if (oword.eo_u8[offset - 1] != key[byte++]) {
835*49ef7e06SGarrett D'Amore 			rc = EFAULT;
836*49ef7e06SGarrett D'Amore 			goto fail2;
837*49ef7e06SGarrett D'Amore 		}
838*49ef7e06SGarrett D'Amore 	}
839*49ef7e06SGarrett D'Amore 
840*49ef7e06SGarrett D'Amore 	/* Verify Toeplitz IPv6 hash key 2 */
841*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
842*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
843*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
844*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
845*49ef7e06SGarrett D'Amore 	    --offset) {
846*49ef7e06SGarrett D'Amore 		if (oword.eo_u8[offset - 1] != key[byte++]) {
847*49ef7e06SGarrett D'Amore 			rc = EFAULT;
848*49ef7e06SGarrett D'Amore 			goto fail3;
849*49ef7e06SGarrett D'Amore 		}
850*49ef7e06SGarrett D'Amore 	}
851*49ef7e06SGarrett D'Amore 
852*49ef7e06SGarrett D'Amore 	/* Verify Toeplitz IPv6 hash key 1 */
853*49ef7e06SGarrett D'Amore 	EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
854*49ef7e06SGarrett D'Amore 	for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
855*49ef7e06SGarrett D'Amore 	    FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
856*49ef7e06SGarrett D'Amore 	    offset > 0 && byte < n;
857*49ef7e06SGarrett D'Amore 	    --offset) {
858*49ef7e06SGarrett D'Amore 		if (oword.eo_u8[offset - 1] != key[byte++]) {
859*49ef7e06SGarrett D'Amore 			rc = EFAULT;
860*49ef7e06SGarrett D'Amore 			goto fail4;
861*49ef7e06SGarrett D'Amore 		}
862*49ef7e06SGarrett D'Amore 	}
863*49ef7e06SGarrett D'Amore 
864*49ef7e06SGarrett D'Amore done:
865*49ef7e06SGarrett D'Amore 	return (0);
866*49ef7e06SGarrett D'Amore 
867*49ef7e06SGarrett D'Amore fail4:
868*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail4);
869*49ef7e06SGarrett D'Amore fail3:
870*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail3);
871*49ef7e06SGarrett D'Amore fail2:
872*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
873*49ef7e06SGarrett D'Amore fail1:
874*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
875*49ef7e06SGarrett D'Amore 
876*49ef7e06SGarrett D'Amore 	return (rc);
877*49ef7e06SGarrett D'Amore }
878*49ef7e06SGarrett D'Amore #endif
879*49ef7e06SGarrett D'Amore 
880*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
881*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_scale_tbl_set(__in efx_nic_t * enp,__in_ecount (n)unsigned int * table,__in size_t n)882*49ef7e06SGarrett D'Amore siena_rx_scale_tbl_set(
883*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
884*49ef7e06SGarrett D'Amore 	__in_ecount(n)	unsigned int *table,
885*49ef7e06SGarrett D'Amore 	__in		size_t n)
886*49ef7e06SGarrett D'Amore {
887*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
888*49ef7e06SGarrett D'Amore 	int index;
889*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
890*49ef7e06SGarrett D'Amore 
891*49ef7e06SGarrett D'Amore 	EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
892*49ef7e06SGarrett D'Amore 	EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
893*49ef7e06SGarrett D'Amore 
894*49ef7e06SGarrett D'Amore 	if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
895*49ef7e06SGarrett D'Amore 		rc = EINVAL;
896*49ef7e06SGarrett D'Amore 		goto fail1;
897*49ef7e06SGarrett D'Amore 	}
898*49ef7e06SGarrett D'Amore 
899*49ef7e06SGarrett D'Amore 	for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
900*49ef7e06SGarrett D'Amore 		uint32_t byte;
901*49ef7e06SGarrett D'Amore 
902*49ef7e06SGarrett D'Amore 		/* Calculate the entry to place in the table */
903*49ef7e06SGarrett D'Amore 		byte = (n > 0) ? (uint32_t)table[index % n] : 0;
904*49ef7e06SGarrett D'Amore 
905*49ef7e06SGarrett D'Amore 		EFSYS_PROBE2(table, int, index, uint32_t, byte);
906*49ef7e06SGarrett D'Amore 
907*49ef7e06SGarrett D'Amore 		EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
908*49ef7e06SGarrett D'Amore 
909*49ef7e06SGarrett D'Amore 		/* Write the table */
910*49ef7e06SGarrett D'Amore 		EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
911*49ef7e06SGarrett D'Amore 				    index, &oword, B_TRUE);
912*49ef7e06SGarrett D'Amore 	}
913*49ef7e06SGarrett D'Amore 
914*49ef7e06SGarrett D'Amore 	for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
915*49ef7e06SGarrett D'Amore 		uint32_t byte;
916*49ef7e06SGarrett D'Amore 
917*49ef7e06SGarrett D'Amore 		/* Determine if we're starting a new batch */
918*49ef7e06SGarrett D'Amore 		byte = (n > 0) ? (uint32_t)table[index % n] : 0;
919*49ef7e06SGarrett D'Amore 
920*49ef7e06SGarrett D'Amore 		/* Read the table */
921*49ef7e06SGarrett D'Amore 		EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
922*49ef7e06SGarrett D'Amore 				    index, &oword, B_TRUE);
923*49ef7e06SGarrett D'Amore 
924*49ef7e06SGarrett D'Amore 		/* Verify the entry */
925*49ef7e06SGarrett D'Amore 		if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
926*49ef7e06SGarrett D'Amore 			rc = EFAULT;
927*49ef7e06SGarrett D'Amore 			goto fail2;
928*49ef7e06SGarrett D'Amore 		}
929*49ef7e06SGarrett D'Amore 	}
930*49ef7e06SGarrett D'Amore 
931*49ef7e06SGarrett D'Amore 	return (0);
932*49ef7e06SGarrett D'Amore 
933*49ef7e06SGarrett D'Amore fail2:
934*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
935*49ef7e06SGarrett D'Amore fail1:
936*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
937*49ef7e06SGarrett D'Amore 
938*49ef7e06SGarrett D'Amore 	return (rc);
939*49ef7e06SGarrett D'Amore }
940*49ef7e06SGarrett D'Amore #endif
941*49ef7e06SGarrett D'Amore 
942*49ef7e06SGarrett D'Amore /*
943*49ef7e06SGarrett D'Amore  * Falcon/Siena psuedo-header
944*49ef7e06SGarrett D'Amore  * --------------------------
945*49ef7e06SGarrett D'Amore  *
946*49ef7e06SGarrett D'Amore  * Receive packets are prefixed by an optional 16 byte pseudo-header.
947*49ef7e06SGarrett D'Amore  * The psuedo-header is a byte array of one of the forms:
948*49ef7e06SGarrett D'Amore  *
949*49ef7e06SGarrett D'Amore  *  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
950*49ef7e06SGarrett D'Amore  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
951*49ef7e06SGarrett D'Amore  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
952*49ef7e06SGarrett D'Amore  *
953*49ef7e06SGarrett D'Amore  * where:
954*49ef7e06SGarrett D'Amore  *   TT.TT.TT.TT   Toeplitz hash (32-bit big-endian)
955*49ef7e06SGarrett D'Amore  *   LL.LL         LFSR hash     (16-bit big-endian)
956*49ef7e06SGarrett D'Amore  */
957*49ef7e06SGarrett D'Amore 
958*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCALE
959*49ef7e06SGarrett D'Amore static	__checkReturn	uint32_t
siena_rx_prefix_hash(__in efx_nic_t * enp,__in efx_rx_hash_alg_t func,__in uint8_t * buffer)960*49ef7e06SGarrett D'Amore siena_rx_prefix_hash(
961*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
962*49ef7e06SGarrett D'Amore 	__in		efx_rx_hash_alg_t func,
963*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer)
964*49ef7e06SGarrett D'Amore {
965*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(enp));
966*49ef7e06SGarrett D'Amore 
967*49ef7e06SGarrett D'Amore 	switch (func) {
968*49ef7e06SGarrett D'Amore 	case EFX_RX_HASHALG_TOEPLITZ:
969*49ef7e06SGarrett D'Amore 		return ((buffer[12] << 24) |
970*49ef7e06SGarrett D'Amore 		    (buffer[13] << 16) |
971*49ef7e06SGarrett D'Amore 		    (buffer[14] <<  8) |
972*49ef7e06SGarrett D'Amore 		    buffer[15]);
973*49ef7e06SGarrett D'Amore 
974*49ef7e06SGarrett D'Amore 	case EFX_RX_HASHALG_LFSR:
975*49ef7e06SGarrett D'Amore 		return ((buffer[14] << 8) | buffer[15]);
976*49ef7e06SGarrett D'Amore 
977*49ef7e06SGarrett D'Amore 	default:
978*49ef7e06SGarrett D'Amore 		EFSYS_ASSERT(0);
979*49ef7e06SGarrett D'Amore 		return (0);
980*49ef7e06SGarrett D'Amore 	}
981*49ef7e06SGarrett D'Amore }
982*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_RX_SCALE */
983*49ef7e06SGarrett D'Amore 
984*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_prefix_pktlen(__in efx_nic_t * enp,__in uint8_t * buffer,__out uint16_t * lengthp)985*49ef7e06SGarrett D'Amore siena_rx_prefix_pktlen(
986*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
987*49ef7e06SGarrett D'Amore 	__in		uint8_t *buffer,
988*49ef7e06SGarrett D'Amore 	__out		uint16_t *lengthp)
989*49ef7e06SGarrett D'Amore {
990*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(enp));
991*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(buffer));
992*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(lengthp));
993*49ef7e06SGarrett D'Amore 	/* Not supported by Falcon/Siena hardware */
994*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT(0);
995*49ef7e06SGarrett D'Amore 	return (ENOTSUP);
996*49ef7e06SGarrett D'Amore }
997*49ef7e06SGarrett D'Amore 
998*49ef7e06SGarrett D'Amore 
999*49ef7e06SGarrett D'Amore static			void
siena_rx_qpost(__in efx_rxq_t * erp,__in_ecount (n)efsys_dma_addr_t * addrp,__in size_t size,__in unsigned int n,__in unsigned int completed,__in unsigned int added)1000*49ef7e06SGarrett D'Amore siena_rx_qpost(
1001*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp,
1002*49ef7e06SGarrett D'Amore 	__in_ecount(n)	efsys_dma_addr_t *addrp,
1003*49ef7e06SGarrett D'Amore 	__in		size_t size,
1004*49ef7e06SGarrett D'Amore 	__in		unsigned int n,
1005*49ef7e06SGarrett D'Amore 	__in		unsigned int completed,
1006*49ef7e06SGarrett D'Amore 	__in		unsigned int added)
1007*49ef7e06SGarrett D'Amore {
1008*49ef7e06SGarrett D'Amore 	efx_qword_t qword;
1009*49ef7e06SGarrett D'Amore 	unsigned int i;
1010*49ef7e06SGarrett D'Amore 	unsigned int offset;
1011*49ef7e06SGarrett D'Amore 	unsigned int id;
1012*49ef7e06SGarrett D'Amore 
1013*49ef7e06SGarrett D'Amore 	/* The client driver must not overfill the queue */
1014*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(added - completed + n, <=,
1015*49ef7e06SGarrett D'Amore 	    EFX_RXQ_LIMIT(erp->er_mask + 1));
1016*49ef7e06SGarrett D'Amore 
1017*49ef7e06SGarrett D'Amore 	id = added & (erp->er_mask);
1018*49ef7e06SGarrett D'Amore 	for (i = 0; i < n; i++) {
1019*49ef7e06SGarrett D'Amore 		EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1020*49ef7e06SGarrett D'Amore 		    unsigned int, id, efsys_dma_addr_t, addrp[i],
1021*49ef7e06SGarrett D'Amore 		    size_t, size);
1022*49ef7e06SGarrett D'Amore 
1023*49ef7e06SGarrett D'Amore 		EFX_POPULATE_QWORD_3(qword,
1024*49ef7e06SGarrett D'Amore 		    FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1025*49ef7e06SGarrett D'Amore 		    FSF_AZ_RX_KER_BUF_ADDR_DW0,
1026*49ef7e06SGarrett D'Amore 		    (uint32_t)(addrp[i] & 0xffffffff),
1027*49ef7e06SGarrett D'Amore 		    FSF_AZ_RX_KER_BUF_ADDR_DW1,
1028*49ef7e06SGarrett D'Amore 		    (uint32_t)(addrp[i] >> 32));
1029*49ef7e06SGarrett D'Amore 
1030*49ef7e06SGarrett D'Amore 		offset = id * sizeof (efx_qword_t);
1031*49ef7e06SGarrett D'Amore 		EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1032*49ef7e06SGarrett D'Amore 
1033*49ef7e06SGarrett D'Amore 		id = (id + 1) & (erp->er_mask);
1034*49ef7e06SGarrett D'Amore 	}
1035*49ef7e06SGarrett D'Amore }
1036*49ef7e06SGarrett D'Amore 
1037*49ef7e06SGarrett D'Amore static			void
siena_rx_qpush(__in efx_rxq_t * erp,__in unsigned int added,__inout unsigned int * pushedp)1038*49ef7e06SGarrett D'Amore siena_rx_qpush(
1039*49ef7e06SGarrett D'Amore 	__in	efx_rxq_t *erp,
1040*49ef7e06SGarrett D'Amore 	__in	unsigned int added,
1041*49ef7e06SGarrett D'Amore 	__inout	unsigned int *pushedp)
1042*49ef7e06SGarrett D'Amore {
1043*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
1044*49ef7e06SGarrett D'Amore 	unsigned int pushed = *pushedp;
1045*49ef7e06SGarrett D'Amore 	uint32_t wptr;
1046*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
1047*49ef7e06SGarrett D'Amore 	efx_dword_t dword;
1048*49ef7e06SGarrett D'Amore 
1049*49ef7e06SGarrett D'Amore 	/* All descriptors are pushed */
1050*49ef7e06SGarrett D'Amore 	*pushedp = added;
1051*49ef7e06SGarrett D'Amore 
1052*49ef7e06SGarrett D'Amore 	/* Push the populated descriptors out */
1053*49ef7e06SGarrett D'Amore 	wptr = added & erp->er_mask;
1054*49ef7e06SGarrett D'Amore 
1055*49ef7e06SGarrett D'Amore 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1056*49ef7e06SGarrett D'Amore 
1057*49ef7e06SGarrett D'Amore 	/* Only write the third DWORD */
1058*49ef7e06SGarrett D'Amore 	EFX_POPULATE_DWORD_1(dword,
1059*49ef7e06SGarrett D'Amore 	    EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1060*49ef7e06SGarrett D'Amore 
1061*49ef7e06SGarrett D'Amore 	/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1062*49ef7e06SGarrett D'Amore 	EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1063*49ef7e06SGarrett D'Amore 	    wptr, pushed & erp->er_mask);
1064*49ef7e06SGarrett D'Amore 	EFSYS_PIO_WRITE_BARRIER();
1065*49ef7e06SGarrett D'Amore 	EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1066*49ef7e06SGarrett D'Amore 			    erp->er_index, &dword, B_FALSE);
1067*49ef7e06SGarrett D'Amore }
1068*49ef7e06SGarrett D'Amore 
1069*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_qflush(__in efx_rxq_t * erp)1070*49ef7e06SGarrett D'Amore siena_rx_qflush(
1071*49ef7e06SGarrett D'Amore 	__in	efx_rxq_t *erp)
1072*49ef7e06SGarrett D'Amore {
1073*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
1074*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
1075*49ef7e06SGarrett D'Amore 	uint32_t label;
1076*49ef7e06SGarrett D'Amore 
1077*49ef7e06SGarrett D'Amore 	label = erp->er_index;
1078*49ef7e06SGarrett D'Amore 
1079*49ef7e06SGarrett D'Amore 	/* Flush the queue */
1080*49ef7e06SGarrett D'Amore 	EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1081*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_FLUSH_DESCQ, label);
1082*49ef7e06SGarrett D'Amore 	EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1083*49ef7e06SGarrett D'Amore 
1084*49ef7e06SGarrett D'Amore 	return (0);
1085*49ef7e06SGarrett D'Amore }
1086*49ef7e06SGarrett D'Amore 
1087*49ef7e06SGarrett D'Amore static		void
siena_rx_qenable(__in efx_rxq_t * erp)1088*49ef7e06SGarrett D'Amore siena_rx_qenable(
1089*49ef7e06SGarrett D'Amore 	__in	efx_rxq_t *erp)
1090*49ef7e06SGarrett D'Amore {
1091*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
1092*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
1093*49ef7e06SGarrett D'Amore 
1094*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1095*49ef7e06SGarrett D'Amore 
1096*49ef7e06SGarrett D'Amore 	EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1097*49ef7e06SGarrett D'Amore 			    erp->er_index, &oword, B_TRUE);
1098*49ef7e06SGarrett D'Amore 
1099*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1100*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1101*49ef7e06SGarrett D'Amore 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1102*49ef7e06SGarrett D'Amore 
1103*49ef7e06SGarrett D'Amore 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1104*49ef7e06SGarrett D'Amore 			    erp->er_index, &oword, B_TRUE);
1105*49ef7e06SGarrett D'Amore }
1106*49ef7e06SGarrett D'Amore 
1107*49ef7e06SGarrett D'Amore static	__checkReturn	efx_rc_t
siena_rx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efx_rxq_type_t type,__in efsys_mem_t * esmp,__in size_t n,__in uint32_t id,__in efx_evq_t * eep,__in efx_rxq_t * erp)1108*49ef7e06SGarrett D'Amore siena_rx_qcreate(
1109*49ef7e06SGarrett D'Amore 	__in		efx_nic_t *enp,
1110*49ef7e06SGarrett D'Amore 	__in		unsigned int index,
1111*49ef7e06SGarrett D'Amore 	__in		unsigned int label,
1112*49ef7e06SGarrett D'Amore 	__in		efx_rxq_type_t type,
1113*49ef7e06SGarrett D'Amore 	__in		efsys_mem_t *esmp,
1114*49ef7e06SGarrett D'Amore 	__in		size_t n,
1115*49ef7e06SGarrett D'Amore 	__in		uint32_t id,
1116*49ef7e06SGarrett D'Amore 	__in		efx_evq_t *eep,
1117*49ef7e06SGarrett D'Amore 	__in		efx_rxq_t *erp)
1118*49ef7e06SGarrett D'Amore {
1119*49ef7e06SGarrett D'Amore 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1120*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
1121*49ef7e06SGarrett D'Amore 	uint32_t size;
1122*49ef7e06SGarrett D'Amore 	boolean_t jumbo;
1123*49ef7e06SGarrett D'Amore 	efx_rc_t rc;
1124*49ef7e06SGarrett D'Amore 
1125*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(esmp));
1126*49ef7e06SGarrett D'Amore 
1127*49ef7e06SGarrett D'Amore 	EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1128*49ef7e06SGarrett D'Amore 	    (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1129*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1130*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1131*49ef7e06SGarrett D'Amore 
1132*49ef7e06SGarrett D'Amore 	EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1133*49ef7e06SGarrett D'Amore 	EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1134*49ef7e06SGarrett D'Amore 
1135*49ef7e06SGarrett D'Amore 	if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
1136*49ef7e06SGarrett D'Amore 		rc = EINVAL;
1137*49ef7e06SGarrett D'Amore 		goto fail1;
1138*49ef7e06SGarrett D'Amore 	}
1139*49ef7e06SGarrett D'Amore 	if (index >= encp->enc_rxq_limit) {
1140*49ef7e06SGarrett D'Amore 		rc = EINVAL;
1141*49ef7e06SGarrett D'Amore 		goto fail2;
1142*49ef7e06SGarrett D'Amore 	}
1143*49ef7e06SGarrett D'Amore 	for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1144*49ef7e06SGarrett D'Amore 	    size++)
1145*49ef7e06SGarrett D'Amore 		if ((1 << size) == (int)(n / EFX_RXQ_MINNDESCS))
1146*49ef7e06SGarrett D'Amore 			break;
1147*49ef7e06SGarrett D'Amore 	if (id + (1 << size) >= encp->enc_buftbl_limit) {
1148*49ef7e06SGarrett D'Amore 		rc = EINVAL;
1149*49ef7e06SGarrett D'Amore 		goto fail3;
1150*49ef7e06SGarrett D'Amore 	}
1151*49ef7e06SGarrett D'Amore 
1152*49ef7e06SGarrett D'Amore 	switch (type) {
1153*49ef7e06SGarrett D'Amore 	case EFX_RXQ_TYPE_DEFAULT:
1154*49ef7e06SGarrett D'Amore 		jumbo = B_FALSE;
1155*49ef7e06SGarrett D'Amore 		break;
1156*49ef7e06SGarrett D'Amore 
1157*49ef7e06SGarrett D'Amore #if EFSYS_OPT_RX_SCATTER
1158*49ef7e06SGarrett D'Amore 	case EFX_RXQ_TYPE_SCATTER:
1159*49ef7e06SGarrett D'Amore 		if (enp->en_family < EFX_FAMILY_SIENA) {
1160*49ef7e06SGarrett D'Amore 			rc = EINVAL;
1161*49ef7e06SGarrett D'Amore 			goto fail4;
1162*49ef7e06SGarrett D'Amore 		}
1163*49ef7e06SGarrett D'Amore 		jumbo = B_TRUE;
1164*49ef7e06SGarrett D'Amore 		break;
1165*49ef7e06SGarrett D'Amore #endif	/* EFSYS_OPT_RX_SCATTER */
1166*49ef7e06SGarrett D'Amore 
1167*49ef7e06SGarrett D'Amore 	default:
1168*49ef7e06SGarrett D'Amore 		rc = EINVAL;
1169*49ef7e06SGarrett D'Amore 		goto fail4;
1170*49ef7e06SGarrett D'Amore 	}
1171*49ef7e06SGarrett D'Amore 
1172*49ef7e06SGarrett D'Amore 	/* Set up the new descriptor queue */
1173*49ef7e06SGarrett D'Amore 	EFX_POPULATE_OWORD_7(oword,
1174*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1175*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1176*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1177*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_LABEL, label,
1178*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_SIZE, size,
1179*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_TYPE, 0,
1180*49ef7e06SGarrett D'Amore 	    FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1181*49ef7e06SGarrett D'Amore 
1182*49ef7e06SGarrett D'Amore 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1183*49ef7e06SGarrett D'Amore 			    erp->er_index, &oword, B_TRUE);
1184*49ef7e06SGarrett D'Amore 
1185*49ef7e06SGarrett D'Amore 	return (0);
1186*49ef7e06SGarrett D'Amore 
1187*49ef7e06SGarrett D'Amore fail4:
1188*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail4);
1189*49ef7e06SGarrett D'Amore fail3:
1190*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail3);
1191*49ef7e06SGarrett D'Amore fail2:
1192*49ef7e06SGarrett D'Amore 	EFSYS_PROBE(fail2);
1193*49ef7e06SGarrett D'Amore fail1:
1194*49ef7e06SGarrett D'Amore 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1195*49ef7e06SGarrett D'Amore 
1196*49ef7e06SGarrett D'Amore 	return (rc);
1197*49ef7e06SGarrett D'Amore }
1198*49ef7e06SGarrett D'Amore 
1199*49ef7e06SGarrett D'Amore static		void
siena_rx_qdestroy(__in efx_rxq_t * erp)1200*49ef7e06SGarrett D'Amore siena_rx_qdestroy(
1201*49ef7e06SGarrett D'Amore 	__in	efx_rxq_t *erp)
1202*49ef7e06SGarrett D'Amore {
1203*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = erp->er_enp;
1204*49ef7e06SGarrett D'Amore 	efx_oword_t oword;
1205*49ef7e06SGarrett D'Amore 
1206*49ef7e06SGarrett D'Amore 	EFSYS_ASSERT(enp->en_rx_qcount != 0);
1207*49ef7e06SGarrett D'Amore 	--enp->en_rx_qcount;
1208*49ef7e06SGarrett D'Amore 
1209*49ef7e06SGarrett D'Amore 	/* Purge descriptor queue */
1210*49ef7e06SGarrett D'Amore 	EFX_ZERO_OWORD(oword);
1211*49ef7e06SGarrett D'Amore 
1212*49ef7e06SGarrett D'Amore 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1213*49ef7e06SGarrett D'Amore 			    erp->er_index, &oword, B_TRUE);
1214*49ef7e06SGarrett D'Amore 
1215*49ef7e06SGarrett D'Amore 	/* Free the RXQ object */
1216*49ef7e06SGarrett D'Amore 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1217*49ef7e06SGarrett D'Amore }
1218*49ef7e06SGarrett D'Amore 
1219*49ef7e06SGarrett D'Amore static		void
siena_rx_fini(__in efx_nic_t * enp)1220*49ef7e06SGarrett D'Amore siena_rx_fini(
1221*49ef7e06SGarrett D'Amore 	__in	efx_nic_t *enp)
1222*49ef7e06SGarrett D'Amore {
1223*49ef7e06SGarrett D'Amore 	_NOTE(ARGUNUSED(enp))
1224*49ef7e06SGarrett D'Amore }
1225*49ef7e06SGarrett D'Amore 
1226*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_SIENA */
1227