net/mlx5: add reference counter on DPDK Rx queues
[dpdk.git] / drivers / net / mlx5 / mlx5_rxq.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright 2015 6WIND S.A.
5  *   Copyright 2015 Mellanox.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of 6WIND S.A. nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stddef.h>
35 #include <assert.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <stdint.h>
39 #include <fcntl.h>
40 #include <sys/queue.h>
41
42 /* Verbs header. */
43 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
44 #ifdef PEDANTIC
45 #pragma GCC diagnostic ignored "-Wpedantic"
46 #endif
47 #include <infiniband/verbs.h>
48 #include <infiniband/mlx5dv.h>
49 #ifdef PEDANTIC
50 #pragma GCC diagnostic error "-Wpedantic"
51 #endif
52
53 #include <rte_mbuf.h>
54 #include <rte_malloc.h>
55 #include <rte_ethdev.h>
56 #include <rte_common.h>
57 #include <rte_interrupts.h>
58 #include <rte_debug.h>
59 #include <rte_io.h>
60
61 #include "mlx5.h"
62 #include "mlx5_rxtx.h"
63 #include "mlx5_utils.h"
64 #include "mlx5_autoconf.h"
65 #include "mlx5_defs.h"
66
67 /* Initialization data for hash RX queues. */
68 const struct hash_rxq_init hash_rxq_init[] = {
69         [HASH_RXQ_TCPV4] = {
70                 .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
71                                 IBV_RX_HASH_DST_IPV4 |
72                                 IBV_RX_HASH_SRC_PORT_TCP |
73                                 IBV_RX_HASH_DST_PORT_TCP),
74                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_TCP,
75                 .flow_priority = 0,
76                 .flow_spec.tcp_udp = {
77                         .type = IBV_FLOW_SPEC_TCP,
78                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
79                 },
80                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
81         },
82         [HASH_RXQ_UDPV4] = {
83                 .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
84                                 IBV_RX_HASH_DST_IPV4 |
85                                 IBV_RX_HASH_SRC_PORT_UDP |
86                                 IBV_RX_HASH_DST_PORT_UDP),
87                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_UDP,
88                 .flow_priority = 0,
89                 .flow_spec.tcp_udp = {
90                         .type = IBV_FLOW_SPEC_UDP,
91                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
92                 },
93                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
94         },
95         [HASH_RXQ_IPV4] = {
96                 .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
97                                 IBV_RX_HASH_DST_IPV4),
98                 .dpdk_rss_hf = (ETH_RSS_IPV4 |
99                                 ETH_RSS_FRAG_IPV4),
100                 .flow_priority = 1,
101                 .flow_spec.ipv4 = {
102                         .type = IBV_FLOW_SPEC_IPV4,
103                         .size = sizeof(hash_rxq_init[0].flow_spec.ipv4),
104                 },
105                 .underlayer = &hash_rxq_init[HASH_RXQ_ETH],
106         },
107         [HASH_RXQ_TCPV6] = {
108                 .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
109                                 IBV_RX_HASH_DST_IPV6 |
110                                 IBV_RX_HASH_SRC_PORT_TCP |
111                                 IBV_RX_HASH_DST_PORT_TCP),
112                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_TCP,
113                 .flow_priority = 0,
114                 .flow_spec.tcp_udp = {
115                         .type = IBV_FLOW_SPEC_TCP,
116                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
117                 },
118                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
119         },
120         [HASH_RXQ_UDPV6] = {
121                 .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
122                                 IBV_RX_HASH_DST_IPV6 |
123                                 IBV_RX_HASH_SRC_PORT_UDP |
124                                 IBV_RX_HASH_DST_PORT_UDP),
125                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_UDP,
126                 .flow_priority = 0,
127                 .flow_spec.tcp_udp = {
128                         .type = IBV_FLOW_SPEC_UDP,
129                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
130                 },
131                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
132         },
133         [HASH_RXQ_IPV6] = {
134                 .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
135                                 IBV_RX_HASH_DST_IPV6),
136                 .dpdk_rss_hf = (ETH_RSS_IPV6 |
137                                 ETH_RSS_FRAG_IPV6),
138                 .flow_priority = 1,
139                 .flow_spec.ipv6 = {
140                         .type = IBV_FLOW_SPEC_IPV6,
141                         .size = sizeof(hash_rxq_init[0].flow_spec.ipv6),
142                 },
143                 .underlayer = &hash_rxq_init[HASH_RXQ_ETH],
144         },
145         [HASH_RXQ_ETH] = {
146                 .hash_fields = 0,
147                 .dpdk_rss_hf = 0,
148                 .flow_priority = 2,
149                 .flow_spec.eth = {
150                         .type = IBV_FLOW_SPEC_ETH,
151                         .size = sizeof(hash_rxq_init[0].flow_spec.eth),
152                 },
153                 .underlayer = NULL,
154         },
155 };
156
157 /* Number of entries in hash_rxq_init[]. */
158 const unsigned int hash_rxq_init_n = RTE_DIM(hash_rxq_init);
159
160 /* Initialization data for hash RX queue indirection tables. */
161 static const struct ind_table_init ind_table_init[] = {
162         {
163                 .max_size = -1u, /* Superseded by HW limitations. */
164                 .hash_types =
165                         1 << HASH_RXQ_TCPV4 |
166                         1 << HASH_RXQ_UDPV4 |
167                         1 << HASH_RXQ_IPV4 |
168                         1 << HASH_RXQ_TCPV6 |
169                         1 << HASH_RXQ_UDPV6 |
170                         1 << HASH_RXQ_IPV6 |
171                         0,
172                 .hash_types_n = 6,
173         },
174         {
175                 .max_size = 1,
176                 .hash_types = 1 << HASH_RXQ_ETH,
177                 .hash_types_n = 1,
178         },
179 };
180
181 #define IND_TABLE_INIT_N RTE_DIM(ind_table_init)
182
183 /* Default RSS hash key also used for ConnectX-3. */
184 uint8_t rss_hash_default_key[] = {
185         0x2c, 0xc6, 0x81, 0xd1,
186         0x5b, 0xdb, 0xf4, 0xf7,
187         0xfc, 0xa2, 0x83, 0x19,
188         0xdb, 0x1a, 0x3e, 0x94,
189         0x6b, 0x9e, 0x38, 0xd9,
190         0x2c, 0x9c, 0x03, 0xd1,
191         0xad, 0x99, 0x44, 0xa7,
192         0xd9, 0x56, 0x3d, 0x59,
193         0x06, 0x3c, 0x25, 0xf3,
194         0xfc, 0x1f, 0xdc, 0x2a,
195 };
196
197 /* Length of the default RSS hash key. */
198 const size_t rss_hash_default_key_len = sizeof(rss_hash_default_key);
199
200 /**
201  * Populate flow steering rule for a given hash RX queue type using
202  * information from hash_rxq_init[]. Nothing is written to flow_attr when
203  * flow_attr_size is not large enough, but the required size is still returned.
204  *
205  * @param priv
206  *   Pointer to private structure.
207  * @param[out] flow_attr
208  *   Pointer to flow attribute structure to fill. Note that the allocated
209  *   area must be larger and large enough to hold all flow specifications.
210  * @param flow_attr_size
211  *   Entire size of flow_attr and trailing room for flow specifications.
212  * @param type
213  *   Hash RX queue type to use for flow steering rule.
214  *
215  * @return
216  *   Total size of the flow attribute buffer. No errors are defined.
217  */
218 size_t
219 priv_flow_attr(struct priv *priv, struct ibv_flow_attr *flow_attr,
220                size_t flow_attr_size, enum hash_rxq_type type)
221 {
222         size_t offset = sizeof(*flow_attr);
223         const struct hash_rxq_init *init = &hash_rxq_init[type];
224
225         assert(priv != NULL);
226         assert((size_t)type < RTE_DIM(hash_rxq_init));
227         do {
228                 offset += init->flow_spec.hdr.size;
229                 init = init->underlayer;
230         } while (init != NULL);
231         if (offset > flow_attr_size)
232                 return offset;
233         flow_attr_size = offset;
234         init = &hash_rxq_init[type];
235         *flow_attr = (struct ibv_flow_attr){
236                 .type = IBV_FLOW_ATTR_NORMAL,
237                 /* Priorities < 3 are reserved for flow director. */
238                 .priority = init->flow_priority + 3,
239                 .num_of_specs = 0,
240                 .port = priv->port,
241                 .flags = 0,
242         };
243         do {
244                 offset -= init->flow_spec.hdr.size;
245                 memcpy((void *)((uintptr_t)flow_attr + offset),
246                        &init->flow_spec,
247                        init->flow_spec.hdr.size);
248                 ++flow_attr->num_of_specs;
249                 init = init->underlayer;
250         } while (init != NULL);
251         return flow_attr_size;
252 }
253
254 /**
255  * Convert hash type position in indirection table initializer to
256  * hash RX queue type.
257  *
258  * @param table
259  *   Indirection table initializer.
260  * @param pos
261  *   Hash type position.
262  *
263  * @return
264  *   Hash RX queue type.
265  */
266 static enum hash_rxq_type
267 hash_rxq_type_from_pos(const struct ind_table_init *table, unsigned int pos)
268 {
269         enum hash_rxq_type type = HASH_RXQ_TCPV4;
270
271         assert(pos < table->hash_types_n);
272         do {
273                 if ((table->hash_types & (1 << type)) && (pos-- == 0))
274                         break;
275                 ++type;
276         } while (1);
277         return type;
278 }
279
280 /**
281  * Filter out disabled hash RX queue types from ind_table_init[].
282  *
283  * @param priv
284  *   Pointer to private structure.
285  * @param[out] table
286  *   Output table.
287  *
288  * @return
289  *   Number of table entries.
290  */
291 static unsigned int
292 priv_make_ind_table_init(struct priv *priv,
293                          struct ind_table_init (*table)[IND_TABLE_INIT_N])
294 {
295         uint64_t rss_hf;
296         unsigned int i;
297         unsigned int j;
298         unsigned int table_n = 0;
299         /* Mandatory to receive frames not handled by normal hash RX queues. */
300         unsigned int hash_types_sup = 1 << HASH_RXQ_ETH;
301
302         rss_hf = priv->rss_hf;
303         /* Process other protocols only if more than one queue. */
304         if (priv->rxqs_n > 1)
305                 for (i = 0; (i != hash_rxq_init_n); ++i)
306                         if (rss_hf & hash_rxq_init[i].dpdk_rss_hf)
307                                 hash_types_sup |= (1 << i);
308
309         /* Filter out entries whose protocols are not in the set. */
310         for (i = 0, j = 0; (i != IND_TABLE_INIT_N); ++i) {
311                 unsigned int nb;
312                 unsigned int h;
313
314                 /* j is increased only if the table has valid protocols. */
315                 assert(j <= i);
316                 (*table)[j] = ind_table_init[i];
317                 (*table)[j].hash_types &= hash_types_sup;
318                 for (h = 0, nb = 0; (h != hash_rxq_init_n); ++h)
319                         if (((*table)[j].hash_types >> h) & 0x1)
320                                 ++nb;
321                 (*table)[i].hash_types_n = nb;
322                 if (nb) {
323                         ++table_n;
324                         ++j;
325                 }
326         }
327         return table_n;
328 }
329
330 /**
331  * Initialize hash RX queues and indirection table.
332  *
333  * @param priv
334  *   Pointer to private structure.
335  *
336  * @return
337  *   0 on success, errno value on failure.
338  */
339 int
340 priv_create_hash_rxqs(struct priv *priv)
341 {
342         struct ibv_wq *wqs[priv->reta_idx_n];
343         struct ind_table_init ind_table_init[IND_TABLE_INIT_N];
344         unsigned int ind_tables_n =
345                 priv_make_ind_table_init(priv, &ind_table_init);
346         unsigned int hash_rxqs_n = 0;
347         struct hash_rxq (*hash_rxqs)[] = NULL;
348         struct ibv_rwq_ind_table *(*ind_tables)[] = NULL;
349         unsigned int i;
350         unsigned int j;
351         unsigned int k;
352         int err = 0;
353
354         assert(priv->ind_tables == NULL);
355         assert(priv->ind_tables_n == 0);
356         assert(priv->hash_rxqs == NULL);
357         assert(priv->hash_rxqs_n == 0);
358         assert(priv->pd != NULL);
359         assert(priv->ctx != NULL);
360         if (priv->isolated)
361                 return 0;
362         if (priv->rxqs_n == 0)
363                 return EINVAL;
364         assert(priv->rxqs != NULL);
365         if (ind_tables_n == 0) {
366                 ERROR("all hash RX queue types have been filtered out,"
367                       " indirection table cannot be created");
368                 return EINVAL;
369         }
370         if (priv->rxqs_n & (priv->rxqs_n - 1)) {
371                 INFO("%u RX queues are configured, consider rounding this"
372                      " number to the next power of two for better balancing",
373                      priv->rxqs_n);
374                 DEBUG("indirection table extended to assume %u WQs",
375                       priv->reta_idx_n);
376         }
377         for (i = 0; (i != priv->reta_idx_n); ++i) {
378                 struct mlx5_rxq_ctrl *rxq_ctrl;
379
380                 rxq_ctrl = container_of((*priv->rxqs)[(*priv->reta_idx)[i]],
381                                         struct mlx5_rxq_ctrl, rxq);
382                 wqs[i] = rxq_ctrl->ibv->wq;
383         }
384         /* Get number of hash RX queues to configure. */
385         for (i = 0, hash_rxqs_n = 0; (i != ind_tables_n); ++i)
386                 hash_rxqs_n += ind_table_init[i].hash_types_n;
387         DEBUG("allocating %u hash RX queues for %u WQs, %u indirection tables",
388               hash_rxqs_n, priv->rxqs_n, ind_tables_n);
389         /* Create indirection tables. */
390         ind_tables = rte_calloc(__func__, ind_tables_n,
391                                 sizeof((*ind_tables)[0]), 0);
392         if (ind_tables == NULL) {
393                 err = ENOMEM;
394                 ERROR("cannot allocate indirection tables container: %s",
395                       strerror(err));
396                 goto error;
397         }
398         for (i = 0; (i != ind_tables_n); ++i) {
399                 struct ibv_rwq_ind_table_init_attr ind_init_attr = {
400                         .log_ind_tbl_size = 0, /* Set below. */
401                         .ind_tbl = wqs,
402                         .comp_mask = 0,
403                 };
404                 unsigned int ind_tbl_size = ind_table_init[i].max_size;
405                 struct ibv_rwq_ind_table *ind_table;
406
407                 if (priv->reta_idx_n < ind_tbl_size)
408                         ind_tbl_size = priv->reta_idx_n;
409                 ind_init_attr.log_ind_tbl_size = log2above(ind_tbl_size);
410                 errno = 0;
411                 ind_table = ibv_create_rwq_ind_table(priv->ctx,
412                                                      &ind_init_attr);
413                 if (ind_table != NULL) {
414                         (*ind_tables)[i] = ind_table;
415                         continue;
416                 }
417                 /* Not clear whether errno is set. */
418                 err = (errno ? errno : EINVAL);
419                 ERROR("RX indirection table creation failed with error %d: %s",
420                       err, strerror(err));
421                 goto error;
422         }
423         /* Allocate array that holds hash RX queues and related data. */
424         hash_rxqs = rte_calloc(__func__, hash_rxqs_n,
425                                sizeof((*hash_rxqs)[0]), 0);
426         if (hash_rxqs == NULL) {
427                 err = ENOMEM;
428                 ERROR("cannot allocate hash RX queues container: %s",
429                       strerror(err));
430                 goto error;
431         }
432         for (i = 0, j = 0, k = 0;
433              ((i != hash_rxqs_n) && (j != ind_tables_n));
434              ++i) {
435                 struct hash_rxq *hash_rxq = &(*hash_rxqs)[i];
436                 enum hash_rxq_type type =
437                         hash_rxq_type_from_pos(&ind_table_init[j], k);
438                 struct rte_eth_rss_conf *priv_rss_conf =
439                         (*priv->rss_conf)[type];
440                 struct ibv_rx_hash_conf hash_conf = {
441                         .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
442                         .rx_hash_key_len = (priv_rss_conf ?
443                                             priv_rss_conf->rss_key_len :
444                                             rss_hash_default_key_len),
445                         .rx_hash_key = (priv_rss_conf ?
446                                         priv_rss_conf->rss_key :
447                                         rss_hash_default_key),
448                         .rx_hash_fields_mask = hash_rxq_init[type].hash_fields,
449                 };
450                 struct ibv_qp_init_attr_ex qp_init_attr = {
451                         .qp_type = IBV_QPT_RAW_PACKET,
452                         .comp_mask = (IBV_QP_INIT_ATTR_PD |
453                                       IBV_QP_INIT_ATTR_IND_TABLE |
454                                       IBV_QP_INIT_ATTR_RX_HASH),
455                         .rx_hash_conf = hash_conf,
456                         .rwq_ind_tbl = (*ind_tables)[j],
457                         .pd = priv->pd,
458                 };
459
460                 DEBUG("using indirection table %u for hash RX queue %u type %d",
461                       j, i, type);
462                 *hash_rxq = (struct hash_rxq){
463                         .priv = priv,
464                         .qp = ibv_create_qp_ex(priv->ctx, &qp_init_attr),
465                         .type = type,
466                 };
467                 if (hash_rxq->qp == NULL) {
468                         err = (errno ? errno : EINVAL);
469                         ERROR("Hash RX QP creation failure: %s",
470                               strerror(err));
471                         goto error;
472                 }
473                 if (++k < ind_table_init[j].hash_types_n)
474                         continue;
475                 /* Switch to the next indirection table and reset hash RX
476                  * queue type array index. */
477                 ++j;
478                 k = 0;
479         }
480         priv->ind_tables = ind_tables;
481         priv->ind_tables_n = ind_tables_n;
482         priv->hash_rxqs = hash_rxqs;
483         priv->hash_rxqs_n = hash_rxqs_n;
484         assert(err == 0);
485         return 0;
486 error:
487         if (hash_rxqs != NULL) {
488                 for (i = 0; (i != hash_rxqs_n); ++i) {
489                         struct ibv_qp *qp = (*hash_rxqs)[i].qp;
490
491                         if (qp == NULL)
492                                 continue;
493                         claim_zero(ibv_destroy_qp(qp));
494                 }
495                 rte_free(hash_rxqs);
496         }
497         if (ind_tables != NULL) {
498                 for (j = 0; (j != ind_tables_n); ++j) {
499                         struct ibv_rwq_ind_table *ind_table =
500                                 (*ind_tables)[j];
501
502                         if (ind_table == NULL)
503                                 continue;
504                         claim_zero(ibv_destroy_rwq_ind_table(ind_table));
505                 }
506                 rte_free(ind_tables);
507         }
508         return err;
509 }
510
511 /**
512  * Clean up hash RX queues and indirection table.
513  *
514  * @param priv
515  *   Pointer to private structure.
516  */
517 void
518 priv_destroy_hash_rxqs(struct priv *priv)
519 {
520         unsigned int i;
521
522         DEBUG("destroying %u hash RX queues", priv->hash_rxqs_n);
523         if (priv->hash_rxqs_n == 0) {
524                 assert(priv->hash_rxqs == NULL);
525                 assert(priv->ind_tables == NULL);
526                 return;
527         }
528         for (i = 0; (i != priv->hash_rxqs_n); ++i) {
529                 struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
530                 unsigned int j, k;
531
532                 assert(hash_rxq->priv == priv);
533                 assert(hash_rxq->qp != NULL);
534                 /* Also check that there are no remaining flows. */
535                 for (j = 0; (j != RTE_DIM(hash_rxq->special_flow)); ++j)
536                         for (k = 0;
537                              (k != RTE_DIM(hash_rxq->special_flow[j]));
538                              ++k)
539                                 assert(hash_rxq->special_flow[j][k] == NULL);
540                 for (j = 0; (j != RTE_DIM(hash_rxq->mac_flow)); ++j)
541                         for (k = 0; (k != RTE_DIM(hash_rxq->mac_flow[j])); ++k)
542                                 assert(hash_rxq->mac_flow[j][k] == NULL);
543                 claim_zero(ibv_destroy_qp(hash_rxq->qp));
544         }
545         priv->hash_rxqs_n = 0;
546         rte_free(priv->hash_rxqs);
547         priv->hash_rxqs = NULL;
548         for (i = 0; (i != priv->ind_tables_n); ++i) {
549                 struct ibv_rwq_ind_table *ind_table =
550                         (*priv->ind_tables)[i];
551
552                 assert(ind_table != NULL);
553                 claim_zero(ibv_destroy_rwq_ind_table(ind_table));
554         }
555         priv->ind_tables_n = 0;
556         rte_free(priv->ind_tables);
557         priv->ind_tables = NULL;
558 }
559
560 /**
561  * Check whether a given flow type is allowed.
562  *
563  * @param priv
564  *   Pointer to private structure.
565  * @param type
566  *   Flow type to check.
567  *
568  * @return
569  *   Nonzero if the given flow type is allowed.
570  */
571 int
572 priv_allow_flow_type(struct priv *priv, enum hash_rxq_flow_type type)
573 {
574         /* Only FLOW_TYPE_PROMISC is allowed when promiscuous mode
575          * has been requested. */
576         if (priv->promisc_req)
577                 return type == HASH_RXQ_FLOW_TYPE_PROMISC;
578         switch (type) {
579         case HASH_RXQ_FLOW_TYPE_PROMISC:
580                 return !!priv->promisc_req;
581         case HASH_RXQ_FLOW_TYPE_ALLMULTI:
582                 return !!priv->allmulti_req;
583         case HASH_RXQ_FLOW_TYPE_BROADCAST:
584         case HASH_RXQ_FLOW_TYPE_IPV6MULTI:
585                 /* If allmulti is enabled, broadcast and ipv6multi
586                  * are unnecessary. */
587                 return !priv->allmulti_req;
588         case HASH_RXQ_FLOW_TYPE_MAC:
589                 return 1;
590         default:
591                 /* Unsupported flow type is not allowed. */
592                 return 0;
593         }
594         return 0;
595 }
596
597 /**
598  * Automatically enable/disable flows according to configuration.
599  *
600  * @param priv
601  *   Private structure.
602  *
603  * @return
604  *   0 on success, errno value on failure.
605  */
606 int
607 priv_rehash_flows(struct priv *priv)
608 {
609         enum hash_rxq_flow_type i;
610
611         for (i = HASH_RXQ_FLOW_TYPE_PROMISC;
612                         i != RTE_DIM((*priv->hash_rxqs)[0].special_flow);
613                         ++i)
614                 if (!priv_allow_flow_type(priv, i)) {
615                         priv_special_flow_disable(priv, i);
616                 } else {
617                         int ret = priv_special_flow_enable(priv, i);
618
619                         if (ret)
620                                 return ret;
621                 }
622         if (priv_allow_flow_type(priv, HASH_RXQ_FLOW_TYPE_MAC))
623                 return priv_mac_addrs_enable(priv);
624         priv_mac_addrs_disable(priv);
625         return 0;
626 }
627
628 /**
629  * Allocate RX queue elements.
630  *
631  * @param rxq_ctrl
632  *   Pointer to RX queue structure.
633  *
634  * @return
635  *   0 on success, errno value on failure.
636  */
637 int
638 rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl)
639 {
640         const unsigned int sges_n = 1 << rxq_ctrl->rxq.sges_n;
641         unsigned int elts_n = 1 << rxq_ctrl->rxq.elts_n;
642         unsigned int i;
643         int ret = 0;
644
645         /* Iterate on segments. */
646         for (i = 0; (i != elts_n); ++i) {
647                 struct rte_mbuf *buf;
648
649                 buf = rte_pktmbuf_alloc(rxq_ctrl->rxq.mp);
650                 if (buf == NULL) {
651                         ERROR("%p: empty mbuf pool", (void *)rxq_ctrl);
652                         ret = ENOMEM;
653                         goto error;
654                 }
655                 /* Headroom is reserved by rte_pktmbuf_alloc(). */
656                 assert(DATA_OFF(buf) == RTE_PKTMBUF_HEADROOM);
657                 /* Buffer is supposed to be empty. */
658                 assert(rte_pktmbuf_data_len(buf) == 0);
659                 assert(rte_pktmbuf_pkt_len(buf) == 0);
660                 assert(!buf->next);
661                 /* Only the first segment keeps headroom. */
662                 if (i % sges_n)
663                         SET_DATA_OFF(buf, 0);
664                 PORT(buf) = rxq_ctrl->rxq.port_id;
665                 DATA_LEN(buf) = rte_pktmbuf_tailroom(buf);
666                 PKT_LEN(buf) = DATA_LEN(buf);
667                 NB_SEGS(buf) = 1;
668                 (*rxq_ctrl->rxq.elts)[i] = buf;
669         }
670         /* If Rx vector is activated. */
671         if (rxq_check_vec_support(&rxq_ctrl->rxq) > 0) {
672                 struct mlx5_rxq_data *rxq = &rxq_ctrl->rxq;
673                 struct rte_mbuf *mbuf_init = &rxq->fake_mbuf;
674                 int j;
675
676                 /* Initialize default rearm_data for vPMD. */
677                 mbuf_init->data_off = RTE_PKTMBUF_HEADROOM;
678                 rte_mbuf_refcnt_set(mbuf_init, 1);
679                 mbuf_init->nb_segs = 1;
680                 mbuf_init->port = rxq->port_id;
681                 /*
682                  * prevent compiler reordering:
683                  * rearm_data covers previous fields.
684                  */
685                 rte_compiler_barrier();
686                 rxq->mbuf_initializer =
687                         *(uint64_t *)&mbuf_init->rearm_data;
688                 /* Padding with a fake mbuf for vectorized Rx. */
689                 for (j = 0; j < MLX5_VPMD_DESCS_PER_LOOP; ++j)
690                         (*rxq->elts)[elts_n + j] = &rxq->fake_mbuf;
691         }
692         DEBUG("%p: allocated and configured %u segments (max %u packets)",
693               (void *)rxq_ctrl, elts_n, elts_n / (1 << rxq_ctrl->rxq.sges_n));
694         assert(ret == 0);
695         return 0;
696 error:
697         elts_n = i;
698         for (i = 0; (i != elts_n); ++i) {
699                 if ((*rxq_ctrl->rxq.elts)[i] != NULL)
700                         rte_pktmbuf_free_seg((*rxq_ctrl->rxq.elts)[i]);
701                 (*rxq_ctrl->rxq.elts)[i] = NULL;
702         }
703         DEBUG("%p: failed, freed everything", (void *)rxq_ctrl);
704         assert(ret > 0);
705         return ret;
706 }
707
708 /**
709  * Free RX queue elements.
710  *
711  * @param rxq_ctrl
712  *   Pointer to RX queue structure.
713  */
714 static void
715 rxq_free_elts(struct mlx5_rxq_ctrl *rxq_ctrl)
716 {
717         struct mlx5_rxq_data *rxq = &rxq_ctrl->rxq;
718         const uint16_t q_n = (1 << rxq->elts_n);
719         const uint16_t q_mask = q_n - 1;
720         uint16_t used = q_n - (rxq->rq_ci - rxq->rq_pi);
721         uint16_t i;
722
723         DEBUG("%p: freeing WRs", (void *)rxq_ctrl);
724         if (rxq->elts == NULL)
725                 return;
726         /**
727          * Some mbuf in the Ring belongs to the application.  They cannot be
728          * freed.
729          */
730         if (rxq_check_vec_support(rxq) > 0) {
731                 for (i = 0; i < used; ++i)
732                         (*rxq->elts)[(rxq->rq_ci + i) & q_mask] = NULL;
733                 rxq->rq_pi = rxq->rq_ci;
734         }
735         for (i = 0; (i != (1u << rxq->elts_n)); ++i) {
736                 if ((*rxq->elts)[i] != NULL)
737                         rte_pktmbuf_free_seg((*rxq->elts)[i]);
738                 (*rxq->elts)[i] = NULL;
739         }
740 }
741
742 /**
743  * Clean up a RX queue.
744  *
745  * Destroy objects, free allocated memory and reset the structure for reuse.
746  *
747  * @param rxq_ctrl
748  *   Pointer to RX queue structure.
749  */
750 void
751 mlx5_rxq_cleanup(struct mlx5_rxq_ctrl *rxq_ctrl)
752 {
753         DEBUG("cleaning up %p", (void *)rxq_ctrl);
754         if (rxq_ctrl->ibv)
755                 mlx5_priv_rxq_ibv_release(rxq_ctrl->priv, rxq_ctrl->ibv);
756         memset(rxq_ctrl, 0, sizeof(*rxq_ctrl));
757 }
758
759 /**
760  *
761  * @param dev
762  *   Pointer to Ethernet device structure.
763  * @param idx
764  *   RX queue index.
765  * @param desc
766  *   Number of descriptors to configure in queue.
767  * @param socket
768  *   NUMA socket on which memory must be allocated.
769  * @param[in] conf
770  *   Thresholds parameters.
771  * @param mp
772  *   Memory pool for buffer allocations.
773  *
774  * @return
775  *   0 on success, negative errno value on failure.
776  */
777 int
778 mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
779                     unsigned int socket, const struct rte_eth_rxconf *conf,
780                     struct rte_mempool *mp)
781 {
782         struct priv *priv = dev->data->dev_private;
783         struct mlx5_rxq_data *rxq = (*priv->rxqs)[idx];
784         struct mlx5_rxq_ctrl *rxq_ctrl =
785                 container_of(rxq, struct mlx5_rxq_ctrl, rxq);
786         int ret = 0;
787
788         (void)conf;
789         if (mlx5_is_secondary())
790                 return -E_RTE_SECONDARY;
791         priv_lock(priv);
792         if (!rte_is_power_of_2(desc)) {
793                 desc = 1 << log2above(desc);
794                 WARN("%p: increased number of descriptors in RX queue %u"
795                      " to the next power of two (%d)",
796                      (void *)dev, idx, desc);
797         }
798         DEBUG("%p: configuring queue %u for %u descriptors",
799               (void *)dev, idx, desc);
800         if (idx >= priv->rxqs_n) {
801                 ERROR("%p: queue index out of range (%u >= %u)",
802                       (void *)dev, idx, priv->rxqs_n);
803                 priv_unlock(priv);
804                 return -EOVERFLOW;
805         }
806         if (!mlx5_priv_rxq_releasable(priv, idx)) {
807                 ret = EBUSY;
808                 ERROR("%p: unable to release queue index %u",
809                       (void *)dev, idx);
810                 goto out;
811         }
812         mlx5_priv_rxq_release(priv, idx);
813         rxq_ctrl = mlx5_priv_rxq_new(priv, idx, desc, socket, mp);
814         if (!rxq_ctrl) {
815                 ERROR("%p: unable to allocate queue index %u",
816                       (void *)dev, idx);
817                 ret = ENOMEM;
818                 goto out;
819         }
820         DEBUG("%p: adding RX queue %p to list",
821               (void *)dev, (void *)rxq_ctrl);
822         (*priv->rxqs)[idx] = &rxq_ctrl->rxq;
823 out:
824         priv_unlock(priv);
825         return -ret;
826 }
827
828 /**
829  * DPDK callback to release a RX queue.
830  *
831  * @param dpdk_rxq
832  *   Generic RX queue pointer.
833  */
834 void
835 mlx5_rx_queue_release(void *dpdk_rxq)
836 {
837         struct mlx5_rxq_data *rxq = (struct mlx5_rxq_data *)dpdk_rxq;
838         struct mlx5_rxq_ctrl *rxq_ctrl;
839         struct priv *priv;
840
841         if (mlx5_is_secondary())
842                 return;
843
844         if (rxq == NULL)
845                 return;
846         rxq_ctrl = container_of(rxq, struct mlx5_rxq_ctrl, rxq);
847         priv = rxq_ctrl->priv;
848         priv_lock(priv);
849         if (!mlx5_priv_rxq_releasable(priv, rxq_ctrl->rxq.stats.idx))
850                 rte_panic("Rx queue %p is still used by a flow and cannot be"
851                           " removed\n", (void *)rxq_ctrl);
852         mlx5_priv_rxq_release(priv, rxq_ctrl->rxq.stats.idx);
853         priv_unlock(priv);
854 }
855
856 /**
857  * Allocate queue vector and fill epoll fd list for Rx interrupts.
858  *
859  * @param priv
860  *   Pointer to private structure.
861  *
862  * @return
863  *   0 on success, negative on failure.
864  */
865 int
866 priv_rx_intr_vec_enable(struct priv *priv)
867 {
868         unsigned int i;
869         unsigned int rxqs_n = priv->rxqs_n;
870         unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
871         unsigned int count = 0;
872         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
873
874         assert(!mlx5_is_secondary());
875         if (!priv->dev->data->dev_conf.intr_conf.rxq)
876                 return 0;
877         priv_rx_intr_vec_disable(priv);
878         intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n]));
879         if (intr_handle->intr_vec == NULL) {
880                 ERROR("failed to allocate memory for interrupt vector,"
881                       " Rx interrupts will not be supported");
882                 return -ENOMEM;
883         }
884         intr_handle->type = RTE_INTR_HANDLE_EXT;
885         for (i = 0; i != n; ++i) {
886                 /* This rxq ibv must not be released in this function. */
887                 struct mlx5_rxq_ibv *rxq_ibv = mlx5_priv_rxq_ibv_get(priv, i);
888                 int fd;
889                 int flags;
890                 int rc;
891
892                 /* Skip queues that cannot request interrupts. */
893                 if (!rxq_ibv || !rxq_ibv->channel) {
894                         /* Use invalid intr_vec[] index to disable entry. */
895                         intr_handle->intr_vec[i] =
896                                 RTE_INTR_VEC_RXTX_OFFSET +
897                                 RTE_MAX_RXTX_INTR_VEC_ID;
898                         continue;
899                 }
900                 if (count >= RTE_MAX_RXTX_INTR_VEC_ID) {
901                         ERROR("too many Rx queues for interrupt vector size"
902                               " (%d), Rx interrupts cannot be enabled",
903                               RTE_MAX_RXTX_INTR_VEC_ID);
904                         priv_rx_intr_vec_disable(priv);
905                         return -1;
906                 }
907                 fd = rxq_ibv->channel->fd;
908                 flags = fcntl(fd, F_GETFL);
909                 rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
910                 if (rc < 0) {
911                         ERROR("failed to make Rx interrupt file descriptor"
912                               " %d non-blocking for queue index %d", fd, i);
913                         priv_rx_intr_vec_disable(priv);
914                         return -1;
915                 }
916                 intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;
917                 intr_handle->efds[count] = fd;
918                 count++;
919         }
920         if (!count)
921                 priv_rx_intr_vec_disable(priv);
922         else
923                 intr_handle->nb_efd = count;
924         return 0;
925 }
926
927 /**
928  * Clean up Rx interrupts handler.
929  *
930  * @param priv
931  *   Pointer to private structure.
932  */
933 void
934 priv_rx_intr_vec_disable(struct priv *priv)
935 {
936         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
937         unsigned int i;
938         unsigned int rxqs_n = priv->rxqs_n;
939         unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
940
941         if (!priv->dev->data->dev_conf.intr_conf.rxq)
942                 return;
943         for (i = 0; i != n; ++i) {
944                 struct mlx5_rxq_ctrl *rxq_ctrl;
945                 struct mlx5_rxq_data *rxq_data;
946
947                 if (intr_handle->intr_vec[i] == RTE_INTR_VEC_RXTX_OFFSET +
948                     RTE_MAX_RXTX_INTR_VEC_ID)
949                         continue;
950                 /**
951                  * Need to access directly the queue to release the reference
952                  * kept in priv_rx_intr_vec_enable().
953                  */
954                 rxq_data = (*priv->rxqs)[i];
955                 rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
956                 mlx5_priv_rxq_ibv_release(priv, rxq_ctrl->ibv);
957         }
958         rte_intr_free_epoll_fd(intr_handle);
959         free(intr_handle->intr_vec);
960         intr_handle->nb_efd = 0;
961         intr_handle->intr_vec = NULL;
962 }
963
964 /**
965  *  MLX5 CQ notification .
966  *
967  *  @param rxq
968  *     Pointer to receive queue structure.
969  *  @param sq_n_rxq
970  *     Sequence number per receive queue .
971  */
972 static inline void
973 mlx5_arm_cq(struct mlx5_rxq_data *rxq, int sq_n_rxq)
974 {
975         int sq_n = 0;
976         uint32_t doorbell_hi;
977         uint64_t doorbell;
978         void *cq_db_reg = (char *)rxq->cq_uar + MLX5_CQ_DOORBELL;
979
980         sq_n = sq_n_rxq & MLX5_CQ_SQN_MASK;
981         doorbell_hi = sq_n << MLX5_CQ_SQN_OFFSET | (rxq->cq_ci & MLX5_CI_MASK);
982         doorbell = (uint64_t)doorbell_hi << 32;
983         doorbell |=  rxq->cqn;
984         rxq->cq_db[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);
985         rte_wmb();
986         rte_write64(rte_cpu_to_be_64(doorbell), cq_db_reg);
987 }
988
989 /**
990  * DPDK callback for Rx queue interrupt enable.
991  *
992  * @param dev
993  *   Pointer to Ethernet device structure.
994  * @param rx_queue_id
995  *   Rx queue number.
996  *
997  * @return
998  *   0 on success, negative on failure.
999  */
1000 int
1001 mlx5_rx_intr_enable(struct rte_eth_dev *dev, uint16_t rx_queue_id)
1002 {
1003         struct priv *priv = mlx5_get_priv(dev);
1004         struct mlx5_rxq_data *rxq_data;
1005         struct mlx5_rxq_ctrl *rxq_ctrl;
1006         int ret = 0;
1007
1008         priv_lock(priv);
1009         rxq_data = (*priv->rxqs)[rx_queue_id];
1010         if (!rxq_data) {
1011                 ret = EINVAL;
1012                 goto exit;
1013         }
1014         rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
1015         if (rxq_ctrl->irq) {
1016                 struct mlx5_rxq_ibv *rxq_ibv;
1017
1018                 rxq_ibv = mlx5_priv_rxq_ibv_get(priv, rx_queue_id);
1019                 if (!rxq_ibv) {
1020                         ret = EINVAL;
1021                         goto exit;
1022                 }
1023                 mlx5_arm_cq(rxq_data, rxq_data->cq_arm_sn);
1024                 mlx5_priv_rxq_ibv_release(priv, rxq_ibv);
1025         }
1026 exit:
1027         priv_unlock(priv);
1028         if (ret)
1029                 WARN("unable to arm interrupt on rx queue %d", rx_queue_id);
1030         return -ret;
1031 }
1032
1033 /**
1034  * DPDK callback for Rx queue interrupt disable.
1035  *
1036  * @param dev
1037  *   Pointer to Ethernet device structure.
1038  * @param rx_queue_id
1039  *   Rx queue number.
1040  *
1041  * @return
1042  *   0 on success, negative on failure.
1043  */
1044 int
1045 mlx5_rx_intr_disable(struct rte_eth_dev *dev, uint16_t rx_queue_id)
1046 {
1047         struct priv *priv = mlx5_get_priv(dev);
1048         struct mlx5_rxq_data *rxq_data;
1049         struct mlx5_rxq_ctrl *rxq_ctrl;
1050         struct mlx5_rxq_ibv *rxq_ibv = NULL;
1051         struct ibv_cq *ev_cq;
1052         void *ev_ctx;
1053         int ret = 0;
1054
1055         priv_lock(priv);
1056         rxq_data = (*priv->rxqs)[rx_queue_id];
1057         if (!rxq_data) {
1058                 ret = EINVAL;
1059                 goto exit;
1060         }
1061         rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
1062         if (!rxq_ctrl->irq)
1063                 goto exit;
1064         rxq_ibv = mlx5_priv_rxq_ibv_get(priv, rx_queue_id);
1065         if (!rxq_ibv) {
1066                 ret = EINVAL;
1067                 goto exit;
1068         }
1069         ret = ibv_get_cq_event(rxq_ibv->channel, &ev_cq, &ev_ctx);
1070         if (ret || ev_cq != rxq_ibv->cq) {
1071                 ret = EINVAL;
1072                 goto exit;
1073         }
1074         rxq_data->cq_arm_sn++;
1075         ibv_ack_cq_events(rxq_ibv->cq, 1);
1076 exit:
1077         if (rxq_ibv)
1078                 mlx5_priv_rxq_ibv_release(priv, rxq_ibv);
1079         priv_unlock(priv);
1080         if (ret)
1081                 WARN("unable to disable interrupt on rx queue %d",
1082                      rx_queue_id);
1083         return -ret;
1084 }
1085
1086 /**
1087  * Create the Rx queue Verbs object.
1088  *
1089  * @param priv
1090  *   Pointer to private structure.
1091  * @param idx
1092  *   Queue index in DPDK Rx queue array
1093  *
1094  * @return
1095  *   The Verbs object initialised if it can be created.
1096  */
1097 struct mlx5_rxq_ibv*
1098 mlx5_priv_rxq_ibv_new(struct priv *priv, uint16_t idx)
1099 {
1100         struct mlx5_rxq_data *rxq_data = (*priv->rxqs)[idx];
1101         struct mlx5_rxq_ctrl *rxq_ctrl =
1102                 container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
1103         struct ibv_wq_attr mod;
1104         union {
1105                 struct ibv_cq_init_attr_ex cq;
1106                 struct ibv_wq_init_attr wq;
1107                 struct ibv_cq_ex cq_attr;
1108         } attr;
1109         unsigned int cqe_n = (1 << rxq_data->elts_n) - 1;
1110         struct mlx5_rxq_ibv *tmpl;
1111         struct mlx5dv_cq cq_info;
1112         struct mlx5dv_rwq rwq;
1113         unsigned int i;
1114         int ret = 0;
1115         struct mlx5dv_obj obj;
1116
1117         assert(rxq_data);
1118         assert(!rxq_ctrl->ibv);
1119         tmpl = rte_calloc_socket(__func__, 1, sizeof(*tmpl), 0,
1120                                  rxq_ctrl->socket);
1121         if (!tmpl) {
1122                 ERROR("%p: cannot allocate verbs resources",
1123                        (void *)rxq_ctrl);
1124                 goto error;
1125         }
1126         tmpl->rxq_ctrl = rxq_ctrl;
1127         /* Use the entire RX mempool as the memory region. */
1128         tmpl->mr = priv_mr_get(priv, rxq_data->mp);
1129         if (!tmpl->mr) {
1130                 tmpl->mr = priv_mr_new(priv, rxq_data->mp);
1131                 if (!tmpl->mr) {
1132                         ERROR("%p: MR creation failure", (void *)rxq_ctrl);
1133                         goto error;
1134                 }
1135         }
1136         if (rxq_ctrl->irq) {
1137                 tmpl->channel = ibv_create_comp_channel(priv->ctx);
1138                 if (!tmpl->channel) {
1139                         ERROR("%p: Comp Channel creation failure",
1140                               (void *)rxq_ctrl);
1141                         goto error;
1142                 }
1143         }
1144         attr.cq = (struct ibv_cq_init_attr_ex){
1145                 .comp_mask = 0,
1146         };
1147         if (priv->cqe_comp) {
1148                 attr.cq.comp_mask |= IBV_CQ_INIT_ATTR_MASK_FLAGS;
1149                 attr.cq.flags |= MLX5DV_CQ_INIT_ATTR_MASK_COMPRESSED_CQE;
1150                 /*
1151                  * For vectorized Rx, it must not be doubled in order to
1152                  * make cq_ci and rq_ci aligned.
1153                  */
1154                 if (rxq_check_vec_support(rxq_data) < 0)
1155                         cqe_n *= 2;
1156         }
1157         tmpl->cq = ibv_create_cq(priv->ctx, cqe_n, NULL, tmpl->channel, 0);
1158         if (tmpl->cq == NULL) {
1159                 ERROR("%p: CQ creation failure", (void *)rxq_ctrl);
1160                 goto error;
1161         }
1162         DEBUG("priv->device_attr.max_qp_wr is %d",
1163               priv->device_attr.orig_attr.max_qp_wr);
1164         DEBUG("priv->device_attr.max_sge is %d",
1165               priv->device_attr.orig_attr.max_sge);
1166         attr.wq = (struct ibv_wq_init_attr){
1167                 .wq_context = NULL, /* Could be useful in the future. */
1168                 .wq_type = IBV_WQT_RQ,
1169                 /* Max number of outstanding WRs. */
1170                 .max_wr = (1 << rxq_data->elts_n) >> rxq_data->sges_n,
1171                 /* Max number of scatter/gather elements in a WR. */
1172                 .max_sge = 1 << rxq_data->sges_n,
1173                 .pd = priv->pd,
1174                 .cq = tmpl->cq,
1175                 .comp_mask =
1176                         IBV_WQ_FLAGS_CVLAN_STRIPPING |
1177                         0,
1178                 .create_flags = (rxq_data->vlan_strip ?
1179                                  IBV_WQ_FLAGS_CVLAN_STRIPPING :
1180                                  0),
1181         };
1182         /* By default, FCS (CRC) is stripped by hardware. */
1183         if (rxq_data->crc_present) {
1184                 attr.wq.create_flags |= IBV_WQ_FLAGS_SCATTER_FCS;
1185                 attr.wq.comp_mask |= IBV_WQ_INIT_ATTR_FLAGS;
1186         }
1187 #ifdef HAVE_IBV_WQ_FLAG_RX_END_PADDING
1188         if (priv->hw_padding) {
1189                 attr.wq.create_flags |= IBV_WQ_FLAG_RX_END_PADDING;
1190                 attr.wq.comp_mask |= IBV_WQ_INIT_ATTR_FLAGS;
1191         }
1192 #endif
1193         tmpl->wq = ibv_create_wq(priv->ctx, &attr.wq);
1194         if (tmpl->wq == NULL) {
1195                 ERROR("%p: WQ creation failure", (void *)rxq_ctrl);
1196                 goto error;
1197         }
1198         /*
1199          * Make sure number of WRs*SGEs match expectations since a queue
1200          * cannot allocate more than "desc" buffers.
1201          */
1202         if (((int)attr.wq.max_wr !=
1203              ((1 << rxq_data->elts_n) >> rxq_data->sges_n)) ||
1204             ((int)attr.wq.max_sge != (1 << rxq_data->sges_n))) {
1205                 ERROR("%p: requested %u*%u but got %u*%u WRs*SGEs",
1206                       (void *)rxq_ctrl,
1207                       ((1 << rxq_data->elts_n) >> rxq_data->sges_n),
1208                       (1 << rxq_data->sges_n),
1209                       attr.wq.max_wr, attr.wq.max_sge);
1210                 goto error;
1211         }
1212         /* Change queue state to ready. */
1213         mod = (struct ibv_wq_attr){
1214                 .attr_mask = IBV_WQ_ATTR_STATE,
1215                 .wq_state = IBV_WQS_RDY,
1216         };
1217         ret = ibv_modify_wq(tmpl->wq, &mod);
1218         if (ret) {
1219                 ERROR("%p: WQ state to IBV_WQS_RDY failed",
1220                       (void *)rxq_ctrl);
1221                 goto error;
1222         }
1223         obj.cq.in = tmpl->cq;
1224         obj.cq.out = &cq_info;
1225         obj.rwq.in = tmpl->wq;
1226         obj.rwq.out = &rwq;
1227         ret = mlx5dv_init_obj(&obj, MLX5DV_OBJ_CQ | MLX5DV_OBJ_RWQ);
1228         if (ret != 0)
1229                 goto error;
1230         if (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {
1231                 ERROR("Wrong MLX5_CQE_SIZE environment variable value: "
1232                       "it should be set to %u", RTE_CACHE_LINE_SIZE);
1233                 goto error;
1234         }
1235         /* Fill the rings. */
1236         rxq_data->wqes = (volatile struct mlx5_wqe_data_seg (*)[])
1237                 (uintptr_t)rwq.buf;
1238         for (i = 0; (i != (unsigned int)(1 << rxq_data->elts_n)); ++i) {
1239                 struct rte_mbuf *buf = (*rxq_data->elts)[i];
1240                 volatile struct mlx5_wqe_data_seg *scat = &(*rxq_data->wqes)[i];
1241
1242                 /* scat->addr must be able to store a pointer. */
1243                 assert(sizeof(scat->addr) >= sizeof(uintptr_t));
1244                 *scat = (struct mlx5_wqe_data_seg){
1245                         .addr = rte_cpu_to_be_64(rte_pktmbuf_mtod(buf,
1246                                                                   uintptr_t)),
1247                         .byte_count = rte_cpu_to_be_32(DATA_LEN(buf)),
1248                         .lkey = tmpl->mr->lkey,
1249                 };
1250         }
1251         rxq_data->rq_db = rwq.dbrec;
1252         rxq_data->cqe_n = log2above(cq_info.cqe_cnt);
1253         rxq_data->cq_ci = 0;
1254         rxq_data->rq_ci = 0;
1255         rxq_data->rq_pi = 0;
1256         rxq_data->zip = (struct rxq_zip){
1257                 .ai = 0,
1258         };
1259         rxq_data->cq_db = cq_info.dbrec;
1260         rxq_data->cqes = (volatile struct mlx5_cqe (*)[])(uintptr_t)cq_info.buf;
1261         /* Update doorbell counter. */
1262         rxq_data->rq_ci = (1 << rxq_data->elts_n) >> rxq_data->sges_n;
1263         rte_wmb();
1264         *rxq_data->rq_db = rte_cpu_to_be_32(rxq_data->rq_ci);
1265         DEBUG("%p: rxq updated with %p", (void *)rxq_ctrl, (void *)&tmpl);
1266         rte_atomic32_inc(&tmpl->refcnt);
1267         DEBUG("%p: Verbs Rx queue %p: refcnt %d", (void *)priv,
1268               (void *)tmpl, rte_atomic32_read(&tmpl->refcnt));
1269         LIST_INSERT_HEAD(&priv->rxqsibv, tmpl, next);
1270         return tmpl;
1271 error:
1272         if (tmpl->wq)
1273                 claim_zero(ibv_destroy_wq(tmpl->wq));
1274         if (tmpl->cq)
1275                 claim_zero(ibv_destroy_cq(tmpl->cq));
1276         if (tmpl->channel)
1277                 claim_zero(ibv_destroy_comp_channel(tmpl->channel));
1278         if (tmpl->mr)
1279                 priv_mr_release(priv, tmpl->mr);
1280         return NULL;
1281 }
1282
1283 /**
1284  * Get an Rx queue Verbs object.
1285  *
1286  * @param priv
1287  *   Pointer to private structure.
1288  * @param idx
1289  *   Queue index in DPDK Rx queue array
1290  *
1291  * @return
1292  *   The Verbs object if it exists.
1293  */
1294 struct mlx5_rxq_ibv*
1295 mlx5_priv_rxq_ibv_get(struct priv *priv, uint16_t idx)
1296 {
1297         struct mlx5_rxq_data *rxq_data = (*priv->rxqs)[idx];
1298         struct mlx5_rxq_ctrl *rxq_ctrl;
1299
1300         if (idx >= priv->rxqs_n)
1301                 return NULL;
1302         if (!rxq_data)
1303                 return NULL;
1304         rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
1305         if (rxq_ctrl->ibv) {
1306                 priv_mr_get(priv, rxq_data->mp);
1307                 rte_atomic32_inc(&rxq_ctrl->ibv->refcnt);
1308                 DEBUG("%p: Verbs Rx queue %p: refcnt %d", (void *)priv,
1309                       (void *)rxq_ctrl->ibv,
1310                       rte_atomic32_read(&rxq_ctrl->ibv->refcnt));
1311         }
1312         return rxq_ctrl->ibv;
1313 }
1314
1315 /**
1316  * Release an Rx verbs queue object.
1317  *
1318  * @param priv
1319  *   Pointer to private structure.
1320  * @param rxq_ibv
1321  *   Verbs Rx queue object.
1322  *
1323  * @return
1324  *   0 on success, errno value on failure.
1325  */
1326 int
1327 mlx5_priv_rxq_ibv_release(struct priv *priv, struct mlx5_rxq_ibv *rxq_ibv)
1328 {
1329         int ret;
1330
1331         assert(rxq_ibv);
1332         assert(rxq_ibv->wq);
1333         assert(rxq_ibv->cq);
1334         assert(rxq_ibv->mr);
1335         ret = priv_mr_release(priv, rxq_ibv->mr);
1336         if (!ret)
1337                 rxq_ibv->mr = NULL;
1338         DEBUG("%p: Verbs Rx queue %p: refcnt %d", (void *)priv,
1339               (void *)rxq_ibv, rte_atomic32_read(&rxq_ibv->refcnt));
1340         if (rte_atomic32_dec_and_test(&rxq_ibv->refcnt)) {
1341                 rxq_free_elts(rxq_ibv->rxq_ctrl);
1342                 claim_zero(ibv_destroy_wq(rxq_ibv->wq));
1343                 claim_zero(ibv_destroy_cq(rxq_ibv->cq));
1344                 if (rxq_ibv->channel)
1345                         claim_zero(ibv_destroy_comp_channel(rxq_ibv->channel));
1346                 LIST_REMOVE(rxq_ibv, next);
1347                 rte_free(rxq_ibv);
1348                 return 0;
1349         }
1350         return EBUSY;
1351 }
1352
1353 /**
1354  * Verify the Verbs Rx queue list is empty
1355  *
1356  * @param priv
1357  *  Pointer to private structure.
1358  *
1359  * @return the number of object not released.
1360  */
1361 int
1362 mlx5_priv_rxq_ibv_verify(struct priv *priv)
1363 {
1364         int ret = 0;
1365         struct mlx5_rxq_ibv *rxq_ibv;
1366
1367         LIST_FOREACH(rxq_ibv, &priv->rxqsibv, next) {
1368                 DEBUG("%p: Verbs Rx queue %p still referenced", (void *)priv,
1369                       (void *)rxq_ibv);
1370                 ++ret;
1371         }
1372         return ret;
1373 }
1374
1375 /**
1376  * Return true if a single reference exists on the object.
1377  *
1378  * @param priv
1379  *   Pointer to private structure.
1380  * @param rxq_ibv
1381  *   Verbs Rx queue object.
1382  */
1383 int
1384 mlx5_priv_rxq_ibv_releasable(struct priv *priv, struct mlx5_rxq_ibv *rxq_ibv)
1385 {
1386         (void)priv;
1387         assert(rxq_ibv);
1388         return (rte_atomic32_read(&rxq_ibv->refcnt) == 1);
1389 }
1390
1391 /**
1392  * Create a DPDK Rx queue.
1393  *
1394  * @param priv
1395  *   Pointer to private structure.
1396  * @param idx
1397  *   TX queue index.
1398  * @param desc
1399  *   Number of descriptors to configure in queue.
1400  * @param socket
1401  *   NUMA socket on which memory must be allocated.
1402  *
1403  * @return
1404  *   A DPDK queue object on success.
1405  */
1406 struct mlx5_rxq_ctrl*
1407 mlx5_priv_rxq_new(struct priv *priv, uint16_t idx, uint16_t desc,
1408                   unsigned int socket, struct rte_mempool *mp)
1409 {
1410         struct rte_eth_dev *dev = priv->dev;
1411         struct mlx5_rxq_ctrl *tmpl;
1412         const uint16_t desc_n =
1413                 desc + priv->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
1414         unsigned int mb_len = rte_pktmbuf_data_room_size(mp);
1415
1416         tmpl = rte_calloc_socket("RXQ", 1,
1417                                  sizeof(*tmpl) +
1418                                  desc_n * sizeof(struct rte_mbuf *),
1419                                  0, socket);
1420         if (!tmpl)
1421                 return NULL;
1422         if (priv->dev->data->dev_conf.intr_conf.rxq)
1423                 tmpl->irq = 1;
1424         /* Enable scattered packets support for this queue if necessary. */
1425         assert(mb_len >= RTE_PKTMBUF_HEADROOM);
1426         if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
1427             (mb_len - RTE_PKTMBUF_HEADROOM)) {
1428                 tmpl->rxq.sges_n = 0;
1429         } else if (dev->data->dev_conf.rxmode.enable_scatter) {
1430                 unsigned int size =
1431                         RTE_PKTMBUF_HEADROOM +
1432                         dev->data->dev_conf.rxmode.max_rx_pkt_len;
1433                 unsigned int sges_n;
1434
1435                 /*
1436                  * Determine the number of SGEs needed for a full packet
1437                  * and round it to the next power of two.
1438                  */
1439                 sges_n = log2above((size / mb_len) + !!(size % mb_len));
1440                 tmpl->rxq.sges_n = sges_n;
1441                 /* Make sure rxq.sges_n did not overflow. */
1442                 size = mb_len * (1 << tmpl->rxq.sges_n);
1443                 size -= RTE_PKTMBUF_HEADROOM;
1444                 if (size < dev->data->dev_conf.rxmode.max_rx_pkt_len) {
1445                         ERROR("%p: too many SGEs (%u) needed to handle"
1446                               " requested maximum packet size %u",
1447                               (void *)dev,
1448                               1 << sges_n,
1449                               dev->data->dev_conf.rxmode.max_rx_pkt_len);
1450                         goto error;
1451                 }
1452         } else {
1453                 WARN("%p: the requested maximum Rx packet size (%u) is"
1454                      " larger than a single mbuf (%u) and scattered"
1455                      " mode has not been requested",
1456                      (void *)dev,
1457                      dev->data->dev_conf.rxmode.max_rx_pkt_len,
1458                      mb_len - RTE_PKTMBUF_HEADROOM);
1459         }
1460         DEBUG("%p: maximum number of segments per packet: %u",
1461               (void *)dev, 1 << tmpl->rxq.sges_n);
1462         if (desc % (1 << tmpl->rxq.sges_n)) {
1463                 ERROR("%p: number of RX queue descriptors (%u) is not a"
1464                       " multiple of SGEs per packet (%u)",
1465                       (void *)dev,
1466                       desc,
1467                       1 << tmpl->rxq.sges_n);
1468                 goto error;
1469         }
1470         /* Toggle RX checksum offload if hardware supports it. */
1471         if (priv->hw_csum)
1472                 tmpl->rxq.csum = !!dev->data->dev_conf.rxmode.hw_ip_checksum;
1473         if (priv->hw_csum_l2tun)
1474                 tmpl->rxq.csum_l2tun =
1475                         !!dev->data->dev_conf.rxmode.hw_ip_checksum;
1476         /* Configure VLAN stripping. */
1477         tmpl->rxq.vlan_strip = (priv->hw_vlan_strip &&
1478                                !!dev->data->dev_conf.rxmode.hw_vlan_strip);
1479         /* By default, FCS (CRC) is stripped by hardware. */
1480         if (dev->data->dev_conf.rxmode.hw_strip_crc) {
1481                 tmpl->rxq.crc_present = 0;
1482         } else if (priv->hw_fcs_strip) {
1483                 tmpl->rxq.crc_present = 1;
1484         } else {
1485                 WARN("%p: CRC stripping has been disabled but will still"
1486                      " be performed by hardware, make sure MLNX_OFED and"
1487                      " firmware are up to date",
1488                      (void *)dev);
1489                 tmpl->rxq.crc_present = 0;
1490         }
1491         DEBUG("%p: CRC stripping is %s, %u bytes will be subtracted from"
1492               " incoming frames to hide it",
1493               (void *)dev,
1494               tmpl->rxq.crc_present ? "disabled" : "enabled",
1495               tmpl->rxq.crc_present << 2);
1496         /* Save port ID. */
1497         tmpl->rxq.rss_hash = priv->rxqs_n > 1;
1498         tmpl->rxq.port_id = dev->data->port_id;
1499         tmpl->priv = priv;
1500         tmpl->rxq.mp = mp;
1501         tmpl->rxq.stats.idx = idx;
1502         tmpl->rxq.elts_n = log2above(desc);
1503         tmpl->rxq.elts =
1504                 (struct rte_mbuf *(*)[1 << tmpl->rxq.elts_n])(tmpl + 1);
1505         rte_atomic32_inc(&tmpl->refcnt);
1506         DEBUG("%p: Rx queue %p: refcnt %d", (void *)priv,
1507               (void *)tmpl, rte_atomic32_read(&tmpl->refcnt));
1508         LIST_INSERT_HEAD(&priv->rxqsctrl, tmpl, next);
1509         return tmpl;
1510 error:
1511         rte_free(tmpl);
1512         return NULL;
1513 }
1514
1515 /**
1516  * Get a Rx queue.
1517  *
1518  * @param priv
1519  *   Pointer to private structure.
1520  * @param idx
1521  *   TX queue index.
1522  *
1523  * @return
1524  *   A pointer to the queue if it exists.
1525  */
1526 struct mlx5_rxq_ctrl*
1527 mlx5_priv_rxq_get(struct priv *priv, uint16_t idx)
1528 {
1529         struct mlx5_rxq_ctrl *rxq_ctrl = NULL;
1530
1531         if ((*priv->rxqs)[idx]) {
1532                 rxq_ctrl = container_of((*priv->rxqs)[idx],
1533                                         struct mlx5_rxq_ctrl,
1534                                         rxq);
1535
1536                 mlx5_priv_rxq_ibv_get(priv, idx);
1537                 rte_atomic32_inc(&rxq_ctrl->refcnt);
1538                 DEBUG("%p: Rx queue %p: refcnt %d", (void *)priv,
1539                       (void *)rxq_ctrl, rte_atomic32_read(&rxq_ctrl->refcnt));
1540         }
1541         return rxq_ctrl;
1542 }
1543
1544 /**
1545  * Release a Rx queue.
1546  *
1547  * @param priv
1548  *   Pointer to private structure.
1549  * @param idx
1550  *   TX queue index.
1551  *
1552  * @return
1553  *   0 on success, errno value on failure.
1554  */
1555 int
1556 mlx5_priv_rxq_release(struct priv *priv, uint16_t idx)
1557 {
1558         struct mlx5_rxq_ctrl *rxq_ctrl;
1559
1560         if (!(*priv->rxqs)[idx])
1561                 return 0;
1562         rxq_ctrl = container_of((*priv->rxqs)[idx], struct mlx5_rxq_ctrl, rxq);
1563         assert(rxq_ctrl->priv);
1564         if (rxq_ctrl->ibv) {
1565                 int ret;
1566
1567                 ret = mlx5_priv_rxq_ibv_release(rxq_ctrl->priv, rxq_ctrl->ibv);
1568                 if (!ret)
1569                         rxq_ctrl->ibv = NULL;
1570         }
1571         DEBUG("%p: Rx queue %p: refcnt %d", (void *)priv,
1572               (void *)rxq_ctrl, rte_atomic32_read(&rxq_ctrl->refcnt));
1573         if (rte_atomic32_dec_and_test(&rxq_ctrl->refcnt)) {
1574                 LIST_REMOVE(rxq_ctrl, next);
1575                 rte_free(rxq_ctrl);
1576                 (*priv->rxqs)[idx] = NULL;
1577                 return 0;
1578         }
1579         return EBUSY;
1580 }
1581
1582 /**
1583  * Verify if the queue can be released.
1584  *
1585  * @param priv
1586  *   Pointer to private structure.
1587  * @param idx
1588  *   TX queue index.
1589  *
1590  * @return
1591  *   1 if the queue can be released.
1592  */
1593 int
1594 mlx5_priv_rxq_releasable(struct priv *priv, uint16_t idx)
1595 {
1596         struct mlx5_rxq_ctrl *rxq_ctrl;
1597
1598         if (!(*priv->rxqs)[idx])
1599                 return -1;
1600         rxq_ctrl = container_of((*priv->rxqs)[idx], struct mlx5_rxq_ctrl, rxq);
1601         return (rte_atomic32_read(&rxq_ctrl->refcnt) == 1);
1602 }
1603
1604 /**
1605  * Verify the Rx Queue list is empty
1606  *
1607  * @param priv
1608  *  Pointer to private structure.
1609  *
1610  * @return the number of object not released.
1611  */
1612 int
1613 mlx5_priv_rxq_verify(struct priv *priv)
1614 {
1615         struct mlx5_rxq_ctrl *rxq_ctrl;
1616         int ret = 0;
1617
1618         LIST_FOREACH(rxq_ctrl, &priv->rxqsctrl, next) {
1619                 DEBUG("%p: Rx Queue %p still referenced", (void *)priv,
1620                       (void *)rxq_ctrl);
1621                 ++ret;
1622         }
1623         return ret;
1624 }