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