mlx5_tx_schedule_send(struct mlx5_txq_data *restrict txq,
		      struct mlx5_txq_local *restrict loc,
		      unsigned int olx)
{
	if (MLX5_TXOFF_CONFIG(TXPP) &&
	    loc->mbuf->ol_flags & txq->ts_mask) {
		struct mlx5_wqe *wqe;
		uint64_t ts;
		int32_t wci;

		/*
		 * Estimate the required space quickly and roughly.
		 * We would like to ensure the packet can be pushed
		 * to the queue and we won't get the orphan WAIT WQE.
		 */
		if (loc->wqe_free <= MLX5_WQE_SIZE_MAX / MLX5_WQE_SIZE ||
		    loc->elts_free < NB_SEGS(loc->mbuf))
			return MLX5_TXCMP_CODE_EXIT;
		/* Convert the timestamp into completion to wait. */
		ts = *RTE_MBUF_DYNFIELD(loc->mbuf, txq->ts_offset, uint64_t *);
		wci = mlx5_txpp_convert_tx_ts(txq->sh, ts);
		if (unlikely(wci < 0))
			return MLX5_TXCMP_CODE_SINGLE;
		/* Build the WAIT WQE with specified completion. */
		wqe = txq->wqes + (txq->wqe_ci & txq->wqe_m);
		mlx5_tx_cseg_init(txq, loc, wqe, 2, MLX5_OPCODE_WAIT, olx);
		mlx5_tx_wseg_init(txq, loc, wqe, wci, olx);
		++txq->wqe_ci;
		--loc->wqe_free;
		return MLX5_TXCMP_CODE_MULTI;
	}
	return MLX5_TXCMP_CODE_SINGLE;
}
mlx5_tx_schedule_send(struct mlx5_txq_data *restrict txq,
		      struct mlx5_txq_local *restrict loc,
		      unsigned int olx)
{
	if (MLX5_TXOFF_CONFIG(TXPP) &&
	    loc->mbuf->ol_flags & txq->ts_mask) {
		struct mlx5_wqe *wqe;
		uint64_t ts;
		int32_t wci;

		 
		if (loc->wqe_free <= MLX5_WQE_SIZE_MAX / MLX5_WQE_SIZE ||
		    loc->elts_free < NB_SEGS(loc->mbuf))
			return MLX5_TXCMP_CODE_EXIT;
		 
		ts = *RTE_MBUF_DYNFIELD(loc->mbuf, txq->ts_offset, uint64_t *);
		wci = mlx5_txpp_convert_tx_ts(txq->sh, ts);
		if (unlikely(wci < 0))
			return MLX5_TXCMP_CODE_SINGLE;
		 
		wqe = txq->wqes + (txq->wqe_ci & txq->wqe_m);
		mlx5_tx_cseg_init(txq, loc, wqe, 2, MLX5_OPCODE_WAIT, olx);
		mlx5_tx_wseg_init(txq, loc, wqe, wci, olx);
		++txq->wqe_ci;
		--loc->wqe_free;
		return MLX5_TXCMP_CODE_MULTI;
	}
	return MLX5_TXCMP_CODE_SINGLE;
}