net/mlx5: re-factorize functions
[dpdk.git] / drivers / net / mlx5 / mlx5_rxtx.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright 2015 6WIND S.A.
5  *   Copyright 2015 Mellanox.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of 6WIND S.A. nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <assert.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <stdlib.h>
38
39 /* Verbs header. */
40 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
41 #ifdef PEDANTIC
42 #pragma GCC diagnostic ignored "-pedantic"
43 #endif
44 #include <infiniband/verbs.h>
45 #include <infiniband/mlx5_hw.h>
46 #include <infiniband/arch.h>
47 #ifdef PEDANTIC
48 #pragma GCC diagnostic error "-pedantic"
49 #endif
50
51 /* DPDK headers don't like -pedantic. */
52 #ifdef PEDANTIC
53 #pragma GCC diagnostic ignored "-pedantic"
54 #endif
55 #include <rte_mbuf.h>
56 #include <rte_mempool.h>
57 #include <rte_prefetch.h>
58 #include <rte_common.h>
59 #include <rte_branch_prediction.h>
60 #include <rte_ether.h>
61 #ifdef PEDANTIC
62 #pragma GCC diagnostic error "-pedantic"
63 #endif
64
65 #include "mlx5.h"
66 #include "mlx5_utils.h"
67 #include "mlx5_rxtx.h"
68 #include "mlx5_autoconf.h"
69 #include "mlx5_defs.h"
70 #include "mlx5_prm.h"
71
72 #ifndef NDEBUG
73
74 /**
75  * Verify or set magic value in CQE.
76  *
77  * @param cqe
78  *   Pointer to CQE.
79  *
80  * @return
81  *   0 the first time.
82  */
83 static inline int
84 check_cqe64_seen(volatile struct mlx5_cqe64 *cqe)
85 {
86         static const uint8_t magic[] = "seen";
87         volatile uint8_t (*buf)[sizeof(cqe->rsvd40)] = &cqe->rsvd40;
88         int ret = 1;
89         unsigned int i;
90
91         for (i = 0; i < sizeof(magic) && i < sizeof(*buf); ++i)
92                 if (!ret || (*buf)[i] != magic[i]) {
93                         ret = 0;
94                         (*buf)[i] = magic[i];
95                 }
96         return ret;
97 }
98
99 #endif /* NDEBUG */
100
101 static inline int
102 check_cqe64(volatile struct mlx5_cqe64 *cqe,
103             unsigned int cqes_n, const uint16_t ci)
104             __attribute__((always_inline));
105
106 /**
107  * Check whether CQE is valid.
108  *
109  * @param cqe
110  *   Pointer to CQE.
111  * @param cqes_n
112  *   Size of completion queue.
113  * @param ci
114  *   Consumer index.
115  *
116  * @return
117  *   0 on success, 1 on failure.
118  */
119 static inline int
120 check_cqe64(volatile struct mlx5_cqe64 *cqe,
121                 unsigned int cqes_n, const uint16_t ci)
122 {
123         uint16_t idx = ci & cqes_n;
124         uint8_t op_own = cqe->op_own;
125         uint8_t op_owner = MLX5_CQE_OWNER(op_own);
126         uint8_t op_code = MLX5_CQE_OPCODE(op_own);
127
128         if (unlikely((op_owner != (!!(idx))) || (op_code == MLX5_CQE_INVALID)))
129                 return 1; /* No CQE. */
130 #ifndef NDEBUG
131         if ((op_code == MLX5_CQE_RESP_ERR) ||
132             (op_code == MLX5_CQE_REQ_ERR)) {
133                 volatile struct mlx5_err_cqe *err_cqe = (volatile void *)cqe;
134                 uint8_t syndrome = err_cqe->syndrome;
135
136                 if ((syndrome == MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR) ||
137                     (syndrome == MLX5_CQE_SYNDROME_REMOTE_ABORTED_ERR))
138                         return 0;
139                 if (!check_cqe64_seen(cqe))
140                         ERROR("unexpected CQE error %u (0x%02x)"
141                               " syndrome 0x%02x",
142                               op_code, op_code, syndrome);
143                 return 1;
144         } else if ((op_code != MLX5_CQE_RESP_SEND) &&
145                    (op_code != MLX5_CQE_REQ)) {
146                 if (!check_cqe64_seen(cqe))
147                         ERROR("unexpected CQE opcode %u (0x%02x)",
148                               op_code, op_code);
149                 return 1;
150         }
151 #endif /* NDEBUG */
152         return 0;
153 }
154
155 static inline void
156 txq_complete(struct txq *txq) __attribute__((always_inline));
157
158 /**
159  * Manage TX completions.
160  *
161  * When sending a burst, mlx5_tx_burst() posts several WRs.
162  *
163  * @param txq
164  *   Pointer to TX queue structure.
165  */
166 static inline void
167 txq_complete(struct txq *txq)
168 {
169         const unsigned int elts_n = txq->elts_n;
170         const unsigned int cqe_n = txq->cqe_n;
171         const unsigned int cqe_cnt = cqe_n - 1;
172         uint16_t elts_free = txq->elts_tail;
173         uint16_t elts_tail;
174         uint16_t cq_ci = txq->cq_ci;
175         volatile struct mlx5_cqe64 *cqe = NULL;
176         volatile union mlx5_wqe *wqe;
177
178         do {
179                 volatile struct mlx5_cqe64 *tmp;
180
181                 tmp = &(*txq->cqes)[cq_ci & cqe_cnt].cqe64;
182                 if (check_cqe64(tmp, cqe_n, cq_ci))
183                         break;
184                 cqe = tmp;
185 #ifndef NDEBUG
186                 if (MLX5_CQE_FORMAT(cqe->op_own) == MLX5_COMPRESSED) {
187                         if (!check_cqe64_seen(cqe))
188                                 ERROR("unexpected compressed CQE, TX stopped");
189                         return;
190                 }
191                 if ((MLX5_CQE_OPCODE(cqe->op_own) == MLX5_CQE_RESP_ERR) ||
192                     (MLX5_CQE_OPCODE(cqe->op_own) == MLX5_CQE_REQ_ERR)) {
193                         if (!check_cqe64_seen(cqe))
194                                 ERROR("unexpected error CQE, TX stopped");
195                         return;
196                 }
197 #endif /* NDEBUG */
198                 ++cq_ci;
199         } while (1);
200         if (unlikely(cqe == NULL))
201                 return;
202         wqe = &(*txq->wqes)[htons(cqe->wqe_counter) & (txq->wqe_n - 1)];
203         elts_tail = wqe->wqe.ctrl.data[3];
204         assert(elts_tail < txq->wqe_n);
205         /* Free buffers. */
206         while (elts_free != elts_tail) {
207                 struct rte_mbuf *elt = (*txq->elts)[elts_free];
208                 unsigned int elts_free_next =
209                         (elts_free + 1) & (elts_n - 1);
210                 struct rte_mbuf *elt_next = (*txq->elts)[elts_free_next];
211
212 #ifndef NDEBUG
213                 /* Poisoning. */
214                 memset(&(*txq->elts)[elts_free],
215                        0x66,
216                        sizeof((*txq->elts)[elts_free]));
217 #endif
218                 RTE_MBUF_PREFETCH_TO_FREE(elt_next);
219                 /* Only one segment needs to be freed. */
220                 rte_pktmbuf_free_seg(elt);
221                 elts_free = elts_free_next;
222         }
223         txq->cq_ci = cq_ci;
224         txq->elts_tail = elts_tail;
225         /* Update the consumer index. */
226         rte_wmb();
227         *txq->cq_db = htonl(cq_ci);
228 }
229
230 /**
231  * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which
232  * the cloned mbuf is allocated is returned instead.
233  *
234  * @param buf
235  *   Pointer to mbuf.
236  *
237  * @return
238  *   Memory pool where data is located for given mbuf.
239  */
240 static struct rte_mempool *
241 txq_mb2mp(struct rte_mbuf *buf)
242 {
243         if (unlikely(RTE_MBUF_INDIRECT(buf)))
244                 return rte_mbuf_from_indirect(buf)->pool;
245         return buf->pool;
246 }
247
248 static inline uint32_t
249 txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
250         __attribute__((always_inline));
251
252 /**
253  * Get Memory Region (MR) <-> Memory Pool (MP) association from txq->mp2mr[].
254  * Add MP to txq->mp2mr[] if it's not registered yet. If mp2mr[] is full,
255  * remove an entry first.
256  *
257  * @param txq
258  *   Pointer to TX queue structure.
259  * @param[in] mp
260  *   Memory Pool for which a Memory Region lkey must be returned.
261  *
262  * @return
263  *   mr->lkey on success, (uint32_t)-1 on failure.
264  */
265 static inline uint32_t
266 txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
267 {
268         unsigned int i;
269         uint32_t lkey = (uint32_t)-1;
270
271         for (i = 0; (i != RTE_DIM(txq->mp2mr)); ++i) {
272                 if (unlikely(txq->mp2mr[i].mp == NULL)) {
273                         /* Unknown MP, add a new MR for it. */
274                         break;
275                 }
276                 if (txq->mp2mr[i].mp == mp) {
277                         assert(txq->mp2mr[i].lkey != (uint32_t)-1);
278                         assert(htonl(txq->mp2mr[i].mr->lkey) ==
279                                txq->mp2mr[i].lkey);
280                         lkey = txq->mp2mr[i].lkey;
281                         break;
282                 }
283         }
284         if (unlikely(lkey == (uint32_t)-1))
285                 lkey = txq_mp2mr_reg(txq, mp, i);
286         return lkey;
287 }
288
289 /**
290  * Write a regular WQE.
291  *
292  * @param txq
293  *   Pointer to TX queue structure.
294  * @param wqe
295  *   Pointer to the WQE to fill.
296  * @param buf
297  *   Buffer.
298  * @param length
299  *   Packet length.
300  * @param lkey
301  *   Memory region lkey.
302  */
303 static inline void
304 mlx5_wqe_write(struct txq *txq, volatile union mlx5_wqe *wqe,
305                struct rte_mbuf *buf, uint32_t length, uint32_t lkey)
306 {
307         uintptr_t addr = rte_pktmbuf_mtod(buf, uintptr_t);
308
309         rte_mov16((uint8_t *)&wqe->wqe.eseg.inline_hdr_start,
310                   (uint8_t *)addr);
311         addr += 16;
312         length -= 16;
313         /* Need to insert VLAN ? */
314         if (buf->ol_flags & PKT_TX_VLAN_PKT) {
315                 uint32_t vlan = htonl(0x81000000 | buf->vlan_tci);
316
317                 memcpy((uint8_t *)&wqe->wqe.eseg.inline_hdr_start + 12,
318                        &vlan, sizeof(vlan));
319                 addr -= sizeof(vlan);
320                 length += sizeof(vlan);
321         }
322         /* Write the WQE. */
323         wqe->wqe.ctrl.data[0] = htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND);
324         wqe->wqe.ctrl.data[1] = htonl((txq->qp_num_8s) | 4);
325         wqe->wqe.ctrl.data[2] = 0;
326         wqe->wqe.ctrl.data[3] = 0;
327         wqe->inl.eseg.rsvd0 = 0;
328         wqe->inl.eseg.rsvd1 = 0;
329         wqe->inl.eseg.mss = 0;
330         wqe->inl.eseg.rsvd2 = 0;
331         wqe->wqe.eseg.inline_hdr_sz = htons(16);
332         /* Store remaining data in data segment. */
333         wqe->wqe.dseg.byte_count = htonl(length);
334         wqe->wqe.dseg.lkey = lkey;
335         wqe->wqe.dseg.addr = htonll(addr);
336         /* Increment consumer index. */
337         ++txq->wqe_ci;
338 }
339
340 /**
341  * Write a inline WQE.
342  *
343  * @param txq
344  *   Pointer to TX queue structure.
345  * @param wqe
346  *   Pointer to the WQE to fill.
347  * @param addr
348  *   Buffer data address.
349  * @param length
350  *   Packet length.
351  * @param lkey
352  *   Memory region lkey.
353  */
354 static inline void
355 mlx5_wqe_write_inline(struct txq *txq, volatile union mlx5_wqe *wqe,
356                       uintptr_t addr, uint32_t length)
357 {
358         uint32_t size;
359         uint16_t wqe_cnt = txq->wqe_n - 1;
360         uint16_t wqe_ci = txq->wqe_ci + 1;
361
362         /* Copy the first 16 bytes into inline header. */
363         rte_memcpy((void *)(uintptr_t)wqe->inl.eseg.inline_hdr_start,
364                    (void *)(uintptr_t)addr,
365                    MLX5_ETH_INLINE_HEADER_SIZE);
366         addr += MLX5_ETH_INLINE_HEADER_SIZE;
367         length -= MLX5_ETH_INLINE_HEADER_SIZE;
368         size = 3 + ((4 + length + 15) / 16);
369         wqe->inl.byte_cnt = htonl(length | MLX5_INLINE_SEG);
370         rte_memcpy((void *)(uintptr_t)&wqe->inl.data[0],
371                    (void *)addr, MLX5_WQE64_INL_DATA);
372         addr += MLX5_WQE64_INL_DATA;
373         length -= MLX5_WQE64_INL_DATA;
374         while (length) {
375                 volatile union mlx5_wqe *wqe_next =
376                         &(*txq->wqes)[wqe_ci & wqe_cnt];
377                 uint32_t copy_bytes = (length > sizeof(*wqe)) ?
378                                       sizeof(*wqe) :
379                                       length;
380
381                 rte_mov64((uint8_t *)(uintptr_t)&wqe_next->data[0],
382                           (uint8_t *)addr);
383                 addr += copy_bytes;
384                 length -= copy_bytes;
385                 ++wqe_ci;
386         }
387         assert(size < 64);
388         wqe->inl.ctrl.data[0] = htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND);
389         wqe->inl.ctrl.data[1] = htonl(txq->qp_num_8s | size);
390         wqe->inl.ctrl.data[2] = 0;
391         wqe->inl.ctrl.data[3] = 0;
392         wqe->inl.eseg.rsvd0 = 0;
393         wqe->inl.eseg.rsvd1 = 0;
394         wqe->inl.eseg.mss = 0;
395         wqe->inl.eseg.rsvd2 = 0;
396         wqe->inl.eseg.inline_hdr_sz = htons(MLX5_ETH_INLINE_HEADER_SIZE);
397         /* Increment consumer index. */
398         txq->wqe_ci = wqe_ci;
399 }
400
401 /**
402  * Write a inline WQE with VLAN.
403  *
404  * @param txq
405  *   Pointer to TX queue structure.
406  * @param wqe
407  *   Pointer to the WQE to fill.
408  * @param addr
409  *   Buffer data address.
410  * @param length
411  *   Packet length.
412  * @param lkey
413  *   Memory region lkey.
414  * @param vlan_tci
415  *   VLAN field to insert in packet.
416  */
417 static inline void
418 mlx5_wqe_write_inline_vlan(struct txq *txq, volatile union mlx5_wqe *wqe,
419                            uintptr_t addr, uint32_t length, uint16_t vlan_tci)
420 {
421         uint32_t size;
422         uint32_t wqe_cnt = txq->wqe_n - 1;
423         uint16_t wqe_ci = txq->wqe_ci + 1;
424         uint32_t vlan = htonl(0x81000000 | vlan_tci);
425
426         /*
427          * Copy 12 bytes of source & destination MAC address.
428          * Copy 4 bytes of VLAN.
429          * Copy 2 bytes of Ether type.
430          */
431         rte_memcpy((uint8_t *)(uintptr_t)wqe->inl.eseg.inline_hdr_start,
432                    (uint8_t *)addr, 12);
433         rte_memcpy((uint8_t *)(uintptr_t)wqe->inl.eseg.inline_hdr_start + 12,
434                    &vlan, sizeof(vlan));
435         rte_memcpy((uint8_t *)((uintptr_t)wqe->inl.eseg.inline_hdr_start + 16),
436                    (uint8_t *)(addr + 12), 2);
437         addr += MLX5_ETH_VLAN_INLINE_HEADER_SIZE - sizeof(vlan);
438         length -= MLX5_ETH_VLAN_INLINE_HEADER_SIZE - sizeof(vlan);
439         size = (sizeof(wqe->inl.ctrl.ctrl) +
440                 sizeof(wqe->inl.eseg) +
441                 sizeof(wqe->inl.byte_cnt) +
442                 length + 15) / 16;
443         wqe->inl.byte_cnt = htonl(length | MLX5_INLINE_SEG);
444         rte_memcpy((void *)(uintptr_t)&wqe->inl.data[0],
445                    (void *)addr, MLX5_WQE64_INL_DATA);
446         addr += MLX5_WQE64_INL_DATA;
447         length -= MLX5_WQE64_INL_DATA;
448         while (length) {
449                 volatile union mlx5_wqe *wqe_next =
450                         &(*txq->wqes)[wqe_ci & wqe_cnt];
451                 uint32_t copy_bytes = (length > sizeof(*wqe)) ?
452                                       sizeof(*wqe) :
453                                       length;
454
455                 rte_mov64((uint8_t *)(uintptr_t)&wqe_next->data[0],
456                           (uint8_t *)addr);
457                 addr += copy_bytes;
458                 length -= copy_bytes;
459                 ++wqe_ci;
460         }
461         assert(size < 64);
462         wqe->inl.ctrl.data[0] = htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND);
463         wqe->inl.ctrl.data[1] = htonl(txq->qp_num_8s | size);
464         wqe->inl.ctrl.data[2] = 0;
465         wqe->inl.ctrl.data[3] = 0;
466         wqe->inl.eseg.rsvd0 = 0;
467         wqe->inl.eseg.rsvd1 = 0;
468         wqe->inl.eseg.mss = 0;
469         wqe->inl.eseg.rsvd2 = 0;
470         wqe->inl.eseg.inline_hdr_sz = htons(MLX5_ETH_VLAN_INLINE_HEADER_SIZE);
471         /* Increment consumer index. */
472         txq->wqe_ci = wqe_ci;
473 }
474
475 /**
476  * Ring TX queue doorbell.
477  *
478  * @param txq
479  *   Pointer to TX queue structure.
480  */
481 static inline void
482 mlx5_tx_dbrec(struct txq *txq)
483 {
484         uint8_t *dst = (uint8_t *)((uintptr_t)txq->bf_reg + txq->bf_offset);
485         uint32_t data[4] = {
486                 htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND),
487                 htonl(txq->qp_num_8s),
488                 0,
489                 0,
490         };
491         rte_wmb();
492         *txq->qp_db = htonl(txq->wqe_ci);
493         /* Ensure ordering between DB record and BF copy. */
494         rte_wmb();
495         rte_mov16(dst, (uint8_t *)data);
496         txq->bf_offset ^= txq->bf_buf_size;
497 }
498
499 /**
500  * Prefetch a CQE.
501  *
502  * @param txq
503  *   Pointer to TX queue structure.
504  * @param cqe_ci
505  *   CQE consumer index.
506  */
507 static inline void
508 tx_prefetch_cqe(struct txq *txq, uint16_t ci)
509 {
510         volatile struct mlx5_cqe64 *cqe;
511
512         cqe = &(*txq->cqes)[ci & (txq->cqe_n - 1)].cqe64;
513         rte_prefetch0(cqe);
514 }
515
516 /**
517  * Prefetch a WQE.
518  *
519  * @param txq
520  *   Pointer to TX queue structure.
521  * @param  wqe_ci
522  *   WQE consumer index.
523  */
524 static inline void
525 tx_prefetch_wqe(struct txq *txq, uint16_t ci)
526 {
527         volatile union mlx5_wqe *wqe;
528
529         wqe = &(*txq->wqes)[ci & (txq->wqe_n - 1)];
530         rte_prefetch0(wqe);
531 }
532
533 /**
534  * DPDK callback for TX.
535  *
536  * @param dpdk_txq
537  *   Generic pointer to TX queue structure.
538  * @param[in] pkts
539  *   Packets to transmit.
540  * @param pkts_n
541  *   Number of packets in array.
542  *
543  * @return
544  *   Number of packets successfully transmitted (<= pkts_n).
545  */
546 uint16_t
547 mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
548 {
549         struct txq *txq = (struct txq *)dpdk_txq;
550         uint16_t elts_head = txq->elts_head;
551         const unsigned int elts_n = txq->elts_n;
552         unsigned int i = 0;
553         unsigned int j = 0;
554         unsigned int max;
555         unsigned int comp;
556         volatile union mlx5_wqe *wqe = NULL;
557
558         if (unlikely(!pkts_n))
559                 return 0;
560         /* Prefetch first packet cacheline. */
561         tx_prefetch_cqe(txq, txq->cq_ci);
562         tx_prefetch_cqe(txq, txq->cq_ci + 1);
563         rte_prefetch0(*pkts);
564         /* Start processing. */
565         txq_complete(txq);
566         max = (elts_n - (elts_head - txq->elts_tail));
567         if (max > elts_n)
568                 max -= elts_n;
569         do {
570                 struct rte_mbuf *buf = *(pkts++);
571                 unsigned int elts_head_next;
572                 uint32_t length;
573                 uint32_t lkey;
574                 unsigned int segs_n = buf->nb_segs;
575                 volatile struct mlx5_wqe_data_seg *dseg;
576                 unsigned int ds = sizeof(*wqe) / 16;
577
578                 /*
579                  * Make sure there is enough room to store this packet and
580                  * that one ring entry remains unused.
581                  */
582                 assert(segs_n);
583                 if (max < segs_n + 1)
584                         break;
585                 max -= segs_n;
586                 --pkts_n;
587                 elts_head_next = (elts_head + 1) & (elts_n - 1);
588                 wqe = &(*txq->wqes)[txq->wqe_ci & (txq->wqe_n - 1)];
589                 dseg = &wqe->wqe.dseg;
590                 rte_prefetch0(wqe);
591                 if (pkts_n)
592                         rte_prefetch0(*pkts);
593                 length = DATA_LEN(buf);
594                 /* Update element. */
595                 (*txq->elts)[elts_head] = buf;
596                 /* Prefetch next buffer data. */
597                 if (pkts_n)
598                         rte_prefetch0(rte_pktmbuf_mtod(*pkts,
599                                                        volatile void *));
600                 /* Retrieve Memory Region key for this memory pool. */
601                 lkey = txq_mp2mr(txq, txq_mb2mp(buf));
602                 mlx5_wqe_write(txq, wqe, buf, length, lkey);
603                 /* Should we enable HW CKSUM offload */
604                 if (buf->ol_flags &
605                     (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
606                         wqe->wqe.eseg.cs_flags =
607                                 MLX5_ETH_WQE_L3_CSUM |
608                                 MLX5_ETH_WQE_L4_CSUM;
609                 } else {
610                         wqe->wqe.eseg.cs_flags = 0;
611                 }
612                 while (--segs_n) {
613                         /*
614                          * Spill on next WQE when the current one does not have
615                          * enough room left. Size of WQE must a be a multiple
616                          * of data segment size.
617                          */
618                         assert(!(sizeof(*wqe) % sizeof(*dseg)));
619                         if (!(ds % (sizeof(*wqe) / 16)))
620                                 dseg = (volatile void *)
621                                         &(*txq->wqes)[txq->wqe_ci++ &
622                                                       (txq->wqe_n - 1)];
623                         else
624                                 ++dseg;
625                         ++ds;
626                         buf = buf->next;
627                         assert(buf);
628                         /* Store segment information. */
629                         dseg->byte_count = htonl(DATA_LEN(buf));
630                         dseg->lkey = txq_mp2mr(txq, txq_mb2mp(buf));
631                         dseg->addr = htonll(rte_pktmbuf_mtod(buf, uintptr_t));
632                         (*txq->elts)[elts_head_next] = buf;
633                         elts_head_next = (elts_head_next + 1) & (elts_n - 1);
634 #ifdef MLX5_PMD_SOFT_COUNTERS
635                         length += DATA_LEN(buf);
636 #endif
637                         ++j;
638                 }
639                 /* Update DS field in WQE. */
640                 wqe->wqe.ctrl.data[1] &= htonl(0xffffffc0);
641                 wqe->wqe.ctrl.data[1] |= htonl(ds & 0x3f);
642                 elts_head = elts_head_next;
643 #ifdef MLX5_PMD_SOFT_COUNTERS
644                 /* Increment sent bytes counter. */
645                 txq->stats.obytes += length;
646 #endif
647                 elts_head = elts_head_next;
648                 ++i;
649         } while (pkts_n);
650         /* Take a shortcut if nothing must be sent. */
651         if (unlikely(i == 0))
652                 return 0;
653         /* Check whether completion threshold has been reached. */
654         comp = txq->elts_comp + i + j;
655         if (comp >= MLX5_TX_COMP_THRESH) {
656                 /* Request completion on last WQE. */
657                 wqe->wqe.ctrl.data[2] = htonl(8);
658                 /* Save elts_head in unused "immediate" field of WQE. */
659                 wqe->wqe.ctrl.data[3] = elts_head;
660                 txq->elts_comp = 0;
661         } else {
662                 txq->elts_comp = comp;
663         }
664 #ifdef MLX5_PMD_SOFT_COUNTERS
665         /* Increment sent packets counter. */
666         txq->stats.opackets += i;
667 #endif
668         /* Ring QP doorbell. */
669         mlx5_tx_dbrec(txq);
670         txq->elts_head = elts_head;
671         return i;
672 }
673
674 /**
675  * DPDK callback for TX with inline support.
676  *
677  * @param dpdk_txq
678  *   Generic pointer to TX queue structure.
679  * @param[in] pkts
680  *   Packets to transmit.
681  * @param pkts_n
682  *   Number of packets in array.
683  *
684  * @return
685  *   Number of packets successfully transmitted (<= pkts_n).
686  */
687 uint16_t
688 mlx5_tx_burst_inline(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
689 {
690         struct txq *txq = (struct txq *)dpdk_txq;
691         uint16_t elts_head = txq->elts_head;
692         const unsigned int elts_n = txq->elts_n;
693         unsigned int i = 0;
694         unsigned int j = 0;
695         unsigned int max;
696         unsigned int comp;
697         volatile union mlx5_wqe *wqe = NULL;
698         unsigned int max_inline = txq->max_inline;
699
700         if (unlikely(!pkts_n))
701                 return 0;
702         /* Prefetch first packet cacheline. */
703         tx_prefetch_cqe(txq, txq->cq_ci);
704         tx_prefetch_cqe(txq, txq->cq_ci + 1);
705         rte_prefetch0(*pkts);
706         /* Start processing. */
707         txq_complete(txq);
708         max = (elts_n - (elts_head - txq->elts_tail));
709         if (max > elts_n)
710                 max -= elts_n;
711         do {
712                 struct rte_mbuf *buf = *(pkts++);
713                 unsigned int elts_head_next;
714                 uintptr_t addr;
715                 uint32_t length;
716                 uint32_t lkey;
717                 unsigned int segs_n = buf->nb_segs;
718                 volatile struct mlx5_wqe_data_seg *dseg;
719                 unsigned int ds = sizeof(*wqe) / 16;
720
721                 /*
722                  * Make sure there is enough room to store this packet and
723                  * that one ring entry remains unused.
724                  */
725                 assert(segs_n);
726                 if (max < segs_n + 1)
727                         break;
728                 max -= segs_n;
729                 --pkts_n;
730                 elts_head_next = (elts_head + 1) & (elts_n - 1);
731                 wqe = &(*txq->wqes)[txq->wqe_ci & (txq->wqe_n - 1)];
732                 dseg = &wqe->wqe.dseg;
733                 tx_prefetch_wqe(txq, txq->wqe_ci);
734                 tx_prefetch_wqe(txq, txq->wqe_ci + 1);
735                 if (pkts_n)
736                         rte_prefetch0(*pkts);
737                 /* Should we enable HW CKSUM offload */
738                 if (buf->ol_flags &
739                     (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
740                         wqe->inl.eseg.cs_flags =
741                                 MLX5_ETH_WQE_L3_CSUM |
742                                 MLX5_ETH_WQE_L4_CSUM;
743                 } else {
744                         wqe->inl.eseg.cs_flags = 0;
745                 }
746                 /* Retrieve buffer information. */
747                 addr = rte_pktmbuf_mtod(buf, uintptr_t);
748                 length = DATA_LEN(buf);
749                 /* Update element. */
750                 (*txq->elts)[elts_head] = buf;
751                 /* Prefetch next buffer data. */
752                 if (pkts_n)
753                         rte_prefetch0(rte_pktmbuf_mtod(*pkts,
754                                                        volatile void *));
755                 if ((length <= max_inline) && (segs_n == 1)) {
756                         if (buf->ol_flags & PKT_TX_VLAN_PKT)
757                                 mlx5_wqe_write_inline_vlan(txq, wqe,
758                                                            addr, length,
759                                                            buf->vlan_tci);
760                         else
761                                 mlx5_wqe_write_inline(txq, wqe, addr, length);
762                         goto skip_segs;
763                 } else {
764                         /* Retrieve Memory Region key for this memory pool. */
765                         lkey = txq_mp2mr(txq, txq_mb2mp(buf));
766                         mlx5_wqe_write(txq, wqe, buf, length, lkey);
767                 }
768                 while (--segs_n) {
769                         /*
770                          * Spill on next WQE when the current one does not have
771                          * enough room left. Size of WQE must a be a multiple
772                          * of data segment size.
773                          */
774                         assert(!(sizeof(*wqe) % sizeof(*dseg)));
775                         if (!(ds % (sizeof(*wqe) / 16)))
776                                 dseg = (volatile void *)
777                                         &(*txq->wqes)[txq->wqe_ci++ &
778                                                       (txq->wqe_n - 1)];
779                         else
780                                 ++dseg;
781                         ++ds;
782                         buf = buf->next;
783                         assert(buf);
784                         /* Store segment information. */
785                         dseg->byte_count = htonl(DATA_LEN(buf));
786                         dseg->lkey = txq_mp2mr(txq, txq_mb2mp(buf));
787                         dseg->addr = htonll(rte_pktmbuf_mtod(buf, uintptr_t));
788                         (*txq->elts)[elts_head_next] = buf;
789                         elts_head_next = (elts_head_next + 1) & (elts_n - 1);
790 #ifdef MLX5_PMD_SOFT_COUNTERS
791                         length += DATA_LEN(buf);
792 #endif
793                         ++j;
794                 }
795                 /* Update DS field in WQE. */
796                 wqe->inl.ctrl.data[1] &= htonl(0xffffffc0);
797                 wqe->inl.ctrl.data[1] |= htonl(ds & 0x3f);
798 skip_segs:
799                 elts_head = elts_head_next;
800 #ifdef MLX5_PMD_SOFT_COUNTERS
801                 /* Increment sent bytes counter. */
802                 txq->stats.obytes += length;
803 #endif
804                 ++i;
805         } while (pkts_n);
806         /* Take a shortcut if nothing must be sent. */
807         if (unlikely(i == 0))
808                 return 0;
809         /* Check whether completion threshold has been reached. */
810         comp = txq->elts_comp + i + j;
811         if (comp >= MLX5_TX_COMP_THRESH) {
812                 /* Request completion on last WQE. */
813                 wqe->inl.ctrl.data[2] = htonl(8);
814                 /* Save elts_head in unused "immediate" field of WQE. */
815                 wqe->inl.ctrl.data[3] = elts_head;
816                 txq->elts_comp = 0;
817         } else {
818                 txq->elts_comp = comp;
819         }
820 #ifdef MLX5_PMD_SOFT_COUNTERS
821         /* Increment sent packets counter. */
822         txq->stats.opackets += i;
823 #endif
824         /* Ring QP doorbell. */
825         mlx5_tx_dbrec(txq);
826         txq->elts_head = elts_head;
827         return i;
828 }
829
830 /**
831  * Open a MPW session.
832  *
833  * @param txq
834  *   Pointer to TX queue structure.
835  * @param mpw
836  *   Pointer to MPW session structure.
837  * @param length
838  *   Packet length.
839  */
840 static inline void
841 mlx5_mpw_new(struct txq *txq, struct mlx5_mpw *mpw, uint32_t length)
842 {
843         uint16_t idx = txq->wqe_ci & (txq->wqe_n - 1);
844         volatile struct mlx5_wqe_data_seg (*dseg)[MLX5_MPW_DSEG_MAX] =
845                 (volatile struct mlx5_wqe_data_seg (*)[])
846                 (uintptr_t)&(*txq->wqes)[(idx + 1) & (txq->wqe_n - 1)];
847
848         mpw->state = MLX5_MPW_STATE_OPENED;
849         mpw->pkts_n = 0;
850         mpw->len = length;
851         mpw->total_len = 0;
852         mpw->wqe = &(*txq->wqes)[idx];
853         mpw->wqe->mpw.eseg.mss = htons(length);
854         mpw->wqe->mpw.eseg.inline_hdr_sz = 0;
855         mpw->wqe->mpw.eseg.rsvd0 = 0;
856         mpw->wqe->mpw.eseg.rsvd1 = 0;
857         mpw->wqe->mpw.eseg.rsvd2 = 0;
858         mpw->wqe->mpw.ctrl.data[0] = htonl((MLX5_OPC_MOD_MPW << 24) |
859                                            (txq->wqe_ci << 8) |
860                                            MLX5_OPCODE_LSO_MPW);
861         mpw->wqe->mpw.ctrl.data[2] = 0;
862         mpw->wqe->mpw.ctrl.data[3] = 0;
863         mpw->data.dseg[0] = &mpw->wqe->mpw.dseg[0];
864         mpw->data.dseg[1] = &mpw->wqe->mpw.dseg[1];
865         mpw->data.dseg[2] = &(*dseg)[0];
866         mpw->data.dseg[3] = &(*dseg)[1];
867         mpw->data.dseg[4] = &(*dseg)[2];
868 }
869
870 /**
871  * Close a MPW session.
872  *
873  * @param txq
874  *   Pointer to TX queue structure.
875  * @param mpw
876  *   Pointer to MPW session structure.
877  */
878 static inline void
879 mlx5_mpw_close(struct txq *txq, struct mlx5_mpw *mpw)
880 {
881         unsigned int num = mpw->pkts_n;
882
883         /*
884          * Store size in multiple of 16 bytes. Control and Ethernet segments
885          * count as 2.
886          */
887         mpw->wqe->mpw.ctrl.data[1] = htonl(txq->qp_num_8s | (2 + num));
888         mpw->state = MLX5_MPW_STATE_CLOSED;
889         if (num < 3)
890                 ++txq->wqe_ci;
891         else
892                 txq->wqe_ci += 2;
893         tx_prefetch_wqe(txq, txq->wqe_ci);
894         tx_prefetch_wqe(txq, txq->wqe_ci + 1);
895 }
896
897 /**
898  * DPDK callback for TX with MPW support.
899  *
900  * @param dpdk_txq
901  *   Generic pointer to TX queue structure.
902  * @param[in] pkts
903  *   Packets to transmit.
904  * @param pkts_n
905  *   Number of packets in array.
906  *
907  * @return
908  *   Number of packets successfully transmitted (<= pkts_n).
909  */
910 uint16_t
911 mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
912 {
913         struct txq *txq = (struct txq *)dpdk_txq;
914         uint16_t elts_head = txq->elts_head;
915         const unsigned int elts_n = txq->elts_n;
916         unsigned int i = 0;
917         unsigned int j = 0;
918         unsigned int max;
919         unsigned int comp;
920         struct mlx5_mpw mpw = {
921                 .state = MLX5_MPW_STATE_CLOSED,
922         };
923
924         if (unlikely(!pkts_n))
925                 return 0;
926         /* Prefetch first packet cacheline. */
927         tx_prefetch_cqe(txq, txq->cq_ci);
928         tx_prefetch_wqe(txq, txq->wqe_ci);
929         tx_prefetch_wqe(txq, txq->wqe_ci + 1);
930         /* Start processing. */
931         txq_complete(txq);
932         max = (elts_n - (elts_head - txq->elts_tail));
933         if (max > elts_n)
934                 max -= elts_n;
935         do {
936                 struct rte_mbuf *buf = *(pkts++);
937                 unsigned int elts_head_next;
938                 uint32_t length;
939                 unsigned int segs_n = buf->nb_segs;
940                 uint32_t cs_flags = 0;
941
942                 /*
943                  * Make sure there is enough room to store this packet and
944                  * that one ring entry remains unused.
945                  */
946                 assert(segs_n);
947                 if (max < segs_n + 1)
948                         break;
949                 /* Do not bother with large packets MPW cannot handle. */
950                 if (segs_n > MLX5_MPW_DSEG_MAX)
951                         break;
952                 max -= segs_n;
953                 --pkts_n;
954                 /* Should we enable HW CKSUM offload */
955                 if (buf->ol_flags &
956                     (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM))
957                         cs_flags = MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
958                 /* Retrieve packet information. */
959                 length = PKT_LEN(buf);
960                 assert(length);
961                 /* Start new session if packet differs. */
962                 if ((mpw.state == MLX5_MPW_STATE_OPENED) &&
963                     ((mpw.len != length) ||
964                      (segs_n != 1) ||
965                      (mpw.wqe->mpw.eseg.cs_flags != cs_flags)))
966                         mlx5_mpw_close(txq, &mpw);
967                 if (mpw.state == MLX5_MPW_STATE_CLOSED) {
968                         mlx5_mpw_new(txq, &mpw, length);
969                         mpw.wqe->mpw.eseg.cs_flags = cs_flags;
970                 }
971                 /* Multi-segment packets must be alone in their MPW. */
972                 assert((segs_n == 1) || (mpw.pkts_n == 0));
973 #if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
974                 length = 0;
975 #endif
976                 do {
977                         volatile struct mlx5_wqe_data_seg *dseg;
978                         uintptr_t addr;
979
980                         elts_head_next = (elts_head + 1) & (elts_n - 1);
981                         assert(buf);
982                         (*txq->elts)[elts_head] = buf;
983                         dseg = mpw.data.dseg[mpw.pkts_n];
984                         addr = rte_pktmbuf_mtod(buf, uintptr_t);
985                         *dseg = (struct mlx5_wqe_data_seg){
986                                 .byte_count = htonl(DATA_LEN(buf)),
987                                 .lkey = txq_mp2mr(txq, txq_mb2mp(buf)),
988                                 .addr = htonll(addr),
989                         };
990                         elts_head = elts_head_next;
991 #if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
992                         length += DATA_LEN(buf);
993 #endif
994                         buf = buf->next;
995                         ++mpw.pkts_n;
996                         ++j;
997                 } while (--segs_n);
998                 assert(length == mpw.len);
999                 if (mpw.pkts_n == MLX5_MPW_DSEG_MAX)
1000                         mlx5_mpw_close(txq, &mpw);
1001                 elts_head = elts_head_next;
1002 #ifdef MLX5_PMD_SOFT_COUNTERS
1003                 /* Increment sent bytes counter. */
1004                 txq->stats.obytes += length;
1005 #endif
1006                 ++i;
1007         } while (pkts_n);
1008         /* Take a shortcut if nothing must be sent. */
1009         if (unlikely(i == 0))
1010                 return 0;
1011         /* Check whether completion threshold has been reached. */
1012         /* "j" includes both packets and segments. */
1013         comp = txq->elts_comp + j;
1014         if (comp >= MLX5_TX_COMP_THRESH) {
1015                 volatile union mlx5_wqe *wqe = mpw.wqe;
1016
1017                 /* Request completion on last WQE. */
1018                 wqe->mpw.ctrl.data[2] = htonl(8);
1019                 /* Save elts_head in unused "immediate" field of WQE. */
1020                 wqe->mpw.ctrl.data[3] = elts_head;
1021                 txq->elts_comp = 0;
1022         } else {
1023                 txq->elts_comp = comp;
1024         }
1025 #ifdef MLX5_PMD_SOFT_COUNTERS
1026         /* Increment sent packets counter. */
1027         txq->stats.opackets += i;
1028 #endif
1029         /* Ring QP doorbell. */
1030         if (mpw.state == MLX5_MPW_STATE_OPENED)
1031                 mlx5_mpw_close(txq, &mpw);
1032         mlx5_tx_dbrec(txq);
1033         txq->elts_head = elts_head;
1034         return i;
1035 }
1036
1037 /**
1038  * Open a MPW inline session.
1039  *
1040  * @param txq
1041  *   Pointer to TX queue structure.
1042  * @param mpw
1043  *   Pointer to MPW session structure.
1044  * @param length
1045  *   Packet length.
1046  */
1047 static inline void
1048 mlx5_mpw_inline_new(struct txq *txq, struct mlx5_mpw *mpw, uint32_t length)
1049 {
1050         uint16_t idx = txq->wqe_ci & (txq->wqe_n - 1);
1051
1052         mpw->state = MLX5_MPW_INL_STATE_OPENED;
1053         mpw->pkts_n = 0;
1054         mpw->len = length;
1055         mpw->total_len = 0;
1056         mpw->wqe = &(*txq->wqes)[idx];
1057         mpw->wqe->mpw_inl.ctrl.data[0] = htonl((MLX5_OPC_MOD_MPW << 24) |
1058                                                (txq->wqe_ci << 8) |
1059                                                MLX5_OPCODE_LSO_MPW);
1060         mpw->wqe->mpw_inl.ctrl.data[2] = 0;
1061         mpw->wqe->mpw_inl.ctrl.data[3] = 0;
1062         mpw->wqe->mpw_inl.eseg.mss = htons(length);
1063         mpw->wqe->mpw_inl.eseg.inline_hdr_sz = 0;
1064         mpw->wqe->mpw_inl.eseg.cs_flags = 0;
1065         mpw->wqe->mpw_inl.eseg.rsvd0 = 0;
1066         mpw->wqe->mpw_inl.eseg.rsvd1 = 0;
1067         mpw->wqe->mpw_inl.eseg.rsvd2 = 0;
1068         mpw->data.raw = &mpw->wqe->mpw_inl.data[0];
1069 }
1070
1071 /**
1072  * Close a MPW inline session.
1073  *
1074  * @param txq
1075  *   Pointer to TX queue structure.
1076  * @param mpw
1077  *   Pointer to MPW session structure.
1078  */
1079 static inline void
1080 mlx5_mpw_inline_close(struct txq *txq, struct mlx5_mpw *mpw)
1081 {
1082         unsigned int size;
1083
1084         size = sizeof(*mpw->wqe) - MLX5_MWQE64_INL_DATA + mpw->total_len;
1085         /*
1086          * Store size in multiple of 16 bytes. Control and Ethernet segments
1087          * count as 2.
1088          */
1089         mpw->wqe->mpw_inl.ctrl.data[1] =
1090                 htonl(txq->qp_num_8s | ((size + 15) / 16));
1091         mpw->state = MLX5_MPW_STATE_CLOSED;
1092         mpw->wqe->mpw_inl.byte_cnt = htonl(mpw->total_len | MLX5_INLINE_SEG);
1093         txq->wqe_ci += (size + (sizeof(*mpw->wqe) - 1)) / sizeof(*mpw->wqe);
1094 }
1095
1096 /**
1097  * DPDK callback for TX with MPW inline support.
1098  *
1099  * @param dpdk_txq
1100  *   Generic pointer to TX queue structure.
1101  * @param[in] pkts
1102  *   Packets to transmit.
1103  * @param pkts_n
1104  *   Number of packets in array.
1105  *
1106  * @return
1107  *   Number of packets successfully transmitted (<= pkts_n).
1108  */
1109 uint16_t
1110 mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
1111                          uint16_t pkts_n)
1112 {
1113         struct txq *txq = (struct txq *)dpdk_txq;
1114         uint16_t elts_head = txq->elts_head;
1115         const unsigned int elts_n = txq->elts_n;
1116         unsigned int i = 0;
1117         unsigned int j = 0;
1118         unsigned int max;
1119         unsigned int comp;
1120         unsigned int inline_room = txq->max_inline;
1121         struct mlx5_mpw mpw = {
1122                 .state = MLX5_MPW_STATE_CLOSED,
1123         };
1124
1125         if (unlikely(!pkts_n))
1126                 return 0;
1127         /* Prefetch first packet cacheline. */
1128         tx_prefetch_cqe(txq, txq->cq_ci);
1129         tx_prefetch_wqe(txq, txq->wqe_ci);
1130         tx_prefetch_wqe(txq, txq->wqe_ci + 1);
1131         /* Start processing. */
1132         txq_complete(txq);
1133         max = (elts_n - (elts_head - txq->elts_tail));
1134         if (max > elts_n)
1135                 max -= elts_n;
1136         do {
1137                 struct rte_mbuf *buf = *(pkts++);
1138                 unsigned int elts_head_next;
1139                 uintptr_t addr;
1140                 uint32_t length;
1141                 unsigned int segs_n = buf->nb_segs;
1142                 uint32_t cs_flags = 0;
1143
1144                 /*
1145                  * Make sure there is enough room to store this packet and
1146                  * that one ring entry remains unused.
1147                  */
1148                 assert(segs_n);
1149                 if (max < segs_n + 1)
1150                         break;
1151                 /* Do not bother with large packets MPW cannot handle. */
1152                 if (segs_n > MLX5_MPW_DSEG_MAX)
1153                         break;
1154                 max -= segs_n;
1155                 --pkts_n;
1156                 /* Should we enable HW CKSUM offload */
1157                 if (buf->ol_flags &
1158                     (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM))
1159                         cs_flags = MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
1160                 /* Retrieve packet information. */
1161                 length = PKT_LEN(buf);
1162                 /* Start new session if packet differs. */
1163                 if (mpw.state == MLX5_MPW_STATE_OPENED) {
1164                         if ((mpw.len != length) ||
1165                             (segs_n != 1) ||
1166                             (mpw.wqe->mpw.eseg.cs_flags != cs_flags))
1167                                 mlx5_mpw_close(txq, &mpw);
1168                 } else if (mpw.state == MLX5_MPW_INL_STATE_OPENED) {
1169                         if ((mpw.len != length) ||
1170                             (segs_n != 1) ||
1171                             (length > inline_room) ||
1172                             (mpw.wqe->mpw_inl.eseg.cs_flags != cs_flags)) {
1173                                 mlx5_mpw_inline_close(txq, &mpw);
1174                                 inline_room = txq->max_inline;
1175                         }
1176                 }
1177                 if (mpw.state == MLX5_MPW_STATE_CLOSED) {
1178                         if ((segs_n != 1) ||
1179                             (length > inline_room)) {
1180                                 mlx5_mpw_new(txq, &mpw, length);
1181                                 mpw.wqe->mpw.eseg.cs_flags = cs_flags;
1182                         } else {
1183                                 mlx5_mpw_inline_new(txq, &mpw, length);
1184                                 mpw.wqe->mpw_inl.eseg.cs_flags = cs_flags;
1185                         }
1186                 }
1187                 /* Multi-segment packets must be alone in their MPW. */
1188                 assert((segs_n == 1) || (mpw.pkts_n == 0));
1189                 if (mpw.state == MLX5_MPW_STATE_OPENED) {
1190                         assert(inline_room == txq->max_inline);
1191 #if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
1192                         length = 0;
1193 #endif
1194                         do {
1195                                 volatile struct mlx5_wqe_data_seg *dseg;
1196
1197                                 elts_head_next =
1198                                         (elts_head + 1) & (elts_n - 1);
1199                                 assert(buf);
1200                                 (*txq->elts)[elts_head] = buf;
1201                                 dseg = mpw.data.dseg[mpw.pkts_n];
1202                                 addr = rte_pktmbuf_mtod(buf, uintptr_t);
1203                                 *dseg = (struct mlx5_wqe_data_seg){
1204                                         .byte_count = htonl(DATA_LEN(buf)),
1205                                         .lkey = txq_mp2mr(txq, txq_mb2mp(buf)),
1206                                         .addr = htonll(addr),
1207                                 };
1208                                 elts_head = elts_head_next;
1209 #if defined(MLX5_PMD_SOFT_COUNTERS) || !defined(NDEBUG)
1210                                 length += DATA_LEN(buf);
1211 #endif
1212                                 buf = buf->next;
1213                                 ++mpw.pkts_n;
1214                                 ++j;
1215                         } while (--segs_n);
1216                         assert(length == mpw.len);
1217                         if (mpw.pkts_n == MLX5_MPW_DSEG_MAX)
1218                                 mlx5_mpw_close(txq, &mpw);
1219                 } else {
1220                         unsigned int max;
1221
1222                         assert(mpw.state == MLX5_MPW_INL_STATE_OPENED);
1223                         assert(length <= inline_room);
1224                         assert(length == DATA_LEN(buf));
1225                         elts_head_next = (elts_head + 1) & (elts_n - 1);
1226                         addr = rte_pktmbuf_mtod(buf, uintptr_t);
1227                         (*txq->elts)[elts_head] = buf;
1228                         /* Maximum number of bytes before wrapping. */
1229                         max = ((uintptr_t)&(*txq->wqes)[txq->wqe_n] -
1230                                (uintptr_t)mpw.data.raw);
1231                         if (length > max) {
1232                                 rte_memcpy((void *)(uintptr_t)mpw.data.raw,
1233                                            (void *)addr,
1234                                            max);
1235                                 mpw.data.raw =
1236                                         (volatile void *)&(*txq->wqes)[0];
1237                                 rte_memcpy((void *)(uintptr_t)mpw.data.raw,
1238                                            (void *)(addr + max),
1239                                            length - max);
1240                                 mpw.data.raw += length - max;
1241                         } else {
1242                                 rte_memcpy((void *)(uintptr_t)mpw.data.raw,
1243                                            (void *)addr,
1244                                            length);
1245                                 mpw.data.raw += length;
1246                         }
1247                         if ((uintptr_t)mpw.data.raw ==
1248                             (uintptr_t)&(*txq->wqes)[txq->wqe_n])
1249                                 mpw.data.raw =
1250                                         (volatile void *)&(*txq->wqes)[0];
1251                         ++mpw.pkts_n;
1252                         ++j;
1253                         if (mpw.pkts_n == MLX5_MPW_DSEG_MAX) {
1254                                 mlx5_mpw_inline_close(txq, &mpw);
1255                                 inline_room = txq->max_inline;
1256                         } else {
1257                                 inline_room -= length;
1258                         }
1259                 }
1260                 mpw.total_len += length;
1261                 elts_head = elts_head_next;
1262 #ifdef MLX5_PMD_SOFT_COUNTERS
1263                 /* Increment sent bytes counter. */
1264                 txq->stats.obytes += length;
1265 #endif
1266                 ++i;
1267         } while (pkts_n);
1268         /* Take a shortcut if nothing must be sent. */
1269         if (unlikely(i == 0))
1270                 return 0;
1271         /* Check whether completion threshold has been reached. */
1272         /* "j" includes both packets and segments. */
1273         comp = txq->elts_comp + j;
1274         if (comp >= MLX5_TX_COMP_THRESH) {
1275                 volatile union mlx5_wqe *wqe = mpw.wqe;
1276
1277                 /* Request completion on last WQE. */
1278                 wqe->mpw_inl.ctrl.data[2] = htonl(8);
1279                 /* Save elts_head in unused "immediate" field of WQE. */
1280                 wqe->mpw_inl.ctrl.data[3] = elts_head;
1281                 txq->elts_comp = 0;
1282         } else {
1283                 txq->elts_comp = comp;
1284         }
1285 #ifdef MLX5_PMD_SOFT_COUNTERS
1286         /* Increment sent packets counter. */
1287         txq->stats.opackets += i;
1288 #endif
1289         /* Ring QP doorbell. */
1290         if (mpw.state == MLX5_MPW_INL_STATE_OPENED)
1291                 mlx5_mpw_inline_close(txq, &mpw);
1292         else if (mpw.state == MLX5_MPW_STATE_OPENED)
1293                 mlx5_mpw_close(txq, &mpw);
1294         mlx5_tx_dbrec(txq);
1295         txq->elts_head = elts_head;
1296         return i;
1297 }
1298
1299 /**
1300  * Translate RX completion flags to packet type.
1301  *
1302  * @param[in] cqe
1303  *   Pointer to CQE.
1304  *
1305  * @note: fix mlx5_dev_supported_ptypes_get() if any change here.
1306  *
1307  * @return
1308  *   Packet type for struct rte_mbuf.
1309  */
1310 static inline uint32_t
1311 rxq_cq_to_pkt_type(volatile struct mlx5_cqe64 *cqe)
1312 {
1313         uint32_t pkt_type;
1314         uint8_t flags = cqe->l4_hdr_type_etc;
1315         uint8_t info = cqe->rsvd0[0];
1316
1317         if (info & IBV_EXP_CQ_RX_TUNNEL_PACKET)
1318                 pkt_type =
1319                         TRANSPOSE(flags,
1320                                   IBV_EXP_CQ_RX_OUTER_IPV4_PACKET,
1321                                   RTE_PTYPE_L3_IPV4) |
1322                         TRANSPOSE(flags,
1323                                   IBV_EXP_CQ_RX_OUTER_IPV6_PACKET,
1324                                   RTE_PTYPE_L3_IPV6) |
1325                         TRANSPOSE(flags,
1326                                   IBV_EXP_CQ_RX_IPV4_PACKET,
1327                                   RTE_PTYPE_INNER_L3_IPV4) |
1328                         TRANSPOSE(flags,
1329                                   IBV_EXP_CQ_RX_IPV6_PACKET,
1330                                   RTE_PTYPE_INNER_L3_IPV6);
1331         else
1332                 pkt_type =
1333                         TRANSPOSE(flags,
1334                                   MLX5_CQE_L3_HDR_TYPE_IPV6,
1335                                   RTE_PTYPE_L3_IPV6) |
1336                         TRANSPOSE(flags,
1337                                   MLX5_CQE_L3_HDR_TYPE_IPV4,
1338                                   RTE_PTYPE_L3_IPV4);
1339         return pkt_type;
1340 }
1341
1342 /**
1343  * Get size of the next packet for a given CQE. For compressed CQEs, the
1344  * consumer index is updated only once all packets of the current one have
1345  * been processed.
1346  *
1347  * @param rxq
1348  *   Pointer to RX queue.
1349  * @param cqe
1350  *   CQE to process.
1351  *
1352  * @return
1353  *   Packet size in bytes (0 if there is none), -1 in case of completion
1354  *   with error.
1355  */
1356 static inline int
1357 mlx5_rx_poll_len(struct rxq *rxq, volatile struct mlx5_cqe64 *cqe,
1358                  uint16_t cqe_cnt)
1359 {
1360         struct rxq_zip *zip = &rxq->zip;
1361         uint16_t cqe_n = cqe_cnt + 1;
1362         int len = 0;
1363
1364         /* Process compressed data in the CQE and mini arrays. */
1365         if (zip->ai) {
1366                 volatile struct mlx5_mini_cqe8 (*mc)[8] =
1367                         (volatile struct mlx5_mini_cqe8 (*)[8])
1368                         (uintptr_t)(&(*rxq->cqes)[zip->ca & cqe_cnt].cqe64);
1369
1370                 len = ntohl((*mc)[zip->ai & 7].byte_cnt);
1371                 if ((++zip->ai & 7) == 0) {
1372                         /*
1373                          * Increment consumer index to skip the number of
1374                          * CQEs consumed. Hardware leaves holes in the CQ
1375                          * ring for software use.
1376                          */
1377                         zip->ca = zip->na;
1378                         zip->na += 8;
1379                 }
1380                 if (unlikely(rxq->zip.ai == rxq->zip.cqe_cnt)) {
1381                         uint16_t idx = rxq->cq_ci;
1382                         uint16_t end = zip->cq_ci;
1383
1384                         while (idx != end) {
1385                                 (*rxq->cqes)[idx & cqe_cnt].cqe64.op_own =
1386                                         MLX5_CQE_INVALIDATE;
1387                                 ++idx;
1388                         }
1389                         rxq->cq_ci = zip->cq_ci;
1390                         zip->ai = 0;
1391                 }
1392         /* No compressed data, get next CQE and verify if it is compressed. */
1393         } else {
1394                 int ret;
1395                 int8_t op_own;
1396
1397                 ret = check_cqe64(cqe, cqe_n, rxq->cq_ci);
1398                 if (unlikely(ret == 1))
1399                         return 0;
1400                 ++rxq->cq_ci;
1401                 op_own = cqe->op_own;
1402                 if (MLX5_CQE_FORMAT(op_own) == MLX5_COMPRESSED) {
1403                         volatile struct mlx5_mini_cqe8 (*mc)[8] =
1404                                 (volatile struct mlx5_mini_cqe8 (*)[8])
1405                                 (uintptr_t)(&(*rxq->cqes)[rxq->cq_ci &
1406                                                           cqe_cnt].cqe64);
1407
1408                         /* Fix endianness. */
1409                         zip->cqe_cnt = ntohl(cqe->byte_cnt);
1410                         /*
1411                          * Current mini array position is the one returned by
1412                          * check_cqe64().
1413                          *
1414                          * If completion comprises several mini arrays, as a
1415                          * special case the second one is located 7 CQEs after
1416                          * the initial CQE instead of 8 for subsequent ones.
1417                          */
1418                         zip->ca = rxq->cq_ci & cqe_cnt;
1419                         zip->na = zip->ca + 7;
1420                         /* Compute the next non compressed CQE. */
1421                         --rxq->cq_ci;
1422                         zip->cq_ci = rxq->cq_ci + zip->cqe_cnt;
1423                         /* Get packet size to return. */
1424                         len = ntohl((*mc)[0].byte_cnt);
1425                         zip->ai = 1;
1426                 } else {
1427                         len = ntohl(cqe->byte_cnt);
1428                 }
1429                 /* Error while receiving packet. */
1430                 if (unlikely(MLX5_CQE_OPCODE(op_own) == MLX5_CQE_RESP_ERR))
1431                         return -1;
1432         }
1433         return len;
1434 }
1435
1436 /**
1437  * Translate RX completion flags to offload flags.
1438  *
1439  * @param[in] rxq
1440  *   Pointer to RX queue structure.
1441  * @param[in] cqe
1442  *   Pointer to CQE.
1443  *
1444  * @return
1445  *   Offload flags (ol_flags) for struct rte_mbuf.
1446  */
1447 static inline uint32_t
1448 rxq_cq_to_ol_flags(struct rxq *rxq, volatile struct mlx5_cqe64 *cqe)
1449 {
1450         uint32_t ol_flags = 0;
1451         uint8_t l3_hdr = (cqe->l4_hdr_type_etc) & MLX5_CQE_L3_HDR_TYPE_MASK;
1452         uint8_t l4_hdr = (cqe->l4_hdr_type_etc) & MLX5_CQE_L4_HDR_TYPE_MASK;
1453         uint8_t info = cqe->rsvd0[0];
1454
1455         if ((l3_hdr == MLX5_CQE_L3_HDR_TYPE_IPV4) ||
1456             (l3_hdr == MLX5_CQE_L3_HDR_TYPE_IPV6))
1457                 ol_flags |=
1458                         (!(cqe->hds_ip_ext & MLX5_CQE_L3_OK) *
1459                          PKT_RX_IP_CKSUM_BAD);
1460         if ((l4_hdr == MLX5_CQE_L4_HDR_TYPE_TCP) ||
1461             (l4_hdr == MLX5_CQE_L4_HDR_TYPE_TCP_EMP_ACK) ||
1462             (l4_hdr == MLX5_CQE_L4_HDR_TYPE_TCP_ACK) ||
1463             (l4_hdr == MLX5_CQE_L4_HDR_TYPE_UDP))
1464                 ol_flags |=
1465                         (!(cqe->hds_ip_ext & MLX5_CQE_L4_OK) *
1466                          PKT_RX_L4_CKSUM_BAD);
1467         /*
1468          * PKT_RX_IP_CKSUM_BAD and PKT_RX_L4_CKSUM_BAD are used in place
1469          * of PKT_RX_EIP_CKSUM_BAD because the latter is not functional
1470          * (its value is 0).
1471          */
1472         if ((info & IBV_EXP_CQ_RX_TUNNEL_PACKET) && (rxq->csum_l2tun))
1473                 ol_flags |=
1474                         TRANSPOSE(~cqe->l4_hdr_type_etc,
1475                                   IBV_EXP_CQ_RX_OUTER_IP_CSUM_OK,
1476                                   PKT_RX_IP_CKSUM_BAD) |
1477                         TRANSPOSE(~cqe->l4_hdr_type_etc,
1478                                   IBV_EXP_CQ_RX_OUTER_TCP_UDP_CSUM_OK,
1479                                   PKT_RX_L4_CKSUM_BAD);
1480         return ol_flags;
1481 }
1482
1483 /**
1484  * DPDK callback for RX.
1485  *
1486  * @param dpdk_rxq
1487  *   Generic pointer to RX queue structure.
1488  * @param[out] pkts
1489  *   Array to store received packets.
1490  * @param pkts_n
1491  *   Maximum number of packets in array.
1492  *
1493  * @return
1494  *   Number of packets successfully received (<= pkts_n).
1495  */
1496 uint16_t
1497 mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
1498 {
1499         struct rxq *rxq = dpdk_rxq;
1500         const unsigned int wqe_cnt = rxq->elts_n - 1;
1501         const unsigned int cqe_cnt = rxq->cqe_n - 1;
1502         const unsigned int sges_n = rxq->sges_n;
1503         struct rte_mbuf *pkt = NULL;
1504         struct rte_mbuf *seg = NULL;
1505         volatile struct mlx5_cqe64 *cqe =
1506                 &(*rxq->cqes)[rxq->cq_ci & cqe_cnt].cqe64;
1507         unsigned int i = 0;
1508         unsigned int rq_ci = rxq->rq_ci << sges_n;
1509         int len;
1510
1511         while (pkts_n) {
1512                 unsigned int idx = rq_ci & wqe_cnt;
1513                 volatile struct mlx5_wqe_data_seg *wqe = &(*rxq->wqes)[idx];
1514                 struct rte_mbuf *rep = (*rxq->elts)[idx];
1515
1516                 if (pkt)
1517                         NEXT(seg) = rep;
1518                 seg = rep;
1519                 rte_prefetch0(seg);
1520                 rte_prefetch0(cqe);
1521                 rte_prefetch0(wqe);
1522                 rep = rte_mbuf_raw_alloc(rxq->mp);
1523                 if (unlikely(rep == NULL)) {
1524                         ++rxq->stats.rx_nombuf;
1525                         if (!pkt) {
1526                                 /*
1527                                  * no buffers before we even started,
1528                                  * bail out silently.
1529                                  */
1530                                 break;
1531                         }
1532                         while (pkt != seg) {
1533                                 assert(pkt != (*rxq->elts)[idx]);
1534                                 seg = NEXT(pkt);
1535                                 rte_mbuf_refcnt_set(pkt, 0);
1536                                 __rte_mbuf_raw_free(pkt);
1537                                 pkt = seg;
1538                         }
1539                         break;
1540                 }
1541                 if (!pkt) {
1542                         cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_cnt].cqe64;
1543                         len = mlx5_rx_poll_len(rxq, cqe, cqe_cnt);
1544                         if (len == 0) {
1545                                 rte_mbuf_refcnt_set(rep, 0);
1546                                 __rte_mbuf_raw_free(rep);
1547                                 break;
1548                         }
1549                         if (unlikely(len == -1)) {
1550                                 /* RX error, packet is likely too large. */
1551                                 rte_mbuf_refcnt_set(rep, 0);
1552                                 __rte_mbuf_raw_free(rep);
1553                                 ++rxq->stats.idropped;
1554                                 goto skip;
1555                         }
1556                         pkt = seg;
1557                         assert(len >= (rxq->crc_present << 2));
1558                         /* Update packet information. */
1559                         pkt->packet_type = 0;
1560                         pkt->ol_flags = 0;
1561                         if (rxq->csum | rxq->csum_l2tun | rxq->vlan_strip |
1562                             rxq->crc_present) {
1563                                 if (rxq->csum) {
1564                                         pkt->packet_type =
1565                                                 rxq_cq_to_pkt_type(cqe);
1566                                         pkt->ol_flags =
1567                                                 rxq_cq_to_ol_flags(rxq, cqe);
1568                                 }
1569                                 if (cqe->l4_hdr_type_etc &
1570                                     MLX5_CQE_VLAN_STRIPPED) {
1571                                         pkt->ol_flags |= PKT_RX_VLAN_PKT |
1572                                                 PKT_RX_VLAN_STRIPPED;
1573                                         pkt->vlan_tci = ntohs(cqe->vlan_info);
1574                                 }
1575                                 if (rxq->crc_present)
1576                                         len -= ETHER_CRC_LEN;
1577                         }
1578                         PKT_LEN(pkt) = len;
1579                 }
1580                 DATA_LEN(rep) = DATA_LEN(seg);
1581                 PKT_LEN(rep) = PKT_LEN(seg);
1582                 SET_DATA_OFF(rep, DATA_OFF(seg));
1583                 NB_SEGS(rep) = NB_SEGS(seg);
1584                 PORT(rep) = PORT(seg);
1585                 NEXT(rep) = NULL;
1586                 (*rxq->elts)[idx] = rep;
1587                 /*
1588                  * Fill NIC descriptor with the new buffer.  The lkey and size
1589                  * of the buffers are already known, only the buffer address
1590                  * changes.
1591                  */
1592                 wqe->addr = htonll(rte_pktmbuf_mtod(rep, uintptr_t));
1593                 if (len > DATA_LEN(seg)) {
1594                         len -= DATA_LEN(seg);
1595                         ++NB_SEGS(pkt);
1596                         ++rq_ci;
1597                         continue;
1598                 }
1599                 DATA_LEN(seg) = len;
1600 #ifdef MLX5_PMD_SOFT_COUNTERS
1601                 /* Increment bytes counter. */
1602                 rxq->stats.ibytes += PKT_LEN(pkt);
1603 #endif
1604                 /* Return packet. */
1605                 *(pkts++) = pkt;
1606                 pkt = NULL;
1607                 --pkts_n;
1608                 ++i;
1609 skip:
1610                 /* Align consumer index to the next stride. */
1611                 rq_ci >>= sges_n;
1612                 ++rq_ci;
1613                 rq_ci <<= sges_n;
1614         }
1615         if (unlikely((i == 0) && ((rq_ci >> sges_n) == rxq->rq_ci)))
1616                 return 0;
1617         /* Update the consumer index. */
1618         rxq->rq_ci = rq_ci >> sges_n;
1619         rte_wmb();
1620         *rxq->cq_db = htonl(rxq->cq_ci);
1621         rte_wmb();
1622         *rxq->rq_db = htonl(rxq->rq_ci);
1623 #ifdef MLX5_PMD_SOFT_COUNTERS
1624         /* Increment packets counter. */
1625         rxq->stats.ipackets += i;
1626 #endif
1627         return i;
1628 }
1629
1630 /**
1631  * Dummy DPDK callback for TX.
1632  *
1633  * This function is used to temporarily replace the real callback during
1634  * unsafe control operations on the queue, or in case of error.
1635  *
1636  * @param dpdk_txq
1637  *   Generic pointer to TX queue structure.
1638  * @param[in] pkts
1639  *   Packets to transmit.
1640  * @param pkts_n
1641  *   Number of packets in array.
1642  *
1643  * @return
1644  *   Number of packets successfully transmitted (<= pkts_n).
1645  */
1646 uint16_t
1647 removed_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
1648 {
1649         (void)dpdk_txq;
1650         (void)pkts;
1651         (void)pkts_n;
1652         return 0;
1653 }
1654
1655 /**
1656  * Dummy DPDK callback for RX.
1657  *
1658  * This function is used to temporarily replace the real callback during
1659  * unsafe control operations on the queue, or in case of error.
1660  *
1661  * @param dpdk_rxq
1662  *   Generic pointer to RX queue structure.
1663  * @param[out] pkts
1664  *   Array to store received packets.
1665  * @param pkts_n
1666  *   Maximum number of packets in array.
1667  *
1668  * @return
1669  *   Number of packets successfully received (<= pkts_n).
1670  */
1671 uint16_t
1672 removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
1673 {
1674         (void)dpdk_rxq;
1675         (void)pkts;
1676         (void)pkts_n;
1677         return 0;
1678 }