mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq,
		  struct mlx5_txq_local *restrict loc __rte_unused,
		  struct mlx5_wqe_dseg *restrict dseg,
		  uint8_t *buf,
		  unsigned int len,
		  unsigned int olx __rte_unused)

{
	unsigned int part;
	uint8_t *pdst;

	assert(len > MLX5_ESEG_MIN_INLINE_SIZE);
	static_assert(MLX5_DSEG_MIN_INLINE_SIZE ==
				 (2 * RTE_ETHER_ADDR_LEN),
		      "invalid Data Segment data size");
	if (!MLX5_TXOFF_CONFIG(MPW)) {
		/* Store the descriptor byte counter for eMPW sessions. */
		dseg->bcount = rte_cpu_to_be_32
				((len + sizeof(struct rte_vlan_hdr)) |
				 MLX5_ETH_WQE_DATA_INLINE);
		pdst = &dseg->inline_data[0];
	} else {
		/* The entire legacy MPW session counter is stored on close. */
		pdst = (uint8_t *)dseg;
	}
	memcpy(pdst, buf, MLX5_DSEG_MIN_INLINE_SIZE);
	buf += MLX5_DSEG_MIN_INLINE_SIZE;
	pdst += MLX5_DSEG_MIN_INLINE_SIZE;
	len -= MLX5_DSEG_MIN_INLINE_SIZE;
	/* Insert VLAN ethertype + VLAN tag. Pointer is aligned. */
	assert(pdst == RTE_PTR_ALIGN(pdst, MLX5_WSEG_SIZE));
	if (unlikely(pdst >= (uint8_t *)txq->wqes_end))
		pdst = (uint8_t *)txq->wqes;
	*(uint32_t *)pdst = rte_cpu_to_be_32((RTE_ETHER_TYPE_VLAN << 16) |
					      loc->mbuf->vlan_tci);
	pdst += sizeof(struct rte_vlan_hdr);
	/*
	 * The WQEBB space availability is checked by caller.
	 * Here we should be aware of WQE ring buffer wraparound only.
	 */
	part = (uint8_t *)txq->wqes_end - pdst;
	part = RTE_MIN(part, len);
	do {
		rte_memcpy(pdst, buf, part);
		len -= part;
		if (likely(!len)) {
			pdst += part;
			if (!MLX5_TXOFF_CONFIG(MPW))
				pdst = RTE_PTR_ALIGN(pdst, MLX5_WSEG_SIZE);
			/* Note: no final wraparound check here. */
			return (struct mlx5_wqe_dseg *)pdst;
		}
		pdst = (uint8_t *)txq->wqes;
		buf += part;
		part = len;
	} while (true);
}
mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq,
		  struct mlx5_txq_local *restrict loc __rte_unused,
		  struct mlx5_wqe_dseg *restrict dseg,
		  uint8_t *buf,
		  unsigned int len,
		  unsigned int olx __rte_unused)

{
	unsigned int part;
	uint8_t *pdst;

	assert(len > MLX5_ESEG_MIN_INLINE_SIZE);
	static_assert(MLX5_DSEG_MIN_INLINE_SIZE ==
				 (2 * RTE_ETHER_ADDR_LEN),
		      "invalid Data Segment data size");
	if (!MLX5_TXOFF_CONFIG(MPW)) {
		 
		dseg->bcount = rte_cpu_to_be_32
				((len + sizeof(struct rte_vlan_hdr)) |
				 MLX5_ETH_WQE_DATA_INLINE);
		pdst = &dseg->inline_data[0];
	} else {
		 
		pdst = (uint8_t *)dseg;
	}
	memcpy(pdst, buf, MLX5_DSEG_MIN_INLINE_SIZE);
	buf += MLX5_DSEG_MIN_INLINE_SIZE;
	pdst += MLX5_DSEG_MIN_INLINE_SIZE;
	len -= MLX5_DSEG_MIN_INLINE_SIZE;
	 
	assert(pdst == RTE_PTR_ALIGN(pdst, MLX5_WSEG_SIZE));
	if (unlikely(pdst >= (uint8_t *)txq->wqes_end))
		pdst = (uint8_t *)txq->wqes;
	*(uint32_t *)pdst = rte_cpu_to_be_32((RTE_ETHER_TYPE_VLAN << 16) |
					      loc->mbuf->vlan_tci);
	pdst += sizeof(struct rte_vlan_hdr);
	 
	part = (uint8_t *)txq->wqes_end - pdst;
	part = RTE_MIN(part, len);
	do {
		rte_memcpy(pdst, buf, part);
		len -= part;
		if (likely(!len)) {
			pdst += part;
			if (!MLX5_TXOFF_CONFIG(MPW))
				pdst = RTE_PTR_ALIGN(pdst, MLX5_WSEG_SIZE);
			 
			return (struct mlx5_wqe_dseg *)pdst;
		}
		pdst = (uint8_t *)txq->wqes;
		buf += part;
		part = len;
	} while (true);
}