2 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
34 #define EFX_TX_QSTAT_INCR(_etp, _stat)
38 static __checkReturn efx_rc_t
46 static __checkReturn efx_rc_t
49 __in unsigned int index,
50 __in unsigned int label,
51 __in efsys_mem_t *esmp,
57 __out unsigned int *addedp);
63 static __checkReturn efx_rc_t
66 __in_ecount(n) efx_buffer_t *eb,
68 __in unsigned int completed,
69 __inout unsigned int *addedp);
74 __in unsigned int added,
75 __in unsigned int pushed);
77 static __checkReturn efx_rc_t
80 __in unsigned int ns);
82 static __checkReturn efx_rc_t
90 __checkReturn efx_rc_t
93 __in_ecount(n) efx_desc_t *ed,
95 __in unsigned int completed,
96 __inout unsigned int *addedp);
99 siena_tx_qdesc_dma_create(
101 __in efsys_dma_addr_t addr,
104 __out efx_desc_t *edp);
106 #endif /* EFSYS_OPT_SIENA */
110 static const efx_tx_ops_t __efx_tx_siena_ops = {
111 siena_tx_init, /* etxo_init */
112 siena_tx_fini, /* etxo_fini */
113 siena_tx_qcreate, /* etxo_qcreate */
114 siena_tx_qdestroy, /* etxo_qdestroy */
115 siena_tx_qpost, /* etxo_qpost */
116 siena_tx_qpush, /* etxo_qpush */
117 siena_tx_qpace, /* etxo_qpace */
118 siena_tx_qflush, /* etxo_qflush */
119 siena_tx_qenable, /* etxo_qenable */
120 NULL, /* etxo_qpio_enable */
121 NULL, /* etxo_qpio_disable */
122 NULL, /* etxo_qpio_write */
123 NULL, /* etxo_qpio_post */
124 siena_tx_qdesc_post, /* etxo_qdesc_post */
125 siena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
126 NULL, /* etxo_qdesc_tso_create */
127 NULL, /* etxo_qdesc_tso2_create */
128 NULL, /* etxo_qdesc_vlantci_create */
130 #endif /* EFSYS_OPT_SIENA */
132 #if EFSYS_OPT_HUNTINGTON
133 static const efx_tx_ops_t __efx_tx_hunt_ops = {
134 ef10_tx_init, /* etxo_init */
135 ef10_tx_fini, /* etxo_fini */
136 ef10_tx_qcreate, /* etxo_qcreate */
137 ef10_tx_qdestroy, /* etxo_qdestroy */
138 ef10_tx_qpost, /* etxo_qpost */
139 ef10_tx_qpush, /* etxo_qpush */
140 ef10_tx_qpace, /* etxo_qpace */
141 ef10_tx_qflush, /* etxo_qflush */
142 ef10_tx_qenable, /* etxo_qenable */
143 ef10_tx_qpio_enable, /* etxo_qpio_enable */
144 ef10_tx_qpio_disable, /* etxo_qpio_disable */
145 ef10_tx_qpio_write, /* etxo_qpio_write */
146 ef10_tx_qpio_post, /* etxo_qpio_post */
147 ef10_tx_qdesc_post, /* etxo_qdesc_post */
148 ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
149 ef10_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
150 ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
151 ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
153 #endif /* EFSYS_OPT_HUNTINGTON */
155 __checkReturn efx_rc_t
159 const efx_tx_ops_t *etxop;
162 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
163 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
165 if (!(enp->en_mod_flags & EFX_MOD_EV)) {
170 if (enp->en_mod_flags & EFX_MOD_TX) {
175 switch (enp->en_family) {
177 case EFX_FAMILY_SIENA:
178 etxop = &__efx_tx_siena_ops;
180 #endif /* EFSYS_OPT_SIENA */
182 #if EFSYS_OPT_HUNTINGTON
183 case EFX_FAMILY_HUNTINGTON:
184 etxop = &__efx_tx_hunt_ops;
186 #endif /* EFSYS_OPT_HUNTINGTON */
194 EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
196 if ((rc = etxop->etxo_init(enp)) != 0)
199 enp->en_etxop = etxop;
200 enp->en_mod_flags |= EFX_MOD_TX;
210 EFSYS_PROBE1(fail1, efx_rc_t, rc);
212 enp->en_etxop = NULL;
213 enp->en_mod_flags &= ~EFX_MOD_TX;
221 const efx_tx_ops_t *etxop = enp->en_etxop;
223 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
224 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
225 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
226 EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
228 etxop->etxo_fini(enp);
230 enp->en_etxop = NULL;
231 enp->en_mod_flags &= ~EFX_MOD_TX;
234 __checkReturn efx_rc_t
237 __in unsigned int index,
238 __in unsigned int label,
239 __in efsys_mem_t *esmp,
244 __deref_out efx_txq_t **etpp,
245 __out unsigned int *addedp)
247 const efx_tx_ops_t *etxop = enp->en_etxop;
248 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
252 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
253 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
255 EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
257 /* Allocate an TXQ object */
258 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
265 etp->et_magic = EFX_TXQ_MAGIC;
267 etp->et_index = index;
268 etp->et_mask = n - 1;
271 /* Initial descriptor index may be modified by etxo_qcreate */
274 if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
275 n, id, flags, eep, etp, addedp)) != 0)
285 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
287 EFSYS_PROBE1(fail1, efx_rc_t, rc);
295 efx_nic_t *enp = etp->et_enp;
296 const efx_tx_ops_t *etxop = enp->en_etxop;
298 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
300 EFSYS_ASSERT(enp->en_tx_qcount != 0);
303 etxop->etxo_qdestroy(etp);
305 /* Free the TXQ object */
306 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
309 __checkReturn efx_rc_t
312 __in_ecount(n) efx_buffer_t *eb,
314 __in unsigned int completed,
315 __inout unsigned int *addedp)
317 efx_nic_t *enp = etp->et_enp;
318 const efx_tx_ops_t *etxop = enp->en_etxop;
321 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
323 if ((rc = etxop->etxo_qpost(etp, eb,
324 n, completed, addedp)) != 0)
330 EFSYS_PROBE1(fail1, efx_rc_t, rc);
337 __in unsigned int added,
338 __in unsigned int pushed)
340 efx_nic_t *enp = etp->et_enp;
341 const efx_tx_ops_t *etxop = enp->en_etxop;
343 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
345 etxop->etxo_qpush(etp, added, pushed);
348 __checkReturn efx_rc_t
351 __in unsigned int ns)
353 efx_nic_t *enp = etp->et_enp;
354 const efx_tx_ops_t *etxop = enp->en_etxop;
357 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
359 if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
365 EFSYS_PROBE1(fail1, efx_rc_t, rc);
369 __checkReturn efx_rc_t
373 efx_nic_t *enp = etp->et_enp;
374 const efx_tx_ops_t *etxop = enp->en_etxop;
377 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
379 if ((rc = etxop->etxo_qflush(etp)) != 0)
385 EFSYS_PROBE1(fail1, efx_rc_t, rc);
393 efx_nic_t *enp = etp->et_enp;
394 const efx_tx_ops_t *etxop = enp->en_etxop;
396 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
398 etxop->etxo_qenable(etp);
401 __checkReturn efx_rc_t
405 efx_nic_t *enp = etp->et_enp;
406 const efx_tx_ops_t *etxop = enp->en_etxop;
409 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
411 if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
415 if (etxop->etxo_qpio_enable == NULL) {
419 if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
429 EFSYS_PROBE1(fail1, efx_rc_t, rc);
437 efx_nic_t *enp = etp->et_enp;
438 const efx_tx_ops_t *etxop = enp->en_etxop;
440 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
442 if (etxop->etxo_qpio_disable != NULL)
443 etxop->etxo_qpio_disable(etp);
446 __checkReturn efx_rc_t
449 __in_ecount(buf_length) uint8_t *buffer,
450 __in size_t buf_length,
451 __in size_t pio_buf_offset)
453 efx_nic_t *enp = etp->et_enp;
454 const efx_tx_ops_t *etxop = enp->en_etxop;
457 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
459 if (etxop->etxo_qpio_write != NULL) {
460 if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
461 pio_buf_offset)) != 0)
469 EFSYS_PROBE1(fail1, efx_rc_t, rc);
473 __checkReturn efx_rc_t
476 __in size_t pkt_length,
477 __in unsigned int completed,
478 __inout unsigned int *addedp)
480 efx_nic_t *enp = etp->et_enp;
481 const efx_tx_ops_t *etxop = enp->en_etxop;
484 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
486 if (etxop->etxo_qpio_post != NULL) {
487 if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
496 EFSYS_PROBE1(fail1, efx_rc_t, rc);
500 __checkReturn efx_rc_t
503 __in_ecount(n) efx_desc_t *ed,
505 __in unsigned int completed,
506 __inout unsigned int *addedp)
508 efx_nic_t *enp = etp->et_enp;
509 const efx_tx_ops_t *etxop = enp->en_etxop;
512 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
514 if ((rc = etxop->etxo_qdesc_post(etp, ed,
515 n, completed, addedp)) != 0)
521 EFSYS_PROBE1(fail1, efx_rc_t, rc);
526 efx_tx_qdesc_dma_create(
528 __in efsys_dma_addr_t addr,
531 __out efx_desc_t *edp)
533 efx_nic_t *enp = etp->et_enp;
534 const efx_tx_ops_t *etxop = enp->en_etxop;
536 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
537 EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
539 etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
543 efx_tx_qdesc_tso_create(
545 __in uint16_t ipv4_id,
546 __in uint32_t tcp_seq,
547 __in uint8_t tcp_flags,
548 __out efx_desc_t *edp)
550 efx_nic_t *enp = etp->et_enp;
551 const efx_tx_ops_t *etxop = enp->en_etxop;
553 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
554 EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
556 etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
560 efx_tx_qdesc_tso2_create(
562 __in uint16_t ipv4_id,
563 __in uint32_t tcp_seq,
565 __out_ecount(count) efx_desc_t *edp,
568 efx_nic_t *enp = etp->et_enp;
569 const efx_tx_ops_t *etxop = enp->en_etxop;
571 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
572 EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
574 etxop->etxo_qdesc_tso2_create(etp, ipv4_id, tcp_seq, mss, edp, count);
578 efx_tx_qdesc_vlantci_create(
581 __out efx_desc_t *edp)
583 efx_nic_t *enp = etp->et_enp;
584 const efx_tx_ops_t *etxop = enp->en_etxop;
586 EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
587 EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
589 etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
595 static __checkReturn efx_rc_t
602 * Disable the timer-based TX DMA backoff and allow TX DMA to be
603 * controlled by the RX FIFO fill level (although always allow a
606 EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
607 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
608 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
609 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
610 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
611 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
612 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
613 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
616 * Filter all packets less than 14 bytes to avoid parsing
619 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
620 EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
623 * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
624 * descriptors (which is bad).
626 EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
627 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
628 EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
633 #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \
639 id = (_added)++ & (_etp)->et_mask; \
640 offset = id * sizeof (efx_qword_t); \
642 EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index, \
643 unsigned int, id, efsys_dma_addr_t, (_addr), \
644 size_t, (_size), boolean_t, (_eop)); \
646 EFX_POPULATE_QWORD_4(qword, \
647 FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1, \
648 FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size), \
649 FSF_AZ_TX_KER_BUF_ADDR_DW0, \
650 (uint32_t)((_addr) & 0xffffffff), \
651 FSF_AZ_TX_KER_BUF_ADDR_DW1, \
652 (uint32_t)((_addr) >> 32)); \
653 EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword); \
655 _NOTE(CONSTANTCONDITION) \
658 static __checkReturn efx_rc_t
661 __in_ecount(n) efx_buffer_t *eb,
663 __in unsigned int completed,
664 __inout unsigned int *addedp)
666 unsigned int added = *addedp;
670 if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))
673 for (i = 0; i < n; i++) {
674 efx_buffer_t *ebp = &eb[i];
675 efsys_dma_addr_t start = ebp->eb_addr;
676 size_t size = ebp->eb_size;
677 efsys_dma_addr_t end = start + size;
679 /* Fragments must not span 4k boundaries. */
680 EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end);
682 EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
685 EFX_TX_QSTAT_INCR(etp, TX_POST);
691 EFSYS_PROBE1(fail1, efx_rc_t, rc);
699 __in unsigned int added,
700 __in unsigned int pushed)
702 efx_nic_t *enp = etp->et_enp;
707 /* Push the populated descriptors out */
708 wptr = added & etp->et_mask;
710 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
712 /* Only write the third DWORD */
713 EFX_POPULATE_DWORD_1(dword,
714 EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
716 /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
717 EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
718 wptr, pushed & etp->et_mask);
719 EFSYS_PIO_WRITE_BARRIER();
720 EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
721 etp->et_index, &dword, B_FALSE);
724 #define EFX_MAX_PACE_VALUE 20
726 static __checkReturn efx_rc_t
729 __in unsigned int ns)
731 efx_nic_t *enp = etp->et_enp;
732 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
734 unsigned int pace_val;
735 unsigned int timer_period;
742 * The pace_val to write into the table is s.t
743 * ns <= timer_period * (2 ^ pace_val)
745 timer_period = 104 / encp->enc_clk_mult;
746 for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
747 if ((timer_period << pace_val) >= ns)
751 if (pace_val > EFX_MAX_PACE_VALUE) {
756 /* Update the pacing table */
757 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
758 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
764 EFSYS_PROBE1(fail1, efx_rc_t, rc);
769 static __checkReturn efx_rc_t
773 efx_nic_t *enp = etp->et_enp;
777 efx_tx_qpace(etp, 0);
779 label = etp->et_index;
781 /* Flush the queue */
782 EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
783 FRF_AZ_TX_FLUSH_DESCQ, label);
784 EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
793 efx_nic_t *enp = etp->et_enp;
796 EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
797 etp->et_index, &oword, B_TRUE);
799 EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
800 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
801 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
802 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
803 uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
805 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
806 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
807 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
809 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
810 etp->et_index, &oword, B_TRUE);
813 static __checkReturn efx_rc_t
816 __in unsigned int index,
817 __in unsigned int label,
818 __in efsys_mem_t *esmp,
824 __out unsigned int *addedp)
826 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
831 _NOTE(ARGUNUSED(esmp))
833 EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
834 (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
835 EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
837 EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
838 EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
840 if (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {
844 if (index >= encp->enc_txq_limit) {
849 (1 << size) <= (int)(encp->enc_txq_max_ndescs / EFX_TXQ_MINNDESCS);
851 if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))
853 if (id + (1 << size) >= encp->enc_buftbl_limit) {
858 /* Set up the new descriptor queue */
861 EFX_POPULATE_OWORD_6(oword,
862 FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
863 FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
864 FRF_AZ_TX_DESCQ_OWNER_ID, 0,
865 FRF_AZ_TX_DESCQ_LABEL, label,
866 FRF_AZ_TX_DESCQ_SIZE, size,
867 FRF_AZ_TX_DESCQ_TYPE, 0);
869 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
870 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
871 (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
872 EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
873 (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
875 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
876 etp->et_index, &oword, B_TRUE);
885 EFSYS_PROBE1(fail1, efx_rc_t, rc);
890 __checkReturn efx_rc_t
893 __in_ecount(n) efx_desc_t *ed,
895 __in unsigned int completed,
896 __inout unsigned int *addedp)
898 unsigned int added = *addedp;
902 if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
907 for (i = 0; i < n; i++) {
908 efx_desc_t *edp = &ed[i];
912 id = added++ & etp->et_mask;
913 offset = id * sizeof (efx_desc_t);
915 EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
918 EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
919 unsigned int, added, unsigned int, n);
921 EFX_TX_QSTAT_INCR(etp, TX_POST);
927 EFSYS_PROBE1(fail1, efx_rc_t, rc);
932 siena_tx_qdesc_dma_create(
934 __in efsys_dma_addr_t addr,
937 __out efx_desc_t *edp)
939 /* Fragments must not span 4k boundaries. */
940 EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
942 EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
943 efsys_dma_addr_t, addr,
944 size_t, size, boolean_t, eop);
946 EFX_POPULATE_QWORD_4(edp->ed_eq,
947 FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
948 FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
949 FSF_AZ_TX_KER_BUF_ADDR_DW0,
950 (uint32_t)(addr & 0xffffffff),
951 FSF_AZ_TX_KER_BUF_ADDR_DW1,
952 (uint32_t)(addr >> 32));
955 #endif /* EFSYS_OPT_SIENA */
963 efx_nic_t *enp = etp->et_enp;
966 /* Purge descriptor queue */
967 EFX_ZERO_OWORD(oword);
969 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
970 etp->et_index, &oword, B_TRUE);
977 _NOTE(ARGUNUSED(enp))
980 #endif /* EFSYS_OPT_SIENA */