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