1 /*
2  * Copyright (c) 2007-2015 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30 
31 #include "efx.h"
32 #include "efx_impl.h"
33 
34 #if EFSYS_OPT_QSTATS
35 #define	EFX_TX_QSTAT_INCR(_etp, _stat)					\
36 	do {								\
37 		(_etp)->et_stat[_stat]++;				\
38 	_NOTE(CONSTANTCONDITION)					\
39 	} while (B_FALSE)
40 #else
41 #define	EFX_TX_QSTAT_INCR(_etp, _stat)
42 #endif
43 
44 #if EFSYS_OPT_SIENA
45 
46 static	__checkReturn	efx_rc_t
47 siena_tx_init(
48 	__in		efx_nic_t *enp);
49 
50 static			void
51 siena_tx_fini(
52 	__in		efx_nic_t *enp);
53 
54 static	__checkReturn	efx_rc_t
55 siena_tx_qcreate(
56 	__in		efx_nic_t *enp,
57 	__in		unsigned int index,
58 	__in		unsigned int label,
59 	__in		efsys_mem_t *esmp,
60 	__in		size_t n,
61 	__in		uint32_t id,
62 	__in		uint16_t flags,
63 	__in		efx_evq_t *eep,
64 	__in		efx_txq_t *etp,
65 	__out		unsigned int *addedp);
66 
67 static		void
68 siena_tx_qdestroy(
69 	__in	efx_txq_t *etp);
70 
71 static	__checkReturn	efx_rc_t
72 siena_tx_qpost(
73 	__in		efx_txq_t *etp,
74 	__in_ecount(n)	efx_buffer_t *eb,
75 	__in		unsigned int n,
76 	__in		unsigned int completed,
77 	__inout		unsigned int *addedp);
78 
79 static			void
80 siena_tx_qpush(
81 	__in	efx_txq_t *etp,
82 	__in	unsigned int added,
83 	__in	unsigned int pushed);
84 
85 static	__checkReturn	efx_rc_t
86 siena_tx_qpace(
87 	__in		efx_txq_t *etp,
88 	__in		unsigned int ns);
89 
90 static	__checkReturn	efx_rc_t
91 siena_tx_qflush(
92 	__in		efx_txq_t *etp);
93 
94 static			void
95 siena_tx_qenable(
96 	__in	efx_txq_t *etp);
97 
98 	__checkReturn	efx_rc_t
99 siena_tx_qdesc_post(
100 	__in		efx_txq_t *etp,
101 	__in_ecount(n)	efx_desc_t *ed,
102 	__in		unsigned int n,
103 	__in		unsigned int completed,
104 	__inout		unsigned int *addedp);
105 
106 	void
107 siena_tx_qdesc_dma_create(
108 	__in	efx_txq_t *etp,
109 	__in	efsys_dma_addr_t addr,
110 	__in	size_t size,
111 	__in	boolean_t eop,
112 	__out	efx_desc_t *edp);
113 
114 #if EFSYS_OPT_QSTATS
115 static			void
116 siena_tx_qstats_update(
117 	__in				efx_txq_t *etp,
118 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat);
119 #endif
120 
121 #endif /* EFSYS_OPT_SIENA */
122 
123 
124 #if EFSYS_OPT_SIENA
125 static const efx_tx_ops_t	__efx_tx_siena_ops = {
126 	siena_tx_init,				/* etxo_init */
127 	siena_tx_fini,				/* etxo_fini */
128 	siena_tx_qcreate,			/* etxo_qcreate */
129 	siena_tx_qdestroy,			/* etxo_qdestroy */
130 	siena_tx_qpost,				/* etxo_qpost */
131 	siena_tx_qpush,				/* etxo_qpush */
132 	siena_tx_qpace,				/* etxo_qpace */
133 	siena_tx_qflush,			/* etxo_qflush */
134 	siena_tx_qenable,			/* etxo_qenable */
135 	NULL,					/* etxo_qpio_enable */
136 	NULL,					/* etxo_qpio_disable */
137 	NULL,					/* etxo_qpio_write */
138 	NULL,					/* etxo_qpio_post */
139 	siena_tx_qdesc_post,			/* etxo_qdesc_post */
140 	siena_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
141 	NULL,					/* etxo_qdesc_tso_create */
142 	NULL,					/* etxo_qdesc_tso2_create */
143 	NULL,					/* etxo_qdesc_vlantci_create */
144 #if EFSYS_OPT_QSTATS
145 	siena_tx_qstats_update,			/* etxo_qstats_update */
146 #endif
147 };
148 #endif /* EFSYS_OPT_SIENA */
149 
150 #if EFSYS_OPT_HUNTINGTON
151 static const efx_tx_ops_t	__efx_tx_hunt_ops = {
152 	ef10_tx_init,				/* etxo_init */
153 	ef10_tx_fini,				/* etxo_fini */
154 	ef10_tx_qcreate,			/* etxo_qcreate */
155 	ef10_tx_qdestroy,			/* etxo_qdestroy */
156 	ef10_tx_qpost,				/* etxo_qpost */
157 	ef10_tx_qpush,				/* etxo_qpush */
158 	ef10_tx_qpace,				/* etxo_qpace */
159 	ef10_tx_qflush,				/* etxo_qflush */
160 	ef10_tx_qenable,			/* etxo_qenable */
161 	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
162 	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
163 	ef10_tx_qpio_write,			/* etxo_qpio_write */
164 	ef10_tx_qpio_post,			/* etxo_qpio_post */
165 	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
166 	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
167 	ef10_tx_qdesc_tso_create,		/* etxo_qdesc_tso_create */
168 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
169 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
170 #if EFSYS_OPT_QSTATS
171 	ef10_tx_qstats_update,			/* etxo_qstats_update */
172 #endif
173 };
174 #endif /* EFSYS_OPT_HUNTINGTON */
175 
176 #if EFSYS_OPT_MEDFORD
177 static const efx_tx_ops_t	__efx_tx_medford_ops = {
178 	ef10_tx_init,				/* etxo_init */
179 	ef10_tx_fini,				/* etxo_fini */
180 	ef10_tx_qcreate,			/* etxo_qcreate */
181 	ef10_tx_qdestroy,			/* etxo_qdestroy */
182 	ef10_tx_qpost,				/* etxo_qpost */
183 	ef10_tx_qpush,				/* etxo_qpush */
184 	ef10_tx_qpace,				/* etxo_qpace */
185 	ef10_tx_qflush,				/* etxo_qflush */
186 	ef10_tx_qenable,			/* etxo_qenable */
187 	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
188 	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
189 	ef10_tx_qpio_write,			/* etxo_qpio_write */
190 	ef10_tx_qpio_post,			/* etxo_qpio_post */
191 	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
192 	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
193 	NULL,					/* etxo_qdesc_tso_create */
194 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
195 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
196 #if EFSYS_OPT_QSTATS
197 	ef10_tx_qstats_update,			/* etxo_qstats_update */
198 #endif
199 };
200 #endif /* EFSYS_OPT_MEDFORD */
201 
202 	__checkReturn	efx_rc_t
efx_tx_init(__in efx_nic_t * enp)203 efx_tx_init(
204 	__in		efx_nic_t *enp)
205 {
206 	const efx_tx_ops_t *etxop;
207 	efx_rc_t rc;
208 
209 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
210 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
211 
212 	if (!(enp->en_mod_flags & EFX_MOD_EV)) {
213 		rc = EINVAL;
214 		goto fail1;
215 	}
216 
217 	if (enp->en_mod_flags & EFX_MOD_TX) {
218 		rc = EINVAL;
219 		goto fail2;
220 	}
221 
222 	switch (enp->en_family) {
223 #if EFSYS_OPT_SIENA
224 	case EFX_FAMILY_SIENA:
225 		etxop = &__efx_tx_siena_ops;
226 		break;
227 #endif /* EFSYS_OPT_SIENA */
228 
229 #if EFSYS_OPT_HUNTINGTON
230 	case EFX_FAMILY_HUNTINGTON:
231 		etxop = &__efx_tx_hunt_ops;
232 		break;
233 #endif /* EFSYS_OPT_HUNTINGTON */
234 
235 #if EFSYS_OPT_MEDFORD
236 	case EFX_FAMILY_MEDFORD:
237 		etxop = &__efx_tx_medford_ops;
238 		break;
239 #endif /* EFSYS_OPT_MEDFORD */
240 
241 	default:
242 		EFSYS_ASSERT(0);
243 		rc = ENOTSUP;
244 		goto fail3;
245 	}
246 
247 	EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
248 
249 	if ((rc = etxop->etxo_init(enp)) != 0)
250 		goto fail4;
251 
252 	enp->en_etxop = etxop;
253 	enp->en_mod_flags |= EFX_MOD_TX;
254 	return (0);
255 
256 fail4:
257 	EFSYS_PROBE(fail4);
258 fail3:
259 	EFSYS_PROBE(fail3);
260 fail2:
261 	EFSYS_PROBE(fail2);
262 fail1:
263 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
264 
265 	enp->en_etxop = NULL;
266 	enp->en_mod_flags &= ~EFX_MOD_TX;
267 	return (rc);
268 }
269 
270 			void
efx_tx_fini(__in efx_nic_t * enp)271 efx_tx_fini(
272 	__in	efx_nic_t *enp)
273 {
274 	const efx_tx_ops_t *etxop = enp->en_etxop;
275 
276 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
277 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
278 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
279 	EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
280 
281 	etxop->etxo_fini(enp);
282 
283 	enp->en_etxop = NULL;
284 	enp->en_mod_flags &= ~EFX_MOD_TX;
285 }
286 
287 	__checkReturn	efx_rc_t
efx_tx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efsys_mem_t * esmp,__in size_t n,__in uint32_t id,__in uint16_t flags,__in efx_evq_t * eep,__deref_out efx_txq_t ** etpp,__out unsigned int * addedp)288 efx_tx_qcreate(
289 	__in		efx_nic_t *enp,
290 	__in		unsigned int index,
291 	__in		unsigned int label,
292 	__in		efsys_mem_t *esmp,
293 	__in		size_t n,
294 	__in		uint32_t id,
295 	__in		uint16_t flags,
296 	__in		efx_evq_t *eep,
297 	__deref_out	efx_txq_t **etpp,
298 	__out		unsigned int *addedp)
299 {
300 	const efx_tx_ops_t *etxop = enp->en_etxop;
301 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
302 	efx_txq_t *etp;
303 	efx_rc_t rc;
304 
305 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
306 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
307 
308 	EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
309 
310 	/* Allocate an TXQ object */
311 	EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
312 
313 	if (etp == NULL) {
314 		rc = ENOMEM;
315 		goto fail1;
316 	}
317 
318 	etp->et_magic = EFX_TXQ_MAGIC;
319 	etp->et_enp = enp;
320 	etp->et_index = index;
321 	etp->et_mask = n - 1;
322 	etp->et_esmp = esmp;
323 
324 	/* Initial descriptor index may be modified by etxo_qcreate */
325 	*addedp = 0;
326 
327 	if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
328 	    n, id, flags, eep, etp, addedp)) != 0)
329 			goto fail2;
330 
331 	enp->en_tx_qcount++;
332 	*etpp = etp;
333 
334 	return (0);
335 
336 fail2:
337 	EFSYS_PROBE(fail2);
338 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
339 fail1:
340 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
341 	return (rc);
342 }
343 
344 		void
efx_tx_qdestroy(__in efx_txq_t * etp)345 efx_tx_qdestroy(
346 	__in	efx_txq_t *etp)
347 {
348 	efx_nic_t *enp = etp->et_enp;
349 	const efx_tx_ops_t *etxop = enp->en_etxop;
350 
351 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
352 
353 	EFSYS_ASSERT(enp->en_tx_qcount != 0);
354 	--enp->en_tx_qcount;
355 
356 	etxop->etxo_qdestroy(etp);
357 
358 	/* Free the TXQ object */
359 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
360 }
361 
362 	__checkReturn	efx_rc_t
efx_tx_qpost(__in efx_txq_t * etp,__in_ecount (n)efx_buffer_t * eb,__in unsigned int n,__in unsigned int completed,__inout unsigned int * addedp)363 efx_tx_qpost(
364 	__in		efx_txq_t *etp,
365 	__in_ecount(n)	efx_buffer_t *eb,
366 	__in		unsigned int n,
367 	__in		unsigned int completed,
368 	__inout		unsigned int *addedp)
369 {
370 	efx_nic_t *enp = etp->et_enp;
371 	const efx_tx_ops_t *etxop = enp->en_etxop;
372 	efx_rc_t rc;
373 
374 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
375 
376 	if ((rc = etxop->etxo_qpost(etp, eb,
377 	    n, completed, addedp)) != 0)
378 		goto fail1;
379 
380 	return (0);
381 
382 fail1:
383 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
384 	return (rc);
385 }
386 
387 			void
efx_tx_qpush(__in efx_txq_t * etp,__in unsigned int added,__in unsigned int pushed)388 efx_tx_qpush(
389 	__in	efx_txq_t *etp,
390 	__in	unsigned int added,
391 	__in	unsigned int pushed)
392 {
393 	efx_nic_t *enp = etp->et_enp;
394 	const efx_tx_ops_t *etxop = enp->en_etxop;
395 
396 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
397 
398 	etxop->etxo_qpush(etp, added, pushed);
399 }
400 
401 	__checkReturn	efx_rc_t
efx_tx_qpace(__in efx_txq_t * etp,__in unsigned int ns)402 efx_tx_qpace(
403 	__in		efx_txq_t *etp,
404 	__in		unsigned int ns)
405 {
406 	efx_nic_t *enp = etp->et_enp;
407 	const efx_tx_ops_t *etxop = enp->en_etxop;
408 	efx_rc_t rc;
409 
410 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
411 
412 	if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
413 		goto fail1;
414 
415 	return (0);
416 
417 fail1:
418 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
419 	return (rc);
420 }
421 
422 	__checkReturn	efx_rc_t
efx_tx_qflush(__in efx_txq_t * etp)423 efx_tx_qflush(
424 	__in	efx_txq_t *etp)
425 {
426 	efx_nic_t *enp = etp->et_enp;
427 	const efx_tx_ops_t *etxop = enp->en_etxop;
428 	efx_rc_t rc;
429 
430 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
431 
432 	if ((rc = etxop->etxo_qflush(etp)) != 0)
433 		goto fail1;
434 
435 	return (0);
436 
437 fail1:
438 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
439 	return (rc);
440 }
441 
442 			void
efx_tx_qenable(__in efx_txq_t * etp)443 efx_tx_qenable(
444 	__in	efx_txq_t *etp)
445 {
446 	efx_nic_t *enp = etp->et_enp;
447 	const efx_tx_ops_t *etxop = enp->en_etxop;
448 
449 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
450 
451 	etxop->etxo_qenable(etp);
452 }
453 
454 	__checkReturn	efx_rc_t
efx_tx_qpio_enable(__in efx_txq_t * etp)455 efx_tx_qpio_enable(
456 	__in	efx_txq_t *etp)
457 {
458 	efx_nic_t *enp = etp->et_enp;
459 	const efx_tx_ops_t *etxop = enp->en_etxop;
460 	efx_rc_t rc;
461 
462 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
463 
464 	if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
465 		rc = ENOTSUP;
466 		goto fail1;
467 	}
468 	if (etxop->etxo_qpio_enable == NULL) {
469 		rc = ENOTSUP;
470 		goto fail2;
471 	}
472 	if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
473 		goto fail3;
474 
475 	return (0);
476 
477 fail3:
478 	EFSYS_PROBE(fail3);
479 fail2:
480 	EFSYS_PROBE(fail2);
481 fail1:
482 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
483 	return (rc);
484 }
485 
486 		void
efx_tx_qpio_disable(__in efx_txq_t * etp)487 efx_tx_qpio_disable(
488 	__in	efx_txq_t *etp)
489 {
490 	efx_nic_t *enp = etp->et_enp;
491 	const efx_tx_ops_t *etxop = enp->en_etxop;
492 
493 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
494 
495 	if (etxop->etxo_qpio_disable != NULL)
496 		etxop->etxo_qpio_disable(etp);
497 }
498 
499 	__checkReturn	efx_rc_t
efx_tx_qpio_write(__in efx_txq_t * etp,__in_ecount (buf_length)uint8_t * buffer,__in size_t buf_length,__in size_t pio_buf_offset)500 efx_tx_qpio_write(
501 	__in			efx_txq_t *etp,
502 	__in_ecount(buf_length)	uint8_t *buffer,
503 	__in			size_t buf_length,
504 	__in			size_t pio_buf_offset)
505 {
506 	efx_nic_t *enp = etp->et_enp;
507 	const efx_tx_ops_t *etxop = enp->en_etxop;
508 	efx_rc_t rc;
509 
510 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
511 
512 	if (etxop->etxo_qpio_write != NULL) {
513 		if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
514 						pio_buf_offset)) != 0)
515 			goto fail1;
516 		return (0);
517 	}
518 
519 	return (ENOTSUP);
520 
521 fail1:
522 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
523 	return (rc);
524 }
525 
526 	__checkReturn	efx_rc_t
efx_tx_qpio_post(__in efx_txq_t * etp,__in size_t pkt_length,__in unsigned int completed,__inout unsigned int * addedp)527 efx_tx_qpio_post(
528 	__in			efx_txq_t *etp,
529 	__in			size_t pkt_length,
530 	__in			unsigned int completed,
531 	__inout			unsigned int *addedp)
532 {
533 	efx_nic_t *enp = etp->et_enp;
534 	const efx_tx_ops_t *etxop = enp->en_etxop;
535 	efx_rc_t rc;
536 
537 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
538 
539 	if (etxop->etxo_qpio_post != NULL) {
540 		if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
541 						addedp)) != 0)
542 			goto fail1;
543 		return (0);
544 	}
545 
546 	return (ENOTSUP);
547 
548 fail1:
549 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
550 	return (rc);
551 }
552 
553 	__checkReturn	efx_rc_t
efx_tx_qdesc_post(__in efx_txq_t * etp,__in_ecount (n)efx_desc_t * ed,__in unsigned int n,__in unsigned int completed,__inout unsigned int * addedp)554 efx_tx_qdesc_post(
555 	__in		efx_txq_t *etp,
556 	__in_ecount(n)	efx_desc_t *ed,
557 	__in		unsigned int n,
558 	__in		unsigned int completed,
559 	__inout		unsigned int *addedp)
560 {
561 	efx_nic_t *enp = etp->et_enp;
562 	const efx_tx_ops_t *etxop = enp->en_etxop;
563 	efx_rc_t rc;
564 
565 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
566 
567 	if ((rc = etxop->etxo_qdesc_post(etp, ed,
568 	    n, completed, addedp)) != 0)
569 		goto fail1;
570 
571 	return (0);
572 
573 fail1:
574 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
575 	return (rc);
576 }
577 
578 	void
efx_tx_qdesc_dma_create(__in efx_txq_t * etp,__in efsys_dma_addr_t addr,__in size_t size,__in boolean_t eop,__out efx_desc_t * edp)579 efx_tx_qdesc_dma_create(
580 	__in	efx_txq_t *etp,
581 	__in	efsys_dma_addr_t addr,
582 	__in	size_t size,
583 	__in	boolean_t eop,
584 	__out	efx_desc_t *edp)
585 {
586 	efx_nic_t *enp = etp->et_enp;
587 	const efx_tx_ops_t *etxop = enp->en_etxop;
588 
589 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
590 	EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
591 
592 	etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
593 }
594 
595 	void
efx_tx_qdesc_tso_create(__in efx_txq_t * etp,__in uint16_t ipv4_id,__in uint32_t tcp_seq,__in uint8_t tcp_flags,__out efx_desc_t * edp)596 efx_tx_qdesc_tso_create(
597 	__in	efx_txq_t *etp,
598 	__in	uint16_t ipv4_id,
599 	__in	uint32_t tcp_seq,
600 	__in	uint8_t  tcp_flags,
601 	__out	efx_desc_t *edp)
602 {
603 	efx_nic_t *enp = etp->et_enp;
604 	const efx_tx_ops_t *etxop = enp->en_etxop;
605 
606 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
607 	EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
608 
609 	etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
610 }
611 
612 	void
efx_tx_qdesc_tso2_create(__in efx_txq_t * etp,__in uint16_t ipv4_id,__in uint32_t tcp_seq,__in uint16_t mss,__out_ecount (count)efx_desc_t * edp,__in int count)613 efx_tx_qdesc_tso2_create(
614 	__in			efx_txq_t *etp,
615 	__in			uint16_t ipv4_id,
616 	__in			uint32_t tcp_seq,
617 	__in			uint16_t mss,
618 	__out_ecount(count)	efx_desc_t *edp,
619 	__in			int count)
620 {
621 	efx_nic_t *enp = etp->et_enp;
622 	const efx_tx_ops_t *etxop = enp->en_etxop;
623 
624 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
625 	EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
626 
627 	etxop->etxo_qdesc_tso2_create(etp, ipv4_id, tcp_seq, mss, edp, count);
628 }
629 
630 	void
efx_tx_qdesc_vlantci_create(__in efx_txq_t * etp,__in uint16_t tci,__out efx_desc_t * edp)631 efx_tx_qdesc_vlantci_create(
632 	__in	efx_txq_t *etp,
633 	__in	uint16_t tci,
634 	__out	efx_desc_t *edp)
635 {
636 	efx_nic_t *enp = etp->et_enp;
637 	const efx_tx_ops_t *etxop = enp->en_etxop;
638 
639 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
640 	EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
641 
642 	etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
643 }
644 
645 
646 #if EFSYS_OPT_QSTATS
647 			void
efx_tx_qstats_update(__in efx_txq_t * etp,__inout_ecount (TX_NQSTATS)efsys_stat_t * stat)648 efx_tx_qstats_update(
649 	__in				efx_txq_t *etp,
650 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
651 {
652 	efx_nic_t *enp = etp->et_enp;
653 	const efx_tx_ops_t *etxop = enp->en_etxop;
654 
655 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
656 
657 	etxop->etxo_qstats_update(etp, stat);
658 }
659 #endif
660 
661 
662 #if EFSYS_OPT_SIENA
663 
664 static	__checkReturn	efx_rc_t
siena_tx_init(__in efx_nic_t * enp)665 siena_tx_init(
666 	__in		efx_nic_t *enp)
667 {
668 	efx_oword_t oword;
669 
670 	/*
671 	 * Disable the timer-based TX DMA backoff and allow TX DMA to be
672 	 * controlled by the RX FIFO fill level (although always allow a
673 	 * minimal trickle).
674 	 */
675 	EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
676 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
677 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
678 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
679 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
680 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
681 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
682 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
683 
684 	/*
685 	 * Filter all packets less than 14 bytes to avoid parsing
686 	 * errors.
687 	 */
688 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
689 	EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
690 
691 	/*
692 	 * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
693 	 * descriptors (which is bad).
694 	 */
695 	EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
696 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
697 	EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
698 
699 	return (0);
700 }
701 
702 #define	EFX_TX_DESC(_etp, _addr, _size, _eop, _added)			\
703 	do {								\
704 		unsigned int id;					\
705 		size_t offset;						\
706 		efx_qword_t qword;					\
707 									\
708 		id = (_added)++ & (_etp)->et_mask;			\
709 		offset = id * sizeof (efx_qword_t);			\
710 									\
711 		EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index,	\
712 		    unsigned int, id, efsys_dma_addr_t, (_addr),	\
713 		    size_t, (_size), boolean_t, (_eop));		\
714 									\
715 		EFX_POPULATE_QWORD_4(qword,				\
716 		    FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1,			\
717 		    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size),	\
718 		    FSF_AZ_TX_KER_BUF_ADDR_DW0,				\
719 		    (uint32_t)((_addr) & 0xffffffff),			\
720 		    FSF_AZ_TX_KER_BUF_ADDR_DW1,				\
721 		    (uint32_t)((_addr) >> 32));				\
722 		EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword);	\
723 									\
724 		_NOTE(CONSTANTCONDITION)				\
725 	} while (B_FALSE)
726 
727 static	__checkReturn	efx_rc_t
siena_tx_qpost(__in efx_txq_t * etp,__in_ecount (n)efx_buffer_t * eb,__in unsigned int n,__in unsigned int completed,__inout unsigned int * addedp)728 siena_tx_qpost(
729 	__in		efx_txq_t *etp,
730 	__in_ecount(n)	efx_buffer_t *eb,
731 	__in		unsigned int n,
732 	__in		unsigned int completed,
733 	__inout		unsigned int *addedp)
734 {
735 	unsigned int added = *addedp;
736 	unsigned int i;
737 	int rc = ENOSPC;
738 
739 	if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))
740 		goto fail1;
741 
742 	for (i = 0; i < n; i++) {
743 		efx_buffer_t *ebp = &eb[i];
744 		efsys_dma_addr_t start = ebp->eb_addr;
745 		size_t size = ebp->eb_size;
746 		efsys_dma_addr_t end = start + size;
747 
748 		/* Fragments must not span 4k boundaries. */
749 		EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end);
750 
751 		EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
752 	}
753 
754 	EFX_TX_QSTAT_INCR(etp, TX_POST);
755 
756 	*addedp = added;
757 	return (0);
758 
759 fail1:
760 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
761 
762 	return (rc);
763 }
764 
765 static		void
siena_tx_qpush(__in efx_txq_t * etp,__in unsigned int added,__in unsigned int pushed)766 siena_tx_qpush(
767 	__in	efx_txq_t *etp,
768 	__in	unsigned int added,
769 	__in	unsigned int pushed)
770 {
771 	efx_nic_t *enp = etp->et_enp;
772 	uint32_t wptr;
773 	efx_dword_t dword;
774 	efx_oword_t oword;
775 
776 	/* Push the populated descriptors out */
777 	wptr = added & etp->et_mask;
778 
779 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
780 
781 	/* Only write the third DWORD */
782 	EFX_POPULATE_DWORD_1(dword,
783 	    EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
784 
785 	/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
786 	EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
787 	    wptr, pushed & etp->et_mask);
788 	EFSYS_PIO_WRITE_BARRIER();
789 	EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
790 			    etp->et_index, &dword, B_FALSE);
791 }
792 
793 #define	EFX_MAX_PACE_VALUE 20
794 
795 static	__checkReturn	efx_rc_t
siena_tx_qpace(__in efx_txq_t * etp,__in unsigned int ns)796 siena_tx_qpace(
797 	__in		efx_txq_t *etp,
798 	__in		unsigned int ns)
799 {
800 	efx_nic_t *enp = etp->et_enp;
801 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
802 	efx_oword_t oword;
803 	unsigned int pace_val;
804 	unsigned int timer_period;
805 	efx_rc_t rc;
806 
807 	if (ns == 0) {
808 		pace_val = 0;
809 	} else {
810 		/*
811 		 * The pace_val to write into the table is s.t
812 		 * ns <= timer_period * (2 ^ pace_val)
813 		 */
814 		timer_period = 104 / encp->enc_clk_mult;
815 		for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
816 			if ((timer_period << pace_val) >= ns)
817 				break;
818 		}
819 	}
820 	if (pace_val > EFX_MAX_PACE_VALUE) {
821 		rc = EINVAL;
822 		goto fail1;
823 	}
824 
825 	/* Update the pacing table */
826 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
827 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
828 	    &oword, B_TRUE);
829 
830 	return (0);
831 
832 fail1:
833 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
834 
835 	return (rc);
836 }
837 
838 static	__checkReturn	efx_rc_t
siena_tx_qflush(__in efx_txq_t * etp)839 siena_tx_qflush(
840 	__in		efx_txq_t *etp)
841 {
842 	efx_nic_t *enp = etp->et_enp;
843 	efx_oword_t oword;
844 	uint32_t label;
845 
846 	(void) efx_tx_qpace(etp, 0);
847 
848 	label = etp->et_index;
849 
850 	/* Flush the queue */
851 	EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
852 	    FRF_AZ_TX_FLUSH_DESCQ, label);
853 	EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
854 
855 	return (0);
856 }
857 
858 static		void
siena_tx_qenable(__in efx_txq_t * etp)859 siena_tx_qenable(
860 	__in	efx_txq_t *etp)
861 {
862 	efx_nic_t *enp = etp->et_enp;
863 	efx_oword_t oword;
864 
865 	EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
866 			    etp->et_index, &oword, B_TRUE);
867 
868 	EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
869 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
870 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
871 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
872 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
873 
874 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
875 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
876 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
877 
878 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
879 			    etp->et_index, &oword, B_TRUE);
880 }
881 
882 static	__checkReturn	efx_rc_t
siena_tx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efsys_mem_t * esmp,__in size_t n,__in uint32_t id,__in uint16_t flags,__in efx_evq_t * eep,__in efx_txq_t * etp,__out unsigned int * addedp)883 siena_tx_qcreate(
884 	__in		efx_nic_t *enp,
885 	__in		unsigned int index,
886 	__in		unsigned int label,
887 	__in		efsys_mem_t *esmp,
888 	__in		size_t n,
889 	__in		uint32_t id,
890 	__in		uint16_t flags,
891 	__in		efx_evq_t *eep,
892 	__in		efx_txq_t *etp,
893 	__out		unsigned int *addedp)
894 {
895 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
896 	efx_oword_t oword;
897 	uint32_t size;
898 	efx_rc_t rc;
899 
900 	_NOTE(ARGUNUSED(esmp));
901 
902 	EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
903 	    (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
904 	EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
905 
906 	EFSYS_ASSERT(ISP2(EFX_TXQ_MAXNDESCS(encp)));
907 	EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
908 
909 	if (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {
910 		rc = EINVAL;
911 		goto fail1;
912 	}
913 	if (index >= encp->enc_txq_limit) {
914 		rc = EINVAL;
915 		goto fail2;
916 	}
917 	for (size = 0;
918 	    (1 << size) <= (EFX_TXQ_MAXNDESCS(encp) / EFX_TXQ_MINNDESCS);
919 	    size++)
920 		if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))
921 			break;
922 	if (id + (1 << size) >= encp->enc_buftbl_limit) {
923 		rc = EINVAL;
924 		goto fail3;
925 	}
926 
927 	/* Set up the new descriptor queue */
928 	*addedp = 0;
929 
930 	EFX_POPULATE_OWORD_6(oword,
931 	    FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
932 	    FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
933 	    FRF_AZ_TX_DESCQ_OWNER_ID, 0,
934 	    FRF_AZ_TX_DESCQ_LABEL, label,
935 	    FRF_AZ_TX_DESCQ_SIZE, size,
936 	    FRF_AZ_TX_DESCQ_TYPE, 0);
937 
938 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
939 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
940 	    (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
941 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
942 	    (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
943 
944 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
945 	    etp->et_index, &oword, B_TRUE);
946 
947 	return (0);
948 
949 fail3:
950 	EFSYS_PROBE(fail3);
951 fail2:
952 	EFSYS_PROBE(fail2);
953 fail1:
954 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
955 
956 	return (rc);
957 }
958 
959 	__checkReturn	efx_rc_t
siena_tx_qdesc_post(__in efx_txq_t * etp,__in_ecount (n)efx_desc_t * ed,__in unsigned int n,__in unsigned int completed,__inout unsigned int * addedp)960 siena_tx_qdesc_post(
961 	__in		efx_txq_t *etp,
962 	__in_ecount(n)	efx_desc_t *ed,
963 	__in		unsigned int n,
964 	__in		unsigned int completed,
965 	__inout		unsigned int *addedp)
966 {
967 	unsigned int added = *addedp;
968 	unsigned int i;
969 	efx_rc_t rc;
970 
971 	if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
972 		rc = ENOSPC;
973 		goto fail1;
974 	}
975 
976 	for (i = 0; i < n; i++) {
977 		efx_desc_t *edp = &ed[i];
978 		unsigned int id;
979 		size_t offset;
980 
981 		id = added++ & etp->et_mask;
982 		offset = id * sizeof (efx_desc_t);
983 
984 		EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
985 	}
986 
987 	EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
988 		    unsigned int, added, unsigned int, n);
989 
990 	EFX_TX_QSTAT_INCR(etp, TX_POST);
991 
992 	*addedp = added;
993 	return (0);
994 
995 fail1:
996 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
997 	return (rc);
998 }
999 
1000 	void
siena_tx_qdesc_dma_create(__in efx_txq_t * etp,__in efsys_dma_addr_t addr,__in size_t size,__in boolean_t eop,__out efx_desc_t * edp)1001 siena_tx_qdesc_dma_create(
1002 	__in	efx_txq_t *etp,
1003 	__in	efsys_dma_addr_t addr,
1004 	__in	size_t size,
1005 	__in	boolean_t eop,
1006 	__out	efx_desc_t *edp)
1007 {
1008 	/* Fragments must not span 4k boundaries. */
1009 	EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
1010 
1011 	EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
1012 		    efsys_dma_addr_t, addr,
1013 		    size_t, size, boolean_t, eop);
1014 
1015 	EFX_POPULATE_QWORD_4(edp->ed_eq,
1016 			    FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
1017 			    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
1018 			    FSF_AZ_TX_KER_BUF_ADDR_DW0,
1019 			    (uint32_t)(addr & 0xffffffff),
1020 			    FSF_AZ_TX_KER_BUF_ADDR_DW1,
1021 			    (uint32_t)(addr >> 32));
1022 }
1023 
1024 #endif /* EFSYS_OPT_SIENA */
1025 
1026 #if EFSYS_OPT_QSTATS
1027 #if EFSYS_OPT_NAMES
1028 /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 9d8d26a0a5e2c453 */
1029 static const char 	*__efx_tx_qstat_name[] = {
1030 	"post",
1031 	"post_pio",
1032 };
1033 /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
1034 
1035 		const char *
efx_tx_qstat_name(__in efx_nic_t * enp,__in unsigned int id)1036 efx_tx_qstat_name(
1037 	__in	efx_nic_t *enp,
1038 	__in	unsigned int id)
1039 {
1040 	_NOTE(ARGUNUSED(enp))
1041 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1042 	EFSYS_ASSERT3U(id, <, TX_NQSTATS);
1043 
1044 	return (__efx_tx_qstat_name[id]);
1045 }
1046 #endif	/* EFSYS_OPT_NAMES */
1047 #endif /* EFSYS_OPT_QSTATS */
1048 
1049 #if EFSYS_OPT_SIENA
1050 
1051 #if EFSYS_OPT_QSTATS
1052 static					void
siena_tx_qstats_update(__in efx_txq_t * etp,__inout_ecount (TX_NQSTATS)efsys_stat_t * stat)1053 siena_tx_qstats_update(
1054 	__in				efx_txq_t *etp,
1055 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
1056 {
1057 	unsigned int id;
1058 
1059 	for (id = 0; id < TX_NQSTATS; id++) {
1060 		efsys_stat_t *essp = &stat[id];
1061 
1062 		EFSYS_STAT_INCR(essp, etp->et_stat[id]);
1063 		etp->et_stat[id] = 0;
1064 	}
1065 }
1066 #endif	/* EFSYS_OPT_QSTATS */
1067 
1068 static		void
siena_tx_qdestroy(__in efx_txq_t * etp)1069 siena_tx_qdestroy(
1070 	__in	efx_txq_t *etp)
1071 {
1072 	efx_nic_t *enp = etp->et_enp;
1073 	efx_oword_t oword;
1074 
1075 	/* Purge descriptor queue */
1076 	EFX_ZERO_OWORD(oword);
1077 
1078 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
1079 			    etp->et_index, &oword, B_TRUE);
1080 }
1081 
1082 static		void
siena_tx_fini(__in efx_nic_t * enp)1083 siena_tx_fini(
1084 	__in	efx_nic_t *enp)
1085 {
1086 	_NOTE(ARGUNUSED(enp))
1087 }
1088 
1089 #endif /* EFSYS_OPT_SIENA */
1090