15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko *
3*672386c1SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko * Copyright(c) 2012-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko */
65e111ed8SAndrew Rybchenko
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko
105e111ed8SAndrew Rybchenko
115e111ed8SAndrew Rybchenko #if EFX_OPTS_EF10()
125e111ed8SAndrew Rybchenko
135e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
145e111ed8SAndrew Rybchenko #define EFX_TX_QSTAT_INCR(_etp, _stat) \
155e111ed8SAndrew Rybchenko do { \
165e111ed8SAndrew Rybchenko (_etp)->et_stat[_stat]++; \
175e111ed8SAndrew Rybchenko _NOTE(CONSTANTCONDITION) \
185e111ed8SAndrew Rybchenko } while (B_FALSE)
195e111ed8SAndrew Rybchenko #else
205e111ed8SAndrew Rybchenko #define EFX_TX_QSTAT_INCR(_etp, _stat)
215e111ed8SAndrew Rybchenko #endif
225e111ed8SAndrew Rybchenko
235e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_init(__in efx_nic_t * enp)245e111ed8SAndrew Rybchenko ef10_tx_init(
255e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
265e111ed8SAndrew Rybchenko {
275e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
285e111ed8SAndrew Rybchenko return (0);
295e111ed8SAndrew Rybchenko }
305e111ed8SAndrew Rybchenko
315e111ed8SAndrew Rybchenko void
ef10_tx_fini(__in efx_nic_t * enp)325e111ed8SAndrew Rybchenko ef10_tx_fini(
335e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
345e111ed8SAndrew Rybchenko {
355e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
365e111ed8SAndrew Rybchenko }
375e111ed8SAndrew Rybchenko
385e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efsys_mem_t * esmp,__in size_t ndescs,__in uint32_t id,__in uint16_t flags,__in efx_evq_t * eep,__in efx_txq_t * etp,__out unsigned int * addedp)395e111ed8SAndrew Rybchenko ef10_tx_qcreate(
405e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
415e111ed8SAndrew Rybchenko __in unsigned int index,
425e111ed8SAndrew Rybchenko __in unsigned int label,
435e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp,
445e111ed8SAndrew Rybchenko __in size_t ndescs,
455e111ed8SAndrew Rybchenko __in uint32_t id,
465e111ed8SAndrew Rybchenko __in uint16_t flags,
475e111ed8SAndrew Rybchenko __in efx_evq_t *eep,
485e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
495e111ed8SAndrew Rybchenko __out unsigned int *addedp)
505e111ed8SAndrew Rybchenko {
515e111ed8SAndrew Rybchenko efx_nic_cfg_t *encp = &enp->en_nic_cfg;
525e111ed8SAndrew Rybchenko uint16_t inner_csum;
535e111ed8SAndrew Rybchenko efx_desc_t desc;
545e111ed8SAndrew Rybchenko efx_rc_t rc;
555e111ed8SAndrew Rybchenko
565e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(id))
575e111ed8SAndrew Rybchenko
585e111ed8SAndrew Rybchenko inner_csum = EFX_TXQ_CKSUM_INNER_IPV4 | EFX_TXQ_CKSUM_INNER_TCPUDP;
595e111ed8SAndrew Rybchenko if (((flags & inner_csum) != 0) &&
605e111ed8SAndrew Rybchenko (encp->enc_tunnel_encapsulations_supported == 0)) {
615e111ed8SAndrew Rybchenko rc = EINVAL;
625e111ed8SAndrew Rybchenko goto fail1;
635e111ed8SAndrew Rybchenko }
645e111ed8SAndrew Rybchenko
655e111ed8SAndrew Rybchenko if ((rc = efx_mcdi_init_txq(enp, ndescs, eep->ee_index, label, index,
665e111ed8SAndrew Rybchenko flags, esmp)) != 0)
675e111ed8SAndrew Rybchenko goto fail2;
685e111ed8SAndrew Rybchenko
695e111ed8SAndrew Rybchenko /*
705e111ed8SAndrew Rybchenko * A previous user of this TX queue may have written a descriptor to the
715e111ed8SAndrew Rybchenko * TX push collector, but not pushed the doorbell (e.g. after a crash).
725e111ed8SAndrew Rybchenko * The next doorbell write would then push the stale descriptor.
735e111ed8SAndrew Rybchenko *
745e111ed8SAndrew Rybchenko * Ensure the (per network port) TX push collector is cleared by writing
755e111ed8SAndrew Rybchenko * a no-op TX option descriptor. See bug29981 for details.
765e111ed8SAndrew Rybchenko */
775e111ed8SAndrew Rybchenko *addedp = 1;
785e111ed8SAndrew Rybchenko ef10_tx_qdesc_checksum_create(etp, flags, &desc);
795e111ed8SAndrew Rybchenko
805e111ed8SAndrew Rybchenko EFSYS_MEM_WRITEQ(etp->et_esmp, 0, &desc.ed_eq);
815e111ed8SAndrew Rybchenko ef10_tx_qpush(etp, *addedp, 0);
825e111ed8SAndrew Rybchenko
835e111ed8SAndrew Rybchenko return (0);
845e111ed8SAndrew Rybchenko
855e111ed8SAndrew Rybchenko fail2:
865e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
875e111ed8SAndrew Rybchenko fail1:
885e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
895e111ed8SAndrew Rybchenko
905e111ed8SAndrew Rybchenko return (rc);
915e111ed8SAndrew Rybchenko }
925e111ed8SAndrew Rybchenko
935e111ed8SAndrew Rybchenko void
ef10_tx_qdestroy(__in efx_txq_t * etp)945e111ed8SAndrew Rybchenko ef10_tx_qdestroy(
955e111ed8SAndrew Rybchenko __in efx_txq_t *etp)
965e111ed8SAndrew Rybchenko {
975e111ed8SAndrew Rybchenko /* FIXME */
985e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp))
995e111ed8SAndrew Rybchenko /* FIXME */
1005e111ed8SAndrew Rybchenko }
1015e111ed8SAndrew Rybchenko
1025e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qpio_enable(__in efx_txq_t * etp)1035e111ed8SAndrew Rybchenko ef10_tx_qpio_enable(
1045e111ed8SAndrew Rybchenko __in efx_txq_t *etp)
1055e111ed8SAndrew Rybchenko {
1065e111ed8SAndrew Rybchenko efx_nic_t *enp = etp->et_enp;
1075e111ed8SAndrew Rybchenko efx_piobuf_handle_t handle;
1085e111ed8SAndrew Rybchenko efx_rc_t rc;
1095e111ed8SAndrew Rybchenko
1105e111ed8SAndrew Rybchenko if (etp->et_pio_size != 0) {
1115e111ed8SAndrew Rybchenko rc = EALREADY;
1125e111ed8SAndrew Rybchenko goto fail1;
1135e111ed8SAndrew Rybchenko }
1145e111ed8SAndrew Rybchenko
1155e111ed8SAndrew Rybchenko /* Sub-allocate a PIO block from a piobuf */
1165e111ed8SAndrew Rybchenko if ((rc = ef10_nic_pio_alloc(enp,
1175e111ed8SAndrew Rybchenko &etp->et_pio_bufnum,
1185e111ed8SAndrew Rybchenko &handle,
1195e111ed8SAndrew Rybchenko &etp->et_pio_blknum,
1205e111ed8SAndrew Rybchenko &etp->et_pio_offset,
1215e111ed8SAndrew Rybchenko &etp->et_pio_size)) != 0) {
1225e111ed8SAndrew Rybchenko goto fail2;
1235e111ed8SAndrew Rybchenko }
1245e111ed8SAndrew Rybchenko EFSYS_ASSERT3U(etp->et_pio_size, !=, 0);
1255e111ed8SAndrew Rybchenko
1265e111ed8SAndrew Rybchenko /* Link the piobuf to this TXQ */
1275e111ed8SAndrew Rybchenko if ((rc = ef10_nic_pio_link(enp, etp->et_index, handle)) != 0) {
1285e111ed8SAndrew Rybchenko goto fail3;
1295e111ed8SAndrew Rybchenko }
1305e111ed8SAndrew Rybchenko
1315e111ed8SAndrew Rybchenko /*
1325e111ed8SAndrew Rybchenko * et_pio_offset is the offset of the sub-allocated block within the
1335e111ed8SAndrew Rybchenko * hardware PIO buffer. It is used as the buffer address in the PIO
1345e111ed8SAndrew Rybchenko * option descriptor.
1355e111ed8SAndrew Rybchenko *
1365e111ed8SAndrew Rybchenko * et_pio_write_offset is the offset of the sub-allocated block from the
1375e111ed8SAndrew Rybchenko * start of the write-combined memory mapping, and is used for writing
1385e111ed8SAndrew Rybchenko * data into the PIO buffer.
1395e111ed8SAndrew Rybchenko */
1405e111ed8SAndrew Rybchenko etp->et_pio_write_offset =
1415e111ed8SAndrew Rybchenko (etp->et_pio_bufnum * ER_DZ_TX_PIOBUF_STEP) +
1425e111ed8SAndrew Rybchenko ER_DZ_TX_PIOBUF_OFST + etp->et_pio_offset;
1435e111ed8SAndrew Rybchenko
1445e111ed8SAndrew Rybchenko return (0);
1455e111ed8SAndrew Rybchenko
1465e111ed8SAndrew Rybchenko fail3:
1475e111ed8SAndrew Rybchenko EFSYS_PROBE(fail3);
1485e111ed8SAndrew Rybchenko (void) ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
1495e111ed8SAndrew Rybchenko fail2:
1505e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
1515e111ed8SAndrew Rybchenko etp->et_pio_size = 0;
1525e111ed8SAndrew Rybchenko fail1:
1535e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1545e111ed8SAndrew Rybchenko
1555e111ed8SAndrew Rybchenko return (rc);
1565e111ed8SAndrew Rybchenko }
1575e111ed8SAndrew Rybchenko
1585e111ed8SAndrew Rybchenko void
ef10_tx_qpio_disable(__in efx_txq_t * etp)1595e111ed8SAndrew Rybchenko ef10_tx_qpio_disable(
1605e111ed8SAndrew Rybchenko __in efx_txq_t *etp)
1615e111ed8SAndrew Rybchenko {
1625e111ed8SAndrew Rybchenko efx_nic_t *enp = etp->et_enp;
1635e111ed8SAndrew Rybchenko
1645e111ed8SAndrew Rybchenko if (etp->et_pio_size != 0) {
1655e111ed8SAndrew Rybchenko /* Unlink the piobuf from this TXQ */
1665e111ed8SAndrew Rybchenko if (ef10_nic_pio_unlink(enp, etp->et_index) != 0)
1675e111ed8SAndrew Rybchenko return;
1685e111ed8SAndrew Rybchenko
1695e111ed8SAndrew Rybchenko /* Free the sub-allocated PIO block */
1705e111ed8SAndrew Rybchenko (void) ef10_nic_pio_free(enp, etp->et_pio_bufnum,
1715e111ed8SAndrew Rybchenko etp->et_pio_blknum);
1725e111ed8SAndrew Rybchenko etp->et_pio_size = 0;
1735e111ed8SAndrew Rybchenko etp->et_pio_write_offset = 0;
1745e111ed8SAndrew Rybchenko }
1755e111ed8SAndrew Rybchenko }
1765e111ed8SAndrew Rybchenko
1775e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qpio_write(__in efx_txq_t * etp,__in_ecount (length)uint8_t * buffer,__in size_t length,__in size_t offset)1785e111ed8SAndrew Rybchenko ef10_tx_qpio_write(
1795e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
1805e111ed8SAndrew Rybchenko __in_ecount(length) uint8_t *buffer,
1815e111ed8SAndrew Rybchenko __in size_t length,
1825e111ed8SAndrew Rybchenko __in size_t offset)
1835e111ed8SAndrew Rybchenko {
1845e111ed8SAndrew Rybchenko efx_nic_t *enp = etp->et_enp;
1855e111ed8SAndrew Rybchenko efsys_bar_t *esbp = enp->en_esbp;
1865e111ed8SAndrew Rybchenko uint32_t write_offset;
1875e111ed8SAndrew Rybchenko uint32_t write_offset_limit;
1885e111ed8SAndrew Rybchenko efx_qword_t *eqp;
1895e111ed8SAndrew Rybchenko efx_rc_t rc;
1905e111ed8SAndrew Rybchenko
1915e111ed8SAndrew Rybchenko EFSYS_ASSERT(length % sizeof (efx_qword_t) == 0);
1925e111ed8SAndrew Rybchenko
1935e111ed8SAndrew Rybchenko if (etp->et_pio_size == 0) {
1945e111ed8SAndrew Rybchenko rc = ENOENT;
1955e111ed8SAndrew Rybchenko goto fail1;
1965e111ed8SAndrew Rybchenko }
1975e111ed8SAndrew Rybchenko if (offset + length > etp->et_pio_size) {
1985e111ed8SAndrew Rybchenko rc = ENOSPC;
1995e111ed8SAndrew Rybchenko goto fail2;
2005e111ed8SAndrew Rybchenko }
2015e111ed8SAndrew Rybchenko
2025e111ed8SAndrew Rybchenko /*
2035e111ed8SAndrew Rybchenko * Writes to PIO buffers must be 64 bit aligned, and multiples of
2045e111ed8SAndrew Rybchenko * 64 bits.
2055e111ed8SAndrew Rybchenko */
2065e111ed8SAndrew Rybchenko write_offset = etp->et_pio_write_offset + offset;
2075e111ed8SAndrew Rybchenko write_offset_limit = write_offset + length;
2085e111ed8SAndrew Rybchenko eqp = (efx_qword_t *)buffer;
2095e111ed8SAndrew Rybchenko while (write_offset < write_offset_limit) {
2105e111ed8SAndrew Rybchenko EFSYS_BAR_WC_WRITEQ(esbp, write_offset, eqp);
2115e111ed8SAndrew Rybchenko eqp++;
2125e111ed8SAndrew Rybchenko write_offset += sizeof (efx_qword_t);
2135e111ed8SAndrew Rybchenko }
2145e111ed8SAndrew Rybchenko
2155e111ed8SAndrew Rybchenko return (0);
2165e111ed8SAndrew Rybchenko
2175e111ed8SAndrew Rybchenko fail2:
2185e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
2195e111ed8SAndrew Rybchenko fail1:
2205e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2215e111ed8SAndrew Rybchenko
2225e111ed8SAndrew Rybchenko return (rc);
2235e111ed8SAndrew Rybchenko }
2245e111ed8SAndrew Rybchenko
2255e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qpio_post(__in efx_txq_t * etp,__in size_t pkt_length,__in unsigned int completed,__inout unsigned int * addedp)2265e111ed8SAndrew Rybchenko ef10_tx_qpio_post(
2275e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
2285e111ed8SAndrew Rybchenko __in size_t pkt_length,
2295e111ed8SAndrew Rybchenko __in unsigned int completed,
2305e111ed8SAndrew Rybchenko __inout unsigned int *addedp)
2315e111ed8SAndrew Rybchenko {
2325e111ed8SAndrew Rybchenko efx_qword_t pio_desc;
2335e111ed8SAndrew Rybchenko unsigned int id;
2345e111ed8SAndrew Rybchenko size_t offset;
2355e111ed8SAndrew Rybchenko unsigned int added = *addedp;
2365e111ed8SAndrew Rybchenko efx_rc_t rc;
2375e111ed8SAndrew Rybchenko
2385e111ed8SAndrew Rybchenko
2395e111ed8SAndrew Rybchenko if (added - completed + 1 > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
2405e111ed8SAndrew Rybchenko rc = ENOSPC;
2415e111ed8SAndrew Rybchenko goto fail1;
2425e111ed8SAndrew Rybchenko }
2435e111ed8SAndrew Rybchenko
2445e111ed8SAndrew Rybchenko if (etp->et_pio_size == 0) {
2455e111ed8SAndrew Rybchenko rc = ENOENT;
2465e111ed8SAndrew Rybchenko goto fail2;
2475e111ed8SAndrew Rybchenko }
2485e111ed8SAndrew Rybchenko
2495e111ed8SAndrew Rybchenko id = added++ & etp->et_mask;
2505e111ed8SAndrew Rybchenko offset = id * sizeof (efx_qword_t);
2515e111ed8SAndrew Rybchenko
2525e111ed8SAndrew Rybchenko EFSYS_PROBE4(tx_pio_post, unsigned int, etp->et_index,
2535e111ed8SAndrew Rybchenko unsigned int, id, uint32_t, etp->et_pio_offset,
2545e111ed8SAndrew Rybchenko size_t, pkt_length);
2555e111ed8SAndrew Rybchenko
2565e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(pio_desc,
2575e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
2585e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE, 1,
2595e111ed8SAndrew Rybchenko ESF_DZ_TX_PIO_CONT, 0,
2605e111ed8SAndrew Rybchenko ESF_DZ_TX_PIO_BYTE_CNT, pkt_length,
2615e111ed8SAndrew Rybchenko ESF_DZ_TX_PIO_BUF_ADDR, etp->et_pio_offset);
2625e111ed8SAndrew Rybchenko
2635e111ed8SAndrew Rybchenko EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &pio_desc);
2645e111ed8SAndrew Rybchenko
2655e111ed8SAndrew Rybchenko EFX_TX_QSTAT_INCR(etp, TX_POST_PIO);
2665e111ed8SAndrew Rybchenko
2675e111ed8SAndrew Rybchenko *addedp = added;
2685e111ed8SAndrew Rybchenko return (0);
2695e111ed8SAndrew Rybchenko
2705e111ed8SAndrew Rybchenko fail2:
2715e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
2725e111ed8SAndrew Rybchenko fail1:
2735e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2745e111ed8SAndrew Rybchenko
2755e111ed8SAndrew Rybchenko return (rc);
2765e111ed8SAndrew Rybchenko }
2775e111ed8SAndrew Rybchenko
2785e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qpost(__in efx_txq_t * etp,__in_ecount (ndescs)efx_buffer_t * eb,__in unsigned int ndescs,__in unsigned int completed,__inout unsigned int * addedp)2795e111ed8SAndrew Rybchenko ef10_tx_qpost(
2805e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
2815e111ed8SAndrew Rybchenko __in_ecount(ndescs) efx_buffer_t *eb,
2825e111ed8SAndrew Rybchenko __in unsigned int ndescs,
2835e111ed8SAndrew Rybchenko __in unsigned int completed,
2845e111ed8SAndrew Rybchenko __inout unsigned int *addedp)
2855e111ed8SAndrew Rybchenko {
2865e111ed8SAndrew Rybchenko unsigned int added = *addedp;
2875e111ed8SAndrew Rybchenko unsigned int i;
2885e111ed8SAndrew Rybchenko efx_rc_t rc;
2895e111ed8SAndrew Rybchenko
2905e111ed8SAndrew Rybchenko if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
2915e111ed8SAndrew Rybchenko rc = ENOSPC;
2925e111ed8SAndrew Rybchenko goto fail1;
2935e111ed8SAndrew Rybchenko }
2945e111ed8SAndrew Rybchenko
2955e111ed8SAndrew Rybchenko for (i = 0; i < ndescs; i++) {
2965e111ed8SAndrew Rybchenko efx_buffer_t *ebp = &eb[i];
2975e111ed8SAndrew Rybchenko efsys_dma_addr_t addr = ebp->eb_addr;
2985e111ed8SAndrew Rybchenko size_t size = ebp->eb_size;
2995e111ed8SAndrew Rybchenko boolean_t eop = ebp->eb_eop;
3005e111ed8SAndrew Rybchenko unsigned int id;
3015e111ed8SAndrew Rybchenko size_t offset;
3025e111ed8SAndrew Rybchenko efx_qword_t qword;
3035e111ed8SAndrew Rybchenko
3045e111ed8SAndrew Rybchenko /* No limitations on boundary crossing */
3055e111ed8SAndrew Rybchenko EFSYS_ASSERT(size <=
3065e111ed8SAndrew Rybchenko etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max);
3075e111ed8SAndrew Rybchenko
3085e111ed8SAndrew Rybchenko id = added++ & etp->et_mask;
3095e111ed8SAndrew Rybchenko offset = id * sizeof (efx_qword_t);
3105e111ed8SAndrew Rybchenko
3115e111ed8SAndrew Rybchenko EFSYS_PROBE5(tx_post, unsigned int, etp->et_index,
3125e111ed8SAndrew Rybchenko unsigned int, id, efsys_dma_addr_t, addr,
3135e111ed8SAndrew Rybchenko size_t, size, boolean_t, eop);
3145e111ed8SAndrew Rybchenko
3155e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(qword,
3165e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_TYPE, 0,
3175e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
3185e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
3195e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
3205e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
3215e111ed8SAndrew Rybchenko
3225e111ed8SAndrew Rybchenko EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &qword);
3235e111ed8SAndrew Rybchenko }
3245e111ed8SAndrew Rybchenko
3255e111ed8SAndrew Rybchenko EFX_TX_QSTAT_INCR(etp, TX_POST);
3265e111ed8SAndrew Rybchenko
3275e111ed8SAndrew Rybchenko *addedp = added;
3285e111ed8SAndrew Rybchenko return (0);
3295e111ed8SAndrew Rybchenko
3305e111ed8SAndrew Rybchenko fail1:
3315e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
3325e111ed8SAndrew Rybchenko
3335e111ed8SAndrew Rybchenko return (rc);
3345e111ed8SAndrew Rybchenko }
3355e111ed8SAndrew Rybchenko
3365e111ed8SAndrew Rybchenko /*
3375e111ed8SAndrew Rybchenko * This improves performance by, when possible, pushing a TX descriptor at the
3385e111ed8SAndrew Rybchenko * same time as the doorbell. The descriptor must be added to the TXQ, so that
3395e111ed8SAndrew Rybchenko * can be used if the hardware decides not to use the pushed descriptor.
3405e111ed8SAndrew Rybchenko */
3415e111ed8SAndrew Rybchenko void
ef10_tx_qpush(__in efx_txq_t * etp,__in unsigned int added,__in unsigned int pushed)3425e111ed8SAndrew Rybchenko ef10_tx_qpush(
3435e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
3445e111ed8SAndrew Rybchenko __in unsigned int added,
3455e111ed8SAndrew Rybchenko __in unsigned int pushed)
3465e111ed8SAndrew Rybchenko {
3475e111ed8SAndrew Rybchenko efx_nic_t *enp = etp->et_enp;
3485e111ed8SAndrew Rybchenko unsigned int wptr;
3495e111ed8SAndrew Rybchenko unsigned int id;
3505e111ed8SAndrew Rybchenko size_t offset;
3515e111ed8SAndrew Rybchenko efx_qword_t desc;
3525e111ed8SAndrew Rybchenko efx_oword_t oword;
3535e111ed8SAndrew Rybchenko
3545e111ed8SAndrew Rybchenko wptr = added & etp->et_mask;
3555e111ed8SAndrew Rybchenko id = pushed & etp->et_mask;
3565e111ed8SAndrew Rybchenko offset = id * sizeof (efx_qword_t);
3575e111ed8SAndrew Rybchenko
3585e111ed8SAndrew Rybchenko EFSYS_MEM_READQ(etp->et_esmp, offset, &desc);
3595e111ed8SAndrew Rybchenko
3605e111ed8SAndrew Rybchenko /*
3615e111ed8SAndrew Rybchenko * Bug 65776: TSO option descriptors cannot be pushed if pacer bypass is
3625e111ed8SAndrew Rybchenko * enabled on the event queue this transmit queue is attached to.
3635e111ed8SAndrew Rybchenko *
3645e111ed8SAndrew Rybchenko * To ensure the code is safe, it is easiest to simply test the type of
3655e111ed8SAndrew Rybchenko * the descriptor to push, and only push it is if it not a TSO option
3665e111ed8SAndrew Rybchenko * descriptor.
3675e111ed8SAndrew Rybchenko */
3685e111ed8SAndrew Rybchenko if ((EFX_QWORD_FIELD(desc, ESF_DZ_TX_DESC_IS_OPT) != 1) ||
3695e111ed8SAndrew Rybchenko (EFX_QWORD_FIELD(desc, ESF_DZ_TX_OPTION_TYPE) !=
3705e111ed8SAndrew Rybchenko ESE_DZ_TX_OPTION_DESC_TSO)) {
3715e111ed8SAndrew Rybchenko /* Push the descriptor and update the wptr. */
3725e111ed8SAndrew Rybchenko EFX_POPULATE_OWORD_3(oword, ERF_DZ_TX_DESC_WPTR, wptr,
3735e111ed8SAndrew Rybchenko ERF_DZ_TX_DESC_HWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_1),
3745e111ed8SAndrew Rybchenko ERF_DZ_TX_DESC_LWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_0));
3755e111ed8SAndrew Rybchenko
3765e111ed8SAndrew Rybchenko /* Ensure ordering of memory (descriptors) and PIO (doorbell) */
3775e111ed8SAndrew Rybchenko EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
37882192e22SAndrew Rybchenko EF10_TXQ_DESC_SIZE, wptr, id);
3795e111ed8SAndrew Rybchenko EFSYS_PIO_WRITE_BARRIER();
3805e111ed8SAndrew Rybchenko EFX_BAR_VI_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG,
3815e111ed8SAndrew Rybchenko etp->et_index, &oword);
3825e111ed8SAndrew Rybchenko } else {
3835e111ed8SAndrew Rybchenko efx_dword_t dword;
3845e111ed8SAndrew Rybchenko
3855e111ed8SAndrew Rybchenko /*
3865e111ed8SAndrew Rybchenko * Only update the wptr. This is signalled to the hardware by
3875e111ed8SAndrew Rybchenko * only writing one DWORD of the doorbell register.
3885e111ed8SAndrew Rybchenko */
3895e111ed8SAndrew Rybchenko EFX_POPULATE_OWORD_1(oword, ERF_DZ_TX_DESC_WPTR, wptr);
3905e111ed8SAndrew Rybchenko dword = oword.eo_dword[2];
3915e111ed8SAndrew Rybchenko
3925e111ed8SAndrew Rybchenko /* Ensure ordering of memory (descriptors) and PIO (doorbell) */
3935e111ed8SAndrew Rybchenko EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
39482192e22SAndrew Rybchenko EF10_TXQ_DESC_SIZE, wptr, id);
3955e111ed8SAndrew Rybchenko EFSYS_PIO_WRITE_BARRIER();
3965e111ed8SAndrew Rybchenko EFX_BAR_VI_WRITED2(enp, ER_DZ_TX_DESC_UPD_REG,
3975e111ed8SAndrew Rybchenko etp->et_index, &dword, B_FALSE);
3985e111ed8SAndrew Rybchenko }
3995e111ed8SAndrew Rybchenko }
4005e111ed8SAndrew Rybchenko
4015e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qdesc_post(__in efx_txq_t * etp,__in_ecount (ndescs)efx_desc_t * ed,__in unsigned int ndescs,__in unsigned int completed,__inout unsigned int * addedp)4025e111ed8SAndrew Rybchenko ef10_tx_qdesc_post(
4035e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
4045e111ed8SAndrew Rybchenko __in_ecount(ndescs) efx_desc_t *ed,
4055e111ed8SAndrew Rybchenko __in unsigned int ndescs,
4065e111ed8SAndrew Rybchenko __in unsigned int completed,
4075e111ed8SAndrew Rybchenko __inout unsigned int *addedp)
4085e111ed8SAndrew Rybchenko {
4095e111ed8SAndrew Rybchenko unsigned int added = *addedp;
4105e111ed8SAndrew Rybchenko unsigned int i;
4115e111ed8SAndrew Rybchenko
4125e111ed8SAndrew Rybchenko if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
4135e111ed8SAndrew Rybchenko return (ENOSPC);
4145e111ed8SAndrew Rybchenko
4155e111ed8SAndrew Rybchenko for (i = 0; i < ndescs; i++) {
4165e111ed8SAndrew Rybchenko efx_desc_t *edp = &ed[i];
4175e111ed8SAndrew Rybchenko unsigned int id;
4185e111ed8SAndrew Rybchenko size_t offset;
4195e111ed8SAndrew Rybchenko
4205e111ed8SAndrew Rybchenko id = added++ & etp->et_mask;
4215e111ed8SAndrew Rybchenko offset = id * sizeof (efx_desc_t);
4225e111ed8SAndrew Rybchenko
4235e111ed8SAndrew Rybchenko EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
4245e111ed8SAndrew Rybchenko }
4255e111ed8SAndrew Rybchenko
4265e111ed8SAndrew Rybchenko EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
4275e111ed8SAndrew Rybchenko unsigned int, added, unsigned int, ndescs);
4285e111ed8SAndrew Rybchenko
4295e111ed8SAndrew Rybchenko EFX_TX_QSTAT_INCR(etp, TX_POST);
4305e111ed8SAndrew Rybchenko
4315e111ed8SAndrew Rybchenko *addedp = added;
4325e111ed8SAndrew Rybchenko return (0);
4335e111ed8SAndrew Rybchenko }
4345e111ed8SAndrew Rybchenko
4355e111ed8SAndrew Rybchenko void
ef10_tx_qdesc_dma_create(__in efx_txq_t * etp,__in efsys_dma_addr_t addr,__in size_t size,__in boolean_t eop,__out efx_desc_t * edp)4365e111ed8SAndrew Rybchenko ef10_tx_qdesc_dma_create(
4375e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
4385e111ed8SAndrew Rybchenko __in efsys_dma_addr_t addr,
4395e111ed8SAndrew Rybchenko __in size_t size,
4405e111ed8SAndrew Rybchenko __in boolean_t eop,
4415e111ed8SAndrew Rybchenko __out efx_desc_t *edp)
4425e111ed8SAndrew Rybchenko {
4435e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp))
4445e111ed8SAndrew Rybchenko
4455e111ed8SAndrew Rybchenko /* No limitations on boundary crossing */
4465e111ed8SAndrew Rybchenko EFSYS_ASSERT(size <= etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max);
4475e111ed8SAndrew Rybchenko
4485e111ed8SAndrew Rybchenko EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
4495e111ed8SAndrew Rybchenko efsys_dma_addr_t, addr,
4505e111ed8SAndrew Rybchenko size_t, size, boolean_t, eop);
4515e111ed8SAndrew Rybchenko
4525e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(edp->ed_eq,
4535e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_TYPE, 0,
4545e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
4555e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
4565e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
4575e111ed8SAndrew Rybchenko ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
4585e111ed8SAndrew Rybchenko }
4595e111ed8SAndrew Rybchenko
4605e111ed8SAndrew Rybchenko void
ef10_tx_qdesc_tso_create(__in efx_txq_t * etp,__in uint16_t ipv4_id,__in uint32_t tcp_seq,__in uint8_t tcp_flags,__out efx_desc_t * edp)4615e111ed8SAndrew Rybchenko ef10_tx_qdesc_tso_create(
4625e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
4635e111ed8SAndrew Rybchenko __in uint16_t ipv4_id,
4645e111ed8SAndrew Rybchenko __in uint32_t tcp_seq,
4655e111ed8SAndrew Rybchenko __in uint8_t tcp_flags,
4665e111ed8SAndrew Rybchenko __out efx_desc_t *edp)
4675e111ed8SAndrew Rybchenko {
4685e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp))
4695e111ed8SAndrew Rybchenko
4705e111ed8SAndrew Rybchenko EFSYS_PROBE4(tx_desc_tso_create, unsigned int, etp->et_index,
4715e111ed8SAndrew Rybchenko uint16_t, ipv4_id, uint32_t, tcp_seq,
4725e111ed8SAndrew Rybchenko uint8_t, tcp_flags);
4735e111ed8SAndrew Rybchenko
4745e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(edp->ed_eq,
4755e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
4765e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE,
4775e111ed8SAndrew Rybchenko ESE_DZ_TX_OPTION_DESC_TSO,
4785e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_TCP_FLAGS, tcp_flags,
4795e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_IP_ID, ipv4_id,
4805e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
4815e111ed8SAndrew Rybchenko }
4825e111ed8SAndrew Rybchenko
4835e111ed8SAndrew Rybchenko void
ef10_tx_qdesc_tso2_create(__in efx_txq_t * etp,__in uint16_t ipv4_id,__in uint16_t outer_ipv4_id,__in uint32_t tcp_seq,__in uint16_t tcp_mss,__out_ecount (count)efx_desc_t * edp,__in int count)4845e111ed8SAndrew Rybchenko ef10_tx_qdesc_tso2_create(
4855e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
4865e111ed8SAndrew Rybchenko __in uint16_t ipv4_id,
4875e111ed8SAndrew Rybchenko __in uint16_t outer_ipv4_id,
4885e111ed8SAndrew Rybchenko __in uint32_t tcp_seq,
4895e111ed8SAndrew Rybchenko __in uint16_t tcp_mss,
4905e111ed8SAndrew Rybchenko __out_ecount(count) efx_desc_t *edp,
4915e111ed8SAndrew Rybchenko __in int count)
4925e111ed8SAndrew Rybchenko {
4935e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp, count))
4945e111ed8SAndrew Rybchenko
4955e111ed8SAndrew Rybchenko EFSYS_PROBE4(tx_desc_tso2_create, unsigned int, etp->et_index,
4965e111ed8SAndrew Rybchenko uint16_t, ipv4_id, uint32_t, tcp_seq,
4975e111ed8SAndrew Rybchenko uint16_t, tcp_mss);
4985e111ed8SAndrew Rybchenko
4995e111ed8SAndrew Rybchenko EFSYS_ASSERT(count >= EFX_TX_FATSOV2_OPT_NDESCS);
5005e111ed8SAndrew Rybchenko
5015e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(edp[0].ed_eq,
5025e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
5035e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE,
5045e111ed8SAndrew Rybchenko ESE_DZ_TX_OPTION_DESC_TSO,
5055e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_OPTION_TYPE,
5065e111ed8SAndrew Rybchenko ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A,
5075e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_IP_ID, ipv4_id,
5085e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
5095e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_5(edp[1].ed_eq,
5105e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
5115e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE,
5125e111ed8SAndrew Rybchenko ESE_DZ_TX_OPTION_DESC_TSO,
5135e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_OPTION_TYPE,
5145e111ed8SAndrew Rybchenko ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B,
5155e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_TCP_MSS, tcp_mss,
5165e111ed8SAndrew Rybchenko ESF_DZ_TX_TSO_OUTER_IPID, outer_ipv4_id);
5175e111ed8SAndrew Rybchenko }
5185e111ed8SAndrew Rybchenko
5195e111ed8SAndrew Rybchenko void
ef10_tx_qdesc_vlantci_create(__in efx_txq_t * etp,__in uint16_t tci,__out efx_desc_t * edp)5205e111ed8SAndrew Rybchenko ef10_tx_qdesc_vlantci_create(
5215e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
5225e111ed8SAndrew Rybchenko __in uint16_t tci,
5235e111ed8SAndrew Rybchenko __out efx_desc_t *edp)
5245e111ed8SAndrew Rybchenko {
5255e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp))
5265e111ed8SAndrew Rybchenko
5275e111ed8SAndrew Rybchenko EFSYS_PROBE2(tx_desc_vlantci_create, unsigned int, etp->et_index,
5285e111ed8SAndrew Rybchenko uint16_t, tci);
5295e111ed8SAndrew Rybchenko
5305e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_4(edp->ed_eq,
5315e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
5325e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE,
5335e111ed8SAndrew Rybchenko ESE_DZ_TX_OPTION_DESC_VLAN,
5345e111ed8SAndrew Rybchenko ESF_DZ_TX_VLAN_OP, tci ? 1 : 0,
5355e111ed8SAndrew Rybchenko ESF_DZ_TX_VLAN_TAG1, tci);
5365e111ed8SAndrew Rybchenko }
5375e111ed8SAndrew Rybchenko
5385e111ed8SAndrew Rybchenko void
ef10_tx_qdesc_checksum_create(__in efx_txq_t * etp,__in uint16_t flags,__out efx_desc_t * edp)5395e111ed8SAndrew Rybchenko ef10_tx_qdesc_checksum_create(
5405e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
5415e111ed8SAndrew Rybchenko __in uint16_t flags,
5425e111ed8SAndrew Rybchenko __out efx_desc_t *edp)
5435e111ed8SAndrew Rybchenko {
5445e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp));
5455e111ed8SAndrew Rybchenko
5465e111ed8SAndrew Rybchenko EFSYS_PROBE2(tx_desc_checksum_create, unsigned int, etp->et_index,
5475e111ed8SAndrew Rybchenko uint32_t, flags);
5485e111ed8SAndrew Rybchenko
5495e111ed8SAndrew Rybchenko EFX_POPULATE_QWORD_6(edp->ed_eq,
5505e111ed8SAndrew Rybchenko ESF_DZ_TX_DESC_IS_OPT, 1,
5515e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_CRC_CSUM,
5525e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_UDP_TCP_CSUM,
5535e111ed8SAndrew Rybchenko (flags & EFX_TXQ_CKSUM_TCPUDP) ? 1 : 0,
5545e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_IP_CSUM,
5555e111ed8SAndrew Rybchenko (flags & EFX_TXQ_CKSUM_IPV4) ? 1 : 0,
5565e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_INNER_UDP_TCP_CSUM,
5575e111ed8SAndrew Rybchenko (flags & EFX_TXQ_CKSUM_INNER_TCPUDP) ? 1 : 0,
5585e111ed8SAndrew Rybchenko ESF_DZ_TX_OPTION_INNER_IP_CSUM,
5595e111ed8SAndrew Rybchenko (flags & EFX_TXQ_CKSUM_INNER_IPV4) ? 1 : 0);
5605e111ed8SAndrew Rybchenko }
5615e111ed8SAndrew Rybchenko
5625e111ed8SAndrew Rybchenko
5635e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qpace(__in efx_txq_t * etp,__in unsigned int ns)5645e111ed8SAndrew Rybchenko ef10_tx_qpace(
5655e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
5665e111ed8SAndrew Rybchenko __in unsigned int ns)
5675e111ed8SAndrew Rybchenko {
5685e111ed8SAndrew Rybchenko efx_rc_t rc;
5695e111ed8SAndrew Rybchenko
5705e111ed8SAndrew Rybchenko /* FIXME */
5715e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp, ns))
5725e111ed8SAndrew Rybchenko _NOTE(CONSTANTCONDITION)
5735e111ed8SAndrew Rybchenko if (B_FALSE) {
5745e111ed8SAndrew Rybchenko rc = ENOTSUP;
5755e111ed8SAndrew Rybchenko goto fail1;
5765e111ed8SAndrew Rybchenko }
5775e111ed8SAndrew Rybchenko /* FIXME */
5785e111ed8SAndrew Rybchenko
5795e111ed8SAndrew Rybchenko return (0);
5805e111ed8SAndrew Rybchenko
5815e111ed8SAndrew Rybchenko fail1:
5825e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
5835e111ed8SAndrew Rybchenko
5845e111ed8SAndrew Rybchenko return (rc);
5855e111ed8SAndrew Rybchenko }
5865e111ed8SAndrew Rybchenko
5875e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_tx_qflush(__in efx_txq_t * etp)5885e111ed8SAndrew Rybchenko ef10_tx_qflush(
5895e111ed8SAndrew Rybchenko __in efx_txq_t *etp)
5905e111ed8SAndrew Rybchenko {
5915e111ed8SAndrew Rybchenko efx_nic_t *enp = etp->et_enp;
5925e111ed8SAndrew Rybchenko efx_rc_t rc;
5935e111ed8SAndrew Rybchenko
5945e111ed8SAndrew Rybchenko if ((rc = efx_mcdi_fini_txq(enp, etp->et_index)) != 0)
5955e111ed8SAndrew Rybchenko goto fail1;
5965e111ed8SAndrew Rybchenko
5975e111ed8SAndrew Rybchenko return (0);
5985e111ed8SAndrew Rybchenko
5995e111ed8SAndrew Rybchenko fail1:
6005e111ed8SAndrew Rybchenko /*
6015e111ed8SAndrew Rybchenko * EALREADY is not an error, but indicates that the MC has rebooted and
6025e111ed8SAndrew Rybchenko * that the TXQ has already been destroyed. Callers need to know that
6035e111ed8SAndrew Rybchenko * the TXQ flush has completed to avoid waiting until timeout for a
6045e111ed8SAndrew Rybchenko * flush done event that will not be delivered.
6055e111ed8SAndrew Rybchenko */
6065e111ed8SAndrew Rybchenko if (rc != EALREADY)
6075e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
6085e111ed8SAndrew Rybchenko
6095e111ed8SAndrew Rybchenko return (rc);
6105e111ed8SAndrew Rybchenko }
6115e111ed8SAndrew Rybchenko
6125e111ed8SAndrew Rybchenko void
ef10_tx_qenable(__in efx_txq_t * etp)6135e111ed8SAndrew Rybchenko ef10_tx_qenable(
6145e111ed8SAndrew Rybchenko __in efx_txq_t *etp)
6155e111ed8SAndrew Rybchenko {
6165e111ed8SAndrew Rybchenko /* FIXME */
6175e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(etp))
6185e111ed8SAndrew Rybchenko /* FIXME */
6195e111ed8SAndrew Rybchenko }
6205e111ed8SAndrew Rybchenko
6215e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
6225e111ed8SAndrew Rybchenko void
ef10_tx_qstats_update(__in efx_txq_t * etp,__inout_ecount (TX_NQSTATS)efsys_stat_t * stat)6235e111ed8SAndrew Rybchenko ef10_tx_qstats_update(
6245e111ed8SAndrew Rybchenko __in efx_txq_t *etp,
6255e111ed8SAndrew Rybchenko __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
6265e111ed8SAndrew Rybchenko {
6275e111ed8SAndrew Rybchenko unsigned int id;
6285e111ed8SAndrew Rybchenko
6295e111ed8SAndrew Rybchenko for (id = 0; id < TX_NQSTATS; id++) {
6305e111ed8SAndrew Rybchenko efsys_stat_t *essp = &stat[id];
6315e111ed8SAndrew Rybchenko
6325e111ed8SAndrew Rybchenko EFSYS_STAT_INCR(essp, etp->et_stat[id]);
6335e111ed8SAndrew Rybchenko etp->et_stat[id] = 0;
6345e111ed8SAndrew Rybchenko }
6355e111ed8SAndrew Rybchenko }
6365e111ed8SAndrew Rybchenko
6375e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_QSTATS */
6385e111ed8SAndrew Rybchenko
6395e111ed8SAndrew Rybchenko #endif /* EFX_OPTS_EF10() */
640