ethdev: add namespace
[dpdk.git] / drivers / net / mlx5 / mlx5_txq.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2015 6WIND S.A.
3  * Copyright 2015 Mellanox Technologies, Ltd
4  */
5
6 #include <stddef.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <stdint.h>
10 #include <unistd.h>
11 #include <inttypes.h>
12
13 #include <rte_mbuf.h>
14 #include <rte_malloc.h>
15 #include <ethdev_driver.h>
16 #include <rte_bus_pci.h>
17 #include <rte_common.h>
18 #include <rte_eal_paging.h>
19
20 #include <mlx5_common.h>
21 #include <mlx5_common_mr.h>
22 #include <mlx5_malloc.h>
23
24 #include "mlx5_defs.h"
25 #include "mlx5_utils.h"
26 #include "mlx5.h"
27 #include "mlx5_tx.h"
28 #include "mlx5_rxtx.h"
29 #include "mlx5_autoconf.h"
30
31 /**
32  * Allocate TX queue elements.
33  *
34  * @param txq_ctrl
35  *   Pointer to TX queue structure.
36  */
37 void
38 txq_alloc_elts(struct mlx5_txq_ctrl *txq_ctrl)
39 {
40         const unsigned int elts_n = 1 << txq_ctrl->txq.elts_n;
41         unsigned int i;
42
43         for (i = 0; (i != elts_n); ++i)
44                 txq_ctrl->txq.elts[i] = NULL;
45         DRV_LOG(DEBUG, "port %u Tx queue %u allocated and configured %u WRs",
46                 PORT_ID(txq_ctrl->priv), txq_ctrl->txq.idx, elts_n);
47         txq_ctrl->txq.elts_head = 0;
48         txq_ctrl->txq.elts_tail = 0;
49         txq_ctrl->txq.elts_comp = 0;
50 }
51
52 /**
53  * Free TX queue elements.
54  *
55  * @param txq_ctrl
56  *   Pointer to TX queue structure.
57  */
58 void
59 txq_free_elts(struct mlx5_txq_ctrl *txq_ctrl)
60 {
61         const uint16_t elts_n = 1 << txq_ctrl->txq.elts_n;
62         const uint16_t elts_m = elts_n - 1;
63         uint16_t elts_head = txq_ctrl->txq.elts_head;
64         uint16_t elts_tail = txq_ctrl->txq.elts_tail;
65         struct rte_mbuf *(*elts)[elts_n] = &txq_ctrl->txq.elts;
66
67         DRV_LOG(DEBUG, "port %u Tx queue %u freeing WRs",
68                 PORT_ID(txq_ctrl->priv), txq_ctrl->txq.idx);
69         txq_ctrl->txq.elts_head = 0;
70         txq_ctrl->txq.elts_tail = 0;
71         txq_ctrl->txq.elts_comp = 0;
72
73         while (elts_tail != elts_head) {
74                 struct rte_mbuf *elt = (*elts)[elts_tail & elts_m];
75
76                 MLX5_ASSERT(elt != NULL);
77                 rte_pktmbuf_free_seg(elt);
78 #ifdef RTE_LIBRTE_MLX5_DEBUG
79                 /* Poisoning. */
80                 memset(&(*elts)[elts_tail & elts_m],
81                        0x77,
82                        sizeof((*elts)[elts_tail & elts_m]));
83 #endif
84                 ++elts_tail;
85         }
86 }
87
88 /**
89  * Returns the per-port supported offloads.
90  *
91  * @param dev
92  *   Pointer to Ethernet device.
93  *
94  * @return
95  *   Supported Tx offloads.
96  */
97 uint64_t
98 mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
99 {
100         struct mlx5_priv *priv = dev->data->dev_private;
101         uint64_t offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
102                              RTE_ETH_TX_OFFLOAD_VLAN_INSERT);
103         struct mlx5_dev_config *config = &priv->config;
104
105         if (config->hw_csum)
106                 offloads |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
107                              RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
108                              RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
109         if (config->tso)
110                 offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
111         if (config->tx_pp)
112                 offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
113         if (config->swp) {
114                 if (config->swp & MLX5_SW_PARSING_CSUM_CAP)
115                         offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
116                 if (config->swp & MLX5_SW_PARSING_TSO_CAP)
117                         offloads |= (RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
118                                      RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO);
119         }
120         if (config->tunnel_en) {
121                 if (config->hw_csum)
122                         offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
123                 if (config->tso) {
124                         if (config->tunnel_en &
125                                 MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)
126                                 offloads |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
127                         if (config->tunnel_en &
128                                 MLX5_TUNNELED_OFFLOADS_GRE_CAP)
129                                 offloads |= RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO;
130                         if (config->tunnel_en &
131                                 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)
132                                 offloads |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
133                 }
134         }
135         if (!config->mprq.enabled)
136                 offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
137         return offloads;
138 }
139
140 /* Fetches and drops all SW-owned and error CQEs to synchronize CQ. */
141 static void
142 txq_sync_cq(struct mlx5_txq_data *txq)
143 {
144         volatile struct mlx5_cqe *cqe;
145         int ret, i;
146
147         i = txq->cqe_s;
148         do {
149                 cqe = &txq->cqes[txq->cq_ci & txq->cqe_m];
150                 ret = check_cqe(cqe, txq->cqe_s, txq->cq_ci);
151                 if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) {
152                         if (likely(ret != MLX5_CQE_STATUS_ERR)) {
153                                 /* No new CQEs in completion queue. */
154                                 MLX5_ASSERT(ret == MLX5_CQE_STATUS_HW_OWN);
155                                 break;
156                         }
157                 }
158                 ++txq->cq_ci;
159         } while (--i);
160         /* Move all CQEs to HW ownership. */
161         for (i = 0; i < txq->cqe_s; i++) {
162                 cqe = &txq->cqes[i];
163                 cqe->op_own = MLX5_CQE_INVALIDATE;
164         }
165         /* Resync CQE and WQE (WQ in reset state). */
166         rte_io_wmb();
167         *txq->cq_db = rte_cpu_to_be_32(txq->cq_ci);
168         txq->cq_pi = txq->cq_ci;
169         rte_io_wmb();
170 }
171
172 /**
173  * Tx queue stop. Device queue goes to the idle state,
174  * all involved mbufs are freed from elts/WQ.
175  *
176  * @param dev
177  *   Pointer to Ethernet device structure.
178  * @param idx
179  *   Tx queue index.
180  *
181  * @return
182  *   0 on success, a negative errno value otherwise and rte_errno is set.
183  */
184 int
185 mlx5_tx_queue_stop_primary(struct rte_eth_dev *dev, uint16_t idx)
186 {
187         struct mlx5_priv *priv = dev->data->dev_private;
188         struct mlx5_txq_data *txq = (*priv->txqs)[idx];
189         struct mlx5_txq_ctrl *txq_ctrl =
190                         container_of(txq, struct mlx5_txq_ctrl, txq);
191         int ret;
192
193         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
194         /* Move QP to RESET state. */
195         ret = priv->obj_ops.txq_obj_modify(txq_ctrl->obj, MLX5_TXQ_MOD_RDY2RST,
196                                            (uint8_t)priv->dev_port);
197         if (ret)
198                 return ret;
199         /* Handle all send completions. */
200         txq_sync_cq(txq);
201         /* Free elts stored in the SQ. */
202         txq_free_elts(txq_ctrl);
203         /* Prevent writing new pkts to SQ by setting no free WQE.*/
204         txq->wqe_ci = txq->wqe_s;
205         txq->wqe_pi = 0;
206         txq->elts_comp = 0;
207         /* Set the actual queue state. */
208         dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
209         return 0;
210 }
211
212 /**
213  * Tx queue stop. Device queue goes to the idle state,
214  * all involved mbufs are freed from elts/WQ.
215  *
216  * @param dev
217  *   Pointer to Ethernet device structure.
218  * @param idx
219  *   Tx queue index.
220  *
221  * @return
222  *   0 on success, a negative errno value otherwise and rte_errno is set.
223  */
224 int
225 mlx5_tx_queue_stop(struct rte_eth_dev *dev, uint16_t idx)
226 {
227         int ret;
228
229         if (rte_eth_dev_is_tx_hairpin_queue(dev, idx)) {
230                 DRV_LOG(ERR, "Hairpin queue can't be stopped");
231                 rte_errno = EINVAL;
232                 return -EINVAL;
233         }
234         if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_STOPPED)
235                 return 0;
236         if (rte_eal_process_type() ==  RTE_PROC_SECONDARY) {
237                 ret = mlx5_mp_os_req_queue_control(dev, idx,
238                                                    MLX5_MP_REQ_QUEUE_TX_STOP);
239         } else {
240                 ret = mlx5_tx_queue_stop_primary(dev, idx);
241         }
242         return ret;
243 }
244
245 /**
246  * Rx queue start. Device queue goes to the ready state,
247  * all required mbufs are allocated and WQ is replenished.
248  *
249  * @param dev
250  *   Pointer to Ethernet device structure.
251  * @param idx
252  *   RX queue index.
253  *
254  * @return
255  *   0 on success, a negative errno value otherwise and rte_errno is set.
256  */
257 int
258 mlx5_tx_queue_start_primary(struct rte_eth_dev *dev, uint16_t idx)
259 {
260         struct mlx5_priv *priv = dev->data->dev_private;
261         struct mlx5_txq_data *txq = (*priv->txqs)[idx];
262         struct mlx5_txq_ctrl *txq_ctrl =
263                         container_of(txq, struct mlx5_txq_ctrl, txq);
264         int ret;
265
266         MLX5_ASSERT(rte_eal_process_type() ==  RTE_PROC_PRIMARY);
267         ret = priv->obj_ops.txq_obj_modify(txq_ctrl->obj,
268                                            MLX5_TXQ_MOD_RST2RDY,
269                                            (uint8_t)priv->dev_port);
270         if (ret)
271                 return ret;
272         txq_ctrl->txq.wqe_ci = 0;
273         txq_ctrl->txq.wqe_pi = 0;
274         txq_ctrl->txq.elts_comp = 0;
275         /* Set the actual queue state. */
276         dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED;
277         return 0;
278 }
279
280 /**
281  * Rx queue start. Device queue goes to the ready state,
282  * all required mbufs are allocated and WQ is replenished.
283  *
284  * @param dev
285  *   Pointer to Ethernet device structure.
286  * @param idx
287  *   RX queue index.
288  *
289  * @return
290  *   0 on success, a negative errno value otherwise and rte_errno is set.
291  */
292 int
293 mlx5_tx_queue_start(struct rte_eth_dev *dev, uint16_t idx)
294 {
295         int ret;
296
297         if (rte_eth_dev_is_tx_hairpin_queue(dev, idx)) {
298                 DRV_LOG(ERR, "Hairpin queue can't be started");
299                 rte_errno = EINVAL;
300                 return -EINVAL;
301         }
302         if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_STARTED)
303                 return 0;
304         if (rte_eal_process_type() ==  RTE_PROC_SECONDARY) {
305                 ret = mlx5_mp_os_req_queue_control(dev, idx,
306                                                    MLX5_MP_REQ_QUEUE_TX_START);
307         } else {
308                 ret = mlx5_tx_queue_start_primary(dev, idx);
309         }
310         return ret;
311 }
312
313 /**
314  * Tx queue presetup checks.
315  *
316  * @param dev
317  *   Pointer to Ethernet device structure.
318  * @param idx
319  *   Tx queue index.
320  * @param desc
321  *   Number of descriptors to configure in queue.
322  *
323  * @return
324  *   0 on success, a negative errno value otherwise and rte_errno is set.
325  */
326 static int
327 mlx5_tx_queue_pre_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t *desc)
328 {
329         struct mlx5_priv *priv = dev->data->dev_private;
330
331         if (*desc <= MLX5_TX_COMP_THRESH) {
332                 DRV_LOG(WARNING,
333                         "port %u number of descriptors requested for Tx queue"
334                         " %u must be higher than MLX5_TX_COMP_THRESH, using %u"
335                         " instead of %u", dev->data->port_id, idx,
336                         MLX5_TX_COMP_THRESH + 1, *desc);
337                 *desc = MLX5_TX_COMP_THRESH + 1;
338         }
339         if (!rte_is_power_of_2(*desc)) {
340                 *desc = 1 << log2above(*desc);
341                 DRV_LOG(WARNING,
342                         "port %u increased number of descriptors in Tx queue"
343                         " %u to the next power of two (%d)",
344                         dev->data->port_id, idx, *desc);
345         }
346         DRV_LOG(DEBUG, "port %u configuring queue %u for %u descriptors",
347                 dev->data->port_id, idx, *desc);
348         if (idx >= priv->txqs_n) {
349                 DRV_LOG(ERR, "port %u Tx queue index out of range (%u >= %u)",
350                         dev->data->port_id, idx, priv->txqs_n);
351                 rte_errno = EOVERFLOW;
352                 return -rte_errno;
353         }
354         if (!mlx5_txq_releasable(dev, idx)) {
355                 rte_errno = EBUSY;
356                 DRV_LOG(ERR, "port %u unable to release queue index %u",
357                         dev->data->port_id, idx);
358                 return -rte_errno;
359         }
360         mlx5_txq_release(dev, idx);
361         return 0;
362 }
363
364 /**
365  * DPDK callback to configure a TX queue.
366  *
367  * @param dev
368  *   Pointer to Ethernet device structure.
369  * @param idx
370  *   TX queue index.
371  * @param desc
372  *   Number of descriptors to configure in queue.
373  * @param socket
374  *   NUMA socket on which memory must be allocated.
375  * @param[in] conf
376  *   Thresholds parameters.
377  *
378  * @return
379  *   0 on success, a negative errno value otherwise and rte_errno is set.
380  */
381 int
382 mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
383                     unsigned int socket, const struct rte_eth_txconf *conf)
384 {
385         struct mlx5_priv *priv = dev->data->dev_private;
386         struct mlx5_txq_data *txq = (*priv->txqs)[idx];
387         struct mlx5_txq_ctrl *txq_ctrl =
388                 container_of(txq, struct mlx5_txq_ctrl, txq);
389         int res;
390
391         res = mlx5_tx_queue_pre_setup(dev, idx, &desc);
392         if (res)
393                 return res;
394         txq_ctrl = mlx5_txq_new(dev, idx, desc, socket, conf);
395         if (!txq_ctrl) {
396                 DRV_LOG(ERR, "port %u unable to allocate queue index %u",
397                         dev->data->port_id, idx);
398                 return -rte_errno;
399         }
400         DRV_LOG(DEBUG, "port %u adding Tx queue %u to list",
401                 dev->data->port_id, idx);
402         (*priv->txqs)[idx] = &txq_ctrl->txq;
403         return 0;
404 }
405
406 /**
407  * DPDK callback to configure a TX hairpin queue.
408  *
409  * @param dev
410  *   Pointer to Ethernet device structure.
411  * @param idx
412  *   TX queue index.
413  * @param desc
414  *   Number of descriptors to configure in queue.
415  * @param[in] hairpin_conf
416  *   The hairpin binding configuration.
417  *
418  * @return
419  *   0 on success, a negative errno value otherwise and rte_errno is set.
420  */
421 int
422 mlx5_tx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
423                             uint16_t desc,
424                             const struct rte_eth_hairpin_conf *hairpin_conf)
425 {
426         struct mlx5_priv *priv = dev->data->dev_private;
427         struct mlx5_txq_data *txq = (*priv->txqs)[idx];
428         struct mlx5_txq_ctrl *txq_ctrl =
429                 container_of(txq, struct mlx5_txq_ctrl, txq);
430         int res;
431
432         res = mlx5_tx_queue_pre_setup(dev, idx, &desc);
433         if (res)
434                 return res;
435         if (hairpin_conf->peer_count != 1) {
436                 rte_errno = EINVAL;
437                 DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue index %u"
438                         " peer count is %u", dev->data->port_id,
439                         idx, hairpin_conf->peer_count);
440                 return -rte_errno;
441         }
442         if (hairpin_conf->peers[0].port == dev->data->port_id) {
443                 if (hairpin_conf->peers[0].queue >= priv->rxqs_n) {
444                         rte_errno = EINVAL;
445                         DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue"
446                                 " index %u, Rx %u is larger than %u",
447                                 dev->data->port_id, idx,
448                                 hairpin_conf->peers[0].queue, priv->txqs_n);
449                         return -rte_errno;
450                 }
451         } else {
452                 if (hairpin_conf->manual_bind == 0 ||
453                     hairpin_conf->tx_explicit == 0) {
454                         rte_errno = EINVAL;
455                         DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue"
456                                 " index %u peer port %u with attributes %u %u",
457                                 dev->data->port_id, idx,
458                                 hairpin_conf->peers[0].port,
459                                 hairpin_conf->manual_bind,
460                                 hairpin_conf->tx_explicit);
461                         return -rte_errno;
462                 }
463         }
464         txq_ctrl = mlx5_txq_hairpin_new(dev, idx, desc, hairpin_conf);
465         if (!txq_ctrl) {
466                 DRV_LOG(ERR, "port %u unable to allocate queue index %u",
467                         dev->data->port_id, idx);
468                 return -rte_errno;
469         }
470         DRV_LOG(DEBUG, "port %u adding Tx queue %u to list",
471                 dev->data->port_id, idx);
472         (*priv->txqs)[idx] = &txq_ctrl->txq;
473         dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_HAIRPIN;
474         return 0;
475 }
476
477 /**
478  * DPDK callback to release a TX queue.
479  *
480  * @param dev
481  *   Pointer to Ethernet device structure.
482  * @param qid
483  *   Transmit queue index.
484  */
485 void
486 mlx5_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
487 {
488         struct mlx5_txq_data *txq = dev->data->tx_queues[qid];
489
490         if (txq == NULL)
491                 return;
492         DRV_LOG(DEBUG, "port %u removing Tx queue %u from list",
493                 dev->data->port_id, qid);
494         mlx5_txq_release(dev, qid);
495 }
496
497 /**
498  * Configure the doorbell register non-cached attribute.
499  *
500  * @param txq_ctrl
501  *   Pointer to Tx queue control structure.
502  * @param page_size
503  *   Systme page size
504  */
505 static void
506 txq_uar_ncattr_init(struct mlx5_txq_ctrl *txq_ctrl, size_t page_size)
507 {
508         struct mlx5_common_device *cdev = txq_ctrl->priv->sh->cdev;
509         off_t cmd;
510
511         txq_ctrl->txq.db_heu = cdev->config.dbnc == MLX5_TXDB_HEURISTIC;
512         txq_ctrl->txq.db_nc = 0;
513         /* Check the doorbell register mapping type. */
514         cmd = txq_ctrl->uar_mmap_offset / page_size;
515         cmd >>= MLX5_UAR_MMAP_CMD_SHIFT;
516         cmd &= MLX5_UAR_MMAP_CMD_MASK;
517         if (cmd == MLX5_MMAP_GET_NC_PAGES_CMD)
518                 txq_ctrl->txq.db_nc = 1;
519 }
520
521 /**
522  * Initialize Tx UAR registers for primary process.
523  *
524  * @param txq_ctrl
525  *   Pointer to Tx queue control structure.
526  */
527 void
528 txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl)
529 {
530         struct mlx5_priv *priv = txq_ctrl->priv;
531         struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));
532 #ifndef RTE_ARCH_64
533         unsigned int lock_idx;
534 #endif
535         const size_t page_size = rte_mem_page_size();
536         if (page_size == (size_t)-1) {
537                 DRV_LOG(ERR, "Failed to get mem page size");
538                 rte_errno = ENOMEM;
539         }
540
541         if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD)
542                 return;
543         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
544         MLX5_ASSERT(ppriv);
545         ppriv->uar_table[txq_ctrl->txq.idx] = txq_ctrl->bf_reg;
546         txq_uar_ncattr_init(txq_ctrl, page_size);
547 #ifndef RTE_ARCH_64
548         /* Assign an UAR lock according to UAR page number */
549         lock_idx = (txq_ctrl->uar_mmap_offset / page_size) &
550                    MLX5_UAR_PAGE_NUM_MASK;
551         txq_ctrl->txq.uar_lock = &priv->sh->uar_lock[lock_idx];
552 #endif
553 }
554
555 /**
556  * Remap UAR register of a Tx queue for secondary process.
557  *
558  * Remapped address is stored at the table in the process private structure of
559  * the device, indexed by queue index.
560  *
561  * @param txq_ctrl
562  *   Pointer to Tx queue control structure.
563  * @param fd
564  *   Verbs file descriptor to map UAR pages.
565  *
566  * @return
567  *   0 on success, a negative errno value otherwise and rte_errno is set.
568  */
569 static int
570 txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd)
571 {
572         struct mlx5_priv *priv = txq_ctrl->priv;
573         struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));
574         struct mlx5_txq_data *txq = &txq_ctrl->txq;
575         void *addr;
576         uintptr_t uar_va;
577         uintptr_t offset;
578         const size_t page_size = rte_mem_page_size();
579         if (page_size == (size_t)-1) {
580                 DRV_LOG(ERR, "Failed to get mem page size");
581                 rte_errno = ENOMEM;
582                 return -rte_errno;
583         }
584
585         if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD)
586                 return 0;
587         MLX5_ASSERT(ppriv);
588         /*
589          * As rdma-core, UARs are mapped in size of OS page
590          * size. Ref to libmlx5 function: mlx5_init_context()
591          */
592         uar_va = (uintptr_t)txq_ctrl->bf_reg;
593         offset = uar_va & (page_size - 1); /* Offset in page. */
594         addr = rte_mem_map(NULL, page_size, RTE_PROT_WRITE, RTE_MAP_SHARED,
595                             fd, txq_ctrl->uar_mmap_offset);
596         if (!addr) {
597                 DRV_LOG(ERR,
598                         "port %u mmap failed for BF reg of txq %u",
599                         txq->port_id, txq->idx);
600                 rte_errno = ENXIO;
601                 return -rte_errno;
602         }
603         addr = RTE_PTR_ADD(addr, offset);
604         ppriv->uar_table[txq->idx] = addr;
605         txq_uar_ncattr_init(txq_ctrl, page_size);
606         return 0;
607 }
608
609 /**
610  * Unmap UAR register of a Tx queue for secondary process.
611  *
612  * @param txq_ctrl
613  *   Pointer to Tx queue control structure.
614  */
615 static void
616 txq_uar_uninit_secondary(struct mlx5_txq_ctrl *txq_ctrl)
617 {
618         struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(txq_ctrl->priv));
619         void *addr;
620         const size_t page_size = rte_mem_page_size();
621         if (page_size == (size_t)-1) {
622                 DRV_LOG(ERR, "Failed to get mem page size");
623                 rte_errno = ENOMEM;
624         }
625
626         if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD)
627                 return;
628         addr = ppriv->uar_table[txq_ctrl->txq.idx];
629         rte_mem_unmap(RTE_PTR_ALIGN_FLOOR(addr, page_size), page_size);
630 }
631
632 /**
633  * Deinitialize Tx UAR registers for secondary process.
634  *
635  * @param dev
636  *   Pointer to Ethernet device.
637  */
638 void
639 mlx5_tx_uar_uninit_secondary(struct rte_eth_dev *dev)
640 {
641         struct mlx5_proc_priv *ppriv = (struct mlx5_proc_priv *)
642                                         dev->process_private;
643         const size_t page_size = rte_mem_page_size();
644         void *addr;
645         unsigned int i;
646
647         if (page_size == (size_t)-1) {
648                 DRV_LOG(ERR, "Failed to get mem page size");
649                 return;
650         }
651         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
652         for (i = 0; i != ppriv->uar_table_sz; ++i) {
653                 if (!ppriv->uar_table[i])
654                         continue;
655                 addr = ppriv->uar_table[i];
656                 rte_mem_unmap(RTE_PTR_ALIGN_FLOOR(addr, page_size), page_size);
657
658         }
659 }
660
661 /**
662  * Initialize Tx UAR registers for secondary process.
663  *
664  * @param dev
665  *   Pointer to Ethernet device.
666  * @param fd
667  *   Verbs file descriptor to map UAR pages.
668  *
669  * @return
670  *   0 on success, a negative errno value otherwise and rte_errno is set.
671  */
672 int
673 mlx5_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd)
674 {
675         struct mlx5_priv *priv = dev->data->dev_private;
676         struct mlx5_txq_data *txq;
677         struct mlx5_txq_ctrl *txq_ctrl;
678         unsigned int i;
679         int ret;
680
681         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
682         for (i = 0; i != priv->txqs_n; ++i) {
683                 if (!(*priv->txqs)[i])
684                         continue;
685                 txq = (*priv->txqs)[i];
686                 txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);
687                 if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD)
688                         continue;
689                 MLX5_ASSERT(txq->idx == (uint16_t)i);
690                 ret = txq_uar_init_secondary(txq_ctrl, fd);
691                 if (ret)
692                         goto error;
693         }
694         return 0;
695 error:
696         /* Rollback. */
697         do {
698                 if (!(*priv->txqs)[i])
699                         continue;
700                 txq = (*priv->txqs)[i];
701                 txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);
702                 txq_uar_uninit_secondary(txq_ctrl);
703         } while (i--);
704         return -rte_errno;
705 }
706
707 /**
708  * Verify the Verbs Tx queue list is empty
709  *
710  * @param dev
711  *   Pointer to Ethernet device.
712  *
713  * @return
714  *   The number of object not released.
715  */
716 int
717 mlx5_txq_obj_verify(struct rte_eth_dev *dev)
718 {
719         struct mlx5_priv *priv = dev->data->dev_private;
720         int ret = 0;
721         struct mlx5_txq_obj *txq_obj;
722
723         LIST_FOREACH(txq_obj, &priv->txqsobj, next) {
724                 DRV_LOG(DEBUG, "port %u Verbs Tx queue %u still referenced",
725                         dev->data->port_id, txq_obj->txq_ctrl->txq.idx);
726                 ++ret;
727         }
728         return ret;
729 }
730
731 /**
732  * Calculate the total number of WQEBB for Tx queue.
733  *
734  * Simplified version of calc_sq_size() in rdma-core.
735  *
736  * @param txq_ctrl
737  *   Pointer to Tx queue control structure.
738  *
739  * @return
740  *   The number of WQEBB.
741  */
742 static int
743 txq_calc_wqebb_cnt(struct mlx5_txq_ctrl *txq_ctrl)
744 {
745         unsigned int wqe_size;
746         const unsigned int desc = 1 << txq_ctrl->txq.elts_n;
747
748         wqe_size = MLX5_WQE_CSEG_SIZE +
749                    MLX5_WQE_ESEG_SIZE +
750                    MLX5_WSEG_SIZE -
751                    MLX5_ESEG_MIN_INLINE_SIZE +
752                    txq_ctrl->max_inline_data;
753         return rte_align32pow2(wqe_size * desc) / MLX5_WQE_SIZE;
754 }
755
756 /**
757  * Calculate the maximal inline data size for Tx queue.
758  *
759  * @param txq_ctrl
760  *   Pointer to Tx queue control structure.
761  *
762  * @return
763  *   The maximal inline data size.
764  */
765 static unsigned int
766 txq_calc_inline_max(struct mlx5_txq_ctrl *txq_ctrl)
767 {
768         const unsigned int desc = 1 << txq_ctrl->txq.elts_n;
769         struct mlx5_priv *priv = txq_ctrl->priv;
770         unsigned int wqe_size;
771
772         wqe_size = priv->sh->device_attr.max_qp_wr / desc;
773         if (!wqe_size)
774                 return 0;
775         /*
776          * This calculation is derived from tthe source of
777          * mlx5_calc_send_wqe() in rdma_core library.
778          */
779         wqe_size = wqe_size * MLX5_WQE_SIZE -
780                    MLX5_WQE_CSEG_SIZE -
781                    MLX5_WQE_ESEG_SIZE -
782                    MLX5_WSEG_SIZE -
783                    MLX5_WSEG_SIZE +
784                    MLX5_DSEG_MIN_INLINE_SIZE;
785         return wqe_size;
786 }
787
788 /**
789  * Set Tx queue parameters from device configuration.
790  *
791  * @param txq_ctrl
792  *   Pointer to Tx queue control structure.
793  */
794 static void
795 txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
796 {
797         struct mlx5_priv *priv = txq_ctrl->priv;
798         struct mlx5_dev_config *config = &priv->config;
799         unsigned int inlen_send; /* Inline data for ordinary SEND.*/
800         unsigned int inlen_empw; /* Inline data for enhanced MPW. */
801         unsigned int inlen_mode; /* Minimal required Inline data. */
802         unsigned int txqs_inline; /* Min Tx queues to enable inline. */
803         uint64_t dev_txoff = priv->dev_data->dev_conf.txmode.offloads;
804         bool tso = txq_ctrl->txq.offloads & (RTE_ETH_TX_OFFLOAD_TCP_TSO |
805                                             RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
806                                             RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
807                                             RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
808                                             RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO);
809         bool vlan_inline;
810         unsigned int temp;
811
812         txq_ctrl->txq.fast_free =
813                 !!((txq_ctrl->txq.offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
814                    !(txq_ctrl->txq.offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) &&
815                    !config->mprq.enabled);
816         if (config->txqs_inline == MLX5_ARG_UNSET)
817                 txqs_inline =
818 #if defined(RTE_ARCH_ARM64)
819                 (priv->pci_dev && priv->pci_dev->id.device_id ==
820                         PCI_DEVICE_ID_MELLANOX_CONNECTX5BF) ?
821                         MLX5_INLINE_MAX_TXQS_BLUEFIELD :
822 #endif
823                         MLX5_INLINE_MAX_TXQS;
824         else
825                 txqs_inline = (unsigned int)config->txqs_inline;
826         inlen_send = (config->txq_inline_max == MLX5_ARG_UNSET) ?
827                      MLX5_SEND_DEF_INLINE_LEN :
828                      (unsigned int)config->txq_inline_max;
829         inlen_empw = (config->txq_inline_mpw == MLX5_ARG_UNSET) ?
830                      MLX5_EMPW_DEF_INLINE_LEN :
831                      (unsigned int)config->txq_inline_mpw;
832         inlen_mode = (config->txq_inline_min == MLX5_ARG_UNSET) ?
833                      0 : (unsigned int)config->txq_inline_min;
834         if (config->mps != MLX5_MPW_ENHANCED && config->mps != MLX5_MPW)
835                 inlen_empw = 0;
836         /*
837          * If there is requested minimal amount of data to inline
838          * we MUST enable inlining. This is a case for ConnectX-4
839          * which usually requires L2 inlined for correct operating
840          * and ConnectX-4 Lx which requires L2-L4 inlined to
841          * support E-Switch Flows.
842          */
843         if (inlen_mode) {
844                 if (inlen_mode <= MLX5_ESEG_MIN_INLINE_SIZE) {
845                         /*
846                          * Optimize minimal inlining for single
847                          * segment packets to fill one WQEBB
848                          * without gaps.
849                          */
850                         temp = MLX5_ESEG_MIN_INLINE_SIZE;
851                 } else {
852                         temp = inlen_mode - MLX5_ESEG_MIN_INLINE_SIZE;
853                         temp = RTE_ALIGN(temp, MLX5_WSEG_SIZE) +
854                                MLX5_ESEG_MIN_INLINE_SIZE;
855                         temp = RTE_MIN(temp, MLX5_SEND_MAX_INLINE_LEN);
856                 }
857                 if (temp != inlen_mode) {
858                         DRV_LOG(INFO,
859                                 "port %u minimal required inline setting"
860                                 " aligned from %u to %u",
861                                 PORT_ID(priv), inlen_mode, temp);
862                         inlen_mode = temp;
863                 }
864         }
865         /*
866          * If port is configured to support VLAN insertion and device
867          * does not support this feature by HW (for NICs before ConnectX-5
868          * or in case of wqe_vlan_insert flag is not set) we must enable
869          * data inline on all queues because it is supported by single
870          * tx_burst routine.
871          */
872         txq_ctrl->txq.vlan_en = config->hw_vlan_insert;
873         vlan_inline = (dev_txoff & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) &&
874                       !config->hw_vlan_insert;
875         /*
876          * If there are few Tx queues it is prioritized
877          * to save CPU cycles and disable data inlining at all.
878          */
879         if (inlen_send && priv->txqs_n >= txqs_inline) {
880                 /*
881                  * The data sent with ordinal MLX5_OPCODE_SEND
882                  * may be inlined in Ethernet Segment, align the
883                  * length accordingly to fit entire WQEBBs.
884                  */
885                 temp = RTE_MAX(inlen_send,
886                                MLX5_ESEG_MIN_INLINE_SIZE + MLX5_WQE_DSEG_SIZE);
887                 temp -= MLX5_ESEG_MIN_INLINE_SIZE + MLX5_WQE_DSEG_SIZE;
888                 temp = RTE_ALIGN(temp, MLX5_WQE_SIZE);
889                 temp += MLX5_ESEG_MIN_INLINE_SIZE + MLX5_WQE_DSEG_SIZE;
890                 temp = RTE_MIN(temp, MLX5_WQE_SIZE_MAX +
891                                      MLX5_ESEG_MIN_INLINE_SIZE -
892                                      MLX5_WQE_CSEG_SIZE -
893                                      MLX5_WQE_ESEG_SIZE -
894                                      MLX5_WQE_DSEG_SIZE * 2);
895                 temp = RTE_MIN(temp, MLX5_SEND_MAX_INLINE_LEN);
896                 temp = RTE_MAX(temp, inlen_mode);
897                 if (temp != inlen_send) {
898                         DRV_LOG(INFO,
899                                 "port %u ordinary send inline setting"
900                                 " aligned from %u to %u",
901                                 PORT_ID(priv), inlen_send, temp);
902                         inlen_send = temp;
903                 }
904                 /*
905                  * Not aligned to cache lines, but to WQEs.
906                  * First bytes of data (initial alignment)
907                  * is going to be copied explicitly at the
908                  * beginning of inlining buffer in Ethernet
909                  * Segment.
910                  */
911                 MLX5_ASSERT(inlen_send >= MLX5_ESEG_MIN_INLINE_SIZE);
912                 MLX5_ASSERT(inlen_send <= MLX5_WQE_SIZE_MAX +
913                                           MLX5_ESEG_MIN_INLINE_SIZE -
914                                           MLX5_WQE_CSEG_SIZE -
915                                           MLX5_WQE_ESEG_SIZE -
916                                           MLX5_WQE_DSEG_SIZE * 2);
917         } else if (inlen_mode) {
918                 /*
919                  * If minimal inlining is requested we must
920                  * enable inlining in general, despite the
921                  * number of configured queues. Ignore the
922                  * txq_inline_max devarg, this is not
923                  * full-featured inline.
924                  */
925                 inlen_send = inlen_mode;
926                 inlen_empw = 0;
927         } else if (vlan_inline) {
928                 /*
929                  * Hardware does not report offload for
930                  * VLAN insertion, we must enable data inline
931                  * to implement feature by software.
932                  */
933                 inlen_send = MLX5_ESEG_MIN_INLINE_SIZE;
934                 inlen_empw = 0;
935         } else {
936                 inlen_send = 0;
937                 inlen_empw = 0;
938         }
939         txq_ctrl->txq.inlen_send = inlen_send;
940         txq_ctrl->txq.inlen_mode = inlen_mode;
941         txq_ctrl->txq.inlen_empw = 0;
942         if (inlen_send && inlen_empw && priv->txqs_n >= txqs_inline) {
943                 /*
944                  * The data sent with MLX5_OPCODE_ENHANCED_MPSW
945                  * may be inlined in Data Segment, align the
946                  * length accordingly to fit entire WQEBBs.
947                  */
948                 temp = RTE_MAX(inlen_empw,
949                                MLX5_WQE_SIZE + MLX5_DSEG_MIN_INLINE_SIZE);
950                 temp -= MLX5_DSEG_MIN_INLINE_SIZE;
951                 temp = RTE_ALIGN(temp, MLX5_WQE_SIZE);
952                 temp += MLX5_DSEG_MIN_INLINE_SIZE;
953                 temp = RTE_MIN(temp, MLX5_WQE_SIZE_MAX +
954                                      MLX5_DSEG_MIN_INLINE_SIZE -
955                                      MLX5_WQE_CSEG_SIZE -
956                                      MLX5_WQE_ESEG_SIZE -
957                                      MLX5_WQE_DSEG_SIZE);
958                 temp = RTE_MIN(temp, MLX5_EMPW_MAX_INLINE_LEN);
959                 if (temp != inlen_empw) {
960                         DRV_LOG(INFO,
961                                 "port %u enhanced empw inline setting"
962                                 " aligned from %u to %u",
963                                 PORT_ID(priv), inlen_empw, temp);
964                         inlen_empw = temp;
965                 }
966                 MLX5_ASSERT(inlen_empw >= MLX5_ESEG_MIN_INLINE_SIZE);
967                 MLX5_ASSERT(inlen_empw <= MLX5_WQE_SIZE_MAX +
968                                           MLX5_DSEG_MIN_INLINE_SIZE -
969                                           MLX5_WQE_CSEG_SIZE -
970                                           MLX5_WQE_ESEG_SIZE -
971                                           MLX5_WQE_DSEG_SIZE);
972                 txq_ctrl->txq.inlen_empw = inlen_empw;
973         }
974         txq_ctrl->max_inline_data = RTE_MAX(inlen_send, inlen_empw);
975         if (tso) {
976                 txq_ctrl->max_tso_header = MLX5_MAX_TSO_HEADER;
977                 txq_ctrl->max_inline_data = RTE_MAX(txq_ctrl->max_inline_data,
978                                                     MLX5_MAX_TSO_HEADER);
979                 txq_ctrl->txq.tso_en = 1;
980         }
981         if (((RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO & txq_ctrl->txq.offloads) &&
982             (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
983            ((RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO & txq_ctrl->txq.offloads) &&
984             (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
985            ((RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO & txq_ctrl->txq.offloads) &&
986             (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
987            (config->swp  & MLX5_SW_PARSING_TSO_CAP))
988                 txq_ctrl->txq.tunnel_en = 1;
989         txq_ctrl->txq.swp_en = (((RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
990                                   RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO) &
991                                   txq_ctrl->txq.offloads) && (config->swp &
992                                   MLX5_SW_PARSING_TSO_CAP)) |
993                                 ((RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM &
994                                  txq_ctrl->txq.offloads) && (config->swp &
995                                  MLX5_SW_PARSING_CSUM_CAP));
996 }
997
998 /**
999  * Adjust Tx queue data inline parameters for large queue sizes.
1000  * The data inline feature requires multiple WQEs to fit the packets,
1001  * and if the large amount of Tx descriptors is requested by application
1002  * the total WQE amount may exceed the hardware capabilities. If the
1003  * default inline setting are used we can try to adjust these ones and
1004  * meet the hardware requirements and not exceed the queue size.
1005  *
1006  * @param txq_ctrl
1007  *   Pointer to Tx queue control structure.
1008  *
1009  * @return
1010  *   Zero on success, otherwise the parameters can not be adjusted.
1011  */
1012 static int
1013 txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
1014 {
1015         struct mlx5_priv *priv = txq_ctrl->priv;
1016         struct mlx5_dev_config *config = &priv->config;
1017         unsigned int max_inline;
1018
1019         max_inline = txq_calc_inline_max(txq_ctrl);
1020         if (!txq_ctrl->txq.inlen_send) {
1021                 /*
1022                  * Inline data feature is not engaged at all.
1023                  * There is nothing to adjust.
1024                  */
1025                 return 0;
1026         }
1027         if (txq_ctrl->max_inline_data <= max_inline) {
1028                 /*
1029                  * The requested inline data length does not
1030                  * exceed queue capabilities.
1031                  */
1032                 return 0;
1033         }
1034         if (txq_ctrl->txq.inlen_mode > max_inline) {
1035                 DRV_LOG(ERR,
1036                         "minimal data inline requirements (%u) are not"
1037                         " satisfied (%u) on port %u, try the smaller"
1038                         " Tx queue size (%d)",
1039                         txq_ctrl->txq.inlen_mode, max_inline,
1040                         priv->dev_data->port_id,
1041                         priv->sh->device_attr.max_qp_wr);
1042                 goto error;
1043         }
1044         if (txq_ctrl->txq.inlen_send > max_inline &&
1045             config->txq_inline_max != MLX5_ARG_UNSET &&
1046             config->txq_inline_max > (int)max_inline) {
1047                 DRV_LOG(ERR,
1048                         "txq_inline_max requirements (%u) are not"
1049                         " satisfied (%u) on port %u, try the smaller"
1050                         " Tx queue size (%d)",
1051                         txq_ctrl->txq.inlen_send, max_inline,
1052                         priv->dev_data->port_id,
1053                         priv->sh->device_attr.max_qp_wr);
1054                 goto error;
1055         }
1056         if (txq_ctrl->txq.inlen_empw > max_inline &&
1057             config->txq_inline_mpw != MLX5_ARG_UNSET &&
1058             config->txq_inline_mpw > (int)max_inline) {
1059                 DRV_LOG(ERR,
1060                         "txq_inline_mpw requirements (%u) are not"
1061                         " satisfied (%u) on port %u, try the smaller"
1062                         " Tx queue size (%d)",
1063                         txq_ctrl->txq.inlen_empw, max_inline,
1064                         priv->dev_data->port_id,
1065                         priv->sh->device_attr.max_qp_wr);
1066                 goto error;
1067         }
1068         if (txq_ctrl->txq.tso_en && max_inline < MLX5_MAX_TSO_HEADER) {
1069                 DRV_LOG(ERR,
1070                         "tso header inline requirements (%u) are not"
1071                         " satisfied (%u) on port %u, try the smaller"
1072                         " Tx queue size (%d)",
1073                         MLX5_MAX_TSO_HEADER, max_inline,
1074                         priv->dev_data->port_id,
1075                         priv->sh->device_attr.max_qp_wr);
1076                 goto error;
1077         }
1078         if (txq_ctrl->txq.inlen_send > max_inline) {
1079                 DRV_LOG(WARNING,
1080                         "adjust txq_inline_max (%u->%u)"
1081                         " due to large Tx queue on port %u",
1082                         txq_ctrl->txq.inlen_send, max_inline,
1083                         priv->dev_data->port_id);
1084                 txq_ctrl->txq.inlen_send = max_inline;
1085         }
1086         if (txq_ctrl->txq.inlen_empw > max_inline) {
1087                 DRV_LOG(WARNING,
1088                         "adjust txq_inline_mpw (%u->%u)"
1089                         "due to large Tx queue on port %u",
1090                         txq_ctrl->txq.inlen_empw, max_inline,
1091                         priv->dev_data->port_id);
1092                 txq_ctrl->txq.inlen_empw = max_inline;
1093         }
1094         txq_ctrl->max_inline_data = RTE_MAX(txq_ctrl->txq.inlen_send,
1095                                             txq_ctrl->txq.inlen_empw);
1096         MLX5_ASSERT(txq_ctrl->max_inline_data <= max_inline);
1097         MLX5_ASSERT(txq_ctrl->txq.inlen_mode <= max_inline);
1098         MLX5_ASSERT(txq_ctrl->txq.inlen_mode <= txq_ctrl->txq.inlen_send);
1099         MLX5_ASSERT(txq_ctrl->txq.inlen_mode <= txq_ctrl->txq.inlen_empw ||
1100                     !txq_ctrl->txq.inlen_empw);
1101         return 0;
1102 error:
1103         rte_errno = ENOMEM;
1104         return -ENOMEM;
1105 }
1106
1107 /**
1108  * Create a DPDK Tx queue.
1109  *
1110  * @param dev
1111  *   Pointer to Ethernet device.
1112  * @param idx
1113  *   TX queue index.
1114  * @param desc
1115  *   Number of descriptors to configure in queue.
1116  * @param socket
1117  *   NUMA socket on which memory must be allocated.
1118  * @param[in] conf
1119  *  Thresholds parameters.
1120  *
1121  * @return
1122  *   A DPDK queue object on success, NULL otherwise and rte_errno is set.
1123  */
1124 struct mlx5_txq_ctrl *
1125 mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
1126              unsigned int socket, const struct rte_eth_txconf *conf)
1127 {
1128         struct mlx5_priv *priv = dev->data->dev_private;
1129         struct mlx5_txq_ctrl *tmpl;
1130
1131         tmpl = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*tmpl) +
1132                            desc * sizeof(struct rte_mbuf *), 0, socket);
1133         if (!tmpl) {
1134                 rte_errno = ENOMEM;
1135                 return NULL;
1136         }
1137         if (mlx5_mr_ctrl_init(&tmpl->txq.mr_ctrl,
1138                               &priv->sh->cdev->mr_scache.dev_gen, socket)) {
1139                 /* rte_errno is already set. */
1140                 goto error;
1141         }
1142         MLX5_ASSERT(desc > MLX5_TX_COMP_THRESH);
1143         tmpl->txq.offloads = conf->offloads |
1144                              dev->data->dev_conf.txmode.offloads;
1145         tmpl->priv = priv;
1146         tmpl->socket = socket;
1147         tmpl->txq.elts_n = log2above(desc);
1148         tmpl->txq.elts_s = desc;
1149         tmpl->txq.elts_m = desc - 1;
1150         tmpl->txq.port_id = dev->data->port_id;
1151         tmpl->txq.idx = idx;
1152         txq_set_params(tmpl);
1153         if (txq_adjust_params(tmpl))
1154                 goto error;
1155         if (txq_calc_wqebb_cnt(tmpl) >
1156             priv->sh->device_attr.max_qp_wr) {
1157                 DRV_LOG(ERR,
1158                         "port %u Tx WQEBB count (%d) exceeds the limit (%d),"
1159                         " try smaller queue size",
1160                         dev->data->port_id, txq_calc_wqebb_cnt(tmpl),
1161                         priv->sh->device_attr.max_qp_wr);
1162                 rte_errno = ENOMEM;
1163                 goto error;
1164         }
1165         __atomic_fetch_add(&tmpl->refcnt, 1, __ATOMIC_RELAXED);
1166         tmpl->type = MLX5_TXQ_TYPE_STANDARD;
1167         LIST_INSERT_HEAD(&priv->txqsctrl, tmpl, next);
1168         return tmpl;
1169 error:
1170         mlx5_mr_btree_free(&tmpl->txq.mr_ctrl.cache_bh);
1171         mlx5_free(tmpl);
1172         return NULL;
1173 }
1174
1175 /**
1176  * Create a DPDK Tx hairpin queue.
1177  *
1178  * @param dev
1179  *   Pointer to Ethernet device.
1180  * @param idx
1181  *   TX queue index.
1182  * @param desc
1183  *   Number of descriptors to configure in queue.
1184  * @param hairpin_conf
1185  *  The hairpin configuration.
1186  *
1187  * @return
1188  *   A DPDK queue object on success, NULL otherwise and rte_errno is set.
1189  */
1190 struct mlx5_txq_ctrl *
1191 mlx5_txq_hairpin_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
1192                      const struct rte_eth_hairpin_conf *hairpin_conf)
1193 {
1194         struct mlx5_priv *priv = dev->data->dev_private;
1195         struct mlx5_txq_ctrl *tmpl;
1196
1197         tmpl = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*tmpl), 0,
1198                            SOCKET_ID_ANY);
1199         if (!tmpl) {
1200                 rte_errno = ENOMEM;
1201                 return NULL;
1202         }
1203         tmpl->priv = priv;
1204         tmpl->socket = SOCKET_ID_ANY;
1205         tmpl->txq.elts_n = log2above(desc);
1206         tmpl->txq.port_id = dev->data->port_id;
1207         tmpl->txq.idx = idx;
1208         tmpl->hairpin_conf = *hairpin_conf;
1209         tmpl->type = MLX5_TXQ_TYPE_HAIRPIN;
1210         __atomic_fetch_add(&tmpl->refcnt, 1, __ATOMIC_RELAXED);
1211         LIST_INSERT_HEAD(&priv->txqsctrl, tmpl, next);
1212         return tmpl;
1213 }
1214
1215 /**
1216  * Get a Tx queue.
1217  *
1218  * @param dev
1219  *   Pointer to Ethernet device.
1220  * @param idx
1221  *   TX queue index.
1222  *
1223  * @return
1224  *   A pointer to the queue if it exists.
1225  */
1226 struct mlx5_txq_ctrl *
1227 mlx5_txq_get(struct rte_eth_dev *dev, uint16_t idx)
1228 {
1229         struct mlx5_priv *priv = dev->data->dev_private;
1230         struct mlx5_txq_data *txq_data = (*priv->txqs)[idx];
1231         struct mlx5_txq_ctrl *ctrl = NULL;
1232
1233         if (txq_data) {
1234                 ctrl = container_of(txq_data, struct mlx5_txq_ctrl, txq);
1235                 __atomic_fetch_add(&ctrl->refcnt, 1, __ATOMIC_RELAXED);
1236         }
1237         return ctrl;
1238 }
1239
1240 /**
1241  * Release a Tx queue.
1242  *
1243  * @param dev
1244  *   Pointer to Ethernet device.
1245  * @param idx
1246  *   TX queue index.
1247  *
1248  * @return
1249  *   1 while a reference on it exists, 0 when freed.
1250  */
1251 int
1252 mlx5_txq_release(struct rte_eth_dev *dev, uint16_t idx)
1253 {
1254         struct mlx5_priv *priv = dev->data->dev_private;
1255         struct mlx5_txq_ctrl *txq_ctrl;
1256
1257         if (priv->txqs == NULL || (*priv->txqs)[idx] == NULL)
1258                 return 0;
1259         txq_ctrl = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq);
1260         if (__atomic_sub_fetch(&txq_ctrl->refcnt, 1, __ATOMIC_RELAXED) > 1)
1261                 return 1;
1262         if (txq_ctrl->obj) {
1263                 priv->obj_ops.txq_obj_release(txq_ctrl->obj);
1264                 LIST_REMOVE(txq_ctrl->obj, next);
1265                 mlx5_free(txq_ctrl->obj);
1266                 txq_ctrl->obj = NULL;
1267         }
1268         if (txq_ctrl->type == MLX5_TXQ_TYPE_STANDARD) {
1269                 if (txq_ctrl->txq.fcqs) {
1270                         mlx5_free(txq_ctrl->txq.fcqs);
1271                         txq_ctrl->txq.fcqs = NULL;
1272                 }
1273                 txq_free_elts(txq_ctrl);
1274                 dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
1275         }
1276         if (!__atomic_load_n(&txq_ctrl->refcnt, __ATOMIC_RELAXED)) {
1277                 if (txq_ctrl->type == MLX5_TXQ_TYPE_STANDARD)
1278                         mlx5_mr_btree_free(&txq_ctrl->txq.mr_ctrl.cache_bh);
1279                 LIST_REMOVE(txq_ctrl, next);
1280                 mlx5_free(txq_ctrl);
1281                 (*priv->txqs)[idx] = NULL;
1282         }
1283         return 0;
1284 }
1285
1286 /**
1287  * Verify if the queue can be released.
1288  *
1289  * @param dev
1290  *   Pointer to Ethernet device.
1291  * @param idx
1292  *   TX queue index.
1293  *
1294  * @return
1295  *   1 if the queue can be released.
1296  */
1297 int
1298 mlx5_txq_releasable(struct rte_eth_dev *dev, uint16_t idx)
1299 {
1300         struct mlx5_priv *priv = dev->data->dev_private;
1301         struct mlx5_txq_ctrl *txq;
1302
1303         if (!(*priv->txqs)[idx])
1304                 return -1;
1305         txq = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq);
1306         return (__atomic_load_n(&txq->refcnt, __ATOMIC_RELAXED) == 1);
1307 }
1308
1309 /**
1310  * Verify the Tx Queue list is empty
1311  *
1312  * @param dev
1313  *   Pointer to Ethernet device.
1314  *
1315  * @return
1316  *   The number of object not released.
1317  */
1318 int
1319 mlx5_txq_verify(struct rte_eth_dev *dev)
1320 {
1321         struct mlx5_priv *priv = dev->data->dev_private;
1322         struct mlx5_txq_ctrl *txq_ctrl;
1323         int ret = 0;
1324
1325         LIST_FOREACH(txq_ctrl, &priv->txqsctrl, next) {
1326                 DRV_LOG(DEBUG, "port %u Tx queue %u still referenced",
1327                         dev->data->port_id, txq_ctrl->txq.idx);
1328                 ++ret;
1329         }
1330         return ret;
1331 }
1332
1333 /**
1334  * Set the Tx queue dynamic timestamp (mask and offset)
1335  *
1336  * @param[in] dev
1337  *   Pointer to the Ethernet device structure.
1338  */
1339 void
1340 mlx5_txq_dynf_timestamp_set(struct rte_eth_dev *dev)
1341 {
1342         struct mlx5_priv *priv = dev->data->dev_private;
1343         struct mlx5_dev_ctx_shared *sh = priv->sh;
1344         struct mlx5_txq_data *data;
1345         int off, nbit;
1346         unsigned int i;
1347         uint64_t mask = 0;
1348
1349         nbit = rte_mbuf_dynflag_lookup
1350                                 (RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL);
1351         off = rte_mbuf_dynfield_lookup
1352                                 (RTE_MBUF_DYNFIELD_TIMESTAMP_NAME, NULL);
1353         if (nbit >= 0 && off >= 0 && sh->txpp.refcnt)
1354                 mask = 1ULL << nbit;
1355         for (i = 0; i != priv->txqs_n; ++i) {
1356                 data = (*priv->txqs)[i];
1357                 if (!data)
1358                         continue;
1359                 data->sh = sh;
1360                 data->ts_mask = mask;
1361                 data->ts_offset = off;
1362         }
1363 }