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 */
130 static const efx_tx_ops_t __efx_tx_siena_ops = {
131 siena_tx_init, /* etxo_init */
132 siena_tx_fini, /* etxo_fini */
133 siena_tx_qcreate, /* etxo_qcreate */
134 siena_tx_qdestroy, /* etxo_qdestroy */
135 siena_tx_qpost, /* etxo_qpost */
136 siena_tx_qpush, /* etxo_qpush */
137 siena_tx_qpace, /* etxo_qpace */
138 siena_tx_qflush, /* etxo_qflush */
139 siena_tx_qenable, /* etxo_qenable */
140 NULL, /* etxo_qpio_enable */
141 NULL, /* etxo_qpio_disable */
142 NULL, /* etxo_qpio_write */
143 NULL, /* etxo_qpio_post */
144 siena_tx_qdesc_post, /* etxo_qdesc_post */
145 siena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
146 NULL, /* etxo_qdesc_tso_create */
147 NULL, /* etxo_qdesc_tso2_create */
148 NULL, /* etxo_qdesc_vlantci_create */
149 NULL, /* etxo_qdesc_checksum_create */
151 siena_tx_qstats_update, /* etxo_qstats_update */
154 #endif /* EFSYS_OPT_SIENA */
156 #if EFSYS_OPT_HUNTINGTON
157 static const efx_tx_ops_t __efx_tx_hunt_ops = {
158 ef10_tx_init, /* etxo_init */
159 ef10_tx_fini, /* etxo_fini */
160 ef10_tx_qcreate, /* etxo_qcreate */
161 ef10_tx_qdestroy, /* etxo_qdestroy */
162 ef10_tx_qpost, /* etxo_qpost */
163 ef10_tx_qpush, /* etxo_qpush */
164 ef10_tx_qpace, /* etxo_qpace */
165 ef10_tx_qflush, /* etxo_qflush */
166 ef10_tx_qenable, /* etxo_qenable */
167 ef10_tx_qpio_enable, /* etxo_qpio_enable */
168 ef10_tx_qpio_disable, /* etxo_qpio_disable */
169 ef10_tx_qpio_write, /* etxo_qpio_write */
170 ef10_tx_qpio_post, /* etxo_qpio_post */
171 ef10_tx_qdesc_post, /* etxo_qdesc_post */
172 ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
173 ef10_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
174 ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
175 ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
176 ef10_tx_qdesc_checksum_create, /* etxo_qdesc_checksum_create */
178 ef10_tx_qstats_update, /* etxo_qstats_update */
181 #endif /* EFSYS_OPT_HUNTINGTON */
183 #if EFSYS_OPT_MEDFORD
184 static const efx_tx_ops_t __efx_tx_medford_ops = {
185 ef10_tx_init, /* etxo_init */
186 ef10_tx_fini, /* etxo_fini */
187 ef10_tx_qcreate, /* etxo_qcreate */
188 ef10_tx_qdestroy, /* etxo_qdestroy */
189 ef10_tx_qpost, /* etxo_qpost */
190 ef10_tx_qpush, /* etxo_qpush */
191 ef10_tx_qpace, /* etxo_qpace */
192 ef10_tx_qflush, /* etxo_qflush */
193 ef10_tx_qenable, /* etxo_qenable */
194 ef10_tx_qpio_enable, /* etxo_qpio_enable */
195 ef10_tx_qpio_disable, /* etxo_qpio_disable */
196 ef10_tx_qpio_write, /* etxo_qpio_write */
197 ef10_tx_qpio_post, /* etxo_qpio_post */
198 ef10_tx_qdesc_post, /* etxo_qdesc_post */
199 ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
200 NULL, /* etxo_qdesc_tso_create */
201 ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
202 ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
203 ef10_tx_qdesc_checksum_create, /* etxo_qdesc_checksum_create */
205 ef10_tx_qstats_update, /* etxo_qstats_update */
208 #endif /* EFSYS_OPT_MEDFORD */
210 #if EFSYS_OPT_MEDFORD2
211 static const efx_tx_ops_t __efx_tx_medford2_ops = {
212 ef10_tx_init, /* etxo_init */
213 ef10_tx_fini, /* etxo_fini */
214 ef10_tx_qcreate, /* etxo_qcreate */
215 ef10_tx_qdestroy, /* etxo_qdestroy */
216 ef10_tx_qpost, /* etxo_qpost */
217 ef10_tx_qpush, /* etxo_qpush */
218 ef10_tx_qpace, /* etxo_qpace */
219 ef10_tx_qflush, /* etxo_qflush */
220 ef10_tx_qenable, /* etxo_qenable */
221 ef10_tx_qpio_enable, /* etxo_qpio_enable */
222 ef10_tx_qpio_disable, /* etxo_qpio_disable */
223 ef10_tx_qpio_write, /* etxo_qpio_write */
224 ef10_tx_qpio_post, /* etxo_qpio_post */
225 ef10_tx_qdesc_post, /* etxo_qdesc_post */
226 ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
227 NULL, /* etxo_qdesc_tso_create */
228 ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
229 ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
230 ef10_tx_qdesc_checksum_create, /* etxo_qdesc_checksum_create */
232 ef10_tx_qstats_update, /* etxo_qstats_update */
235 #endif /* EFSYS_OPT_MEDFORD2 */
238 __checkReturn efx_rc_t
242 const efx_tx_ops_t *etxop;
245 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
246 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
248 if (!(enp->en_mod_flags & EFX_MOD_EV)) {
253 if (enp->en_mod_flags & EFX_MOD_TX) {
258 switch (enp->en_family) {
260 case EFX_FAMILY_SIENA:
261 etxop = &__efx_tx_siena_ops;
263 #endif /* EFSYS_OPT_SIENA */
265 #if EFSYS_OPT_HUNTINGTON
266 case EFX_FAMILY_HUNTINGTON:
267 etxop = &__efx_tx_hunt_ops;
269 #endif /* EFSYS_OPT_HUNTINGTON */
271 #if EFSYS_OPT_MEDFORD
272 case EFX_FAMILY_MEDFORD:
273 etxop = &__efx_tx_medford_ops;
275 #endif /* EFSYS_OPT_MEDFORD */
277 #if EFSYS_OPT_MEDFORD2
278 case EFX_FAMILY_MEDFORD2:
279 etxop = &__efx_tx_medford2_ops;
281 #endif /* EFSYS_OPT_MEDFORD2 */
289 EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
291 if ((rc = etxop->etxo_init(enp)) != 0)
294 enp->en_etxop = etxop;
295 enp->en_mod_flags |= EFX_MOD_TX;
305 EFSYS_PROBE1(fail1, efx_rc_t, rc);
307 enp->en_etxop = NULL;
308 enp->en_mod_flags &= ~EFX_MOD_TX;
316 const efx_tx_ops_t *etxop = enp->en_etxop;
318 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
319 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
320 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
321 EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
323 etxop->etxo_fini(enp);
325 enp->en_etxop = NULL;
326 enp->en_mod_flags &= ~EFX_MOD_TX;
329 __checkReturn efx_rc_t
332 __in unsigned int index,
333 __in unsigned int label,
334 __in efsys_mem_t *esmp,
339 __deref_out efx_txq_t **etpp,
340 __out unsigned int *addedp)
342 const efx_tx_ops_t *etxop = enp->en_etxop;
346 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
347 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
349 EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <,
350 enp->en_nic_cfg.enc_txq_limit);
352 /* Allocate an TXQ object */
353 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
360 etp->et_magic = EFX_TXQ_MAGIC;
362 etp->et_index = index;
363 etp->et_mask = ndescs - 1;
366 /* Initial descriptor index may be modified by etxo_qcreate */
369 if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
370 ndescs, id, flags, eep, etp, addedp)) != 0)
380 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
382 EFSYS_PROBE1(fail1, efx_rc_t, rc);
390 efx_nic_t *enp = etp->et_enp;
391 const efx_tx_ops_t *etxop = enp->en_etxop;
393 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
395 EFSYS_ASSERT(enp->en_tx_qcount != 0);
398 etxop->etxo_qdestroy(etp);
400 /* Free the TXQ object */
401 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
404 __checkReturn efx_rc_t
407 __in_ecount(ndescs) efx_buffer_t *eb,
408 __in unsigned int ndescs,
409 __in unsigned int completed,
410 __inout unsigned int *addedp)
412 efx_nic_t *enp = etp->et_enp;
413 const efx_tx_ops_t *etxop = enp->en_etxop;
416 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
418 if ((rc = etxop->etxo_qpost(etp, eb, ndescs, completed, addedp)) != 0)
424 EFSYS_PROBE1(fail1, efx_rc_t, rc);
431 __in unsigned int added,
432 __in unsigned int pushed)
434 efx_nic_t *enp = etp->et_enp;
435 const efx_tx_ops_t *etxop = enp->en_etxop;
437 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
439 etxop->etxo_qpush(etp, added, pushed);
442 __checkReturn efx_rc_t
445 __in unsigned int ns)
447 efx_nic_t *enp = etp->et_enp;
448 const efx_tx_ops_t *etxop = enp->en_etxop;
451 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
453 if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
459 EFSYS_PROBE1(fail1, efx_rc_t, rc);
463 __checkReturn efx_rc_t
467 efx_nic_t *enp = etp->et_enp;
468 const efx_tx_ops_t *etxop = enp->en_etxop;
471 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
473 if ((rc = etxop->etxo_qflush(etp)) != 0)
479 EFSYS_PROBE1(fail1, efx_rc_t, rc);
487 efx_nic_t *enp = etp->et_enp;
488 const efx_tx_ops_t *etxop = enp->en_etxop;
490 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
492 etxop->etxo_qenable(etp);
495 __checkReturn efx_rc_t
499 efx_nic_t *enp = etp->et_enp;
500 const efx_tx_ops_t *etxop = enp->en_etxop;
503 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
505 if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
509 if (etxop->etxo_qpio_enable == NULL) {
513 if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
523 EFSYS_PROBE1(fail1, efx_rc_t, rc);
531 efx_nic_t *enp = etp->et_enp;
532 const efx_tx_ops_t *etxop = enp->en_etxop;
534 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
536 if (etxop->etxo_qpio_disable != NULL)
537 etxop->etxo_qpio_disable(etp);
540 __checkReturn efx_rc_t
543 __in_ecount(buf_length) uint8_t *buffer,
544 __in size_t buf_length,
545 __in size_t pio_buf_offset)
547 efx_nic_t *enp = etp->et_enp;
548 const efx_tx_ops_t *etxop = enp->en_etxop;
551 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
553 if (etxop->etxo_qpio_write != NULL) {
554 if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
555 pio_buf_offset)) != 0)
563 EFSYS_PROBE1(fail1, efx_rc_t, rc);
567 __checkReturn efx_rc_t
570 __in size_t pkt_length,
571 __in unsigned int completed,
572 __inout unsigned int *addedp)
574 efx_nic_t *enp = etp->et_enp;
575 const efx_tx_ops_t *etxop = enp->en_etxop;
578 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
580 if (etxop->etxo_qpio_post != NULL) {
581 if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
590 EFSYS_PROBE1(fail1, efx_rc_t, rc);
594 __checkReturn efx_rc_t
597 __in_ecount(ndescs) efx_desc_t *ed,
598 __in unsigned int ndescs,
599 __in unsigned int completed,
600 __inout unsigned int *addedp)
602 efx_nic_t *enp = etp->et_enp;
603 const efx_tx_ops_t *etxop = enp->en_etxop;
605 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
607 return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
611 efx_tx_qdesc_dma_create(
613 __in efsys_dma_addr_t addr,
616 __out efx_desc_t *edp)
618 efx_nic_t *enp = etp->et_enp;
619 const efx_tx_ops_t *etxop = enp->en_etxop;
621 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
622 EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
624 etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
628 efx_tx_qdesc_tso_create(
630 __in uint16_t ipv4_id,
631 __in uint32_t tcp_seq,
632 __in uint8_t tcp_flags,
633 __out efx_desc_t *edp)
635 efx_nic_t *enp = etp->et_enp;
636 const efx_tx_ops_t *etxop = enp->en_etxop;
638 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
639 EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
641 etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
645 efx_tx_qdesc_tso2_create(
647 __in uint16_t ipv4_id,
648 __in uint16_t outer_ipv4_id,
649 __in uint32_t tcp_seq,
651 __out_ecount(count) efx_desc_t *edp,
654 efx_nic_t *enp = etp->et_enp;
655 const efx_tx_ops_t *etxop = enp->en_etxop;
657 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
658 EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
660 etxop->etxo_qdesc_tso2_create(etp, ipv4_id, outer_ipv4_id,
661 tcp_seq, mss, edp, count);
665 efx_tx_qdesc_vlantci_create(
668 __out efx_desc_t *edp)
670 efx_nic_t *enp = etp->et_enp;
671 const efx_tx_ops_t *etxop = enp->en_etxop;
673 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
674 EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
676 etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
680 efx_tx_qdesc_checksum_create(
683 __out efx_desc_t *edp)
685 efx_nic_t *enp = etp->et_enp;
686 const efx_tx_ops_t *etxop = enp->en_etxop;
688 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
689 EFSYS_ASSERT(etxop->etxo_qdesc_checksum_create != NULL);
691 etxop->etxo_qdesc_checksum_create(etp, flags, edp);
697 efx_tx_qstats_update(
699 __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
701 efx_nic_t *enp = etp->et_enp;
702 const efx_tx_ops_t *etxop = enp->en_etxop;
704 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
706 etxop->etxo_qstats_update(etp, stat);
713 static __checkReturn efx_rc_t
720 * Disable the timer-based TX DMA backoff and allow TX DMA to be
721 * controlled by the RX FIFO fill level (although always allow a
724 EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
725 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
726 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
727 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
728 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
729 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
730 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
731 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
734 * Filter all packets less than 14 bytes to avoid parsing
737 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
738 EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
741 * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
742 * descriptors (which is bad).
744 EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
745 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
746 EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
751 #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \
757 id = (_added)++ & (_etp)->et_mask; \
758 offset = id * sizeof (efx_qword_t); \
760 EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index, \
761 unsigned int, id, efsys_dma_addr_t, (_addr), \
762 size_t, (_size), boolean_t, (_eop)); \
764 EFX_POPULATE_QWORD_4(qword, \
765 FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1, \
766 FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size), \
767 FSF_AZ_TX_KER_BUF_ADDR_DW0, \
768 (uint32_t)((_addr) & 0xffffffff), \
769 FSF_AZ_TX_KER_BUF_ADDR_DW1, \
770 (uint32_t)((_addr) >> 32)); \
771 EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword); \
773 _NOTE(CONSTANTCONDITION) \
776 static __checkReturn efx_rc_t
779 __in_ecount(ndescs) efx_buffer_t *eb,
780 __in unsigned int ndescs,
781 __in unsigned int completed,
782 __inout unsigned int *addedp)
784 unsigned int added = *addedp;
787 if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
790 for (i = 0; i < ndescs; i++) {
791 efx_buffer_t *ebp = &eb[i];
792 efsys_dma_addr_t start = ebp->eb_addr;
793 size_t size = ebp->eb_size;
794 efsys_dma_addr_t end = start + size;
797 * Fragments must not span 4k boundaries.
798 * Here it is a stricter requirement than the maximum length.
800 EFSYS_ASSERT(P2ROUNDUP(start + 1,
801 etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end);
803 EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
806 EFX_TX_QSTAT_INCR(etp, TX_POST);
815 __in unsigned int added,
816 __in unsigned int pushed)
818 efx_nic_t *enp = etp->et_enp;
823 /* Push the populated descriptors out */
824 wptr = added & etp->et_mask;
826 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
828 /* Only write the third DWORD */
829 EFX_POPULATE_DWORD_1(dword,
830 EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
832 /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
833 EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
834 wptr, pushed & etp->et_mask);
835 EFSYS_PIO_WRITE_BARRIER();
836 EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
837 etp->et_index, &dword, B_FALSE);
840 #define EFX_MAX_PACE_VALUE 20
841 #define EFX_TX_PACE_CLOCK_BASE 104
843 static __checkReturn efx_rc_t
846 __in unsigned int ns)
848 efx_nic_t *enp = etp->et_enp;
849 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
851 unsigned int pace_val;
852 unsigned int timer_period;
859 * The pace_val to write into the table is s.t
860 * ns <= timer_period * (2 ^ pace_val)
862 timer_period = EFX_TX_PACE_CLOCK_BASE / encp->enc_clk_mult;
863 for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
864 if ((timer_period << pace_val) >= ns)
868 if (pace_val > EFX_MAX_PACE_VALUE) {
873 /* Update the pacing table */
874 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
875 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
881 EFSYS_PROBE1(fail1, efx_rc_t, rc);
886 static __checkReturn efx_rc_t
890 efx_nic_t *enp = etp->et_enp;
894 efx_tx_qpace(etp, 0);
896 label = etp->et_index;
898 /* Flush the queue */
899 EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
900 FRF_AZ_TX_FLUSH_DESCQ, label);
901 EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
910 efx_nic_t *enp = etp->et_enp;
913 EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
914 etp->et_index, &oword, B_TRUE);
916 EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
917 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
918 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
919 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
920 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
922 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
923 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
924 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
926 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
927 etp->et_index, &oword, B_TRUE);
930 static __checkReturn efx_rc_t
933 __in unsigned int index,
934 __in unsigned int label,
935 __in efsys_mem_t *esmp,
941 __out unsigned int *addedp)
943 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
949 _NOTE(ARGUNUSED(esmp))
951 EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
952 (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
953 EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
955 EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
956 EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
959 (ndescs < EFX_TXQ_MINNDESCS) || (ndescs > EFX_EVQ_MAXNEVS)) {
963 if (index >= encp->enc_txq_limit) {
968 (1 << size) <= (int)(encp->enc_txq_max_ndescs / EFX_TXQ_MINNDESCS);
970 if ((1 << size) == (int)(ndescs / EFX_TXQ_MINNDESCS))
972 if (id + (1 << size) >= encp->enc_buftbl_limit) {
977 inner_csum = EFX_TXQ_CKSUM_INNER_IPV4 | EFX_TXQ_CKSUM_INNER_TCPUDP;
978 if ((flags & inner_csum) != 0) {
983 /* Set up the new descriptor queue */
986 EFX_POPULATE_OWORD_6(oword,
987 FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
988 FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
989 FRF_AZ_TX_DESCQ_OWNER_ID, 0,
990 FRF_AZ_TX_DESCQ_LABEL, label,
991 FRF_AZ_TX_DESCQ_SIZE, size,
992 FRF_AZ_TX_DESCQ_TYPE, 0);
994 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
995 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
996 (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
997 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
998 (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
1000 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
1001 etp->et_index, &oword, B_TRUE);
1012 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1017 __checkReturn efx_rc_t
1018 siena_tx_qdesc_post(
1019 __in efx_txq_t *etp,
1020 __in_ecount(ndescs) efx_desc_t *ed,
1021 __in unsigned int ndescs,
1022 __in unsigned int completed,
1023 __inout unsigned int *addedp)
1025 unsigned int added = *addedp;
1029 if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
1034 for (i = 0; i < ndescs; i++) {
1035 efx_desc_t *edp = &ed[i];
1039 id = added++ & etp->et_mask;
1040 offset = id * sizeof (efx_desc_t);
1042 EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
1045 EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
1046 unsigned int, added, unsigned int, ndescs);
1048 EFX_TX_QSTAT_INCR(etp, TX_POST);
1054 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1059 siena_tx_qdesc_dma_create(
1060 __in efx_txq_t *etp,
1061 __in efsys_dma_addr_t addr,
1064 __out efx_desc_t *edp)
1067 * Fragments must not span 4k boundaries.
1068 * Here it is a stricter requirement than the maximum length.
1070 EFSYS_ASSERT(P2ROUNDUP(addr + 1,
1071 etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size);
1073 EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
1074 efsys_dma_addr_t, addr,
1075 size_t, size, boolean_t, eop);
1077 EFX_POPULATE_QWORD_4(edp->ed_eq,
1078 FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
1079 FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
1080 FSF_AZ_TX_KER_BUF_ADDR_DW0,
1081 (uint32_t)(addr & 0xffffffff),
1082 FSF_AZ_TX_KER_BUF_ADDR_DW1,
1083 (uint32_t)(addr >> 32));
1086 #endif /* EFSYS_OPT_SIENA */
1088 #if EFSYS_OPT_QSTATS
1090 /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 2866874ecd7a363b */
1091 static const char * const __efx_tx_qstat_name[] = {
1095 /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
1099 __in efx_nic_t *enp,
1100 __in unsigned int id)
1102 _NOTE(ARGUNUSED(enp))
1103 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1104 EFSYS_ASSERT3U(id, <, TX_NQSTATS);
1106 return (__efx_tx_qstat_name[id]);
1108 #endif /* EFSYS_OPT_NAMES */
1109 #endif /* EFSYS_OPT_QSTATS */
1113 #if EFSYS_OPT_QSTATS
1115 siena_tx_qstats_update(
1116 __in efx_txq_t *etp,
1117 __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
1121 for (id = 0; id < TX_NQSTATS; id++) {
1122 efsys_stat_t *essp = &stat[id];
1124 EFSYS_STAT_INCR(essp, etp->et_stat[id]);
1125 etp->et_stat[id] = 0;
1128 #endif /* EFSYS_OPT_QSTATS */
1132 __in efx_txq_t *etp)
1134 efx_nic_t *enp = etp->et_enp;
1137 /* Purge descriptor queue */
1138 EFX_ZERO_OWORD(oword);
1140 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
1141 etp->et_index, &oword, B_TRUE);
1146 __in efx_nic_t *enp)
1148 _NOTE(ARGUNUSED(enp))
1151 #endif /* EFSYS_OPT_SIENA */