xref: /dpdk/drivers/common/sfc_efx/base/efx_tx.c (revision 672386c1e9e1f64f7aa3b1360ad22dc737ea8d72)
15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko  *
3*672386c1SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko  * Copyright(c) 2007-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko  */
65e111ed8SAndrew Rybchenko 
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko 
105e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
115e111ed8SAndrew Rybchenko #define	EFX_TX_QSTAT_INCR(_etp, _stat)					\
125e111ed8SAndrew Rybchenko 	do {								\
135e111ed8SAndrew Rybchenko 		(_etp)->et_stat[_stat]++;				\
145e111ed8SAndrew Rybchenko 	_NOTE(CONSTANTCONDITION)					\
155e111ed8SAndrew Rybchenko 	} while (B_FALSE)
165e111ed8SAndrew Rybchenko #else
175e111ed8SAndrew Rybchenko #define	EFX_TX_QSTAT_INCR(_etp, _stat)
185e111ed8SAndrew Rybchenko #endif
195e111ed8SAndrew Rybchenko 
205e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
215e111ed8SAndrew Rybchenko 
225e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
235e111ed8SAndrew Rybchenko siena_tx_init(
245e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp);
255e111ed8SAndrew Rybchenko 
265e111ed8SAndrew Rybchenko static			void
275e111ed8SAndrew Rybchenko siena_tx_fini(
285e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp);
295e111ed8SAndrew Rybchenko 
305e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
315e111ed8SAndrew Rybchenko siena_tx_qcreate(
325e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
335e111ed8SAndrew Rybchenko 	__in		unsigned int index,
345e111ed8SAndrew Rybchenko 	__in		unsigned int label,
355e111ed8SAndrew Rybchenko 	__in		efsys_mem_t *esmp,
365e111ed8SAndrew Rybchenko 	__in		size_t ndescs,
375e111ed8SAndrew Rybchenko 	__in		uint32_t id,
385e111ed8SAndrew Rybchenko 	__in		uint16_t flags,
395e111ed8SAndrew Rybchenko 	__in		efx_evq_t *eep,
405e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp,
415e111ed8SAndrew Rybchenko 	__out		unsigned int *addedp);
425e111ed8SAndrew Rybchenko 
435e111ed8SAndrew Rybchenko static		void
445e111ed8SAndrew Rybchenko siena_tx_qdestroy(
455e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp);
465e111ed8SAndrew Rybchenko 
475e111ed8SAndrew Rybchenko static	__checkReturn		efx_rc_t
485e111ed8SAndrew Rybchenko siena_tx_qpost(
495e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
505e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_buffer_t *eb,
515e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
525e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
535e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp);
545e111ed8SAndrew Rybchenko 
555e111ed8SAndrew Rybchenko static			void
565e111ed8SAndrew Rybchenko siena_tx_qpush(
575e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
585e111ed8SAndrew Rybchenko 	__in	unsigned int added,
595e111ed8SAndrew Rybchenko 	__in	unsigned int pushed);
605e111ed8SAndrew Rybchenko 
615e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
625e111ed8SAndrew Rybchenko siena_tx_qpace(
635e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp,
645e111ed8SAndrew Rybchenko 	__in		unsigned int ns);
655e111ed8SAndrew Rybchenko 
665e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
675e111ed8SAndrew Rybchenko siena_tx_qflush(
685e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp);
695e111ed8SAndrew Rybchenko 
705e111ed8SAndrew Rybchenko static			void
715e111ed8SAndrew Rybchenko siena_tx_qenable(
725e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp);
735e111ed8SAndrew Rybchenko 
745e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
755e111ed8SAndrew Rybchenko siena_tx_qdesc_post(
765e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
775e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_desc_t *ed,
785e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
795e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
805e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp);
815e111ed8SAndrew Rybchenko 
825e111ed8SAndrew Rybchenko 	void
835e111ed8SAndrew Rybchenko siena_tx_qdesc_dma_create(
845e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
855e111ed8SAndrew Rybchenko 	__in	efsys_dma_addr_t addr,
865e111ed8SAndrew Rybchenko 	__in	size_t size,
875e111ed8SAndrew Rybchenko 	__in	boolean_t eop,
885e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp);
895e111ed8SAndrew Rybchenko 
905e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
915e111ed8SAndrew Rybchenko static			void
925e111ed8SAndrew Rybchenko siena_tx_qstats_update(
935e111ed8SAndrew Rybchenko 	__in				efx_txq_t *etp,
945e111ed8SAndrew Rybchenko 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat);
955e111ed8SAndrew Rybchenko #endif
965e111ed8SAndrew Rybchenko 
975e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
985e111ed8SAndrew Rybchenko 
995e111ed8SAndrew Rybchenko 
1005e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
1015e111ed8SAndrew Rybchenko static const efx_tx_ops_t	__efx_tx_siena_ops = {
1025e111ed8SAndrew Rybchenko 	siena_tx_init,				/* etxo_init */
1035e111ed8SAndrew Rybchenko 	siena_tx_fini,				/* etxo_fini */
1045e111ed8SAndrew Rybchenko 	siena_tx_qcreate,			/* etxo_qcreate */
1055e111ed8SAndrew Rybchenko 	siena_tx_qdestroy,			/* etxo_qdestroy */
1065e111ed8SAndrew Rybchenko 	siena_tx_qpost,				/* etxo_qpost */
1075e111ed8SAndrew Rybchenko 	siena_tx_qpush,				/* etxo_qpush */
1085e111ed8SAndrew Rybchenko 	siena_tx_qpace,				/* etxo_qpace */
1095e111ed8SAndrew Rybchenko 	siena_tx_qflush,			/* etxo_qflush */
1105e111ed8SAndrew Rybchenko 	siena_tx_qenable,			/* etxo_qenable */
1115e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qpio_enable */
1125e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qpio_disable */
1135e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qpio_write */
1145e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qpio_post */
1155e111ed8SAndrew Rybchenko 	siena_tx_qdesc_post,			/* etxo_qdesc_post */
1165e111ed8SAndrew Rybchenko 	siena_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
1175e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso_create */
1185e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso2_create */
1195e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_vlantci_create */
1205e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_checksum_create */
1215e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
1225e111ed8SAndrew Rybchenko 	siena_tx_qstats_update,			/* etxo_qstats_update */
1235e111ed8SAndrew Rybchenko #endif
1245e111ed8SAndrew Rybchenko };
1255e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
1265e111ed8SAndrew Rybchenko 
1275e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
1285e111ed8SAndrew Rybchenko static const efx_tx_ops_t	__efx_tx_hunt_ops = {
1295e111ed8SAndrew Rybchenko 	ef10_tx_init,				/* etxo_init */
1305e111ed8SAndrew Rybchenko 	ef10_tx_fini,				/* etxo_fini */
1315e111ed8SAndrew Rybchenko 	ef10_tx_qcreate,			/* etxo_qcreate */
1325e111ed8SAndrew Rybchenko 	ef10_tx_qdestroy,			/* etxo_qdestroy */
1335e111ed8SAndrew Rybchenko 	ef10_tx_qpost,				/* etxo_qpost */
1345e111ed8SAndrew Rybchenko 	ef10_tx_qpush,				/* etxo_qpush */
1355e111ed8SAndrew Rybchenko 	ef10_tx_qpace,				/* etxo_qpace */
1365e111ed8SAndrew Rybchenko 	ef10_tx_qflush,				/* etxo_qflush */
1375e111ed8SAndrew Rybchenko 	ef10_tx_qenable,			/* etxo_qenable */
1385e111ed8SAndrew Rybchenko 	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
1395e111ed8SAndrew Rybchenko 	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
1405e111ed8SAndrew Rybchenko 	ef10_tx_qpio_write,			/* etxo_qpio_write */
1415e111ed8SAndrew Rybchenko 	ef10_tx_qpio_post,			/* etxo_qpio_post */
1425e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
1435e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
1445e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_tso_create,		/* etxo_qdesc_tso_create */
1455e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
1465e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
1475e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_checksum_create,		/* etxo_qdesc_checksum_create */
1485e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
1495e111ed8SAndrew Rybchenko 	ef10_tx_qstats_update,			/* etxo_qstats_update */
1505e111ed8SAndrew Rybchenko #endif
1515e111ed8SAndrew Rybchenko };
1525e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_HUNTINGTON */
1535e111ed8SAndrew Rybchenko 
1545e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
1555e111ed8SAndrew Rybchenko static const efx_tx_ops_t	__efx_tx_medford_ops = {
1565e111ed8SAndrew Rybchenko 	ef10_tx_init,				/* etxo_init */
1575e111ed8SAndrew Rybchenko 	ef10_tx_fini,				/* etxo_fini */
1585e111ed8SAndrew Rybchenko 	ef10_tx_qcreate,			/* etxo_qcreate */
1595e111ed8SAndrew Rybchenko 	ef10_tx_qdestroy,			/* etxo_qdestroy */
1605e111ed8SAndrew Rybchenko 	ef10_tx_qpost,				/* etxo_qpost */
1615e111ed8SAndrew Rybchenko 	ef10_tx_qpush,				/* etxo_qpush */
1625e111ed8SAndrew Rybchenko 	ef10_tx_qpace,				/* etxo_qpace */
1635e111ed8SAndrew Rybchenko 	ef10_tx_qflush,				/* etxo_qflush */
1645e111ed8SAndrew Rybchenko 	ef10_tx_qenable,			/* etxo_qenable */
1655e111ed8SAndrew Rybchenko 	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
1665e111ed8SAndrew Rybchenko 	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
1675e111ed8SAndrew Rybchenko 	ef10_tx_qpio_write,			/* etxo_qpio_write */
1685e111ed8SAndrew Rybchenko 	ef10_tx_qpio_post,			/* etxo_qpio_post */
1695e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
1705e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
1715e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso_create */
1725e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
1735e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
1745e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_checksum_create,		/* etxo_qdesc_checksum_create */
1755e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
1765e111ed8SAndrew Rybchenko 	ef10_tx_qstats_update,			/* etxo_qstats_update */
1775e111ed8SAndrew Rybchenko #endif
1785e111ed8SAndrew Rybchenko };
1795e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD */
1805e111ed8SAndrew Rybchenko 
1815e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
1825e111ed8SAndrew Rybchenko static const efx_tx_ops_t	__efx_tx_medford2_ops = {
1835e111ed8SAndrew Rybchenko 	ef10_tx_init,				/* etxo_init */
1845e111ed8SAndrew Rybchenko 	ef10_tx_fini,				/* etxo_fini */
1855e111ed8SAndrew Rybchenko 	ef10_tx_qcreate,			/* etxo_qcreate */
1865e111ed8SAndrew Rybchenko 	ef10_tx_qdestroy,			/* etxo_qdestroy */
1875e111ed8SAndrew Rybchenko 	ef10_tx_qpost,				/* etxo_qpost */
1885e111ed8SAndrew Rybchenko 	ef10_tx_qpush,				/* etxo_qpush */
1895e111ed8SAndrew Rybchenko 	ef10_tx_qpace,				/* etxo_qpace */
1905e111ed8SAndrew Rybchenko 	ef10_tx_qflush,				/* etxo_qflush */
1915e111ed8SAndrew Rybchenko 	ef10_tx_qenable,			/* etxo_qenable */
1925e111ed8SAndrew Rybchenko 	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
1935e111ed8SAndrew Rybchenko 	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
1945e111ed8SAndrew Rybchenko 	ef10_tx_qpio_write,			/* etxo_qpio_write */
1955e111ed8SAndrew Rybchenko 	ef10_tx_qpio_post,			/* etxo_qpio_post */
1965e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
1975e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
1985e111ed8SAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso_create */
1995e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
2005e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
2015e111ed8SAndrew Rybchenko 	ef10_tx_qdesc_checksum_create,		/* etxo_qdesc_checksum_create */
2025e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
2035e111ed8SAndrew Rybchenko 	ef10_tx_qstats_update,			/* etxo_qstats_update */
2045e111ed8SAndrew Rybchenko #endif
2055e111ed8SAndrew Rybchenko };
2065e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD2 */
2075e111ed8SAndrew Rybchenko 
2084fd0181fSAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
2094fd0181fSAndrew Rybchenko static const efx_tx_ops_t	__efx_tx_rhead_ops = {
2104fd0181fSAndrew Rybchenko 	rhead_tx_init,				/* etxo_init */
2114fd0181fSAndrew Rybchenko 	rhead_tx_fini,				/* etxo_fini */
2124fd0181fSAndrew Rybchenko 	rhead_tx_qcreate,			/* etxo_qcreate */
2134fd0181fSAndrew Rybchenko 	rhead_tx_qdestroy,			/* etxo_qdestroy */
2144fd0181fSAndrew Rybchenko 	rhead_tx_qpost,				/* etxo_qpost */
2154fd0181fSAndrew Rybchenko 	rhead_tx_qpush,				/* etxo_qpush */
2164fd0181fSAndrew Rybchenko 	rhead_tx_qpace,				/* etxo_qpace */
2174fd0181fSAndrew Rybchenko 	rhead_tx_qflush,			/* etxo_qflush */
2184fd0181fSAndrew Rybchenko 	rhead_tx_qenable,			/* etxo_qenable */
2194fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qpio_enable */
2204fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qpio_disable */
2214fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qpio_write */
2224fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qpio_post */
2234fd0181fSAndrew Rybchenko 	rhead_tx_qdesc_post,			/* etxo_qdesc_post */
2244fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qdesc_dma_create */
2254fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso_create */
2264fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qdesc_tso2_create */
2274fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qdesc_vlantci_create */
2284fd0181fSAndrew Rybchenko 	NULL,					/* etxo_qdesc_checksum_create */
2294fd0181fSAndrew Rybchenko #if EFSYS_OPT_QSTATS
2304fd0181fSAndrew Rybchenko 	rhead_tx_qstats_update,			/* etxo_qstats_update */
2314fd0181fSAndrew Rybchenko #endif
2324fd0181fSAndrew Rybchenko };
2334fd0181fSAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD */
2344fd0181fSAndrew Rybchenko 
2355e111ed8SAndrew Rybchenko 
2365e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_init(__in efx_nic_t * enp)2375e111ed8SAndrew Rybchenko efx_tx_init(
2385e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
2395e111ed8SAndrew Rybchenko {
2405e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop;
2415e111ed8SAndrew Rybchenko 	efx_rc_t rc;
2425e111ed8SAndrew Rybchenko 
2435e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
2445e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
2455e111ed8SAndrew Rybchenko 
2465e111ed8SAndrew Rybchenko 	if (!(enp->en_mod_flags & EFX_MOD_EV)) {
2475e111ed8SAndrew Rybchenko 		rc = EINVAL;
2485e111ed8SAndrew Rybchenko 		goto fail1;
2495e111ed8SAndrew Rybchenko 	}
2505e111ed8SAndrew Rybchenko 
2515e111ed8SAndrew Rybchenko 	if (enp->en_mod_flags & EFX_MOD_TX) {
2525e111ed8SAndrew Rybchenko 		rc = EINVAL;
2535e111ed8SAndrew Rybchenko 		goto fail2;
2545e111ed8SAndrew Rybchenko 	}
2555e111ed8SAndrew Rybchenko 
2565e111ed8SAndrew Rybchenko 	switch (enp->en_family) {
2575e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
2585e111ed8SAndrew Rybchenko 	case EFX_FAMILY_SIENA:
2595e111ed8SAndrew Rybchenko 		etxop = &__efx_tx_siena_ops;
2605e111ed8SAndrew Rybchenko 		break;
2615e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
2625e111ed8SAndrew Rybchenko 
2635e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
2645e111ed8SAndrew Rybchenko 	case EFX_FAMILY_HUNTINGTON:
2655e111ed8SAndrew Rybchenko 		etxop = &__efx_tx_hunt_ops;
2665e111ed8SAndrew Rybchenko 		break;
2675e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_HUNTINGTON */
2685e111ed8SAndrew Rybchenko 
2695e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
2705e111ed8SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD:
2715e111ed8SAndrew Rybchenko 		etxop = &__efx_tx_medford_ops;
2725e111ed8SAndrew Rybchenko 		break;
2735e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD */
2745e111ed8SAndrew Rybchenko 
2755e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
2765e111ed8SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD2:
2775e111ed8SAndrew Rybchenko 		etxop = &__efx_tx_medford2_ops;
2785e111ed8SAndrew Rybchenko 		break;
2795e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD2 */
2805e111ed8SAndrew Rybchenko 
2814fd0181fSAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
2824fd0181fSAndrew Rybchenko 	case EFX_FAMILY_RIVERHEAD:
2834fd0181fSAndrew Rybchenko 		etxop = &__efx_tx_rhead_ops;
2844fd0181fSAndrew Rybchenko 		break;
2854fd0181fSAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD */
2864fd0181fSAndrew Rybchenko 
2875e111ed8SAndrew Rybchenko 	default:
2885e111ed8SAndrew Rybchenko 		EFSYS_ASSERT(0);
2895e111ed8SAndrew Rybchenko 		rc = ENOTSUP;
2905e111ed8SAndrew Rybchenko 		goto fail3;
2915e111ed8SAndrew Rybchenko 	}
2925e111ed8SAndrew Rybchenko 
2935e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
2945e111ed8SAndrew Rybchenko 
2955e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_init(enp)) != 0)
2965e111ed8SAndrew Rybchenko 		goto fail4;
2975e111ed8SAndrew Rybchenko 
2985e111ed8SAndrew Rybchenko 	enp->en_etxop = etxop;
2995e111ed8SAndrew Rybchenko 	enp->en_mod_flags |= EFX_MOD_TX;
3005e111ed8SAndrew Rybchenko 	return (0);
3015e111ed8SAndrew Rybchenko 
3025e111ed8SAndrew Rybchenko fail4:
3035e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail4);
3045e111ed8SAndrew Rybchenko fail3:
3055e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
3065e111ed8SAndrew Rybchenko fail2:
3075e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
3085e111ed8SAndrew Rybchenko fail1:
3095e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3105e111ed8SAndrew Rybchenko 
3115e111ed8SAndrew Rybchenko 	enp->en_etxop = NULL;
3125e111ed8SAndrew Rybchenko 	enp->en_mod_flags &= ~EFX_MOD_TX;
3135e111ed8SAndrew Rybchenko 	return (rc);
3145e111ed8SAndrew Rybchenko }
3155e111ed8SAndrew Rybchenko 
3165e111ed8SAndrew Rybchenko 			void
efx_tx_fini(__in efx_nic_t * enp)3175e111ed8SAndrew Rybchenko efx_tx_fini(
3185e111ed8SAndrew Rybchenko 	__in	efx_nic_t *enp)
3195e111ed8SAndrew Rybchenko {
3205e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
3215e111ed8SAndrew Rybchenko 
3225e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
3235e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
3245e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
3255e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
3265e111ed8SAndrew Rybchenko 
3275e111ed8SAndrew Rybchenko 	etxop->etxo_fini(enp);
3285e111ed8SAndrew Rybchenko 
3295e111ed8SAndrew Rybchenko 	enp->en_etxop = NULL;
3305e111ed8SAndrew Rybchenko 	enp->en_mod_flags &= ~EFX_MOD_TX;
3315e111ed8SAndrew Rybchenko }
3325e111ed8SAndrew Rybchenko 
3335e111ed8SAndrew Rybchenko 	__checkReturn	size_t
efx_txq_size(__in const efx_nic_t * enp,__in unsigned int ndescs)3345e111ed8SAndrew Rybchenko efx_txq_size(
3355e111ed8SAndrew Rybchenko 	__in	const efx_nic_t *enp,
3365e111ed8SAndrew Rybchenko 	__in	unsigned int ndescs)
3375e111ed8SAndrew Rybchenko {
3385e111ed8SAndrew Rybchenko 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
3395e111ed8SAndrew Rybchenko 
3405e111ed8SAndrew Rybchenko 	return (ndescs * encp->enc_tx_desc_size);
3415e111ed8SAndrew Rybchenko }
3425e111ed8SAndrew Rybchenko 
3435e111ed8SAndrew Rybchenko 	__checkReturn	unsigned int
efx_txq_nbufs(__in const efx_nic_t * enp,__in unsigned int ndescs)3445e111ed8SAndrew Rybchenko efx_txq_nbufs(
3455e111ed8SAndrew Rybchenko 	__in	const efx_nic_t *enp,
3465e111ed8SAndrew Rybchenko 	__in	unsigned int ndescs)
3475e111ed8SAndrew Rybchenko {
3485e111ed8SAndrew Rybchenko 	return (EFX_DIV_ROUND_UP(efx_txq_size(enp, ndescs), EFX_BUF_SIZE));
3495e111ed8SAndrew Rybchenko }
3505e111ed8SAndrew Rybchenko 
3515e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_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,__deref_out efx_txq_t ** etpp,__out unsigned int * addedp)3525e111ed8SAndrew Rybchenko efx_tx_qcreate(
3535e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
3545e111ed8SAndrew Rybchenko 	__in		unsigned int index,
3555e111ed8SAndrew Rybchenko 	__in		unsigned int label,
3565e111ed8SAndrew Rybchenko 	__in		efsys_mem_t *esmp,
3575e111ed8SAndrew Rybchenko 	__in		size_t ndescs,
3585e111ed8SAndrew Rybchenko 	__in		uint32_t id,
3595e111ed8SAndrew Rybchenko 	__in		uint16_t flags,
3605e111ed8SAndrew Rybchenko 	__in		efx_evq_t *eep,
3615e111ed8SAndrew Rybchenko 	__deref_out	efx_txq_t **etpp,
3625e111ed8SAndrew Rybchenko 	__out		unsigned int *addedp)
3635e111ed8SAndrew Rybchenko {
3645e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
3655e111ed8SAndrew Rybchenko 	efx_txq_t *etp;
3665e111ed8SAndrew Rybchenko 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
3675e111ed8SAndrew Rybchenko 	efx_rc_t rc;
3685e111ed8SAndrew Rybchenko 
3695e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
3705e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
3715e111ed8SAndrew Rybchenko 
3725e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <,
3735e111ed8SAndrew Rybchenko 	    enp->en_nic_cfg.enc_txq_limit);
3745e111ed8SAndrew Rybchenko 
3755e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
3765e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(ISP2(encp->enc_txq_min_ndescs));
3775e111ed8SAndrew Rybchenko 
3785e111ed8SAndrew Rybchenko 	if (!ISP2(ndescs) ||
3795e111ed8SAndrew Rybchenko 	    ndescs < encp->enc_txq_min_ndescs ||
3805e111ed8SAndrew Rybchenko 	    ndescs > encp->enc_txq_max_ndescs) {
3815e111ed8SAndrew Rybchenko 		rc = EINVAL;
3825e111ed8SAndrew Rybchenko 		goto fail1;
3835e111ed8SAndrew Rybchenko 	}
3845e111ed8SAndrew Rybchenko 
3855e111ed8SAndrew Rybchenko 	/* Allocate an TXQ object */
3865e111ed8SAndrew Rybchenko 	EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
3875e111ed8SAndrew Rybchenko 
3885e111ed8SAndrew Rybchenko 	if (etp == NULL) {
3895e111ed8SAndrew Rybchenko 		rc = ENOMEM;
3905e111ed8SAndrew Rybchenko 		goto fail2;
3915e111ed8SAndrew Rybchenko 	}
3925e111ed8SAndrew Rybchenko 
3935e111ed8SAndrew Rybchenko 	etp->et_magic = EFX_TXQ_MAGIC;
3945e111ed8SAndrew Rybchenko 	etp->et_enp = enp;
3955e111ed8SAndrew Rybchenko 	etp->et_index = index;
3965e111ed8SAndrew Rybchenko 	etp->et_mask = ndescs - 1;
3975e111ed8SAndrew Rybchenko 	etp->et_esmp = esmp;
3985e111ed8SAndrew Rybchenko 
3995e111ed8SAndrew Rybchenko 	/* Initial descriptor index may be modified by etxo_qcreate */
4005e111ed8SAndrew Rybchenko 	*addedp = 0;
4015e111ed8SAndrew Rybchenko 
4025e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
4035e111ed8SAndrew Rybchenko 	    ndescs, id, flags, eep, etp, addedp)) != 0)
4045e111ed8SAndrew Rybchenko 		goto fail3;
4055e111ed8SAndrew Rybchenko 
4065e111ed8SAndrew Rybchenko 	enp->en_tx_qcount++;
4075e111ed8SAndrew Rybchenko 	*etpp = etp;
4085e111ed8SAndrew Rybchenko 
4095e111ed8SAndrew Rybchenko 	return (0);
4105e111ed8SAndrew Rybchenko 
4115e111ed8SAndrew Rybchenko fail3:
4125e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
4135e111ed8SAndrew Rybchenko 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
4145e111ed8SAndrew Rybchenko fail2:
4155e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
4165e111ed8SAndrew Rybchenko fail1:
4175e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4185e111ed8SAndrew Rybchenko 	return (rc);
4195e111ed8SAndrew Rybchenko }
4205e111ed8SAndrew Rybchenko 
4215e111ed8SAndrew Rybchenko 		void
efx_tx_qdestroy(__in efx_txq_t * etp)4225e111ed8SAndrew Rybchenko efx_tx_qdestroy(
4235e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
4245e111ed8SAndrew Rybchenko {
4255e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
4265e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
4275e111ed8SAndrew Rybchenko 
4285e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
4295e111ed8SAndrew Rybchenko 
4305e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_tx_qcount != 0);
4315e111ed8SAndrew Rybchenko 	--enp->en_tx_qcount;
4325e111ed8SAndrew Rybchenko 
4335e111ed8SAndrew Rybchenko 	etxop->etxo_qdestroy(etp);
4345e111ed8SAndrew Rybchenko 
4355e111ed8SAndrew Rybchenko 	/* Free the TXQ object */
4365e111ed8SAndrew Rybchenko 	EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
4375e111ed8SAndrew Rybchenko }
4385e111ed8SAndrew Rybchenko 
4395e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_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)4405e111ed8SAndrew Rybchenko efx_tx_qpost(
4415e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
4425e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_buffer_t *eb,
4435e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
4445e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
4455e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp)
4465e111ed8SAndrew Rybchenko {
4475e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
4485e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
4495e111ed8SAndrew Rybchenko 	efx_rc_t rc;
4505e111ed8SAndrew Rybchenko 
4515e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
4525e111ed8SAndrew Rybchenko 
4535e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_qpost(etp, eb, ndescs, completed, addedp)) != 0)
4545e111ed8SAndrew Rybchenko 		goto fail1;
4555e111ed8SAndrew Rybchenko 
4565e111ed8SAndrew Rybchenko 	return (0);
4575e111ed8SAndrew Rybchenko 
4585e111ed8SAndrew Rybchenko fail1:
4595e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4605e111ed8SAndrew Rybchenko 	return (rc);
4615e111ed8SAndrew Rybchenko }
4625e111ed8SAndrew Rybchenko 
4635e111ed8SAndrew Rybchenko 			void
efx_tx_qpush(__in efx_txq_t * etp,__in unsigned int added,__in unsigned int pushed)4645e111ed8SAndrew Rybchenko efx_tx_qpush(
4655e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
4665e111ed8SAndrew Rybchenko 	__in	unsigned int added,
4675e111ed8SAndrew Rybchenko 	__in	unsigned int pushed)
4685e111ed8SAndrew Rybchenko {
4695e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
4705e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
4715e111ed8SAndrew Rybchenko 
4725e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
4735e111ed8SAndrew Rybchenko 
4745e111ed8SAndrew Rybchenko 	etxop->etxo_qpush(etp, added, pushed);
4755e111ed8SAndrew Rybchenko }
4765e111ed8SAndrew Rybchenko 
4775e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_qpace(__in efx_txq_t * etp,__in unsigned int ns)4785e111ed8SAndrew Rybchenko efx_tx_qpace(
4795e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp,
4805e111ed8SAndrew Rybchenko 	__in		unsigned int ns)
4815e111ed8SAndrew Rybchenko {
4825e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
4835e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
4845e111ed8SAndrew Rybchenko 	efx_rc_t rc;
4855e111ed8SAndrew Rybchenko 
4865e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
4875e111ed8SAndrew Rybchenko 
4885e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
4895e111ed8SAndrew Rybchenko 		goto fail1;
4905e111ed8SAndrew Rybchenko 
4915e111ed8SAndrew Rybchenko 	return (0);
4925e111ed8SAndrew Rybchenko 
4935e111ed8SAndrew Rybchenko fail1:
4945e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4955e111ed8SAndrew Rybchenko 	return (rc);
4965e111ed8SAndrew Rybchenko }
4975e111ed8SAndrew Rybchenko 
4985e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_qflush(__in efx_txq_t * etp)4995e111ed8SAndrew Rybchenko efx_tx_qflush(
5005e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
5015e111ed8SAndrew Rybchenko {
5025e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
5035e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
5045e111ed8SAndrew Rybchenko 	efx_rc_t rc;
5055e111ed8SAndrew Rybchenko 
5065e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
5075e111ed8SAndrew Rybchenko 
5085e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_qflush(etp)) != 0)
5095e111ed8SAndrew Rybchenko 		goto fail1;
5105e111ed8SAndrew Rybchenko 
5115e111ed8SAndrew Rybchenko 	return (0);
5125e111ed8SAndrew Rybchenko 
5135e111ed8SAndrew Rybchenko fail1:
5145e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5155e111ed8SAndrew Rybchenko 	return (rc);
5165e111ed8SAndrew Rybchenko }
5175e111ed8SAndrew Rybchenko 
5185e111ed8SAndrew Rybchenko 			void
efx_tx_qenable(__in efx_txq_t * etp)5195e111ed8SAndrew Rybchenko efx_tx_qenable(
5205e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
5215e111ed8SAndrew Rybchenko {
5225e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
5235e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
5245e111ed8SAndrew Rybchenko 
5255e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
5265e111ed8SAndrew Rybchenko 
5275e111ed8SAndrew Rybchenko 	etxop->etxo_qenable(etp);
5285e111ed8SAndrew Rybchenko }
5295e111ed8SAndrew Rybchenko 
5305e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_qpio_enable(__in efx_txq_t * etp)5315e111ed8SAndrew Rybchenko efx_tx_qpio_enable(
5325e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
5335e111ed8SAndrew Rybchenko {
5345e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
5355e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
5365e111ed8SAndrew Rybchenko 	efx_rc_t rc;
5375e111ed8SAndrew Rybchenko 
5385e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
5395e111ed8SAndrew Rybchenko 
5405e111ed8SAndrew Rybchenko 	if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
5415e111ed8SAndrew Rybchenko 		rc = ENOTSUP;
5425e111ed8SAndrew Rybchenko 		goto fail1;
5435e111ed8SAndrew Rybchenko 	}
5445e111ed8SAndrew Rybchenko 	if (etxop->etxo_qpio_enable == NULL) {
5455e111ed8SAndrew Rybchenko 		rc = ENOTSUP;
5465e111ed8SAndrew Rybchenko 		goto fail2;
5475e111ed8SAndrew Rybchenko 	}
5485e111ed8SAndrew Rybchenko 	if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
5495e111ed8SAndrew Rybchenko 		goto fail3;
5505e111ed8SAndrew Rybchenko 
5515e111ed8SAndrew Rybchenko 	return (0);
5525e111ed8SAndrew Rybchenko 
5535e111ed8SAndrew Rybchenko fail3:
5545e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
5555e111ed8SAndrew Rybchenko fail2:
5565e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
5575e111ed8SAndrew Rybchenko fail1:
5585e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5595e111ed8SAndrew Rybchenko 	return (rc);
5605e111ed8SAndrew Rybchenko }
5615e111ed8SAndrew Rybchenko 
5625e111ed8SAndrew Rybchenko 		void
efx_tx_qpio_disable(__in efx_txq_t * etp)5635e111ed8SAndrew Rybchenko efx_tx_qpio_disable(
5645e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
5655e111ed8SAndrew Rybchenko {
5665e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
5675e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
5685e111ed8SAndrew Rybchenko 
5695e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
5705e111ed8SAndrew Rybchenko 
5715e111ed8SAndrew Rybchenko 	if (etxop->etxo_qpio_disable != NULL)
5725e111ed8SAndrew Rybchenko 		etxop->etxo_qpio_disable(etp);
5735e111ed8SAndrew Rybchenko }
5745e111ed8SAndrew Rybchenko 
5755e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_qpio_write(__in efx_txq_t * etp,__in_ecount (buf_length)uint8_t * buffer,__in size_t buf_length,__in size_t pio_buf_offset)5765e111ed8SAndrew Rybchenko efx_tx_qpio_write(
5775e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
5785e111ed8SAndrew Rybchenko 	__in_ecount(buf_length)	uint8_t *buffer,
5795e111ed8SAndrew Rybchenko 	__in			size_t buf_length,
5805e111ed8SAndrew Rybchenko 	__in			size_t pio_buf_offset)
5815e111ed8SAndrew Rybchenko {
5825e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
5835e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
5845e111ed8SAndrew Rybchenko 	efx_rc_t rc;
5855e111ed8SAndrew Rybchenko 
5865e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
5875e111ed8SAndrew Rybchenko 
5885e111ed8SAndrew Rybchenko 	if (etxop->etxo_qpio_write != NULL) {
5895e111ed8SAndrew Rybchenko 		if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
5905e111ed8SAndrew Rybchenko 						pio_buf_offset)) != 0)
5915e111ed8SAndrew Rybchenko 			goto fail1;
5925e111ed8SAndrew Rybchenko 		return (0);
5935e111ed8SAndrew Rybchenko 	}
5945e111ed8SAndrew Rybchenko 
5955e111ed8SAndrew Rybchenko 	return (ENOTSUP);
5965e111ed8SAndrew Rybchenko 
5975e111ed8SAndrew Rybchenko fail1:
5985e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5995e111ed8SAndrew Rybchenko 	return (rc);
6005e111ed8SAndrew Rybchenko }
6015e111ed8SAndrew Rybchenko 
6025e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_tx_qpio_post(__in efx_txq_t * etp,__in size_t pkt_length,__in unsigned int completed,__inout unsigned int * addedp)6035e111ed8SAndrew Rybchenko efx_tx_qpio_post(
6045e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
6055e111ed8SAndrew Rybchenko 	__in			size_t pkt_length,
6065e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
6075e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp)
6085e111ed8SAndrew Rybchenko {
6095e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
6105e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
6115e111ed8SAndrew Rybchenko 	efx_rc_t rc;
6125e111ed8SAndrew Rybchenko 
6135e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
6145e111ed8SAndrew Rybchenko 
6155e111ed8SAndrew Rybchenko 	if (etxop->etxo_qpio_post != NULL) {
6165e111ed8SAndrew Rybchenko 		if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
6175e111ed8SAndrew Rybchenko 						addedp)) != 0)
6185e111ed8SAndrew Rybchenko 			goto fail1;
6195e111ed8SAndrew Rybchenko 		return (0);
6205e111ed8SAndrew Rybchenko 	}
6215e111ed8SAndrew Rybchenko 
6225e111ed8SAndrew Rybchenko 	return (ENOTSUP);
6235e111ed8SAndrew Rybchenko 
6245e111ed8SAndrew Rybchenko fail1:
6255e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
6265e111ed8SAndrew Rybchenko 	return (rc);
6275e111ed8SAndrew Rybchenko }
6285e111ed8SAndrew Rybchenko 
6295e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_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)6305e111ed8SAndrew Rybchenko efx_tx_qdesc_post(
6315e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
6325e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_desc_t *ed,
6335e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
6345e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
6355e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp)
6365e111ed8SAndrew Rybchenko {
6375e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
6385e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
6395e111ed8SAndrew Rybchenko 
6405e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
6415e111ed8SAndrew Rybchenko 
6425e111ed8SAndrew Rybchenko 	return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
6435e111ed8SAndrew Rybchenko }
6445e111ed8SAndrew Rybchenko 
6455e111ed8SAndrew Rybchenko 	void
efx_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)6465e111ed8SAndrew Rybchenko efx_tx_qdesc_dma_create(
6475e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
6485e111ed8SAndrew Rybchenko 	__in	efsys_dma_addr_t addr,
6495e111ed8SAndrew Rybchenko 	__in	size_t size,
6505e111ed8SAndrew Rybchenko 	__in	boolean_t eop,
6515e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp)
6525e111ed8SAndrew Rybchenko {
6535e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
6545e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
6555e111ed8SAndrew Rybchenko 
6565e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
6575e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
6585e111ed8SAndrew Rybchenko 
6595e111ed8SAndrew Rybchenko 	etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
6605e111ed8SAndrew Rybchenko }
6615e111ed8SAndrew Rybchenko 
6625e111ed8SAndrew Rybchenko 	void
efx_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)6635e111ed8SAndrew Rybchenko efx_tx_qdesc_tso_create(
6645e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
6655e111ed8SAndrew Rybchenko 	__in	uint16_t ipv4_id,
6665e111ed8SAndrew Rybchenko 	__in	uint32_t tcp_seq,
6675e111ed8SAndrew Rybchenko 	__in	uint8_t  tcp_flags,
6685e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp)
6695e111ed8SAndrew Rybchenko {
6705e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
6715e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
6725e111ed8SAndrew Rybchenko 
6735e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
6745e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
6755e111ed8SAndrew Rybchenko 
6765e111ed8SAndrew Rybchenko 	etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
6775e111ed8SAndrew Rybchenko }
6785e111ed8SAndrew Rybchenko 
6795e111ed8SAndrew Rybchenko 	void
efx_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 mss,__out_ecount (count)efx_desc_t * edp,__in int count)6805e111ed8SAndrew Rybchenko efx_tx_qdesc_tso2_create(
6815e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
6825e111ed8SAndrew Rybchenko 	__in			uint16_t ipv4_id,
6835e111ed8SAndrew Rybchenko 	__in			uint16_t outer_ipv4_id,
6845e111ed8SAndrew Rybchenko 	__in			uint32_t tcp_seq,
6855e111ed8SAndrew Rybchenko 	__in			uint16_t mss,
6865e111ed8SAndrew Rybchenko 	__out_ecount(count)	efx_desc_t *edp,
6875e111ed8SAndrew Rybchenko 	__in			int count)
6885e111ed8SAndrew Rybchenko {
6895e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
6905e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
6915e111ed8SAndrew Rybchenko 
6925e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
6935e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
6945e111ed8SAndrew Rybchenko 
6955e111ed8SAndrew Rybchenko 	etxop->etxo_qdesc_tso2_create(etp, ipv4_id, outer_ipv4_id,
6965e111ed8SAndrew Rybchenko 	    tcp_seq, mss, edp, count);
6975e111ed8SAndrew Rybchenko }
6985e111ed8SAndrew Rybchenko 
6995e111ed8SAndrew Rybchenko 	void
efx_tx_qdesc_vlantci_create(__in efx_txq_t * etp,__in uint16_t tci,__out efx_desc_t * edp)7005e111ed8SAndrew Rybchenko efx_tx_qdesc_vlantci_create(
7015e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
7025e111ed8SAndrew Rybchenko 	__in	uint16_t tci,
7035e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp)
7045e111ed8SAndrew Rybchenko {
7055e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
7065e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
7075e111ed8SAndrew Rybchenko 
7085e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
7095e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
7105e111ed8SAndrew Rybchenko 
7115e111ed8SAndrew Rybchenko 	etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
7125e111ed8SAndrew Rybchenko }
7135e111ed8SAndrew Rybchenko 
7145e111ed8SAndrew Rybchenko 	void
efx_tx_qdesc_checksum_create(__in efx_txq_t * etp,__in uint16_t flags,__out efx_desc_t * edp)7155e111ed8SAndrew Rybchenko efx_tx_qdesc_checksum_create(
7165e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
7175e111ed8SAndrew Rybchenko 	__in	uint16_t flags,
7185e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp)
7195e111ed8SAndrew Rybchenko {
7205e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
7215e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
7225e111ed8SAndrew Rybchenko 
7235e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
7245e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(etxop->etxo_qdesc_checksum_create != NULL);
7255e111ed8SAndrew Rybchenko 
7265e111ed8SAndrew Rybchenko 	etxop->etxo_qdesc_checksum_create(etp, flags, edp);
7275e111ed8SAndrew Rybchenko }
7285e111ed8SAndrew Rybchenko 
7295e111ed8SAndrew Rybchenko 
7305e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
7315e111ed8SAndrew Rybchenko 			void
efx_tx_qstats_update(__in efx_txq_t * etp,__inout_ecount (TX_NQSTATS)efsys_stat_t * stat)7325e111ed8SAndrew Rybchenko efx_tx_qstats_update(
7335e111ed8SAndrew Rybchenko 	__in				efx_txq_t *etp,
7345e111ed8SAndrew Rybchenko 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
7355e111ed8SAndrew Rybchenko {
7365e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
7375e111ed8SAndrew Rybchenko 	const efx_tx_ops_t *etxop = enp->en_etxop;
7385e111ed8SAndrew Rybchenko 
7395e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
7405e111ed8SAndrew Rybchenko 
7415e111ed8SAndrew Rybchenko 	etxop->etxo_qstats_update(etp, stat);
7425e111ed8SAndrew Rybchenko }
7435e111ed8SAndrew Rybchenko #endif
7445e111ed8SAndrew Rybchenko 
7455e111ed8SAndrew Rybchenko 
7465e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
7475e111ed8SAndrew Rybchenko 
7485e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
siena_tx_init(__in efx_nic_t * enp)7495e111ed8SAndrew Rybchenko siena_tx_init(
7505e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
7515e111ed8SAndrew Rybchenko {
7525e111ed8SAndrew Rybchenko 	efx_oword_t oword;
7535e111ed8SAndrew Rybchenko 
7545e111ed8SAndrew Rybchenko 	/*
7555e111ed8SAndrew Rybchenko 	 * Disable the timer-based TX DMA backoff and allow TX DMA to be
7565e111ed8SAndrew Rybchenko 	 * controlled by the RX FIFO fill level (although always allow a
7575e111ed8SAndrew Rybchenko 	 * minimal trickle).
7585e111ed8SAndrew Rybchenko 	 */
7595e111ed8SAndrew Rybchenko 	EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
7605e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
7615e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
7625e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
7635e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
7645e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
7655e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
7665e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
7675e111ed8SAndrew Rybchenko 
7685e111ed8SAndrew Rybchenko 	/*
7695e111ed8SAndrew Rybchenko 	 * Filter all packets less than 14 bytes to avoid parsing
7705e111ed8SAndrew Rybchenko 	 * errors.
7715e111ed8SAndrew Rybchenko 	 */
7725e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
7735e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
7745e111ed8SAndrew Rybchenko 
7755e111ed8SAndrew Rybchenko 	/*
7765e111ed8SAndrew Rybchenko 	 * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
7775e111ed8SAndrew Rybchenko 	 * descriptors (which is bad).
7785e111ed8SAndrew Rybchenko 	 */
7795e111ed8SAndrew Rybchenko 	EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
7805e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
7815e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
7825e111ed8SAndrew Rybchenko 
7835e111ed8SAndrew Rybchenko 	return (0);
7845e111ed8SAndrew Rybchenko }
7855e111ed8SAndrew Rybchenko 
7865e111ed8SAndrew Rybchenko #define	EFX_TX_DESC(_etp, _addr, _size, _eop, _added)			\
7875e111ed8SAndrew Rybchenko 	do {								\
7885e111ed8SAndrew Rybchenko 		unsigned int id;					\
7895e111ed8SAndrew Rybchenko 		size_t offset;						\
7905e111ed8SAndrew Rybchenko 		efx_qword_t qword;					\
7915e111ed8SAndrew Rybchenko 									\
7925e111ed8SAndrew Rybchenko 		id = (_added)++ & (_etp)->et_mask;			\
7935e111ed8SAndrew Rybchenko 		offset = id * sizeof (efx_qword_t);			\
7945e111ed8SAndrew Rybchenko 									\
7955e111ed8SAndrew Rybchenko 		EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index,	\
7965e111ed8SAndrew Rybchenko 		    unsigned int, id, efsys_dma_addr_t, (_addr),	\
7975e111ed8SAndrew Rybchenko 		    size_t, (_size), boolean_t, (_eop));		\
7985e111ed8SAndrew Rybchenko 									\
7995e111ed8SAndrew Rybchenko 		EFX_POPULATE_QWORD_4(qword,				\
8005e111ed8SAndrew Rybchenko 		    FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1,			\
8015e111ed8SAndrew Rybchenko 		    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size),	\
8025e111ed8SAndrew Rybchenko 		    FSF_AZ_TX_KER_BUF_ADDR_DW0,				\
8035e111ed8SAndrew Rybchenko 		    (uint32_t)((_addr) & 0xffffffff),			\
8045e111ed8SAndrew Rybchenko 		    FSF_AZ_TX_KER_BUF_ADDR_DW1,				\
8055e111ed8SAndrew Rybchenko 		    (uint32_t)((_addr) >> 32));				\
8065e111ed8SAndrew Rybchenko 		EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword);	\
8075e111ed8SAndrew Rybchenko 									\
8085e111ed8SAndrew Rybchenko 		_NOTE(CONSTANTCONDITION)				\
8095e111ed8SAndrew Rybchenko 	} while (B_FALSE)
8105e111ed8SAndrew Rybchenko 
8115e111ed8SAndrew Rybchenko static	__checkReturn		efx_rc_t
siena_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)8125e111ed8SAndrew Rybchenko siena_tx_qpost(
8135e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
8145e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_buffer_t *eb,
8155e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
8165e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
8175e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp)
8185e111ed8SAndrew Rybchenko {
8195e111ed8SAndrew Rybchenko 	unsigned int added = *addedp;
8205e111ed8SAndrew Rybchenko 	unsigned int i;
8215e111ed8SAndrew Rybchenko 
8225e111ed8SAndrew Rybchenko 	if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
8235e111ed8SAndrew Rybchenko 		return (ENOSPC);
8245e111ed8SAndrew Rybchenko 
8255e111ed8SAndrew Rybchenko 	for (i = 0; i < ndescs; i++) {
8265e111ed8SAndrew Rybchenko 		efx_buffer_t *ebp = &eb[i];
8275e111ed8SAndrew Rybchenko 		efsys_dma_addr_t start = ebp->eb_addr;
8285e111ed8SAndrew Rybchenko 		size_t size = ebp->eb_size;
8295e111ed8SAndrew Rybchenko 		efsys_dma_addr_t end = start + size;
8305e111ed8SAndrew Rybchenko 
8315e111ed8SAndrew Rybchenko 		/*
8325e111ed8SAndrew Rybchenko 		 * Fragments must not span 4k boundaries.
8335e111ed8SAndrew Rybchenko 		 * Here it is a stricter requirement than the maximum length.
8345e111ed8SAndrew Rybchenko 		 */
8355e111ed8SAndrew Rybchenko 		EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, start + 1,
8365e111ed8SAndrew Rybchenko 		    etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end);
8375e111ed8SAndrew Rybchenko 
8385e111ed8SAndrew Rybchenko 		EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
8395e111ed8SAndrew Rybchenko 	}
8405e111ed8SAndrew Rybchenko 
8415e111ed8SAndrew Rybchenko 	EFX_TX_QSTAT_INCR(etp, TX_POST);
8425e111ed8SAndrew Rybchenko 
8435e111ed8SAndrew Rybchenko 	*addedp = added;
8445e111ed8SAndrew Rybchenko 	return (0);
8455e111ed8SAndrew Rybchenko }
8465e111ed8SAndrew Rybchenko 
8475e111ed8SAndrew Rybchenko static		void
siena_tx_qpush(__in efx_txq_t * etp,__in unsigned int added,__in unsigned int pushed)8485e111ed8SAndrew Rybchenko siena_tx_qpush(
8495e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
8505e111ed8SAndrew Rybchenko 	__in	unsigned int added,
8515e111ed8SAndrew Rybchenko 	__in	unsigned int pushed)
8525e111ed8SAndrew Rybchenko {
8535e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
8545e111ed8SAndrew Rybchenko 	uint32_t wptr;
8555e111ed8SAndrew Rybchenko 	efx_dword_t dword;
8565e111ed8SAndrew Rybchenko 	efx_oword_t oword;
8575e111ed8SAndrew Rybchenko 
8585e111ed8SAndrew Rybchenko 	/* Push the populated descriptors out */
8595e111ed8SAndrew Rybchenko 	wptr = added & etp->et_mask;
8605e111ed8SAndrew Rybchenko 
8615e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
8625e111ed8SAndrew Rybchenko 
8635e111ed8SAndrew Rybchenko 	/* Only write the third DWORD */
8645e111ed8SAndrew Rybchenko 	EFX_POPULATE_DWORD_1(dword,
8655e111ed8SAndrew Rybchenko 	    EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
8665e111ed8SAndrew Rybchenko 
8675e111ed8SAndrew Rybchenko 	/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
8685e111ed8SAndrew Rybchenko 	EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
86982192e22SAndrew Rybchenko 	    SIENA_TXQ_DESC_SIZE, wptr, pushed & etp->et_mask);
8705e111ed8SAndrew Rybchenko 	EFSYS_PIO_WRITE_BARRIER();
8715e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
8725e111ed8SAndrew Rybchenko 			    etp->et_index, &dword, B_FALSE);
8735e111ed8SAndrew Rybchenko }
8745e111ed8SAndrew Rybchenko 
8755e111ed8SAndrew Rybchenko #define	EFX_MAX_PACE_VALUE 20
8765e111ed8SAndrew Rybchenko 
8775e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
siena_tx_qpace(__in efx_txq_t * etp,__in unsigned int ns)8785e111ed8SAndrew Rybchenko siena_tx_qpace(
8795e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp,
8805e111ed8SAndrew Rybchenko 	__in		unsigned int ns)
8815e111ed8SAndrew Rybchenko {
8825e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
8835e111ed8SAndrew Rybchenko 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
8845e111ed8SAndrew Rybchenko 	efx_oword_t oword;
8855e111ed8SAndrew Rybchenko 	unsigned int pace_val;
8865e111ed8SAndrew Rybchenko 	unsigned int timer_period;
8875e111ed8SAndrew Rybchenko 	efx_rc_t rc;
8885e111ed8SAndrew Rybchenko 
8895e111ed8SAndrew Rybchenko 	if (ns == 0) {
8905e111ed8SAndrew Rybchenko 		pace_val = 0;
8915e111ed8SAndrew Rybchenko 	} else {
8925e111ed8SAndrew Rybchenko 		/*
8935e111ed8SAndrew Rybchenko 		 * The pace_val to write into the table is s.t
8945e111ed8SAndrew Rybchenko 		 * ns <= timer_period * (2 ^ pace_val)
8955e111ed8SAndrew Rybchenko 		 */
8965e111ed8SAndrew Rybchenko 		timer_period = 104 / encp->enc_clk_mult;
8975e111ed8SAndrew Rybchenko 		for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
8985e111ed8SAndrew Rybchenko 			if ((timer_period << pace_val) >= ns)
8995e111ed8SAndrew Rybchenko 				break;
9005e111ed8SAndrew Rybchenko 		}
9015e111ed8SAndrew Rybchenko 	}
9025e111ed8SAndrew Rybchenko 	if (pace_val > EFX_MAX_PACE_VALUE) {
9035e111ed8SAndrew Rybchenko 		rc = EINVAL;
9045e111ed8SAndrew Rybchenko 		goto fail1;
9055e111ed8SAndrew Rybchenko 	}
9065e111ed8SAndrew Rybchenko 
9075e111ed8SAndrew Rybchenko 	/* Update the pacing table */
9085e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
9095e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
9105e111ed8SAndrew Rybchenko 	    &oword, B_TRUE);
9115e111ed8SAndrew Rybchenko 
9125e111ed8SAndrew Rybchenko 	return (0);
9135e111ed8SAndrew Rybchenko 
9145e111ed8SAndrew Rybchenko fail1:
9155e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9165e111ed8SAndrew Rybchenko 
9175e111ed8SAndrew Rybchenko 	return (rc);
9185e111ed8SAndrew Rybchenko }
9195e111ed8SAndrew Rybchenko 
9205e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
siena_tx_qflush(__in efx_txq_t * etp)9215e111ed8SAndrew Rybchenko siena_tx_qflush(
9225e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp)
9235e111ed8SAndrew Rybchenko {
9245e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
9255e111ed8SAndrew Rybchenko 	efx_oword_t oword;
9265e111ed8SAndrew Rybchenko 	uint32_t label;
9275e111ed8SAndrew Rybchenko 
9285e111ed8SAndrew Rybchenko 	efx_tx_qpace(etp, 0);
9295e111ed8SAndrew Rybchenko 
9305e111ed8SAndrew Rybchenko 	label = etp->et_index;
9315e111ed8SAndrew Rybchenko 
9325e111ed8SAndrew Rybchenko 	/* Flush the queue */
9335e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
9345e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_FLUSH_DESCQ, label);
9355e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
9365e111ed8SAndrew Rybchenko 
9375e111ed8SAndrew Rybchenko 	return (0);
9385e111ed8SAndrew Rybchenko }
9395e111ed8SAndrew Rybchenko 
9405e111ed8SAndrew Rybchenko static		void
siena_tx_qenable(__in efx_txq_t * etp)9415e111ed8SAndrew Rybchenko siena_tx_qenable(
9425e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
9435e111ed8SAndrew Rybchenko {
9445e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
9455e111ed8SAndrew Rybchenko 	efx_oword_t oword;
9465e111ed8SAndrew Rybchenko 
9475e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
9485e111ed8SAndrew Rybchenko 			    etp->et_index, &oword, B_TRUE);
9495e111ed8SAndrew Rybchenko 
9505e111ed8SAndrew Rybchenko 	EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
9515e111ed8SAndrew Rybchenko 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
9525e111ed8SAndrew Rybchenko 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
9535e111ed8SAndrew Rybchenko 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
9545e111ed8SAndrew Rybchenko 	    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
9555e111ed8SAndrew Rybchenko 
9565e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
9575e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
9585e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
9595e111ed8SAndrew Rybchenko 
9605e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
9615e111ed8SAndrew Rybchenko 			    etp->et_index, &oword, B_TRUE);
9625e111ed8SAndrew Rybchenko }
9635e111ed8SAndrew Rybchenko 
9645e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
siena_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)9655e111ed8SAndrew Rybchenko siena_tx_qcreate(
9665e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
9675e111ed8SAndrew Rybchenko 	__in		unsigned int index,
9685e111ed8SAndrew Rybchenko 	__in		unsigned int label,
9695e111ed8SAndrew Rybchenko 	__in		efsys_mem_t *esmp,
9705e111ed8SAndrew Rybchenko 	__in		size_t ndescs,
9715e111ed8SAndrew Rybchenko 	__in		uint32_t id,
9725e111ed8SAndrew Rybchenko 	__in		uint16_t flags,
9735e111ed8SAndrew Rybchenko 	__in		efx_evq_t *eep,
9745e111ed8SAndrew Rybchenko 	__in		efx_txq_t *etp,
9755e111ed8SAndrew Rybchenko 	__out		unsigned int *addedp)
9765e111ed8SAndrew Rybchenko {
9775e111ed8SAndrew Rybchenko 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
9785e111ed8SAndrew Rybchenko 	efx_oword_t oword;
9795e111ed8SAndrew Rybchenko 	uint32_t size;
9805e111ed8SAndrew Rybchenko 	uint16_t inner_csum;
9815e111ed8SAndrew Rybchenko 	efx_rc_t rc;
9825e111ed8SAndrew Rybchenko 
9835e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(esmp))
9845e111ed8SAndrew Rybchenko 
9855e111ed8SAndrew Rybchenko 	EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
9865e111ed8SAndrew Rybchenko 	    (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
9875e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
9885e111ed8SAndrew Rybchenko 
9895e111ed8SAndrew Rybchenko 	if (index >= encp->enc_txq_limit) {
9905e111ed8SAndrew Rybchenko 		rc = EINVAL;
9915e111ed8SAndrew Rybchenko 		goto fail1;
9925e111ed8SAndrew Rybchenko 	}
9935e111ed8SAndrew Rybchenko 	for (size = 0;
9945e111ed8SAndrew Rybchenko 	    (1U << size) <= encp->enc_txq_max_ndescs / encp->enc_txq_min_ndescs;
9955e111ed8SAndrew Rybchenko 	    size++)
9965e111ed8SAndrew Rybchenko 		if ((1U << size) == (uint32_t)ndescs / encp->enc_txq_min_ndescs)
9975e111ed8SAndrew Rybchenko 			break;
9985e111ed8SAndrew Rybchenko 	if (id + (1 << size) >= encp->enc_buftbl_limit) {
9995e111ed8SAndrew Rybchenko 		rc = EINVAL;
10005e111ed8SAndrew Rybchenko 		goto fail2;
10015e111ed8SAndrew Rybchenko 	}
10025e111ed8SAndrew Rybchenko 
10035e111ed8SAndrew Rybchenko 	inner_csum = EFX_TXQ_CKSUM_INNER_IPV4 | EFX_TXQ_CKSUM_INNER_TCPUDP;
10045e111ed8SAndrew Rybchenko 	if ((flags & inner_csum) != 0) {
10055e111ed8SAndrew Rybchenko 		rc = EINVAL;
10065e111ed8SAndrew Rybchenko 		goto fail3;
10075e111ed8SAndrew Rybchenko 	}
10085e111ed8SAndrew Rybchenko 
10095e111ed8SAndrew Rybchenko 	/* Set up the new descriptor queue */
10105e111ed8SAndrew Rybchenko 	*addedp = 0;
10115e111ed8SAndrew Rybchenko 
10125e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_6(oword,
10135e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
10145e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
10155e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_OWNER_ID, 0,
10165e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_LABEL, label,
10175e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_SIZE, size,
10185e111ed8SAndrew Rybchenko 	    FRF_AZ_TX_DESCQ_TYPE, 0);
10195e111ed8SAndrew Rybchenko 
10205e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
10215e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
10225e111ed8SAndrew Rybchenko 	    (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
10235e111ed8SAndrew Rybchenko 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
10245e111ed8SAndrew Rybchenko 	    (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
10255e111ed8SAndrew Rybchenko 
10265e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
10275e111ed8SAndrew Rybchenko 	    etp->et_index, &oword, B_TRUE);
10285e111ed8SAndrew Rybchenko 
10295e111ed8SAndrew Rybchenko 	return (0);
10305e111ed8SAndrew Rybchenko 
10315e111ed8SAndrew Rybchenko fail3:
10325e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
10335e111ed8SAndrew Rybchenko fail2:
10345e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
10355e111ed8SAndrew Rybchenko fail1:
10365e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
10375e111ed8SAndrew Rybchenko 
10385e111ed8SAndrew Rybchenko 	return (rc);
10395e111ed8SAndrew Rybchenko }
10405e111ed8SAndrew Rybchenko 
10415e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
siena_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)10425e111ed8SAndrew Rybchenko siena_tx_qdesc_post(
10435e111ed8SAndrew Rybchenko 	__in			efx_txq_t *etp,
10445e111ed8SAndrew Rybchenko 	__in_ecount(ndescs)	efx_desc_t *ed,
10455e111ed8SAndrew Rybchenko 	__in			unsigned int ndescs,
10465e111ed8SAndrew Rybchenko 	__in			unsigned int completed,
10475e111ed8SAndrew Rybchenko 	__inout			unsigned int *addedp)
10485e111ed8SAndrew Rybchenko {
10495e111ed8SAndrew Rybchenko 	unsigned int added = *addedp;
10505e111ed8SAndrew Rybchenko 	unsigned int i;
10515e111ed8SAndrew Rybchenko 	efx_rc_t rc;
10525e111ed8SAndrew Rybchenko 
10535e111ed8SAndrew Rybchenko 	if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
10545e111ed8SAndrew Rybchenko 		rc = ENOSPC;
10555e111ed8SAndrew Rybchenko 		goto fail1;
10565e111ed8SAndrew Rybchenko 	}
10575e111ed8SAndrew Rybchenko 
10585e111ed8SAndrew Rybchenko 	for (i = 0; i < ndescs; i++) {
10595e111ed8SAndrew Rybchenko 		efx_desc_t *edp = &ed[i];
10605e111ed8SAndrew Rybchenko 		unsigned int id;
10615e111ed8SAndrew Rybchenko 		size_t offset;
10625e111ed8SAndrew Rybchenko 
10635e111ed8SAndrew Rybchenko 		id = added++ & etp->et_mask;
10645e111ed8SAndrew Rybchenko 		offset = id * sizeof (efx_desc_t);
10655e111ed8SAndrew Rybchenko 
10665e111ed8SAndrew Rybchenko 		EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
10675e111ed8SAndrew Rybchenko 	}
10685e111ed8SAndrew Rybchenko 
10695e111ed8SAndrew Rybchenko 	EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
10705e111ed8SAndrew Rybchenko 		    unsigned int, added, unsigned int, ndescs);
10715e111ed8SAndrew Rybchenko 
10725e111ed8SAndrew Rybchenko 	EFX_TX_QSTAT_INCR(etp, TX_POST);
10735e111ed8SAndrew Rybchenko 
10745e111ed8SAndrew Rybchenko 	*addedp = added;
10755e111ed8SAndrew Rybchenko 	return (0);
10765e111ed8SAndrew Rybchenko 
10775e111ed8SAndrew Rybchenko fail1:
10785e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
10795e111ed8SAndrew Rybchenko 	return (rc);
10805e111ed8SAndrew Rybchenko }
10815e111ed8SAndrew Rybchenko 
10825e111ed8SAndrew Rybchenko 	void
siena_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)10835e111ed8SAndrew Rybchenko siena_tx_qdesc_dma_create(
10845e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp,
10855e111ed8SAndrew Rybchenko 	__in	efsys_dma_addr_t addr,
10865e111ed8SAndrew Rybchenko 	__in	size_t size,
10875e111ed8SAndrew Rybchenko 	__in	boolean_t eop,
10885e111ed8SAndrew Rybchenko 	__out	efx_desc_t *edp)
10895e111ed8SAndrew Rybchenko {
10905e111ed8SAndrew Rybchenko 	/*
10915e111ed8SAndrew Rybchenko 	 * Fragments must not span 4k boundaries.
10925e111ed8SAndrew Rybchenko 	 * Here it is a stricter requirement than the maximum length.
10935e111ed8SAndrew Rybchenko 	 */
10945e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, addr + 1,
10955e111ed8SAndrew Rybchenko 	    etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size);
10965e111ed8SAndrew Rybchenko 
10975e111ed8SAndrew Rybchenko 	EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
10985e111ed8SAndrew Rybchenko 		    efsys_dma_addr_t, addr,
10995e111ed8SAndrew Rybchenko 		    size_t, size, boolean_t, eop);
11005e111ed8SAndrew Rybchenko 
11015e111ed8SAndrew Rybchenko 	EFX_POPULATE_QWORD_4(edp->ed_eq,
11025e111ed8SAndrew Rybchenko 			    FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
11035e111ed8SAndrew Rybchenko 			    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
11045e111ed8SAndrew Rybchenko 			    FSF_AZ_TX_KER_BUF_ADDR_DW0,
11055e111ed8SAndrew Rybchenko 			    (uint32_t)(addr & 0xffffffff),
11065e111ed8SAndrew Rybchenko 			    FSF_AZ_TX_KER_BUF_ADDR_DW1,
11075e111ed8SAndrew Rybchenko 			    (uint32_t)(addr >> 32));
11085e111ed8SAndrew Rybchenko }
11095e111ed8SAndrew Rybchenko 
11105e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
11115e111ed8SAndrew Rybchenko 
11125e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
11135e111ed8SAndrew Rybchenko #if EFSYS_OPT_NAMES
11145e111ed8SAndrew Rybchenko /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 2866874ecd7a363b */
11155e111ed8SAndrew Rybchenko static const char * const __efx_tx_qstat_name[] = {
11165e111ed8SAndrew Rybchenko 	"post",
11175e111ed8SAndrew Rybchenko 	"post_pio",
11185e111ed8SAndrew Rybchenko };
11195e111ed8SAndrew Rybchenko /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
11205e111ed8SAndrew Rybchenko 
11215e111ed8SAndrew Rybchenko 		const char *
efx_tx_qstat_name(__in efx_nic_t * enp,__in unsigned int id)11225e111ed8SAndrew Rybchenko efx_tx_qstat_name(
11235e111ed8SAndrew Rybchenko 	__in	efx_nic_t *enp,
11245e111ed8SAndrew Rybchenko 	__in	unsigned int id)
11255e111ed8SAndrew Rybchenko {
11265e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11275e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
11285e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(id, <, TX_NQSTATS);
11295e111ed8SAndrew Rybchenko 
11305e111ed8SAndrew Rybchenko 	return (__efx_tx_qstat_name[id]);
11315e111ed8SAndrew Rybchenko }
11325e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_NAMES */
11335e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_QSTATS */
11345e111ed8SAndrew Rybchenko 
11355e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
11365e111ed8SAndrew Rybchenko 
11375e111ed8SAndrew Rybchenko #if EFSYS_OPT_QSTATS
11385e111ed8SAndrew Rybchenko static					void
siena_tx_qstats_update(__in efx_txq_t * etp,__inout_ecount (TX_NQSTATS)efsys_stat_t * stat)11395e111ed8SAndrew Rybchenko siena_tx_qstats_update(
11405e111ed8SAndrew Rybchenko 	__in				efx_txq_t *etp,
11415e111ed8SAndrew Rybchenko 	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
11425e111ed8SAndrew Rybchenko {
11435e111ed8SAndrew Rybchenko 	unsigned int id;
11445e111ed8SAndrew Rybchenko 
11455e111ed8SAndrew Rybchenko 	for (id = 0; id < TX_NQSTATS; id++) {
11465e111ed8SAndrew Rybchenko 		efsys_stat_t *essp = &stat[id];
11475e111ed8SAndrew Rybchenko 
11485e111ed8SAndrew Rybchenko 		EFSYS_STAT_INCR(essp, etp->et_stat[id]);
11495e111ed8SAndrew Rybchenko 		etp->et_stat[id] = 0;
11505e111ed8SAndrew Rybchenko 	}
11515e111ed8SAndrew Rybchenko }
11525e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_QSTATS */
11535e111ed8SAndrew Rybchenko 
11545e111ed8SAndrew Rybchenko static		void
siena_tx_qdestroy(__in efx_txq_t * etp)11555e111ed8SAndrew Rybchenko siena_tx_qdestroy(
11565e111ed8SAndrew Rybchenko 	__in	efx_txq_t *etp)
11575e111ed8SAndrew Rybchenko {
11585e111ed8SAndrew Rybchenko 	efx_nic_t *enp = etp->et_enp;
11595e111ed8SAndrew Rybchenko 	efx_oword_t oword;
11605e111ed8SAndrew Rybchenko 
11615e111ed8SAndrew Rybchenko 	/* Purge descriptor queue */
11625e111ed8SAndrew Rybchenko 	EFX_ZERO_OWORD(oword);
11635e111ed8SAndrew Rybchenko 
11645e111ed8SAndrew Rybchenko 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
11655e111ed8SAndrew Rybchenko 			    etp->et_index, &oword, B_TRUE);
11665e111ed8SAndrew Rybchenko }
11675e111ed8SAndrew Rybchenko 
11685e111ed8SAndrew Rybchenko static		void
siena_tx_fini(__in efx_nic_t * enp)11695e111ed8SAndrew Rybchenko siena_tx_fini(
11705e111ed8SAndrew Rybchenko 	__in	efx_nic_t *enp)
11715e111ed8SAndrew Rybchenko {
11725e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11735e111ed8SAndrew Rybchenko }
11745e111ed8SAndrew Rybchenko 
11755e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_SIENA */
1176