xref: /dpdk/drivers/net/mlx5/mlx5_rxtx.c (revision 0431c40f47021fefd6b2064be1c02596e07f858e)
12e22920bSAdrien Mazarguil /*-
22e22920bSAdrien Mazarguil  *   BSD LICENSE
32e22920bSAdrien Mazarguil  *
42e22920bSAdrien Mazarguil  *   Copyright 2015 6WIND S.A.
52e22920bSAdrien Mazarguil  *   Copyright 2015 Mellanox.
62e22920bSAdrien Mazarguil  *
72e22920bSAdrien Mazarguil  *   Redistribution and use in source and binary forms, with or without
82e22920bSAdrien Mazarguil  *   modification, are permitted provided that the following conditions
92e22920bSAdrien Mazarguil  *   are met:
102e22920bSAdrien Mazarguil  *
112e22920bSAdrien Mazarguil  *     * Redistributions of source code must retain the above copyright
122e22920bSAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer.
132e22920bSAdrien Mazarguil  *     * Redistributions in binary form must reproduce the above copyright
142e22920bSAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer in
152e22920bSAdrien Mazarguil  *       the documentation and/or other materials provided with the
162e22920bSAdrien Mazarguil  *       distribution.
172e22920bSAdrien Mazarguil  *     * Neither the name of 6WIND S.A. nor the names of its
182e22920bSAdrien Mazarguil  *       contributors may be used to endorse or promote products derived
192e22920bSAdrien Mazarguil  *       from this software without specific prior written permission.
202e22920bSAdrien Mazarguil  *
212e22920bSAdrien Mazarguil  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222e22920bSAdrien Mazarguil  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
232e22920bSAdrien Mazarguil  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
242e22920bSAdrien Mazarguil  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
252e22920bSAdrien Mazarguil  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
262e22920bSAdrien Mazarguil  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
272e22920bSAdrien Mazarguil  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
282e22920bSAdrien Mazarguil  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
292e22920bSAdrien Mazarguil  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
302e22920bSAdrien Mazarguil  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
312e22920bSAdrien Mazarguil  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
322e22920bSAdrien Mazarguil  */
332e22920bSAdrien Mazarguil 
342e22920bSAdrien Mazarguil #include <assert.h>
352e22920bSAdrien Mazarguil #include <stdint.h>
362e22920bSAdrien Mazarguil #include <string.h>
372e22920bSAdrien Mazarguil #include <stdlib.h>
382e22920bSAdrien Mazarguil 
392e22920bSAdrien Mazarguil /* Verbs header. */
402e22920bSAdrien Mazarguil /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
412e22920bSAdrien Mazarguil #ifdef PEDANTIC
422e22920bSAdrien Mazarguil #pragma GCC diagnostic ignored "-pedantic"
432e22920bSAdrien Mazarguil #endif
442e22920bSAdrien Mazarguil #include <infiniband/verbs.h>
452e22920bSAdrien Mazarguil #ifdef PEDANTIC
462e22920bSAdrien Mazarguil #pragma GCC diagnostic error "-pedantic"
472e22920bSAdrien Mazarguil #endif
482e22920bSAdrien Mazarguil 
492e22920bSAdrien Mazarguil /* DPDK headers don't like -pedantic. */
502e22920bSAdrien Mazarguil #ifdef PEDANTIC
512e22920bSAdrien Mazarguil #pragma GCC diagnostic ignored "-pedantic"
522e22920bSAdrien Mazarguil #endif
532e22920bSAdrien Mazarguil #include <rte_mbuf.h>
542e22920bSAdrien Mazarguil #include <rte_mempool.h>
552e22920bSAdrien Mazarguil #include <rte_prefetch.h>
562e22920bSAdrien Mazarguil #include <rte_common.h>
572e22920bSAdrien Mazarguil #include <rte_branch_prediction.h>
580dc02ccaSAdrien Mazarguil #include <rte_memory.h>
592e22920bSAdrien Mazarguil #ifdef PEDANTIC
602e22920bSAdrien Mazarguil #pragma GCC diagnostic error "-pedantic"
612e22920bSAdrien Mazarguil #endif
622e22920bSAdrien Mazarguil 
632e22920bSAdrien Mazarguil #include "mlx5.h"
642e22920bSAdrien Mazarguil #include "mlx5_utils.h"
652e22920bSAdrien Mazarguil #include "mlx5_rxtx.h"
66f3db9489SYaacov Hazan #include "mlx5_autoconf.h"
672e22920bSAdrien Mazarguil #include "mlx5_defs.h"
682e22920bSAdrien Mazarguil 
692e22920bSAdrien Mazarguil /**
702e22920bSAdrien Mazarguil  * Manage TX completions.
712e22920bSAdrien Mazarguil  *
722e22920bSAdrien Mazarguil  * When sending a burst, mlx5_tx_burst() posts several WRs.
732e22920bSAdrien Mazarguil  * To improve performance, a completion event is only required once every
742e22920bSAdrien Mazarguil  * MLX5_PMD_TX_PER_COMP_REQ sends. Doing so discards completion information
752e22920bSAdrien Mazarguil  * for other WRs, but this information would not be used anyway.
762e22920bSAdrien Mazarguil  *
772e22920bSAdrien Mazarguil  * @param txq
782e22920bSAdrien Mazarguil  *   Pointer to TX queue structure.
792e22920bSAdrien Mazarguil  *
802e22920bSAdrien Mazarguil  * @return
812e22920bSAdrien Mazarguil  *   0 on success, -1 on failure.
822e22920bSAdrien Mazarguil  */
832e22920bSAdrien Mazarguil static int
842e22920bSAdrien Mazarguil txq_complete(struct txq *txq)
852e22920bSAdrien Mazarguil {
862e22920bSAdrien Mazarguil 	unsigned int elts_comp = txq->elts_comp;
872e22920bSAdrien Mazarguil 	unsigned int elts_tail = txq->elts_tail;
88a859e8a9SNelio Laranjeiro 	unsigned int elts_free = txq->elts_tail;
892e22920bSAdrien Mazarguil 	const unsigned int elts_n = txq->elts_n;
902e22920bSAdrien Mazarguil 	int wcs_n;
912e22920bSAdrien Mazarguil 
922e22920bSAdrien Mazarguil 	if (unlikely(elts_comp == 0))
932e22920bSAdrien Mazarguil 		return 0;
942e22920bSAdrien Mazarguil #ifdef DEBUG_SEND
952e22920bSAdrien Mazarguil 	DEBUG("%p: processing %u work requests completions",
962e22920bSAdrien Mazarguil 	      (void *)txq, elts_comp);
972e22920bSAdrien Mazarguil #endif
98e1682023SNelio Laranjeiro 	wcs_n = txq->poll_cnt(txq->cq, elts_comp);
992e22920bSAdrien Mazarguil 	if (unlikely(wcs_n == 0))
1002e22920bSAdrien Mazarguil 		return 0;
1012e22920bSAdrien Mazarguil 	if (unlikely(wcs_n < 0)) {
1022e22920bSAdrien Mazarguil 		DEBUG("%p: ibv_poll_cq() failed (wcs_n=%d)",
1032e22920bSAdrien Mazarguil 		      (void *)txq, wcs_n);
1042e22920bSAdrien Mazarguil 		return -1;
1052e22920bSAdrien Mazarguil 	}
1062e22920bSAdrien Mazarguil 	elts_comp -= wcs_n;
1072e22920bSAdrien Mazarguil 	assert(elts_comp <= txq->elts_comp);
1082e22920bSAdrien Mazarguil 	/*
1092e22920bSAdrien Mazarguil 	 * Assume WC status is successful as nothing can be done about it
1102e22920bSAdrien Mazarguil 	 * anyway.
1112e22920bSAdrien Mazarguil 	 */
1122e22920bSAdrien Mazarguil 	elts_tail += wcs_n * txq->elts_comp_cd_init;
1132e22920bSAdrien Mazarguil 	if (elts_tail >= elts_n)
1142e22920bSAdrien Mazarguil 		elts_tail -= elts_n;
115a859e8a9SNelio Laranjeiro 
116a859e8a9SNelio Laranjeiro 	while (elts_free != elts_tail) {
117a859e8a9SNelio Laranjeiro 		struct txq_elt *elt = &(*txq->elts)[elts_free];
118a859e8a9SNelio Laranjeiro 		unsigned int elts_free_next =
119a859e8a9SNelio Laranjeiro 			(((elts_free + 1) == elts_n) ? 0 : elts_free + 1);
120a859e8a9SNelio Laranjeiro 		struct rte_mbuf *tmp = elt->buf;
121a859e8a9SNelio Laranjeiro 		struct txq_elt *elt_next = &(*txq->elts)[elts_free_next];
122a859e8a9SNelio Laranjeiro 
123b185e63fSAdrien Mazarguil #ifndef NDEBUG
124b185e63fSAdrien Mazarguil 		/* Poisoning. */
125b185e63fSAdrien Mazarguil 		memset(elt, 0x66, sizeof(*elt));
126b185e63fSAdrien Mazarguil #endif
127a859e8a9SNelio Laranjeiro 		RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);
128a859e8a9SNelio Laranjeiro 		/* Faster than rte_pktmbuf_free(). */
129a859e8a9SNelio Laranjeiro 		do {
130a859e8a9SNelio Laranjeiro 			struct rte_mbuf *next = NEXT(tmp);
131a859e8a9SNelio Laranjeiro 
132a859e8a9SNelio Laranjeiro 			rte_pktmbuf_free_seg(tmp);
133a859e8a9SNelio Laranjeiro 			tmp = next;
134a859e8a9SNelio Laranjeiro 		} while (tmp != NULL);
135a859e8a9SNelio Laranjeiro 		elts_free = elts_free_next;
136a859e8a9SNelio Laranjeiro 	}
137a859e8a9SNelio Laranjeiro 
1382e22920bSAdrien Mazarguil 	txq->elts_tail = elts_tail;
1392e22920bSAdrien Mazarguil 	txq->elts_comp = elts_comp;
1402e22920bSAdrien Mazarguil 	return 0;
1412e22920bSAdrien Mazarguil }
1422e22920bSAdrien Mazarguil 
1432e22920bSAdrien Mazarguil /**
1448340392eSAdrien Mazarguil  * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which
1458340392eSAdrien Mazarguil  * the cloned mbuf is allocated is returned instead.
1468340392eSAdrien Mazarguil  *
1478340392eSAdrien Mazarguil  * @param buf
1488340392eSAdrien Mazarguil  *   Pointer to mbuf.
1498340392eSAdrien Mazarguil  *
1508340392eSAdrien Mazarguil  * @return
1518340392eSAdrien Mazarguil  *   Memory pool where data is located for given mbuf.
1528340392eSAdrien Mazarguil  */
1538340392eSAdrien Mazarguil static struct rte_mempool *
1548340392eSAdrien Mazarguil txq_mb2mp(struct rte_mbuf *buf)
1558340392eSAdrien Mazarguil {
1568340392eSAdrien Mazarguil 	if (unlikely(RTE_MBUF_INDIRECT(buf)))
1578340392eSAdrien Mazarguil 		return rte_mbuf_from_indirect(buf)->pool;
1588340392eSAdrien Mazarguil 	return buf->pool;
1598340392eSAdrien Mazarguil }
1608340392eSAdrien Mazarguil 
161491770faSNélio Laranjeiro static inline uint32_t
162491770faSNélio Laranjeiro txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
163491770faSNélio Laranjeiro 	__attribute__((always_inline));
164491770faSNélio Laranjeiro 
1658340392eSAdrien Mazarguil /**
1662e22920bSAdrien Mazarguil  * Get Memory Region (MR) <-> Memory Pool (MP) association from txq->mp2mr[].
1672e22920bSAdrien Mazarguil  * Add MP to txq->mp2mr[] if it's not registered yet. If mp2mr[] is full,
1682e22920bSAdrien Mazarguil  * remove an entry first.
1692e22920bSAdrien Mazarguil  *
1702e22920bSAdrien Mazarguil  * @param txq
1712e22920bSAdrien Mazarguil  *   Pointer to TX queue structure.
1722e22920bSAdrien Mazarguil  * @param[in] mp
1732e22920bSAdrien Mazarguil  *   Memory Pool for which a Memory Region lkey must be returned.
1742e22920bSAdrien Mazarguil  *
1752e22920bSAdrien Mazarguil  * @return
1762e22920bSAdrien Mazarguil  *   mr->lkey on success, (uint32_t)-1 on failure.
1772e22920bSAdrien Mazarguil  */
178491770faSNélio Laranjeiro static inline uint32_t
179d1d914ebSOlivier Matz txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
1802e22920bSAdrien Mazarguil {
1812e22920bSAdrien Mazarguil 	unsigned int i;
182491770faSNélio Laranjeiro 	uint32_t lkey = (uint32_t)-1;
1832e22920bSAdrien Mazarguil 
1842e22920bSAdrien Mazarguil 	for (i = 0; (i != RTE_DIM(txq->mp2mr)); ++i) {
1852e22920bSAdrien Mazarguil 		if (unlikely(txq->mp2mr[i].mp == NULL)) {
1862e22920bSAdrien Mazarguil 			/* Unknown MP, add a new MR for it. */
1872e22920bSAdrien Mazarguil 			break;
1882e22920bSAdrien Mazarguil 		}
1892e22920bSAdrien Mazarguil 		if (txq->mp2mr[i].mp == mp) {
1902e22920bSAdrien Mazarguil 			assert(txq->mp2mr[i].lkey != (uint32_t)-1);
1912e22920bSAdrien Mazarguil 			assert(txq->mp2mr[i].mr->lkey == txq->mp2mr[i].lkey);
192491770faSNélio Laranjeiro 			lkey = txq->mp2mr[i].lkey;
193491770faSNélio Laranjeiro 			break;
1942e22920bSAdrien Mazarguil 		}
1952e22920bSAdrien Mazarguil 	}
196491770faSNélio Laranjeiro 	if (unlikely(lkey == (uint32_t)-1))
197491770faSNélio Laranjeiro 		lkey = txq_mp2mr_reg(txq, mp, i);
198491770faSNélio Laranjeiro 	return lkey;
1990a3b350dSOlga Shern }
2000a3b350dSOlga Shern 
201e192ef80SYaacov Hazan /**
202e192ef80SYaacov Hazan  * Insert VLAN using mbuf headroom space.
203e192ef80SYaacov Hazan  *
204e192ef80SYaacov Hazan  * @param buf
205e192ef80SYaacov Hazan  *   Buffer for VLAN insertion.
206e192ef80SYaacov Hazan  *
207e192ef80SYaacov Hazan  * @return
208e192ef80SYaacov Hazan  *   0 on success, errno value on failure.
209e192ef80SYaacov Hazan  */
210e192ef80SYaacov Hazan static inline int
211e192ef80SYaacov Hazan insert_vlan_sw(struct rte_mbuf *buf)
212e192ef80SYaacov Hazan {
213e192ef80SYaacov Hazan 	uintptr_t addr;
214e192ef80SYaacov Hazan 	uint32_t vlan;
215e192ef80SYaacov Hazan 	uint16_t head_room_len = rte_pktmbuf_headroom(buf);
216e192ef80SYaacov Hazan 
217e192ef80SYaacov Hazan 	if (head_room_len < 4)
218e192ef80SYaacov Hazan 		return EINVAL;
219e192ef80SYaacov Hazan 
220e192ef80SYaacov Hazan 	addr = rte_pktmbuf_mtod(buf, uintptr_t);
221e192ef80SYaacov Hazan 	vlan = htonl(0x81000000 | buf->vlan_tci);
222e192ef80SYaacov Hazan 	memmove((void *)(addr - 4), (void *)addr, 12);
223e192ef80SYaacov Hazan 	memcpy((void *)(addr + 8), &vlan, sizeof(vlan));
224e192ef80SYaacov Hazan 
225e192ef80SYaacov Hazan 	SET_DATA_OFF(buf, head_room_len - 4);
226e192ef80SYaacov Hazan 	DATA_LEN(buf) += 4;
227e192ef80SYaacov Hazan 
228e192ef80SYaacov Hazan 	return 0;
229e192ef80SYaacov Hazan }
230e192ef80SYaacov Hazan 
2312e22920bSAdrien Mazarguil /**
2322e22920bSAdrien Mazarguil  * DPDK callback for TX.
2332e22920bSAdrien Mazarguil  *
2342e22920bSAdrien Mazarguil  * @param dpdk_txq
2352e22920bSAdrien Mazarguil  *   Generic pointer to TX queue structure.
2362e22920bSAdrien Mazarguil  * @param[in] pkts
2372e22920bSAdrien Mazarguil  *   Packets to transmit.
2382e22920bSAdrien Mazarguil  * @param pkts_n
2392e22920bSAdrien Mazarguil  *   Number of packets in array.
2402e22920bSAdrien Mazarguil  *
2412e22920bSAdrien Mazarguil  * @return
2422e22920bSAdrien Mazarguil  *   Number of packets successfully transmitted (<= pkts_n).
2432e22920bSAdrien Mazarguil  */
2442e22920bSAdrien Mazarguil uint16_t
2452e22920bSAdrien Mazarguil mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
2462e22920bSAdrien Mazarguil {
2472e22920bSAdrien Mazarguil 	struct txq *txq = (struct txq *)dpdk_txq;
2482e22920bSAdrien Mazarguil 	unsigned int elts_head = txq->elts_head;
2492e22920bSAdrien Mazarguil 	const unsigned int elts_n = txq->elts_n;
2502e22920bSAdrien Mazarguil 	unsigned int elts_comp_cd = txq->elts_comp_cd;
2512e22920bSAdrien Mazarguil 	unsigned int elts_comp = 0;
2522e22920bSAdrien Mazarguil 	unsigned int i;
2532e22920bSAdrien Mazarguil 	unsigned int max;
2542e22920bSAdrien Mazarguil 	int err;
2555e1d11ecSNelio Laranjeiro 	struct rte_mbuf *buf = pkts[0];
2562e22920bSAdrien Mazarguil 
2572e22920bSAdrien Mazarguil 	assert(elts_comp_cd != 0);
2585e1d11ecSNelio Laranjeiro 	/* Prefetch first packet cacheline. */
2595e1d11ecSNelio Laranjeiro 	rte_prefetch0(buf);
2602e22920bSAdrien Mazarguil 	txq_complete(txq);
2614f52bbfbSNelio Laranjeiro 	max = (elts_n - (elts_head - txq->elts_tail));
2622e22920bSAdrien Mazarguil 	if (max > elts_n)
2632e22920bSAdrien Mazarguil 		max -= elts_n;
2642e22920bSAdrien Mazarguil 	assert(max >= 1);
2652e22920bSAdrien Mazarguil 	assert(max <= elts_n);
2662e22920bSAdrien Mazarguil 	/* Always leave one free entry in the ring. */
2672e22920bSAdrien Mazarguil 	--max;
2682e22920bSAdrien Mazarguil 	if (max == 0)
2692e22920bSAdrien Mazarguil 		return 0;
2702e22920bSAdrien Mazarguil 	if (max > pkts_n)
2712e22920bSAdrien Mazarguil 		max = pkts_n;
2722e22920bSAdrien Mazarguil 	for (i = 0; (i != max); ++i) {
2735e1d11ecSNelio Laranjeiro 		struct rte_mbuf *buf_next = pkts[i + 1];
2742e22920bSAdrien Mazarguil 		unsigned int elts_head_next =
2752e22920bSAdrien Mazarguil 			(((elts_head + 1) == elts_n) ? 0 : elts_head + 1);
2762e22920bSAdrien Mazarguil 		struct txq_elt *elt = &(*txq->elts)[elts_head];
2772e22920bSAdrien Mazarguil 		uint32_t send_flags = 0;
278e192ef80SYaacov Hazan #ifdef HAVE_VERBS_VLAN_INSERTION
279e192ef80SYaacov Hazan 		int insert_vlan = 0;
280e192ef80SYaacov Hazan #endif /* HAVE_VERBS_VLAN_INSERTION */
281573f54afSNélio Laranjeiro 		uintptr_t addr;
282573f54afSNélio Laranjeiro 		uint32_t length;
283573f54afSNélio Laranjeiro 		uint32_t lkey;
284573f54afSNélio Laranjeiro 		uintptr_t buf_next_addr;
2852e22920bSAdrien Mazarguil 
2865e1d11ecSNelio Laranjeiro 		if (i + 1 < max)
2875e1d11ecSNelio Laranjeiro 			rte_prefetch0(buf_next);
2882e22920bSAdrien Mazarguil 		/* Request TX completion. */
2892e22920bSAdrien Mazarguil 		if (unlikely(--elts_comp_cd == 0)) {
2902e22920bSAdrien Mazarguil 			elts_comp_cd = txq->elts_comp_cd_init;
2912e22920bSAdrien Mazarguil 			++elts_comp;
2922e22920bSAdrien Mazarguil 			send_flags |= IBV_EXP_QP_BURST_SIGNALED;
2932e22920bSAdrien Mazarguil 		}
29467fa62bcSAdrien Mazarguil 		/* Should we enable HW CKSUM offload */
29567fa62bcSAdrien Mazarguil 		if (buf->ol_flags &
29667fa62bcSAdrien Mazarguil 		    (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
29767fa62bcSAdrien Mazarguil 			send_flags |= IBV_EXP_QP_BURST_IP_CSUM;
29867fa62bcSAdrien Mazarguil 			/* HW does not support checksum offloads at arbitrary
29967fa62bcSAdrien Mazarguil 			 * offsets but automatically recognizes the packet
30067fa62bcSAdrien Mazarguil 			 * type. For inner L3/L4 checksums, only VXLAN (UDP)
30167fa62bcSAdrien Mazarguil 			 * tunnels are currently supported. */
30267fa62bcSAdrien Mazarguil 			if (RTE_ETH_IS_TUNNEL_PKT(buf->packet_type))
30367fa62bcSAdrien Mazarguil 				send_flags |= IBV_EXP_QP_BURST_TUNNEL;
30467fa62bcSAdrien Mazarguil 		}
305e192ef80SYaacov Hazan 		if (buf->ol_flags & PKT_TX_VLAN_PKT) {
306e192ef80SYaacov Hazan #ifdef HAVE_VERBS_VLAN_INSERTION
307e192ef80SYaacov Hazan 			if (!txq->priv->mps)
308e192ef80SYaacov Hazan 				insert_vlan = 1;
309e192ef80SYaacov Hazan 			else
310e192ef80SYaacov Hazan #endif /* HAVE_VERBS_VLAN_INSERTION */
311e192ef80SYaacov Hazan 			{
312e192ef80SYaacov Hazan 				err = insert_vlan_sw(buf);
313e192ef80SYaacov Hazan 				if (unlikely(err))
314e192ef80SYaacov Hazan 					goto stop;
315e192ef80SYaacov Hazan 			}
316e192ef80SYaacov Hazan 		}
3172e22920bSAdrien Mazarguil 		/* Retrieve buffer information. */
3182e22920bSAdrien Mazarguil 		addr = rte_pktmbuf_mtod(buf, uintptr_t);
3192e22920bSAdrien Mazarguil 		length = DATA_LEN(buf);
3202e22920bSAdrien Mazarguil 		/* Update element. */
3212e22920bSAdrien Mazarguil 		elt->buf = buf;
32285e347dbSNélio Laranjeiro 		if (txq->priv->sriov)
3232e22920bSAdrien Mazarguil 			rte_prefetch0((volatile void *)
3242e22920bSAdrien Mazarguil 				      (uintptr_t)addr);
3255e1d11ecSNelio Laranjeiro 		/* Prefetch next buffer data. */
3265e1d11ecSNelio Laranjeiro 		if (i + 1 < max) {
3275e1d11ecSNelio Laranjeiro 			buf_next_addr =
3285e1d11ecSNelio Laranjeiro 				rte_pktmbuf_mtod(buf_next, uintptr_t);
3295e1d11ecSNelio Laranjeiro 			rte_prefetch0((volatile void *)
3305e1d11ecSNelio Laranjeiro 				      (uintptr_t)buf_next_addr);
3315e1d11ecSNelio Laranjeiro 		}
332*0431c40fSNélio Laranjeiro 		/* Retrieve Memory Region key for this memory pool. */
333d970e992SNelio Laranjeiro 		lkey = txq_mp2mr(txq, txq_mb2mp(buf));
334d970e992SNelio Laranjeiro 		if (unlikely(lkey == (uint32_t)-1)) {
335d970e992SNelio Laranjeiro 			/* MR does not exist. */
336d970e992SNelio Laranjeiro 			DEBUG("%p: unable to get MP <-> MR"
337d970e992SNelio Laranjeiro 			      " association", (void *)txq);
338d970e992SNelio Laranjeiro 			/* Clean up TX element. */
339d970e992SNelio Laranjeiro 			elt->buf = NULL;
340d970e992SNelio Laranjeiro 			goto stop;
341d970e992SNelio Laranjeiro 		}
342e192ef80SYaacov Hazan #ifdef HAVE_VERBS_VLAN_INSERTION
343e192ef80SYaacov Hazan 		if (insert_vlan)
344e192ef80SYaacov Hazan 			err = txq->send_pending_vlan
345e192ef80SYaacov Hazan 				(txq->qp,
346e192ef80SYaacov Hazan 				 addr,
347e192ef80SYaacov Hazan 				 length,
348e192ef80SYaacov Hazan 				 lkey,
349e192ef80SYaacov Hazan 				 send_flags,
350e192ef80SYaacov Hazan 				 &buf->vlan_tci);
351e192ef80SYaacov Hazan 		else
352e192ef80SYaacov Hazan #endif /* HAVE_VERBS_VLAN_INSERTION */
353e1682023SNelio Laranjeiro 			err = txq->send_pending
3542e22920bSAdrien Mazarguil 				(txq->qp,
3552e22920bSAdrien Mazarguil 				 addr,
3562e22920bSAdrien Mazarguil 				 length,
3572e22920bSAdrien Mazarguil 				 lkey,
3582e22920bSAdrien Mazarguil 				 send_flags);
3592e22920bSAdrien Mazarguil 		if (unlikely(err))
3602e22920bSAdrien Mazarguil 			goto stop;
36187011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
362573f54afSNélio Laranjeiro 		/* Increment sent bytes counter. */
363573f54afSNélio Laranjeiro 		txq->stats.obytes += length;
36487011737SAdrien Mazarguil #endif
365573f54afSNélio Laranjeiro stop:
3662e22920bSAdrien Mazarguil 		elts_head = elts_head_next;
3675e1d11ecSNelio Laranjeiro 		buf = buf_next;
3682e22920bSAdrien Mazarguil 	}
3692e22920bSAdrien Mazarguil 	/* Take a shortcut if nothing must be sent. */
3702e22920bSAdrien Mazarguil 	if (unlikely(i == 0))
3712e22920bSAdrien Mazarguil 		return 0;
37287011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
37387011737SAdrien Mazarguil 	/* Increment sent packets counter. */
37487011737SAdrien Mazarguil 	txq->stats.opackets += i;
37587011737SAdrien Mazarguil #endif
3762e22920bSAdrien Mazarguil 	/* Ring QP doorbell. */
377e1682023SNelio Laranjeiro 	err = txq->send_flush(txq->qp);
3782e22920bSAdrien Mazarguil 	if (unlikely(err)) {
3792e22920bSAdrien Mazarguil 		/* A nonzero value is not supposed to be returned.
3802e22920bSAdrien Mazarguil 		 * Nothing can be done about it. */
3812e22920bSAdrien Mazarguil 		DEBUG("%p: send_flush() failed with error %d",
3822e22920bSAdrien Mazarguil 		      (void *)txq, err);
3832e22920bSAdrien Mazarguil 	}
3842e22920bSAdrien Mazarguil 	txq->elts_head = elts_head;
3852e22920bSAdrien Mazarguil 	txq->elts_comp += elts_comp;
3862e22920bSAdrien Mazarguil 	txq->elts_comp_cd = elts_comp_cd;
3872e22920bSAdrien Mazarguil 	return i;
3882e22920bSAdrien Mazarguil }
3892e22920bSAdrien Mazarguil 
3902e22920bSAdrien Mazarguil /**
39167fa62bcSAdrien Mazarguil  * Translate RX completion flags to packet type.
39267fa62bcSAdrien Mazarguil  *
39367fa62bcSAdrien Mazarguil  * @param flags
39467fa62bcSAdrien Mazarguil  *   RX completion flags returned by poll_length_flags().
39567fa62bcSAdrien Mazarguil  *
39678a38edfSJianfeng Tan  * @note: fix mlx5_dev_supported_ptypes_get() if any change here.
39778a38edfSJianfeng Tan  *
39867fa62bcSAdrien Mazarguil  * @return
39967fa62bcSAdrien Mazarguil  *   Packet type for struct rte_mbuf.
40067fa62bcSAdrien Mazarguil  */
40167fa62bcSAdrien Mazarguil static inline uint32_t
40267fa62bcSAdrien Mazarguil rxq_cq_to_pkt_type(uint32_t flags)
40367fa62bcSAdrien Mazarguil {
40467fa62bcSAdrien Mazarguil 	uint32_t pkt_type;
40567fa62bcSAdrien Mazarguil 
40667fa62bcSAdrien Mazarguil 	if (flags & IBV_EXP_CQ_RX_TUNNEL_PACKET)
40767fa62bcSAdrien Mazarguil 		pkt_type =
40867fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
40967fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_OUTER_IPV4_PACKET,
41067fa62bcSAdrien Mazarguil 				  RTE_PTYPE_L3_IPV4) |
41167fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
41267fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_OUTER_IPV6_PACKET,
41367fa62bcSAdrien Mazarguil 				  RTE_PTYPE_L3_IPV6) |
41467fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
41567fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_IPV4_PACKET,
41667fa62bcSAdrien Mazarguil 				  RTE_PTYPE_INNER_L3_IPV4) |
41767fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
41867fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_IPV6_PACKET,
41967fa62bcSAdrien Mazarguil 				  RTE_PTYPE_INNER_L3_IPV6);
42067fa62bcSAdrien Mazarguil 	else
42167fa62bcSAdrien Mazarguil 		pkt_type =
42267fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
42367fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_IPV4_PACKET,
42467fa62bcSAdrien Mazarguil 				  RTE_PTYPE_L3_IPV4) |
42567fa62bcSAdrien Mazarguil 			TRANSPOSE(flags,
42667fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_IPV6_PACKET,
42767fa62bcSAdrien Mazarguil 				  RTE_PTYPE_L3_IPV6);
42867fa62bcSAdrien Mazarguil 	return pkt_type;
42967fa62bcSAdrien Mazarguil }
43067fa62bcSAdrien Mazarguil 
43167fa62bcSAdrien Mazarguil /**
43267fa62bcSAdrien Mazarguil  * Translate RX completion flags to offload flags.
43367fa62bcSAdrien Mazarguil  *
43467fa62bcSAdrien Mazarguil  * @param[in] rxq
43567fa62bcSAdrien Mazarguil  *   Pointer to RX queue structure.
43667fa62bcSAdrien Mazarguil  * @param flags
43767fa62bcSAdrien Mazarguil  *   RX completion flags returned by poll_length_flags().
43867fa62bcSAdrien Mazarguil  *
43967fa62bcSAdrien Mazarguil  * @return
44067fa62bcSAdrien Mazarguil  *   Offload flags (ol_flags) for struct rte_mbuf.
44167fa62bcSAdrien Mazarguil  */
44267fa62bcSAdrien Mazarguil static inline uint32_t
44367fa62bcSAdrien Mazarguil rxq_cq_to_ol_flags(const struct rxq *rxq, uint32_t flags)
44467fa62bcSAdrien Mazarguil {
44567fa62bcSAdrien Mazarguil 	uint32_t ol_flags = 0;
44667fa62bcSAdrien Mazarguil 
447d0087d76SYaacov Hazan 	if (rxq->csum) {
448d0087d76SYaacov Hazan 		/* Set IP checksum flag only for IPv4/IPv6 packets. */
449d0087d76SYaacov Hazan 		if (flags &
450d0087d76SYaacov Hazan 		    (IBV_EXP_CQ_RX_IPV4_PACKET | IBV_EXP_CQ_RX_IPV6_PACKET))
45167fa62bcSAdrien Mazarguil 			ol_flags |=
45267fa62bcSAdrien Mazarguil 				TRANSPOSE(~flags,
45367fa62bcSAdrien Mazarguil 					IBV_EXP_CQ_RX_IP_CSUM_OK,
454d0087d76SYaacov Hazan 					PKT_RX_IP_CKSUM_BAD);
455d0087d76SYaacov Hazan #ifdef HAVE_EXP_CQ_RX_TCP_PACKET
456d0087d76SYaacov Hazan 		/* Set L4 checksum flag only for TCP/UDP packets. */
457d0087d76SYaacov Hazan 		if (flags &
458d0087d76SYaacov Hazan 		    (IBV_EXP_CQ_RX_TCP_PACKET | IBV_EXP_CQ_RX_UDP_PACKET))
459d0087d76SYaacov Hazan #endif /* HAVE_EXP_CQ_RX_TCP_PACKET */
460d0087d76SYaacov Hazan 			ol_flags |=
46167fa62bcSAdrien Mazarguil 				TRANSPOSE(~flags,
46267fa62bcSAdrien Mazarguil 					IBV_EXP_CQ_RX_TCP_UDP_CSUM_OK,
46367fa62bcSAdrien Mazarguil 					PKT_RX_L4_CKSUM_BAD);
464d0087d76SYaacov Hazan 	}
46567fa62bcSAdrien Mazarguil 	/*
46667fa62bcSAdrien Mazarguil 	 * PKT_RX_IP_CKSUM_BAD and PKT_RX_L4_CKSUM_BAD are used in place
46767fa62bcSAdrien Mazarguil 	 * of PKT_RX_EIP_CKSUM_BAD because the latter is not functional
46867fa62bcSAdrien Mazarguil 	 * (its value is 0).
46967fa62bcSAdrien Mazarguil 	 */
47067fa62bcSAdrien Mazarguil 	if ((flags & IBV_EXP_CQ_RX_TUNNEL_PACKET) && (rxq->csum_l2tun))
47167fa62bcSAdrien Mazarguil 		ol_flags |=
47267fa62bcSAdrien Mazarguil 			TRANSPOSE(~flags,
47367fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_OUTER_IP_CSUM_OK,
47467fa62bcSAdrien Mazarguil 				  PKT_RX_IP_CKSUM_BAD) |
47567fa62bcSAdrien Mazarguil 			TRANSPOSE(~flags,
47667fa62bcSAdrien Mazarguil 				  IBV_EXP_CQ_RX_OUTER_TCP_UDP_CSUM_OK,
47767fa62bcSAdrien Mazarguil 				  PKT_RX_L4_CKSUM_BAD);
47867fa62bcSAdrien Mazarguil 	return ol_flags;
47967fa62bcSAdrien Mazarguil }
48067fa62bcSAdrien Mazarguil 
48167fa62bcSAdrien Mazarguil /**
4822e22920bSAdrien Mazarguil  * DPDK callback for RX.
4832e22920bSAdrien Mazarguil  *
4842e22920bSAdrien Mazarguil  * @param dpdk_rxq
4852e22920bSAdrien Mazarguil  *   Generic pointer to RX queue structure.
4862e22920bSAdrien Mazarguil  * @param[out] pkts
4872e22920bSAdrien Mazarguil  *   Array to store received packets.
4882e22920bSAdrien Mazarguil  * @param pkts_n
4892e22920bSAdrien Mazarguil  *   Maximum number of packets in array.
4902e22920bSAdrien Mazarguil  *
4912e22920bSAdrien Mazarguil  * @return
4922e22920bSAdrien Mazarguil  *   Number of packets successfully received (<= pkts_n).
4932e22920bSAdrien Mazarguil  */
4942e22920bSAdrien Mazarguil uint16_t
4952e22920bSAdrien Mazarguil mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
4962e22920bSAdrien Mazarguil {
4972e22920bSAdrien Mazarguil 	struct rxq *rxq = (struct rxq *)dpdk_rxq;
4983f5ac8f2SNélio Laranjeiro 	struct rxq_elt (*elts)[rxq->elts_n] = rxq->elts;
4992e22920bSAdrien Mazarguil 	const unsigned int elts_n = rxq->elts_n;
5002e22920bSAdrien Mazarguil 	unsigned int elts_head = rxq->elts_head;
5012e22920bSAdrien Mazarguil 	struct ibv_sge sges[pkts_n];
5022e22920bSAdrien Mazarguil 	unsigned int i;
5032e22920bSAdrien Mazarguil 	unsigned int pkts_ret = 0;
5042e22920bSAdrien Mazarguil 	int ret;
5052e22920bSAdrien Mazarguil 
5062e22920bSAdrien Mazarguil 	for (i = 0; (i != pkts_n); ++i) {
5072e22920bSAdrien Mazarguil 		struct rxq_elt *elt = &(*elts)[elts_head];
5082e22920bSAdrien Mazarguil 		unsigned int len;
509aa7f63abSAdrien Mazarguil 		struct rte_mbuf *seg = elt->buf;
5102e22920bSAdrien Mazarguil 		struct rte_mbuf *rep;
5112e22920bSAdrien Mazarguil 		uint32_t flags;
512f3db9489SYaacov Hazan 		uint16_t vlan_tci;
5132e22920bSAdrien Mazarguil 
5142e22920bSAdrien Mazarguil 		/* Sanity checks. */
515aa7f63abSAdrien Mazarguil 		assert(seg != NULL);
5162e22920bSAdrien Mazarguil 		assert(elts_head < rxq->elts_n);
5172e22920bSAdrien Mazarguil 		assert(rxq->elts_head < rxq->elts_n);
5182e22920bSAdrien Mazarguil 		/*
5192e22920bSAdrien Mazarguil 		 * Fetch initial bytes of packet descriptor into a
5202e22920bSAdrien Mazarguil 		 * cacheline while allocating rep.
5212e22920bSAdrien Mazarguil 		 */
522e8988095SOlivier Matz 		rte_mbuf_prefetch_part1(seg);
523e8988095SOlivier Matz 		rte_mbuf_prefetch_part2(seg);
524e1682023SNelio Laranjeiro 		ret = rxq->poll(rxq->cq, NULL, NULL, &flags, &vlan_tci);
5252e22920bSAdrien Mazarguil 		if (unlikely(ret < 0)) {
5262e22920bSAdrien Mazarguil 			struct ibv_wc wc;
5272e22920bSAdrien Mazarguil 			int wcs_n;
5282e22920bSAdrien Mazarguil 
5292e22920bSAdrien Mazarguil 			DEBUG("rxq=%p, poll_length() failed (ret=%d)",
5302e22920bSAdrien Mazarguil 			      (void *)rxq, ret);
5312e22920bSAdrien Mazarguil 			/* ibv_poll_cq() must be used in case of failure. */
5322e22920bSAdrien Mazarguil 			wcs_n = ibv_poll_cq(rxq->cq, 1, &wc);
5332e22920bSAdrien Mazarguil 			if (unlikely(wcs_n == 0))
5342e22920bSAdrien Mazarguil 				break;
5352e22920bSAdrien Mazarguil 			if (unlikely(wcs_n < 0)) {
5362e22920bSAdrien Mazarguil 				DEBUG("rxq=%p, ibv_poll_cq() failed (wcs_n=%d)",
5372e22920bSAdrien Mazarguil 				      (void *)rxq, wcs_n);
5382e22920bSAdrien Mazarguil 				break;
5392e22920bSAdrien Mazarguil 			}
5402e22920bSAdrien Mazarguil 			assert(wcs_n == 1);
5412e22920bSAdrien Mazarguil 			if (unlikely(wc.status != IBV_WC_SUCCESS)) {
5422e22920bSAdrien Mazarguil 				/* Whatever, just repost the offending WR. */
5432e22920bSAdrien Mazarguil 				DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work"
5442e22920bSAdrien Mazarguil 				      " completion status (%d): %s",
5452e22920bSAdrien Mazarguil 				      (void *)rxq, wc.wr_id, wc.status,
5462e22920bSAdrien Mazarguil 				      ibv_wc_status_str(wc.status));
54787011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
54887011737SAdrien Mazarguil 				/* Increment dropped packets counter. */
54987011737SAdrien Mazarguil 				++rxq->stats.idropped;
55087011737SAdrien Mazarguil #endif
5512e22920bSAdrien Mazarguil 				/* Add SGE to array for repost. */
5522e22920bSAdrien Mazarguil 				sges[i] = elt->sge;
5532e22920bSAdrien Mazarguil 				goto repost;
5542e22920bSAdrien Mazarguil 			}
5552e22920bSAdrien Mazarguil 			ret = wc.byte_len;
5562e22920bSAdrien Mazarguil 		}
5572e22920bSAdrien Mazarguil 		if (ret == 0)
5582e22920bSAdrien Mazarguil 			break;
5594d326709SOlga Shern 		assert(ret >= (rxq->crc_present << 2));
5604d326709SOlga Shern 		len = ret - (rxq->crc_present << 2);
561fbfd9955SOlivier Matz 		rep = rte_mbuf_raw_alloc(rxq->mp);
5622e22920bSAdrien Mazarguil 		if (unlikely(rep == NULL)) {
5632e22920bSAdrien Mazarguil 			/*
5642e22920bSAdrien Mazarguil 			 * Unable to allocate a replacement mbuf,
5652e22920bSAdrien Mazarguil 			 * repost WR.
5662e22920bSAdrien Mazarguil 			 */
567aa7f63abSAdrien Mazarguil 			DEBUG("rxq=%p: can't allocate a new mbuf",
568aa7f63abSAdrien Mazarguil 			      (void *)rxq);
5692e22920bSAdrien Mazarguil 			/* Increment out of memory counters. */
57087011737SAdrien Mazarguil 			++rxq->stats.rx_nombuf;
5712e22920bSAdrien Mazarguil 			++rxq->priv->dev->data->rx_mbuf_alloc_failed;
5722e22920bSAdrien Mazarguil 			goto repost;
5732e22920bSAdrien Mazarguil 		}
5742e22920bSAdrien Mazarguil 
5752e22920bSAdrien Mazarguil 		/* Reconfigure sge to use rep instead of seg. */
5762e22920bSAdrien Mazarguil 		elt->sge.addr = (uintptr_t)rep->buf_addr + RTE_PKTMBUF_HEADROOM;
5772e22920bSAdrien Mazarguil 		assert(elt->sge.lkey == rxq->mr->lkey);
578aa7f63abSAdrien Mazarguil 		elt->buf = rep;
5792e22920bSAdrien Mazarguil 
5802e22920bSAdrien Mazarguil 		/* Add SGE to array for repost. */
5812e22920bSAdrien Mazarguil 		sges[i] = elt->sge;
5822e22920bSAdrien Mazarguil 
5832e22920bSAdrien Mazarguil 		/* Update seg information. */
5842e22920bSAdrien Mazarguil 		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
5852e22920bSAdrien Mazarguil 		NB_SEGS(seg) = 1;
5862e22920bSAdrien Mazarguil 		PORT(seg) = rxq->port_id;
5872e22920bSAdrien Mazarguil 		NEXT(seg) = NULL;
5882e22920bSAdrien Mazarguil 		PKT_LEN(seg) = len;
5892e22920bSAdrien Mazarguil 		DATA_LEN(seg) = len;
590081f7eaeSNelio Laranjeiro 		if (rxq->csum | rxq->csum_l2tun | rxq->vlan_strip) {
59167fa62bcSAdrien Mazarguil 			seg->packet_type = rxq_cq_to_pkt_type(flags);
59267fa62bcSAdrien Mazarguil 			seg->ol_flags = rxq_cq_to_ol_flags(rxq, flags);
593f3db9489SYaacov Hazan #ifdef HAVE_EXP_DEVICE_ATTR_VLAN_OFFLOADS
594f3db9489SYaacov Hazan 			if (flags & IBV_EXP_CQ_RX_CVLAN_STRIPPED_V1) {
595b37b528dSOlivier Matz 				seg->ol_flags |= PKT_RX_VLAN_PKT |
596b37b528dSOlivier Matz 					PKT_RX_VLAN_STRIPPED;
597f3db9489SYaacov Hazan 				seg->vlan_tci = vlan_tci;
598f3db9489SYaacov Hazan 			}
599f3db9489SYaacov Hazan #endif /* HAVE_EXP_DEVICE_ATTR_VLAN_OFFLOADS */
600081f7eaeSNelio Laranjeiro 		}
6012e22920bSAdrien Mazarguil 		/* Return packet. */
6022e22920bSAdrien Mazarguil 		*(pkts++) = seg;
6032e22920bSAdrien Mazarguil 		++pkts_ret;
60487011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
60587011737SAdrien Mazarguil 		/* Increment bytes counter. */
60687011737SAdrien Mazarguil 		rxq->stats.ibytes += len;
60787011737SAdrien Mazarguil #endif
6082e22920bSAdrien Mazarguil repost:
6092e22920bSAdrien Mazarguil 		if (++elts_head >= elts_n)
6102e22920bSAdrien Mazarguil 			elts_head = 0;
6112e22920bSAdrien Mazarguil 		continue;
6122e22920bSAdrien Mazarguil 	}
6132e22920bSAdrien Mazarguil 	if (unlikely(i == 0))
6142e22920bSAdrien Mazarguil 		return 0;
6152e22920bSAdrien Mazarguil 	/* Repost WRs. */
6162e22920bSAdrien Mazarguil #ifdef DEBUG_RECV
6172e22920bSAdrien Mazarguil 	DEBUG("%p: reposting %u WRs", (void *)rxq, i);
6182e22920bSAdrien Mazarguil #endif
619e1682023SNelio Laranjeiro 	ret = rxq->recv(rxq->wq, sges, i);
6202e22920bSAdrien Mazarguil 	if (unlikely(ret)) {
6212e22920bSAdrien Mazarguil 		/* Inability to repost WRs is fatal. */
6222e22920bSAdrien Mazarguil 		DEBUG("%p: recv_burst(): failed (ret=%d)",
6232e22920bSAdrien Mazarguil 		      (void *)rxq->priv,
6242e22920bSAdrien Mazarguil 		      ret);
6252e22920bSAdrien Mazarguil 		abort();
6262e22920bSAdrien Mazarguil 	}
6272e22920bSAdrien Mazarguil 	rxq->elts_head = elts_head;
62887011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
62987011737SAdrien Mazarguil 	/* Increment packets counter. */
63087011737SAdrien Mazarguil 	rxq->stats.ipackets += pkts_ret;
63187011737SAdrien Mazarguil #endif
6322e22920bSAdrien Mazarguil 	return pkts_ret;
6332e22920bSAdrien Mazarguil }
6342e22920bSAdrien Mazarguil 
6352e22920bSAdrien Mazarguil /**
6362e22920bSAdrien Mazarguil  * Dummy DPDK callback for TX.
6372e22920bSAdrien Mazarguil  *
6382e22920bSAdrien Mazarguil  * This function is used to temporarily replace the real callback during
6392e22920bSAdrien Mazarguil  * unsafe control operations on the queue, or in case of error.
6402e22920bSAdrien Mazarguil  *
6412e22920bSAdrien Mazarguil  * @param dpdk_txq
6422e22920bSAdrien Mazarguil  *   Generic pointer to TX queue structure.
6432e22920bSAdrien Mazarguil  * @param[in] pkts
6442e22920bSAdrien Mazarguil  *   Packets to transmit.
6452e22920bSAdrien Mazarguil  * @param pkts_n
6462e22920bSAdrien Mazarguil  *   Number of packets in array.
6472e22920bSAdrien Mazarguil  *
6482e22920bSAdrien Mazarguil  * @return
6492e22920bSAdrien Mazarguil  *   Number of packets successfully transmitted (<= pkts_n).
6502e22920bSAdrien Mazarguil  */
6512e22920bSAdrien Mazarguil uint16_t
6522e22920bSAdrien Mazarguil removed_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
6532e22920bSAdrien Mazarguil {
6542e22920bSAdrien Mazarguil 	(void)dpdk_txq;
6552e22920bSAdrien Mazarguil 	(void)pkts;
6562e22920bSAdrien Mazarguil 	(void)pkts_n;
6572e22920bSAdrien Mazarguil 	return 0;
6582e22920bSAdrien Mazarguil }
6592e22920bSAdrien Mazarguil 
6602e22920bSAdrien Mazarguil /**
6612e22920bSAdrien Mazarguil  * Dummy DPDK callback for RX.
6622e22920bSAdrien Mazarguil  *
6632e22920bSAdrien Mazarguil  * This function is used to temporarily replace the real callback during
6642e22920bSAdrien Mazarguil  * unsafe control operations on the queue, or in case of error.
6652e22920bSAdrien Mazarguil  *
6662e22920bSAdrien Mazarguil  * @param dpdk_rxq
6672e22920bSAdrien Mazarguil  *   Generic pointer to RX queue structure.
6682e22920bSAdrien Mazarguil  * @param[out] pkts
6692e22920bSAdrien Mazarguil  *   Array to store received packets.
6702e22920bSAdrien Mazarguil  * @param pkts_n
6712e22920bSAdrien Mazarguil  *   Maximum number of packets in array.
6722e22920bSAdrien Mazarguil  *
6732e22920bSAdrien Mazarguil  * @return
6742e22920bSAdrien Mazarguil  *   Number of packets successfully received (<= pkts_n).
6752e22920bSAdrien Mazarguil  */
6762e22920bSAdrien Mazarguil uint16_t
6772e22920bSAdrien Mazarguil removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
6782e22920bSAdrien Mazarguil {
6792e22920bSAdrien Mazarguil 	(void)dpdk_rxq;
6802e22920bSAdrien Mazarguil 	(void)pkts;
6812e22920bSAdrien Mazarguil 	(void)pkts_n;
6822e22920bSAdrien Mazarguil 	return 0;
6832e22920bSAdrien Mazarguil }
684