mlx5_tx_burst_mseg(struct mlx5_txq_data *restrict txq,
		   struct rte_mbuf **restrict pkts,
		   unsigned int pkts_n,
		   struct mlx5_txq_local *restrict loc,
		   unsigned int olx)
{
	assert(loc->elts_free && loc->wqe_free);
	assert(pkts_n > loc->pkts_sent);
	pkts += loc->pkts_sent + 1;
	pkts_n -= loc->pkts_sent;
	for (;;) {
		enum mlx5_txcmp_code ret;

		assert(NB_SEGS(loc->mbuf) > 1);
		/*
		 * Estimate the number of free elts quickly but
		 * conservatively. Some segment may be fully inlined
		 * and freed, ignore this here - precise estimation
		 * is costly.
		 */
		if (loc->elts_free < NB_SEGS(loc->mbuf))
			return MLX5_TXCMP_CODE_EXIT;
		if (MLX5_TXOFF_CONFIG(TSO) &&
		    unlikely(loc->mbuf->ol_flags & PKT_TX_TCP_SEG)) {
			/* Proceed with multi-segment TSO. */
			ret = mlx5_tx_packet_multi_tso(txq, loc, olx);
		} else if (MLX5_TXOFF_CONFIG(INLINE)) {
			/* Proceed with multi-segment SEND with inlining. */
			ret = mlx5_tx_packet_multi_inline(txq, loc, olx);
		} else {
			/* Proceed with multi-segment SEND w/o inlining. */
			ret = mlx5_tx_packet_multi_send(txq, loc, olx);
		}
		if (ret == MLX5_TXCMP_CODE_EXIT)
			return MLX5_TXCMP_CODE_EXIT;
		if (ret == MLX5_TXCMP_CODE_ERROR)
			return MLX5_TXCMP_CODE_ERROR;
		/* WQE is built, go to the next packet. */
		++loc->pkts_sent;
		--pkts_n;
		if (unlikely(!pkts_n || !loc->elts_free || !loc->wqe_free))
			return MLX5_TXCMP_CODE_EXIT;
		loc->mbuf = *pkts++;
		if (pkts_n > 1)
			rte_prefetch0(*pkts);
		if (likely(NB_SEGS(loc->mbuf) > 1))
			continue;
		/* Here ends the series of multi-segment packets. */
		if (MLX5_TXOFF_CONFIG(TSO) &&
		    unlikely(loc->mbuf->ol_flags & PKT_TX_TCP_SEG))
			return MLX5_TXCMP_CODE_TSO;
		return MLX5_TXCMP_CODE_SINGLE;
	}
	assert(false);
}
mlx5_tx_burst_mseg(struct mlx5_txq_data *restrict txq,
		   struct rte_mbuf **restrict pkts,
		   unsigned int pkts_n,
		   struct mlx5_txq_local *restrict loc,
		   unsigned int olx)
{
	assert(loc->elts_free && loc->wqe_free);
	assert(pkts_n > loc->pkts_sent);
	pkts += loc->pkts_sent + 1;
	pkts_n -= loc->pkts_sent;
	for (;;) {
		enum mlx5_txcmp_code ret;

		assert(NB_SEGS(loc->mbuf) > 1);
		 
		if (loc->elts_free < NB_SEGS(loc->mbuf))
			return MLX5_TXCMP_CODE_EXIT;
		if (MLX5_TXOFF_CONFIG(TSO) &&
		    unlikely(loc->mbuf->ol_flags & PKT_TX_TCP_SEG)) {
			 
			ret = mlx5_tx_packet_multi_tso(txq, loc, olx);
		} else if (MLX5_TXOFF_CONFIG(INLINE)) {
			 
			ret = mlx5_tx_packet_multi_inline(txq, loc, olx);
		} else {
			 
			ret = mlx5_tx_packet_multi_send(txq, loc, olx);
		}
		if (ret == MLX5_TXCMP_CODE_EXIT)
			return MLX5_TXCMP_CODE_EXIT;
		if (ret == MLX5_TXCMP_CODE_ERROR)
			return MLX5_TXCMP_CODE_ERROR;
		 
		++loc->pkts_sent;
		--pkts_n;
		if (unlikely(!pkts_n || !loc->elts_free || !loc->wqe_free))
			return MLX5_TXCMP_CODE_EXIT;
		loc->mbuf = *pkts++;
		if (pkts_n > 1)
			rte_prefetch0(*pkts);
		if (likely(NB_SEGS(loc->mbuf) > 1))
			continue;
		 
		if (MLX5_TXOFF_CONFIG(TSO) &&
		    unlikely(loc->mbuf->ol_flags & PKT_TX_TCP_SEG))
			return MLX5_TXCMP_CODE_TSO;
		return MLX5_TXCMP_CODE_SINGLE;
	}
	assert(false);
}