2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
40 #define EFX_TX_QSTAT_INCR(_etp, _stat) \
42 (_etp)->et_stat[_stat]++; \
43 _NOTE(CONSTANTCONDITION) \
46 #define EFX_TX_QSTAT_INCR(_etp, _stat)
51 static __checkReturn efx_rc_t
59 static __checkReturn efx_rc_t
62 __in unsigned int index,
63 __in unsigned int label,
64 __in efsys_mem_t *esmp,
70 __out unsigned int *addedp);
76 static __checkReturn efx_rc_t
79 __in_ecount(ndescs) efx_buffer_t *eb,
80 __in unsigned int ndescs,
81 __in unsigned int completed,
82 __inout unsigned int *addedp);
87 __in unsigned int added,
88 __in unsigned int pushed);
90 static __checkReturn efx_rc_t
93 __in unsigned int ns);
95 static __checkReturn efx_rc_t
101 __in efx_txq_t *etp);
103 __checkReturn efx_rc_t
106 __in_ecount(ndescs) efx_desc_t *ed,
107 __in unsigned int ndescs,
108 __in unsigned int completed,
109 __inout unsigned int *addedp);
112 siena_tx_qdesc_dma_create(
114 __in efsys_dma_addr_t addr,
117 __out efx_desc_t *edp);
121 siena_tx_qstats_update(
123 __inout_ecount(TX_NQSTATS) efsys_stat_t *stat);
126 #endif /* 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 */
150 siena_tx_qstats_update, /* etxo_qstats_update */
153 #endif /* EFSYS_OPT_SIENA */
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 */
177 ef10_tx_qstats_update, /* etxo_qstats_update */
180 #endif /* EFSYS_OPT_HUNTINGTON */
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 */
204 ef10_tx_qstats_update, /* etxo_qstats_update */
207 #endif /* EFSYS_OPT_MEDFORD */
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 */
231 ef10_tx_qstats_update, /* etxo_qstats_update */
234 #endif /* EFSYS_OPT_MEDFORD2 */
236 __checkReturn efx_rc_t
240 const efx_tx_ops_t *etxop;
243 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
244 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
246 if (!(enp->en_mod_flags & EFX_MOD_EV)) {
251 if (enp->en_mod_flags & EFX_MOD_TX) {
256 switch (enp->en_family) {
258 case EFX_FAMILY_SIENA:
259 etxop = &__efx_tx_siena_ops;
261 #endif /* EFSYS_OPT_SIENA */
263 #if EFSYS_OPT_HUNTINGTON
264 case EFX_FAMILY_HUNTINGTON:
265 etxop = &__efx_tx_hunt_ops;
267 #endif /* EFSYS_OPT_HUNTINGTON */
269 #if EFSYS_OPT_MEDFORD
270 case EFX_FAMILY_MEDFORD:
271 etxop = &__efx_tx_medford_ops;
273 #endif /* EFSYS_OPT_MEDFORD */
275 #if EFSYS_OPT_MEDFORD2
276 case EFX_FAMILY_MEDFORD2:
277 etxop = &__efx_tx_medford2_ops;
279 #endif /* EFSYS_OPT_MEDFORD2 */
287 EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
289 if ((rc = etxop->etxo_init(enp)) != 0)
292 enp->en_etxop = etxop;
293 enp->en_mod_flags |= EFX_MOD_TX;
303 EFSYS_PROBE1(fail1, efx_rc_t, rc);
305 enp->en_etxop = NULL;
306 enp->en_mod_flags &= ~EFX_MOD_TX;
314 const efx_tx_ops_t *etxop = enp->en_etxop;
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);
321 etxop->etxo_fini(enp);
323 enp->en_etxop = NULL;
324 enp->en_mod_flags &= ~EFX_MOD_TX;
327 __checkReturn efx_rc_t
330 __in unsigned int index,
331 __in unsigned int label,
332 __in efsys_mem_t *esmp,
337 __deref_out efx_txq_t **etpp,
338 __out unsigned int *addedp)
340 const efx_tx_ops_t *etxop = enp->en_etxop;
344 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
345 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
347 EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <,
348 enp->en_nic_cfg.enc_txq_limit);
350 /* Allocate an TXQ object */
351 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
358 etp->et_magic = EFX_TXQ_MAGIC;
360 etp->et_index = index;
361 etp->et_mask = ndescs - 1;
364 /* Initial descriptor index may be modified by etxo_qcreate */
367 if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
368 ndescs, id, flags, eep, etp, addedp)) != 0)
378 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
380 EFSYS_PROBE1(fail1, efx_rc_t, rc);
388 efx_nic_t *enp = etp->et_enp;
389 const efx_tx_ops_t *etxop = enp->en_etxop;
391 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
393 EFSYS_ASSERT(enp->en_tx_qcount != 0);
396 etxop->etxo_qdestroy(etp);
398 /* Free the TXQ object */
399 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
402 __checkReturn efx_rc_t
405 __in_ecount(ndescs) efx_buffer_t *eb,
406 __in unsigned int ndescs,
407 __in unsigned int completed,
408 __inout unsigned int *addedp)
410 efx_nic_t *enp = etp->et_enp;
411 const efx_tx_ops_t *etxop = enp->en_etxop;
414 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
416 if ((rc = etxop->etxo_qpost(etp, eb, ndescs, completed, addedp)) != 0)
422 EFSYS_PROBE1(fail1, efx_rc_t, rc);
429 __in unsigned int added,
430 __in unsigned int pushed)
432 efx_nic_t *enp = etp->et_enp;
433 const efx_tx_ops_t *etxop = enp->en_etxop;
435 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
437 etxop->etxo_qpush(etp, added, pushed);
440 __checkReturn efx_rc_t
443 __in unsigned int ns)
445 efx_nic_t *enp = etp->et_enp;
446 const efx_tx_ops_t *etxop = enp->en_etxop;
449 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
451 if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
457 EFSYS_PROBE1(fail1, efx_rc_t, rc);
461 __checkReturn efx_rc_t
465 efx_nic_t *enp = etp->et_enp;
466 const efx_tx_ops_t *etxop = enp->en_etxop;
469 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
471 if ((rc = etxop->etxo_qflush(etp)) != 0)
477 EFSYS_PROBE1(fail1, efx_rc_t, rc);
485 efx_nic_t *enp = etp->et_enp;
486 const efx_tx_ops_t *etxop = enp->en_etxop;
488 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
490 etxop->etxo_qenable(etp);
493 __checkReturn efx_rc_t
497 efx_nic_t *enp = etp->et_enp;
498 const efx_tx_ops_t *etxop = enp->en_etxop;
501 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
503 if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
507 if (etxop->etxo_qpio_enable == NULL) {
511 if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
521 EFSYS_PROBE1(fail1, efx_rc_t, rc);
529 efx_nic_t *enp = etp->et_enp;
530 const efx_tx_ops_t *etxop = enp->en_etxop;
532 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
534 if (etxop->etxo_qpio_disable != NULL)
535 etxop->etxo_qpio_disable(etp);
538 __checkReturn efx_rc_t
541 __in_ecount(buf_length) uint8_t *buffer,
542 __in size_t buf_length,
543 __in size_t pio_buf_offset)
545 efx_nic_t *enp = etp->et_enp;
546 const efx_tx_ops_t *etxop = enp->en_etxop;
549 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
551 if (etxop->etxo_qpio_write != NULL) {
552 if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
553 pio_buf_offset)) != 0)
561 EFSYS_PROBE1(fail1, efx_rc_t, rc);
565 __checkReturn efx_rc_t
568 __in size_t pkt_length,
569 __in unsigned int completed,
570 __inout unsigned int *addedp)
572 efx_nic_t *enp = etp->et_enp;
573 const efx_tx_ops_t *etxop = enp->en_etxop;
576 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
578 if (etxop->etxo_qpio_post != NULL) {
579 if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
588 EFSYS_PROBE1(fail1, efx_rc_t, rc);
592 __checkReturn efx_rc_t
595 __in_ecount(ndescs) efx_desc_t *ed,
596 __in unsigned int ndescs,
597 __in unsigned int completed,
598 __inout unsigned int *addedp)
600 efx_nic_t *enp = etp->et_enp;
601 const efx_tx_ops_t *etxop = enp->en_etxop;
603 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
605 return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
609 efx_tx_qdesc_dma_create(
611 __in efsys_dma_addr_t addr,
614 __out efx_desc_t *edp)
616 efx_nic_t *enp = etp->et_enp;
617 const efx_tx_ops_t *etxop = enp->en_etxop;
619 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
620 EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
622 etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
626 efx_tx_qdesc_tso_create(
628 __in uint16_t ipv4_id,
629 __in uint32_t tcp_seq,
630 __in uint8_t tcp_flags,
631 __out efx_desc_t *edp)
633 efx_nic_t *enp = etp->et_enp;
634 const efx_tx_ops_t *etxop = enp->en_etxop;
636 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
637 EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
639 etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
643 efx_tx_qdesc_tso2_create(
645 __in uint16_t ipv4_id,
646 __in uint16_t outer_ipv4_id,
647 __in uint32_t tcp_seq,
649 __out_ecount(count) efx_desc_t *edp,
652 efx_nic_t *enp = etp->et_enp;
653 const efx_tx_ops_t *etxop = enp->en_etxop;
655 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
656 EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
658 etxop->etxo_qdesc_tso2_create(etp, ipv4_id, outer_ipv4_id,
659 tcp_seq, mss, edp, count);
663 efx_tx_qdesc_vlantci_create(
666 __out efx_desc_t *edp)
668 efx_nic_t *enp = etp->et_enp;
669 const efx_tx_ops_t *etxop = enp->en_etxop;
671 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
672 EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
674 etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
678 efx_tx_qdesc_checksum_create(
681 __out efx_desc_t *edp)
683 efx_nic_t *enp = etp->et_enp;
684 const efx_tx_ops_t *etxop = enp->en_etxop;
686 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
687 EFSYS_ASSERT(etxop->etxo_qdesc_checksum_create != NULL);
689 etxop->etxo_qdesc_checksum_create(etp, flags, edp);
694 efx_tx_qstats_update(
696 __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
698 efx_nic_t *enp = etp->et_enp;
699 const efx_tx_ops_t *etxop = enp->en_etxop;
701 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
703 etxop->etxo_qstats_update(etp, stat);
709 static __checkReturn efx_rc_t
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
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);
730 * Filter all packets less than 14 bytes to avoid parsing
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);
737 * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
738 * descriptors (which is bad).
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);
747 #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \
753 id = (_added)++ & (_etp)->et_mask; \
754 offset = id * sizeof (efx_qword_t); \
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)); \
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); \
769 _NOTE(CONSTANTCONDITION) \
772 static __checkReturn efx_rc_t
775 __in_ecount(ndescs) efx_buffer_t *eb,
776 __in unsigned int ndescs,
777 __in unsigned int completed,
778 __inout unsigned int *addedp)
780 unsigned int added = *addedp;
783 if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
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;
793 * Fragments must not span 4k boundaries.
794 * Here it is a stricter requirement than the maximum length.
796 EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, start + 1,
797 etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end);
799 EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
802 EFX_TX_QSTAT_INCR(etp, TX_POST);
811 __in unsigned int added,
812 __in unsigned int pushed)
814 efx_nic_t *enp = etp->et_enp;
819 /* Push the populated descriptors out */
820 wptr = added & etp->et_mask;
822 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
824 /* Only write the third DWORD */
825 EFX_POPULATE_DWORD_1(dword,
826 EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
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);
836 #define EFX_MAX_PACE_VALUE 20
837 #define EFX_TX_PACE_CLOCK_BASE 104
839 static __checkReturn efx_rc_t
842 __in unsigned int ns)
844 efx_nic_t *enp = etp->et_enp;
845 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
847 unsigned int pace_val;
848 unsigned int timer_period;
855 * The pace_val to write into the table is s.t
856 * ns <= timer_period * (2 ^ pace_val)
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)
864 if (pace_val > EFX_MAX_PACE_VALUE) {
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,
877 EFSYS_PROBE1(fail1, efx_rc_t, rc);
882 static __checkReturn efx_rc_t
886 efx_nic_t *enp = etp->et_enp;
890 efx_tx_qpace(etp, 0);
892 label = etp->et_index;
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);
906 efx_nic_t *enp = etp->et_enp;
909 EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
910 etp->et_index, &oword, B_TRUE);
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));
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);
922 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
923 etp->et_index, &oword, B_TRUE);
926 static __checkReturn efx_rc_t
929 __in unsigned int index,
930 __in unsigned int label,
931 __in efsys_mem_t *esmp,
937 __out unsigned int *addedp)
939 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
945 _NOTE(ARGUNUSED(esmp))
947 EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
948 (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
949 EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
951 EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
952 EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
955 (ndescs < EFX_TXQ_MINNDESCS) || (ndescs > EFX_EVQ_MAXNEVS)) {
959 if (index >= encp->enc_txq_limit) {
964 (1 << size) <= (int)(encp->enc_txq_max_ndescs / EFX_TXQ_MINNDESCS);
966 if ((1 << size) == (int)(ndescs / EFX_TXQ_MINNDESCS))
968 if (id + (1 << size) >= encp->enc_buftbl_limit) {
973 inner_csum = EFX_TXQ_CKSUM_INNER_IPV4 | EFX_TXQ_CKSUM_INNER_TCPUDP;
974 if ((flags & inner_csum) != 0) {
979 /* Set up the new descriptor queue */
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);
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);
996 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
997 etp->et_index, &oword, B_TRUE);
1008 EFSYS_PROBE1(fail1, efx_rc_t, rc);
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)
1021 unsigned int added = *addedp;
1025 if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
1030 for (i = 0; i < ndescs; i++) {
1031 efx_desc_t *edp = &ed[i];
1035 id = added++ & etp->et_mask;
1036 offset = id * sizeof (efx_desc_t);
1038 EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
1041 EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
1042 unsigned int, added, unsigned int, ndescs);
1044 EFX_TX_QSTAT_INCR(etp, TX_POST);
1050 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1055 siena_tx_qdesc_dma_create(
1056 __in efx_txq_t *etp,
1057 __in efsys_dma_addr_t addr,
1060 __out efx_desc_t *edp)
1063 * Fragments must not span 4k boundaries.
1064 * Here it is a stricter requirement than the maximum length.
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);
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);
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));
1082 #endif /* EFSYS_OPT_SIENA */
1084 #if EFSYS_OPT_QSTATS
1086 /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 2866874ecd7a363b */
1087 static const char * const __efx_tx_qstat_name[] = {
1091 /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
1095 __in efx_nic_t *enp,
1096 __in unsigned int id)
1098 _NOTE(ARGUNUSED(enp))
1099 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1100 EFSYS_ASSERT3U(id, <, TX_NQSTATS);
1102 return (__efx_tx_qstat_name[id]);
1104 #endif /* EFSYS_OPT_NAMES */
1105 #endif /* EFSYS_OPT_QSTATS */
1109 #if EFSYS_OPT_QSTATS
1111 siena_tx_qstats_update(
1112 __in efx_txq_t *etp,
1113 __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
1117 for (id = 0; id < TX_NQSTATS; id++) {
1118 efsys_stat_t *essp = &stat[id];
1120 EFSYS_STAT_INCR(essp, etp->et_stat[id]);
1121 etp->et_stat[id] = 0;
1124 #endif /* EFSYS_OPT_QSTATS */
1128 __in efx_txq_t *etp)
1130 efx_nic_t *enp = etp->et_enp;
1133 /* Purge descriptor queue */
1134 EFX_ZERO_OWORD(oword);
1136 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
1137 etp->et_index, &oword, B_TRUE);
1142 __in efx_nic_t *enp)
1144 _NOTE(ARGUNUSED(enp))
1147 #endif /* EFSYS_OPT_SIENA */