src/dpdk/drivers/net/mlx4/mlx4_rxtx.c
static volatile struct mlx4_wqe_ctrl_seg *
mlx4_tx_burst_tso(struct rte_mbuf *buf, struct txq *txq,
		  volatile struct mlx4_wqe_ctrl_seg *ctrl)
{
	volatile struct mlx4_wqe_data_seg *dseg;
	volatile struct mlx4_wqe_ctrl_seg *ctrl_next;
	struct mlx4_sq *sq = &txq->msq;
	struct tso_info tinfo;
	struct pv *pv;
	int pv_counter;
	int ret;

	ret = mlx4_tx_burst_tso_get_params(buf, txq, &tinfo);
	if (unlikely(ret))
		goto error;
	dseg = mlx4_tx_burst_fill_tso_hdr(buf, txq, &tinfo, ctrl);
	if (unlikely(dseg == NULL))
		goto error;
	if ((uintptr_t)dseg >= (uintptr_t)sq->eob)
		dseg = (volatile struct mlx4_wqe_data_seg *)
					((uintptr_t)dseg - sq->size);
	ctrl_next = mlx4_tx_burst_fill_tso_dsegs(buf, txq, &tinfo, dseg, ctrl);
	if (unlikely(ctrl_next == NULL))
		goto error;
	/* Write the first DWORD of each TXBB save earlier. */
	if (likely(tinfo.pv_counter)) {
		pv = tinfo.pv;
		pv_counter = tinfo.pv_counter;
		/* Need a barrier here before writing the first TXBB word. */
		rte_io_wmb();
		do {
			--pv_counter;
			*pv[pv_counter].dst = pv[pv_counter].val;
		} while (pv_counter > 0);
	}
	ctrl->fence_size = tinfo.fence_size;
	sq->remain_size -= tinfo.wqe_size;
	return ctrl_next;
error:
	txq->stats.odropped++;
	return NULL;
}
/**
 * Write data segments and header for TSO uni/multi segment packet.
 *
 * @param buf
 *   Pointer to the first packet mbuf.
 * @param txq
 *   Pointer to Tx queue structure.
 * @param ctrl
 *   Pointer to the WQE control segment.
 *
 * @return
 *   Pointer to the next WQE control segment on success, NULL otherwise.
 */
Write data segments and header for TSO uni/multi segment packet.
@param buf
Pointer to the first packet mbuf.
@param txq
Pointer to Tx queue structure.
@param ctrl
Pointer to the WQE control segment.

@return
Pointer to the next WQE control segment on success, NULL otherwise.
Write data segments and header for TSO uni / multi segment packet . @param buf Pointer to the first packet mbuf . @param txq Pointer to Tx queue structure . @param ctrl Pointer to the WQE control segment . @return Pointer to the next WQE control segment on success NULL otherwise .
static volatile struct mlx4_wqe_ctrl_seg *
mlx4_tx_burst_tso(struct rte_mbuf *buf, struct txq *txq,
		  volatile struct mlx4_wqe_ctrl_seg *ctrl)
{
	volatile struct mlx4_wqe_data_seg *dseg;
	volatile struct mlx4_wqe_ctrl_seg *ctrl_next;
	struct mlx4_sq *sq = &txq->msq;
	struct tso_info tinfo;
	struct pv *pv;
	int pv_counter;
	int ret;
	ret = mlx4_tx_burst_tso_get_params(buf, txq, &tinfo);
	if (unlikely(ret))
		goto error;
	dseg = mlx4_tx_burst_fill_tso_hdr(buf, txq, &tinfo, ctrl);
	if (unlikely(dseg == NULL))
		goto error;
	if ((uintptr_t)dseg >= (uintptr_t)sq->eob)
		dseg = (volatile struct mlx4_wqe_data_seg *)
					((uintptr_t)dseg - sq->size);
	ctrl_next = mlx4_tx_burst_fill_tso_dsegs(buf, txq, &tinfo, dseg, ctrl);
	if (unlikely(ctrl_next == NULL))
		goto error;
	if (likely(tinfo.pv_counter)) {
		pv = tinfo.pv;
		pv_counter = tinfo.pv_counter;
		rte_io_wmb();
		do {
			--pv_counter;
			*pv[pv_counter].dst = pv[pv_counter].val;
		} while (pv_counter > 0);
	}
	ctrl->fence_size = tinfo.fence_size;
	sq->remain_size -= tinfo.wqe_size;
	return ctrl_next;
error:
	txq->stats.odropped++;
	return NULL;
}
static volatile struct mlx4_wqe_ctrl_seg * mlx4_tx_burst_tso ( struct rte_mbuf * buf , struct txq * txq , volatile struct mlx4_wqe_ctrl_seg * ctrl ) { volatile struct mlx4_wqe_data_seg * dseg ; volatile struct mlx4_wqe_ctrl_seg * ctrl_next ; struct mlx4_sq * sq = & txq -> msq ; struct tso_info tinfo ; struct pv * pv ; int pv_counter ; int ret ; ret = mlx4_tx_burst_tso_get_params ( buf , txq , & tinfo ) ; if ( unlikely ( ret ) ) goto error ; dseg = mlx4_tx_burst_fill_tso_hdr ( buf , txq , & tinfo , ctrl ) ; if ( unlikely ( dseg == NULL ) ) goto error ; if ( ( uintptr_t ) dseg >= ( uintptr_t ) sq -> eob ) dseg = ( volatile struct mlx4_wqe_data_seg * ) ( ( uintptr_t ) dseg - sq -> size ) ; ctrl_next = mlx4_tx_burst_fill_tso_dsegs ( buf , txq , & tinfo , dseg , ctrl ) ; if ( unlikely ( ctrl_next == NULL ) ) goto error ; if ( likely ( tinfo . pv_counter ) ) { pv = tinfo . pv ; pv_counter = tinfo . pv_counter ; rte_io_wmb ( ) ; do { -- pv_counter ; * pv [ pv_counter ] . dst = pv [ pv_counter ] . val ; } while ( pv_counter > 0 ) ; } ctrl -> fence_size = tinfo . fence_size ; sq -> remain_size -= tinfo . wqe_size ; return ctrl_next ; error : txq -> stats . odropped ++ ; return NULL ; }
Write data segments and header for TSO uni/multi segment packet.
Write data segments and header for TSO uni / multi segment packet .
/* Write the first DWORD of each TXBB save earlier. */ /* Need a barrier here before writing the first TXBB word. */