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