net/mlx: enhance Rx scatter mode detection
[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
41 /* Verbs header. */
42 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
43 #ifdef PEDANTIC
44 #pragma GCC diagnostic ignored "-Wpedantic"
45 #endif
46 #include <infiniband/verbs.h>
47 #include <infiniband/arch.h>
48 #include <infiniband/mlx5_hw.h>
49 #ifdef PEDANTIC
50 #pragma GCC diagnostic error "-Wpedantic"
51 #endif
52
53 /* DPDK headers don't like -pedantic. */
54 #ifdef PEDANTIC
55 #pragma GCC diagnostic ignored "-Wpedantic"
56 #endif
57 #include <rte_mbuf.h>
58 #include <rte_malloc.h>
59 #include <rte_ethdev.h>
60 #include <rte_common.h>
61 #include <rte_interrupts.h>
62 #ifdef PEDANTIC
63 #pragma GCC diagnostic error "-Wpedantic"
64 #endif
65
66 #include "mlx5.h"
67 #include "mlx5_rxtx.h"
68 #include "mlx5_utils.h"
69 #include "mlx5_autoconf.h"
70 #include "mlx5_defs.h"
71
72 /* Initialization data for hash RX queues. */
73 const struct hash_rxq_init hash_rxq_init[] = {
74         [HASH_RXQ_TCPV4] = {
75                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
76                                 IBV_EXP_RX_HASH_DST_IPV4 |
77                                 IBV_EXP_RX_HASH_SRC_PORT_TCP |
78                                 IBV_EXP_RX_HASH_DST_PORT_TCP),
79                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_TCP,
80                 .flow_priority = 0,
81                 .flow_spec.tcp_udp = {
82                         .type = IBV_EXP_FLOW_SPEC_TCP,
83                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
84                 },
85                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
86         },
87         [HASH_RXQ_UDPV4] = {
88                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
89                                 IBV_EXP_RX_HASH_DST_IPV4 |
90                                 IBV_EXP_RX_HASH_SRC_PORT_UDP |
91                                 IBV_EXP_RX_HASH_DST_PORT_UDP),
92                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_UDP,
93                 .flow_priority = 0,
94                 .flow_spec.tcp_udp = {
95                         .type = IBV_EXP_FLOW_SPEC_UDP,
96                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
97                 },
98                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
99         },
100         [HASH_RXQ_IPV4] = {
101                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
102                                 IBV_EXP_RX_HASH_DST_IPV4),
103                 .dpdk_rss_hf = (ETH_RSS_IPV4 |
104                                 ETH_RSS_FRAG_IPV4),
105                 .flow_priority = 1,
106                 .flow_spec.ipv4 = {
107                         .type = IBV_EXP_FLOW_SPEC_IPV4,
108                         .size = sizeof(hash_rxq_init[0].flow_spec.ipv4),
109                 },
110                 .underlayer = &hash_rxq_init[HASH_RXQ_ETH],
111         },
112         [HASH_RXQ_TCPV6] = {
113                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
114                                 IBV_EXP_RX_HASH_DST_IPV6 |
115                                 IBV_EXP_RX_HASH_SRC_PORT_TCP |
116                                 IBV_EXP_RX_HASH_DST_PORT_TCP),
117                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_TCP,
118                 .flow_priority = 0,
119                 .flow_spec.tcp_udp = {
120                         .type = IBV_EXP_FLOW_SPEC_TCP,
121                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
122                 },
123                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
124         },
125         [HASH_RXQ_UDPV6] = {
126                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
127                                 IBV_EXP_RX_HASH_DST_IPV6 |
128                                 IBV_EXP_RX_HASH_SRC_PORT_UDP |
129                                 IBV_EXP_RX_HASH_DST_PORT_UDP),
130                 .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_UDP,
131                 .flow_priority = 0,
132                 .flow_spec.tcp_udp = {
133                         .type = IBV_EXP_FLOW_SPEC_UDP,
134                         .size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
135                 },
136                 .underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
137         },
138         [HASH_RXQ_IPV6] = {
139                 .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
140                                 IBV_EXP_RX_HASH_DST_IPV6),
141                 .dpdk_rss_hf = (ETH_RSS_IPV6 |
142                                 ETH_RSS_FRAG_IPV6),
143                 .flow_priority = 1,
144                 .flow_spec.ipv6 = {
145                         .type = IBV_EXP_FLOW_SPEC_IPV6,
146                         .size = sizeof(hash_rxq_init[0].flow_spec.ipv6),
147                 },
148                 .underlayer = &hash_rxq_init[HASH_RXQ_ETH],
149         },
150         [HASH_RXQ_ETH] = {
151                 .hash_fields = 0,
152                 .dpdk_rss_hf = 0,
153                 .flow_priority = 2,
154                 .flow_spec.eth = {
155                         .type = IBV_EXP_FLOW_SPEC_ETH,
156                         .size = sizeof(hash_rxq_init[0].flow_spec.eth),
157                 },
158                 .underlayer = NULL,
159         },
160 };
161
162 /* Number of entries in hash_rxq_init[]. */
163 const unsigned int hash_rxq_init_n = RTE_DIM(hash_rxq_init);
164
165 /* Initialization data for hash RX queue indirection tables. */
166 static const struct ind_table_init ind_table_init[] = {
167         {
168                 .max_size = -1u, /* Superseded by HW limitations. */
169                 .hash_types =
170                         1 << HASH_RXQ_TCPV4 |
171                         1 << HASH_RXQ_UDPV4 |
172                         1 << HASH_RXQ_IPV4 |
173                         1 << HASH_RXQ_TCPV6 |
174                         1 << HASH_RXQ_UDPV6 |
175                         1 << HASH_RXQ_IPV6 |
176                         0,
177                 .hash_types_n = 6,
178         },
179         {
180                 .max_size = 1,
181                 .hash_types = 1 << HASH_RXQ_ETH,
182                 .hash_types_n = 1,
183         },
184 };
185
186 #define IND_TABLE_INIT_N RTE_DIM(ind_table_init)
187
188 /* Default RSS hash key also used for ConnectX-3. */
189 uint8_t rss_hash_default_key[] = {
190         0x2c, 0xc6, 0x81, 0xd1,
191         0x5b, 0xdb, 0xf4, 0xf7,
192         0xfc, 0xa2, 0x83, 0x19,
193         0xdb, 0x1a, 0x3e, 0x94,
194         0x6b, 0x9e, 0x38, 0xd9,
195         0x2c, 0x9c, 0x03, 0xd1,
196         0xad, 0x99, 0x44, 0xa7,
197         0xd9, 0x56, 0x3d, 0x59,
198         0x06, 0x3c, 0x25, 0xf3,
199         0xfc, 0x1f, 0xdc, 0x2a,
200 };
201
202 /* Length of the default RSS hash key. */
203 const size_t rss_hash_default_key_len = sizeof(rss_hash_default_key);
204
205 /**
206  * Populate flow steering rule for a given hash RX queue type using
207  * information from hash_rxq_init[]. Nothing is written to flow_attr when
208  * flow_attr_size is not large enough, but the required size is still returned.
209  *
210  * @param priv
211  *   Pointer to private structure.
212  * @param[out] flow_attr
213  *   Pointer to flow attribute structure to fill. Note that the allocated
214  *   area must be larger and large enough to hold all flow specifications.
215  * @param flow_attr_size
216  *   Entire size of flow_attr and trailing room for flow specifications.
217  * @param type
218  *   Hash RX queue type to use for flow steering rule.
219  *
220  * @return
221  *   Total size of the flow attribute buffer. No errors are defined.
222  */
223 size_t
224 priv_flow_attr(struct priv *priv, struct ibv_exp_flow_attr *flow_attr,
225                size_t flow_attr_size, enum hash_rxq_type type)
226 {
227         size_t offset = sizeof(*flow_attr);
228         const struct hash_rxq_init *init = &hash_rxq_init[type];
229
230         assert(priv != NULL);
231         assert((size_t)type < RTE_DIM(hash_rxq_init));
232         do {
233                 offset += init->flow_spec.hdr.size;
234                 init = init->underlayer;
235         } while (init != NULL);
236         if (offset > flow_attr_size)
237                 return offset;
238         flow_attr_size = offset;
239         init = &hash_rxq_init[type];
240         *flow_attr = (struct ibv_exp_flow_attr){
241                 .type = IBV_EXP_FLOW_ATTR_NORMAL,
242                 /* Priorities < 3 are reserved for flow director. */
243                 .priority = init->flow_priority + 3,
244                 .num_of_specs = 0,
245                 .port = priv->port,
246                 .flags = 0,
247         };
248         do {
249                 offset -= init->flow_spec.hdr.size;
250                 memcpy((void *)((uintptr_t)flow_attr + offset),
251                        &init->flow_spec,
252                        init->flow_spec.hdr.size);
253                 ++flow_attr->num_of_specs;
254                 init = init->underlayer;
255         } while (init != NULL);
256         return flow_attr_size;
257 }
258
259 /**
260  * Convert hash type position in indirection table initializer to
261  * hash RX queue type.
262  *
263  * @param table
264  *   Indirection table initializer.
265  * @param pos
266  *   Hash type position.
267  *
268  * @return
269  *   Hash RX queue type.
270  */
271 static enum hash_rxq_type
272 hash_rxq_type_from_pos(const struct ind_table_init *table, unsigned int pos)
273 {
274         enum hash_rxq_type type = HASH_RXQ_TCPV4;
275
276         assert(pos < table->hash_types_n);
277         do {
278                 if ((table->hash_types & (1 << type)) && (pos-- == 0))
279                         break;
280                 ++type;
281         } while (1);
282         return type;
283 }
284
285 /**
286  * Filter out disabled hash RX queue types from ind_table_init[].
287  *
288  * @param priv
289  *   Pointer to private structure.
290  * @param[out] table
291  *   Output table.
292  *
293  * @return
294  *   Number of table entries.
295  */
296 static unsigned int
297 priv_make_ind_table_init(struct priv *priv,
298                          struct ind_table_init (*table)[IND_TABLE_INIT_N])
299 {
300         uint64_t rss_hf;
301         unsigned int i;
302         unsigned int j;
303         unsigned int table_n = 0;
304         /* Mandatory to receive frames not handled by normal hash RX queues. */
305         unsigned int hash_types_sup = 1 << HASH_RXQ_ETH;
306
307         rss_hf = priv->rss_hf;
308         /* Process other protocols only if more than one queue. */
309         if (priv->rxqs_n > 1)
310                 for (i = 0; (i != hash_rxq_init_n); ++i)
311                         if (rss_hf & hash_rxq_init[i].dpdk_rss_hf)
312                                 hash_types_sup |= (1 << i);
313
314         /* Filter out entries whose protocols are not in the set. */
315         for (i = 0, j = 0; (i != IND_TABLE_INIT_N); ++i) {
316                 unsigned int nb;
317                 unsigned int h;
318
319                 /* j is increased only if the table has valid protocols. */
320                 assert(j <= i);
321                 (*table)[j] = ind_table_init[i];
322                 (*table)[j].hash_types &= hash_types_sup;
323                 for (h = 0, nb = 0; (h != hash_rxq_init_n); ++h)
324                         if (((*table)[j].hash_types >> h) & 0x1)
325                                 ++nb;
326                 (*table)[i].hash_types_n = nb;
327                 if (nb) {
328                         ++table_n;
329                         ++j;
330                 }
331         }
332         return table_n;
333 }
334
335 /**
336  * Initialize hash RX queues and indirection table.
337  *
338  * @param priv
339  *   Pointer to private structure.
340  *
341  * @return
342  *   0 on success, errno value on failure.
343  */
344 int
345 priv_create_hash_rxqs(struct priv *priv)
346 {
347         struct ibv_exp_wq *wqs[priv->reta_idx_n];
348         struct ind_table_init ind_table_init[IND_TABLE_INIT_N];
349         unsigned int ind_tables_n =
350                 priv_make_ind_table_init(priv, &ind_table_init);
351         unsigned int hash_rxqs_n = 0;
352         struct hash_rxq (*hash_rxqs)[] = NULL;
353         struct ibv_exp_rwq_ind_table *(*ind_tables)[] = NULL;
354         unsigned int i;
355         unsigned int j;
356         unsigned int k;
357         int err = 0;
358
359         assert(priv->ind_tables == NULL);
360         assert(priv->ind_tables_n == 0);
361         assert(priv->hash_rxqs == NULL);
362         assert(priv->hash_rxqs_n == 0);
363         assert(priv->pd != NULL);
364         assert(priv->ctx != NULL);
365         if (priv->rxqs_n == 0)
366                 return EINVAL;
367         assert(priv->rxqs != NULL);
368         if (ind_tables_n == 0) {
369                 ERROR("all hash RX queue types have been filtered out,"
370                       " indirection table cannot be created");
371                 return EINVAL;
372         }
373         if (priv->rxqs_n & (priv->rxqs_n - 1)) {
374                 INFO("%u RX queues are configured, consider rounding this"
375                      " number to the next power of two for better balancing",
376                      priv->rxqs_n);
377                 DEBUG("indirection table extended to assume %u WQs",
378                       priv->reta_idx_n);
379         }
380         for (i = 0; (i != priv->reta_idx_n); ++i) {
381                 struct rxq_ctrl *rxq_ctrl;
382
383                 rxq_ctrl = container_of((*priv->rxqs)[(*priv->reta_idx)[i]],
384                                         struct rxq_ctrl, rxq);
385                 wqs[i] = rxq_ctrl->wq;
386         }
387         /* Get number of hash RX queues to configure. */
388         for (i = 0, hash_rxqs_n = 0; (i != ind_tables_n); ++i)
389                 hash_rxqs_n += ind_table_init[i].hash_types_n;
390         DEBUG("allocating %u hash RX queues for %u WQs, %u indirection tables",
391               hash_rxqs_n, priv->rxqs_n, ind_tables_n);
392         /* Create indirection tables. */
393         ind_tables = rte_calloc(__func__, ind_tables_n,
394                                 sizeof((*ind_tables)[0]), 0);
395         if (ind_tables == NULL) {
396                 err = ENOMEM;
397                 ERROR("cannot allocate indirection tables container: %s",
398                       strerror(err));
399                 goto error;
400         }
401         for (i = 0; (i != ind_tables_n); ++i) {
402                 struct ibv_exp_rwq_ind_table_init_attr ind_init_attr = {
403                         .pd = priv->pd,
404                         .log_ind_tbl_size = 0, /* Set below. */
405                         .ind_tbl = wqs,
406                         .comp_mask = 0,
407                 };
408                 unsigned int ind_tbl_size = ind_table_init[i].max_size;
409                 struct ibv_exp_rwq_ind_table *ind_table;
410
411                 if (priv->reta_idx_n < ind_tbl_size)
412                         ind_tbl_size = priv->reta_idx_n;
413                 ind_init_attr.log_ind_tbl_size = log2above(ind_tbl_size);
414                 errno = 0;
415                 ind_table = ibv_exp_create_rwq_ind_table(priv->ctx,
416                                                          &ind_init_attr);
417                 if (ind_table != NULL) {
418                         (*ind_tables)[i] = ind_table;
419                         continue;
420                 }
421                 /* Not clear whether errno is set. */
422                 err = (errno ? errno : EINVAL);
423                 ERROR("RX indirection table creation failed with error %d: %s",
424                       err, strerror(err));
425                 goto error;
426         }
427         /* Allocate array that holds hash RX queues and related data. */
428         hash_rxqs = rte_calloc(__func__, hash_rxqs_n,
429                                sizeof((*hash_rxqs)[0]), 0);
430         if (hash_rxqs == NULL) {
431                 err = ENOMEM;
432                 ERROR("cannot allocate hash RX queues container: %s",
433                       strerror(err));
434                 goto error;
435         }
436         for (i = 0, j = 0, k = 0;
437              ((i != hash_rxqs_n) && (j != ind_tables_n));
438              ++i) {
439                 struct hash_rxq *hash_rxq = &(*hash_rxqs)[i];
440                 enum hash_rxq_type type =
441                         hash_rxq_type_from_pos(&ind_table_init[j], k);
442                 struct rte_eth_rss_conf *priv_rss_conf =
443                         (*priv->rss_conf)[type];
444                 struct ibv_exp_rx_hash_conf hash_conf = {
445                         .rx_hash_function = IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
446                         .rx_hash_key_len = (priv_rss_conf ?
447                                             priv_rss_conf->rss_key_len :
448                                             rss_hash_default_key_len),
449                         .rx_hash_key = (priv_rss_conf ?
450                                         priv_rss_conf->rss_key :
451                                         rss_hash_default_key),
452                         .rx_hash_fields_mask = hash_rxq_init[type].hash_fields,
453                         .rwq_ind_tbl = (*ind_tables)[j],
454                 };
455                 struct ibv_exp_qp_init_attr qp_init_attr = {
456                         .max_inl_recv = 0, /* Currently not supported. */
457                         .qp_type = IBV_QPT_RAW_PACKET,
458                         .comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
459                                       IBV_EXP_QP_INIT_ATTR_RX_HASH),
460                         .pd = priv->pd,
461                         .rx_hash_conf = &hash_conf,
462                         .port_num = priv->port,
463                 };
464
465                 DEBUG("using indirection table %u for hash RX queue %u type %d",
466                       j, i, type);
467                 *hash_rxq = (struct hash_rxq){
468                         .priv = priv,
469                         .qp = ibv_exp_create_qp(priv->ctx, &qp_init_attr),
470                         .type = type,
471                 };
472                 if (hash_rxq->qp == NULL) {
473                         err = (errno ? errno : EINVAL);
474                         ERROR("Hash RX QP creation failure: %s",
475                               strerror(err));
476                         goto error;
477                 }
478                 if (++k < ind_table_init[j].hash_types_n)
479                         continue;
480                 /* Switch to the next indirection table and reset hash RX
481                  * queue type array index. */
482                 ++j;
483                 k = 0;
484         }
485         priv->ind_tables = ind_tables;
486         priv->ind_tables_n = ind_tables_n;
487         priv->hash_rxqs = hash_rxqs;
488         priv->hash_rxqs_n = hash_rxqs_n;
489         assert(err == 0);
490         return 0;
491 error:
492         if (hash_rxqs != NULL) {
493                 for (i = 0; (i != hash_rxqs_n); ++i) {
494                         struct ibv_qp *qp = (*hash_rxqs)[i].qp;
495
496                         if (qp == NULL)
497                                 continue;
498                         claim_zero(ibv_destroy_qp(qp));
499                 }
500                 rte_free(hash_rxqs);
501         }
502         if (ind_tables != NULL) {
503                 for (j = 0; (j != ind_tables_n); ++j) {
504                         struct ibv_exp_rwq_ind_table *ind_table =
505                                 (*ind_tables)[j];
506
507                         if (ind_table == NULL)
508                                 continue;
509                         claim_zero(ibv_exp_destroy_rwq_ind_table(ind_table));
510                 }
511                 rte_free(ind_tables);
512         }
513         return err;
514 }
515
516 /**
517  * Clean up hash RX queues and indirection table.
518  *
519  * @param priv
520  *   Pointer to private structure.
521  */
522 void
523 priv_destroy_hash_rxqs(struct priv *priv)
524 {
525         unsigned int i;
526
527         DEBUG("destroying %u hash RX queues", priv->hash_rxqs_n);
528         if (priv->hash_rxqs_n == 0) {
529                 assert(priv->hash_rxqs == NULL);
530                 assert(priv->ind_tables == NULL);
531                 return;
532         }
533         for (i = 0; (i != priv->hash_rxqs_n); ++i) {
534                 struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
535                 unsigned int j, k;
536
537                 assert(hash_rxq->priv == priv);
538                 assert(hash_rxq->qp != NULL);
539                 /* Also check that there are no remaining flows. */
540                 for (j = 0; (j != RTE_DIM(hash_rxq->special_flow)); ++j)
541                         for (k = 0;
542                              (k != RTE_DIM(hash_rxq->special_flow[j]));
543                              ++k)
544                                 assert(hash_rxq->special_flow[j][k] == NULL);
545                 for (j = 0; (j != RTE_DIM(hash_rxq->mac_flow)); ++j)
546                         for (k = 0; (k != RTE_DIM(hash_rxq->mac_flow[j])); ++k)
547                                 assert(hash_rxq->mac_flow[j][k] == NULL);
548                 claim_zero(ibv_destroy_qp(hash_rxq->qp));
549         }
550         priv->hash_rxqs_n = 0;
551         rte_free(priv->hash_rxqs);
552         priv->hash_rxqs = NULL;
553         for (i = 0; (i != priv->ind_tables_n); ++i) {
554                 struct ibv_exp_rwq_ind_table *ind_table =
555                         (*priv->ind_tables)[i];
556
557                 assert(ind_table != NULL);
558                 claim_zero(ibv_exp_destroy_rwq_ind_table(ind_table));
559         }
560         priv->ind_tables_n = 0;
561         rte_free(priv->ind_tables);
562         priv->ind_tables = NULL;
563 }
564
565 /**
566  * Check whether a given flow type is allowed.
567  *
568  * @param priv
569  *   Pointer to private structure.
570  * @param type
571  *   Flow type to check.
572  *
573  * @return
574  *   Nonzero if the given flow type is allowed.
575  */
576 int
577 priv_allow_flow_type(struct priv *priv, enum hash_rxq_flow_type type)
578 {
579         /* Only FLOW_TYPE_PROMISC is allowed when promiscuous mode
580          * has been requested. */
581         if (priv->promisc_req)
582                 return type == HASH_RXQ_FLOW_TYPE_PROMISC;
583         switch (type) {
584         case HASH_RXQ_FLOW_TYPE_PROMISC:
585                 return !!priv->promisc_req;
586         case HASH_RXQ_FLOW_TYPE_ALLMULTI:
587                 return !!priv->allmulti_req;
588         case HASH_RXQ_FLOW_TYPE_BROADCAST:
589         case HASH_RXQ_FLOW_TYPE_IPV6MULTI:
590                 /* If allmulti is enabled, broadcast and ipv6multi
591                  * are unnecessary. */
592                 return !priv->allmulti_req;
593         case HASH_RXQ_FLOW_TYPE_MAC:
594                 return 1;
595         default:
596                 /* Unsupported flow type is not allowed. */
597                 return 0;
598         }
599         return 0;
600 }
601
602 /**
603  * Automatically enable/disable flows according to configuration.
604  *
605  * @param priv
606  *   Private structure.
607  *
608  * @return
609  *   0 on success, errno value on failure.
610  */
611 int
612 priv_rehash_flows(struct priv *priv)
613 {
614         enum hash_rxq_flow_type i;
615
616         for (i = HASH_RXQ_FLOW_TYPE_PROMISC;
617                         i != RTE_DIM((*priv->hash_rxqs)[0].special_flow);
618                         ++i)
619                 if (!priv_allow_flow_type(priv, i)) {
620                         priv_special_flow_disable(priv, i);
621                 } else {
622                         int ret = priv_special_flow_enable(priv, i);
623
624                         if (ret)
625                                 return ret;
626                 }
627         if (priv_allow_flow_type(priv, HASH_RXQ_FLOW_TYPE_MAC))
628                 return priv_mac_addrs_enable(priv);
629         priv_mac_addrs_disable(priv);
630         return 0;
631 }
632
633 /**
634  * Allocate RX queue elements.
635  *
636  * @param rxq_ctrl
637  *   Pointer to RX queue structure.
638  * @param elts_n
639  *   Number of elements to allocate.
640  * @param[in] pool
641  *   If not NULL, fetch buffers from this array instead of allocating them
642  *   with rte_pktmbuf_alloc().
643  *
644  * @return
645  *   0 on success, errno value on failure.
646  */
647 static int
648 rxq_alloc_elts(struct rxq_ctrl *rxq_ctrl, unsigned int elts_n,
649                struct rte_mbuf *(*pool)[])
650 {
651         const unsigned int sges_n = 1 << rxq_ctrl->rxq.sges_n;
652         unsigned int i;
653         int ret = 0;
654
655         /* Iterate on segments. */
656         for (i = 0; (i != elts_n); ++i) {
657                 struct rte_mbuf *buf;
658                 volatile struct mlx5_wqe_data_seg *scat =
659                         &(*rxq_ctrl->rxq.wqes)[i];
660
661                 if (pool != NULL) {
662                         buf = (*pool)[i];
663                         assert(buf != NULL);
664                         rte_pktmbuf_reset(buf);
665                         rte_pktmbuf_refcnt_update(buf, 1);
666                 } else
667                         buf = rte_pktmbuf_alloc(rxq_ctrl->rxq.mp);
668                 if (buf == NULL) {
669                         assert(pool == NULL);
670                         ERROR("%p: empty mbuf pool", (void *)rxq_ctrl);
671                         ret = ENOMEM;
672                         goto error;
673                 }
674                 /* Headroom is reserved by rte_pktmbuf_alloc(). */
675                 assert(DATA_OFF(buf) == RTE_PKTMBUF_HEADROOM);
676                 /* Buffer is supposed to be empty. */
677                 assert(rte_pktmbuf_data_len(buf) == 0);
678                 assert(rte_pktmbuf_pkt_len(buf) == 0);
679                 assert(!buf->next);
680                 /* Only the first segment keeps headroom. */
681                 if (i % sges_n)
682                         SET_DATA_OFF(buf, 0);
683                 PORT(buf) = rxq_ctrl->rxq.port_id;
684                 DATA_LEN(buf) = rte_pktmbuf_tailroom(buf);
685                 PKT_LEN(buf) = DATA_LEN(buf);
686                 NB_SEGS(buf) = 1;
687                 /* scat->addr must be able to store a pointer. */
688                 assert(sizeof(scat->addr) >= sizeof(uintptr_t));
689                 *scat = (struct mlx5_wqe_data_seg){
690                         .addr = htonll(rte_pktmbuf_mtod(buf, uintptr_t)),
691                         .byte_count = htonl(DATA_LEN(buf)),
692                         .lkey = htonl(rxq_ctrl->mr->lkey),
693                 };
694                 (*rxq_ctrl->rxq.elts)[i] = buf;
695         }
696         DEBUG("%p: allocated and configured %u segments (max %u packets)",
697               (void *)rxq_ctrl, elts_n, elts_n / (1 << rxq_ctrl->rxq.sges_n));
698         assert(ret == 0);
699         return 0;
700 error:
701         assert(pool == NULL);
702         elts_n = i;
703         for (i = 0; (i != elts_n); ++i) {
704                 if ((*rxq_ctrl->rxq.elts)[i] != NULL)
705                         rte_pktmbuf_free_seg((*rxq_ctrl->rxq.elts)[i]);
706                 (*rxq_ctrl->rxq.elts)[i] = NULL;
707         }
708         DEBUG("%p: failed, freed everything", (void *)rxq_ctrl);
709         assert(ret > 0);
710         return ret;
711 }
712
713 /**
714  * Free RX queue elements.
715  *
716  * @param rxq_ctrl
717  *   Pointer to RX queue structure.
718  */
719 static void
720 rxq_free_elts(struct rxq_ctrl *rxq_ctrl)
721 {
722         unsigned int i;
723
724         DEBUG("%p: freeing WRs", (void *)rxq_ctrl);
725         if (rxq_ctrl->rxq.elts == NULL)
726                 return;
727
728         for (i = 0; (i != (1u << rxq_ctrl->rxq.elts_n)); ++i) {
729                 if ((*rxq_ctrl->rxq.elts)[i] != NULL)
730                         rte_pktmbuf_free_seg((*rxq_ctrl->rxq.elts)[i]);
731                 (*rxq_ctrl->rxq.elts)[i] = NULL;
732         }
733 }
734
735 /**
736  * Clean up a RX queue.
737  *
738  * Destroy objects, free allocated memory and reset the structure for reuse.
739  *
740  * @param rxq_ctrl
741  *   Pointer to RX queue structure.
742  */
743 void
744 rxq_cleanup(struct rxq_ctrl *rxq_ctrl)
745 {
746         struct ibv_exp_release_intf_params params;
747
748         DEBUG("cleaning up %p", (void *)rxq_ctrl);
749         rxq_free_elts(rxq_ctrl);
750         if (rxq_ctrl->fdir_queue != NULL)
751                 priv_fdir_queue_destroy(rxq_ctrl->priv, rxq_ctrl->fdir_queue);
752         if (rxq_ctrl->if_wq != NULL) {
753                 assert(rxq_ctrl->priv != NULL);
754                 assert(rxq_ctrl->priv->ctx != NULL);
755                 assert(rxq_ctrl->wq != NULL);
756                 params = (struct ibv_exp_release_intf_params){
757                         .comp_mask = 0,
758                 };
759                 claim_zero(ibv_exp_release_intf(rxq_ctrl->priv->ctx,
760                                                 rxq_ctrl->if_wq,
761                                                 &params));
762         }
763         if (rxq_ctrl->if_cq != NULL) {
764                 assert(rxq_ctrl->priv != NULL);
765                 assert(rxq_ctrl->priv->ctx != NULL);
766                 assert(rxq_ctrl->cq != NULL);
767                 params = (struct ibv_exp_release_intf_params){
768                         .comp_mask = 0,
769                 };
770                 claim_zero(ibv_exp_release_intf(rxq_ctrl->priv->ctx,
771                                                 rxq_ctrl->if_cq,
772                                                 &params));
773         }
774         if (rxq_ctrl->wq != NULL)
775                 claim_zero(ibv_exp_destroy_wq(rxq_ctrl->wq));
776         if (rxq_ctrl->cq != NULL)
777                 claim_zero(ibv_destroy_cq(rxq_ctrl->cq));
778         if (rxq_ctrl->channel != NULL)
779                 claim_zero(ibv_destroy_comp_channel(rxq_ctrl->channel));
780         if (rxq_ctrl->rd != NULL) {
781                 struct ibv_exp_destroy_res_domain_attr attr = {
782                         .comp_mask = 0,
783                 };
784
785                 assert(rxq_ctrl->priv != NULL);
786                 assert(rxq_ctrl->priv->ctx != NULL);
787                 claim_zero(ibv_exp_destroy_res_domain(rxq_ctrl->priv->ctx,
788                                                       rxq_ctrl->rd,
789                                                       &attr));
790         }
791         if (rxq_ctrl->mr != NULL)
792                 claim_zero(ibv_dereg_mr(rxq_ctrl->mr));
793         memset(rxq_ctrl, 0, sizeof(*rxq_ctrl));
794 }
795
796 /**
797  * Reconfigure RX queue buffers.
798  *
799  * rxq_rehash() does not allocate mbufs, which, if not done from the right
800  * thread (such as a control thread), may corrupt the pool.
801  * In case of failure, the queue is left untouched.
802  *
803  * @param dev
804  *   Pointer to Ethernet device structure.
805  * @param rxq_ctrl
806  *   RX queue pointer.
807  *
808  * @return
809  *   0 on success, errno value on failure.
810  */
811 int
812 rxq_rehash(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl)
813 {
814         unsigned int elts_n = 1 << rxq_ctrl->rxq.elts_n;
815         unsigned int i;
816         struct ibv_exp_wq_attr mod;
817         int err;
818
819         DEBUG("%p: rehashing queue %p with %u SGE(s) per packet",
820               (void *)dev, (void *)rxq_ctrl, 1 << rxq_ctrl->rxq.sges_n);
821         assert(!(elts_n % (1 << rxq_ctrl->rxq.sges_n)));
822         /* From now on, any failure will render the queue unusable.
823          * Reinitialize WQ. */
824         mod = (struct ibv_exp_wq_attr){
825                 .attr_mask = IBV_EXP_WQ_ATTR_STATE,
826                 .wq_state = IBV_EXP_WQS_RESET,
827         };
828         err = ibv_exp_modify_wq(rxq_ctrl->wq, &mod);
829         if (err) {
830                 ERROR("%p: cannot reset WQ: %s", (void *)dev, strerror(err));
831                 assert(err > 0);
832                 return err;
833         }
834         /* Snatch mbufs from original queue. */
835         claim_zero(rxq_alloc_elts(rxq_ctrl, elts_n, rxq_ctrl->rxq.elts));
836         for (i = 0; i != elts_n; ++i) {
837                 struct rte_mbuf *buf = (*rxq_ctrl->rxq.elts)[i];
838
839                 assert(rte_mbuf_refcnt_read(buf) == 2);
840                 rte_pktmbuf_free_seg(buf);
841         }
842         /* Change queue state to ready. */
843         mod = (struct ibv_exp_wq_attr){
844                 .attr_mask = IBV_EXP_WQ_ATTR_STATE,
845                 .wq_state = IBV_EXP_WQS_RDY,
846         };
847         err = ibv_exp_modify_wq(rxq_ctrl->wq, &mod);
848         if (err) {
849                 ERROR("%p: WQ state to IBV_EXP_WQS_RDY failed: %s",
850                       (void *)dev, strerror(err));
851                 goto error;
852         }
853         /* Update doorbell counter. */
854         rxq_ctrl->rxq.rq_ci = elts_n >> rxq_ctrl->rxq.sges_n;
855         rte_wmb();
856         *rxq_ctrl->rxq.rq_db = htonl(rxq_ctrl->rxq.rq_ci);
857 error:
858         assert(err >= 0);
859         return err;
860 }
861
862 /**
863  * Initialize RX queue.
864  *
865  * @param tmpl
866  *   Pointer to RX queue control template.
867  *
868  * @return
869  *   0 on success, errno value on failure.
870  */
871 static inline int
872 rxq_setup(struct rxq_ctrl *tmpl)
873 {
874         struct ibv_cq *ibcq = tmpl->cq;
875         struct mlx5_cq *cq = to_mxxx(cq, cq);
876         struct mlx5_rwq *rwq = container_of(tmpl->wq, struct mlx5_rwq, wq);
877         struct rte_mbuf *(*elts)[1 << tmpl->rxq.elts_n] =
878                 rte_calloc_socket("RXQ", 1, sizeof(*elts), 0, tmpl->socket);
879
880         if (cq->cqe_sz != RTE_CACHE_LINE_SIZE) {
881                 ERROR("Wrong MLX5_CQE_SIZE environment variable value: "
882                       "it should be set to %u", RTE_CACHE_LINE_SIZE);
883                 return EINVAL;
884         }
885         if (elts == NULL)
886                 return ENOMEM;
887         tmpl->rxq.rq_db = rwq->rq.db;
888         tmpl->rxq.cqe_n = log2above(ibcq->cqe);
889         tmpl->rxq.cq_ci = 0;
890         tmpl->rxq.rq_ci = 0;
891         tmpl->rxq.cq_db = cq->dbrec;
892         tmpl->rxq.wqes =
893                 (volatile struct mlx5_wqe_data_seg (*)[])
894                 (uintptr_t)rwq->rq.buff;
895         tmpl->rxq.cqes =
896                 (volatile struct mlx5_cqe (*)[])
897                 (uintptr_t)cq->active_buf->buf;
898         tmpl->rxq.elts = elts;
899         return 0;
900 }
901
902 /**
903  * Configure a RX queue.
904  *
905  * @param dev
906  *   Pointer to Ethernet device structure.
907  * @param rxq_ctrl
908  *   Pointer to RX queue structure.
909  * @param desc
910  *   Number of descriptors to configure in queue.
911  * @param socket
912  *   NUMA socket on which memory must be allocated.
913  * @param[in] conf
914  *   Thresholds parameters.
915  * @param mp
916  *   Memory pool for buffer allocations.
917  *
918  * @return
919  *   0 on success, errno value on failure.
920  */
921 int
922 rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
923                uint16_t desc, unsigned int socket,
924                const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
925 {
926         struct priv *priv = dev->data->dev_private;
927         struct rxq_ctrl tmpl = {
928                 .priv = priv,
929                 .socket = socket,
930                 .rxq = {
931                         .elts_n = log2above(desc),
932                         .mp = mp,
933                         .rss_hash = priv->rxqs_n > 1,
934                 },
935         };
936         struct ibv_exp_wq_attr mod;
937         union {
938                 struct ibv_exp_query_intf_params params;
939                 struct ibv_exp_cq_init_attr cq;
940                 struct ibv_exp_res_domain_init_attr rd;
941                 struct ibv_exp_wq_init_attr wq;
942                 struct ibv_exp_cq_attr cq_attr;
943         } attr;
944         enum ibv_exp_query_intf_status status;
945         unsigned int mb_len = rte_pktmbuf_data_room_size(mp);
946         unsigned int cqe_n = desc - 1;
947         struct rte_mbuf *(*elts)[desc] = NULL;
948         int ret = 0;
949
950         (void)conf; /* Thresholds configuration (ignored). */
951         /* Enable scattered packets support for this queue if necessary. */
952         assert(mb_len >= RTE_PKTMBUF_HEADROOM);
953         if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
954             (mb_len - RTE_PKTMBUF_HEADROOM)) {
955                 tmpl.rxq.sges_n = 0;
956         } else if (dev->data->dev_conf.rxmode.enable_scatter) {
957                 unsigned int size =
958                         RTE_PKTMBUF_HEADROOM +
959                         dev->data->dev_conf.rxmode.max_rx_pkt_len;
960                 unsigned int sges_n;
961
962                 /*
963                  * Determine the number of SGEs needed for a full packet
964                  * and round it to the next power of two.
965                  */
966                 sges_n = log2above((size / mb_len) + !!(size % mb_len));
967                 tmpl.rxq.sges_n = sges_n;
968                 /* Make sure rxq.sges_n did not overflow. */
969                 size = mb_len * (1 << tmpl.rxq.sges_n);
970                 size -= RTE_PKTMBUF_HEADROOM;
971                 if (size < dev->data->dev_conf.rxmode.max_rx_pkt_len) {
972                         ERROR("%p: too many SGEs (%u) needed to handle"
973                               " requested maximum packet size %u",
974                               (void *)dev,
975                               1 << sges_n,
976                               dev->data->dev_conf.rxmode.max_rx_pkt_len);
977                         return EOVERFLOW;
978                 }
979         } else {
980                 WARN("%p: the requested maximum Rx packet size (%u) is"
981                      " larger than a single mbuf (%u) and scattered"
982                      " mode has not been requested",
983                      (void *)dev,
984                      dev->data->dev_conf.rxmode.max_rx_pkt_len,
985                      mb_len - RTE_PKTMBUF_HEADROOM);
986         }
987         DEBUG("%p: maximum number of segments per packet: %u",
988               (void *)dev, 1 << tmpl.rxq.sges_n);
989         if (desc % (1 << tmpl.rxq.sges_n)) {
990                 ERROR("%p: number of RX queue descriptors (%u) is not a"
991                       " multiple of SGEs per packet (%u)",
992                       (void *)dev,
993                       desc,
994                       1 << tmpl.rxq.sges_n);
995                 return EINVAL;
996         }
997         /* Toggle RX checksum offload if hardware supports it. */
998         if (priv->hw_csum)
999                 tmpl.rxq.csum = !!dev->data->dev_conf.rxmode.hw_ip_checksum;
1000         if (priv->hw_csum_l2tun)
1001                 tmpl.rxq.csum_l2tun =
1002                         !!dev->data->dev_conf.rxmode.hw_ip_checksum;
1003         /* Use the entire RX mempool as the memory region. */
1004         tmpl.mr = mlx5_mp2mr(priv->pd, mp);
1005         if (tmpl.mr == NULL) {
1006                 ret = EINVAL;
1007                 ERROR("%p: MR creation failure: %s",
1008                       (void *)dev, strerror(ret));
1009                 goto error;
1010         }
1011         attr.rd = (struct ibv_exp_res_domain_init_attr){
1012                 .comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |
1013                               IBV_EXP_RES_DOMAIN_MSG_MODEL),
1014                 .thread_model = IBV_EXP_THREAD_SINGLE,
1015                 .msg_model = IBV_EXP_MSG_HIGH_BW,
1016         };
1017         tmpl.rd = ibv_exp_create_res_domain(priv->ctx, &attr.rd);
1018         if (tmpl.rd == NULL) {
1019                 ret = ENOMEM;
1020                 ERROR("%p: RD creation failure: %s",
1021                       (void *)dev, strerror(ret));
1022                 goto error;
1023         }
1024         if (dev->data->dev_conf.intr_conf.rxq) {
1025                 tmpl.channel = ibv_create_comp_channel(priv->ctx);
1026                 if (tmpl.channel == NULL) {
1027                         dev->data->dev_conf.intr_conf.rxq = 0;
1028                         ret = ENOMEM;
1029                         ERROR("%p: Comp Channel creation failure: %s",
1030                         (void *)dev, strerror(ret));
1031                         goto error;
1032                 }
1033         }
1034         attr.cq = (struct ibv_exp_cq_init_attr){
1035                 .comp_mask = IBV_EXP_CQ_INIT_ATTR_RES_DOMAIN,
1036                 .res_domain = tmpl.rd,
1037         };
1038         if (priv->cqe_comp) {
1039                 attr.cq.comp_mask |= IBV_EXP_CQ_INIT_ATTR_FLAGS;
1040                 attr.cq.flags |= IBV_EXP_CQ_COMPRESSED_CQE;
1041                 cqe_n = (desc * 2) - 1; /* Double the number of CQEs. */
1042         }
1043         tmpl.cq = ibv_exp_create_cq(priv->ctx, cqe_n, NULL, tmpl.channel, 0,
1044                                     &attr.cq);
1045         if (tmpl.cq == NULL) {
1046                 ret = ENOMEM;
1047                 ERROR("%p: CQ creation failure: %s",
1048                       (void *)dev, strerror(ret));
1049                 goto error;
1050         }
1051         DEBUG("priv->device_attr.max_qp_wr is %d",
1052               priv->device_attr.max_qp_wr);
1053         DEBUG("priv->device_attr.max_sge is %d",
1054               priv->device_attr.max_sge);
1055         /* Configure VLAN stripping. */
1056         tmpl.rxq.vlan_strip = (priv->hw_vlan_strip &&
1057                                !!dev->data->dev_conf.rxmode.hw_vlan_strip);
1058         attr.wq = (struct ibv_exp_wq_init_attr){
1059                 .wq_context = NULL, /* Could be useful in the future. */
1060                 .wq_type = IBV_EXP_WQT_RQ,
1061                 /* Max number of outstanding WRs. */
1062                 .max_recv_wr = desc >> tmpl.rxq.sges_n,
1063                 /* Max number of scatter/gather elements in a WR. */
1064                 .max_recv_sge = 1 << tmpl.rxq.sges_n,
1065                 .pd = priv->pd,
1066                 .cq = tmpl.cq,
1067                 .comp_mask =
1068                         IBV_EXP_CREATE_WQ_RES_DOMAIN |
1069                         IBV_EXP_CREATE_WQ_VLAN_OFFLOADS |
1070                         0,
1071                 .res_domain = tmpl.rd,
1072                 .vlan_offloads = (tmpl.rxq.vlan_strip ?
1073                                   IBV_EXP_RECEIVE_WQ_CVLAN_STRIP :
1074                                   0),
1075         };
1076         /* By default, FCS (CRC) is stripped by hardware. */
1077         if (dev->data->dev_conf.rxmode.hw_strip_crc) {
1078                 tmpl.rxq.crc_present = 0;
1079         } else if (priv->hw_fcs_strip) {
1080                 /* Ask HW/Verbs to leave CRC in place when supported. */
1081                 attr.wq.flags |= IBV_EXP_CREATE_WQ_FLAG_SCATTER_FCS;
1082                 attr.wq.comp_mask |= IBV_EXP_CREATE_WQ_FLAGS;
1083                 tmpl.rxq.crc_present = 1;
1084         } else {
1085                 WARN("%p: CRC stripping has been disabled but will still"
1086                      " be performed by hardware, make sure MLNX_OFED and"
1087                      " firmware are up to date",
1088                      (void *)dev);
1089                 tmpl.rxq.crc_present = 0;
1090         }
1091         DEBUG("%p: CRC stripping is %s, %u bytes will be subtracted from"
1092               " incoming frames to hide it",
1093               (void *)dev,
1094               tmpl.rxq.crc_present ? "disabled" : "enabled",
1095               tmpl.rxq.crc_present << 2);
1096         if (!mlx5_getenv_int("MLX5_PMD_ENABLE_PADDING"))
1097                 ; /* Nothing else to do. */
1098         else if (priv->hw_padding) {
1099                 INFO("%p: enabling packet padding on queue %p",
1100                      (void *)dev, (void *)rxq_ctrl);
1101                 attr.wq.flags |= IBV_EXP_CREATE_WQ_FLAG_RX_END_PADDING;
1102                 attr.wq.comp_mask |= IBV_EXP_CREATE_WQ_FLAGS;
1103         } else
1104                 WARN("%p: packet padding has been requested but is not"
1105                      " supported, make sure MLNX_OFED and firmware are"
1106                      " up to date",
1107                      (void *)dev);
1108
1109         tmpl.wq = ibv_exp_create_wq(priv->ctx, &attr.wq);
1110         if (tmpl.wq == NULL) {
1111                 ret = (errno ? errno : EINVAL);
1112                 ERROR("%p: WQ creation failure: %s",
1113                       (void *)dev, strerror(ret));
1114                 goto error;
1115         }
1116         /*
1117          * Make sure number of WRs*SGEs match expectations since a queue
1118          * cannot allocate more than "desc" buffers.
1119          */
1120         if (((int)attr.wq.max_recv_wr != (desc >> tmpl.rxq.sges_n)) ||
1121             ((int)attr.wq.max_recv_sge != (1 << tmpl.rxq.sges_n))) {
1122                 ERROR("%p: requested %u*%u but got %u*%u WRs*SGEs",
1123                       (void *)dev,
1124                       (desc >> tmpl.rxq.sges_n), (1 << tmpl.rxq.sges_n),
1125                       attr.wq.max_recv_wr, attr.wq.max_recv_sge);
1126                 ret = EINVAL;
1127                 goto error;
1128         }
1129         /* Save port ID. */
1130         tmpl.rxq.port_id = dev->data->port_id;
1131         DEBUG("%p: RTE port ID: %u", (void *)rxq_ctrl, tmpl.rxq.port_id);
1132         attr.params = (struct ibv_exp_query_intf_params){
1133                 .intf_scope = IBV_EXP_INTF_GLOBAL,
1134                 .intf_version = 1,
1135                 .intf = IBV_EXP_INTF_CQ,
1136                 .obj = tmpl.cq,
1137         };
1138         tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
1139         if (tmpl.if_cq == NULL) {
1140                 ERROR("%p: CQ interface family query failed with status %d",
1141                       (void *)dev, status);
1142                 goto error;
1143         }
1144         attr.params = (struct ibv_exp_query_intf_params){
1145                 .intf_scope = IBV_EXP_INTF_GLOBAL,
1146                 .intf = IBV_EXP_INTF_WQ,
1147                 .obj = tmpl.wq,
1148         };
1149         tmpl.if_wq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
1150         if (tmpl.if_wq == NULL) {
1151                 ERROR("%p: WQ interface family query failed with status %d",
1152                       (void *)dev, status);
1153                 goto error;
1154         }
1155         /* Change queue state to ready. */
1156         mod = (struct ibv_exp_wq_attr){
1157                 .attr_mask = IBV_EXP_WQ_ATTR_STATE,
1158                 .wq_state = IBV_EXP_WQS_RDY,
1159         };
1160         ret = ibv_exp_modify_wq(tmpl.wq, &mod);
1161         if (ret) {
1162                 ERROR("%p: WQ state to IBV_EXP_WQS_RDY failed: %s",
1163                       (void *)dev, strerror(ret));
1164                 goto error;
1165         }
1166         ret = rxq_setup(&tmpl);
1167         if (ret) {
1168                 ERROR("%p: cannot initialize RX queue structure: %s",
1169                       (void *)dev, strerror(ret));
1170                 goto error;
1171         }
1172         /* Reuse buffers from original queue if possible. */
1173         if (rxq_ctrl->rxq.elts_n) {
1174                 assert(1 << rxq_ctrl->rxq.elts_n == desc);
1175                 assert(rxq_ctrl->rxq.elts != tmpl.rxq.elts);
1176                 ret = rxq_alloc_elts(&tmpl, desc, rxq_ctrl->rxq.elts);
1177         } else
1178                 ret = rxq_alloc_elts(&tmpl, desc, NULL);
1179         if (ret) {
1180                 ERROR("%p: RXQ allocation failed: %s",
1181                       (void *)dev, strerror(ret));
1182                 goto error;
1183         }
1184         /* Clean up rxq in case we're reinitializing it. */
1185         DEBUG("%p: cleaning-up old rxq just in case", (void *)rxq_ctrl);
1186         rxq_cleanup(rxq_ctrl);
1187         /* Move mbuf pointers to dedicated storage area in RX queue. */
1188         elts = (void *)(rxq_ctrl + 1);
1189         rte_memcpy(elts, tmpl.rxq.elts, sizeof(*elts));
1190 #ifndef NDEBUG
1191         memset(tmpl.rxq.elts, 0x55, sizeof(*elts));
1192 #endif
1193         rte_free(tmpl.rxq.elts);
1194         tmpl.rxq.elts = elts;
1195         *rxq_ctrl = tmpl;
1196         /* Update doorbell counter. */
1197         rxq_ctrl->rxq.rq_ci = desc >> rxq_ctrl->rxq.sges_n;
1198         rte_wmb();
1199         *rxq_ctrl->rxq.rq_db = htonl(rxq_ctrl->rxq.rq_ci);
1200         DEBUG("%p: rxq updated with %p", (void *)rxq_ctrl, (void *)&tmpl);
1201         assert(ret == 0);
1202         return 0;
1203 error:
1204         elts = tmpl.rxq.elts;
1205         rxq_cleanup(&tmpl);
1206         rte_free(elts);
1207         assert(ret > 0);
1208         return ret;
1209 }
1210
1211 /**
1212  * DPDK callback to configure a RX queue.
1213  *
1214  * @param dev
1215  *   Pointer to Ethernet device structure.
1216  * @param idx
1217  *   RX queue index.
1218  * @param desc
1219  *   Number of descriptors to configure in queue.
1220  * @param socket
1221  *   NUMA socket on which memory must be allocated.
1222  * @param[in] conf
1223  *   Thresholds parameters.
1224  * @param mp
1225  *   Memory pool for buffer allocations.
1226  *
1227  * @return
1228  *   0 on success, negative errno value on failure.
1229  */
1230 int
1231 mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
1232                     unsigned int socket, const struct rte_eth_rxconf *conf,
1233                     struct rte_mempool *mp)
1234 {
1235         struct priv *priv = dev->data->dev_private;
1236         struct rxq *rxq = (*priv->rxqs)[idx];
1237         struct rxq_ctrl *rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
1238         int ret;
1239
1240         if (mlx5_is_secondary())
1241                 return -E_RTE_SECONDARY;
1242
1243         priv_lock(priv);
1244         if (!rte_is_power_of_2(desc)) {
1245                 desc = 1 << log2above(desc);
1246                 WARN("%p: increased number of descriptors in RX queue %u"
1247                      " to the next power of two (%d)",
1248                      (void *)dev, idx, desc);
1249         }
1250         DEBUG("%p: configuring queue %u for %u descriptors",
1251               (void *)dev, idx, desc);
1252         if (idx >= priv->rxqs_n) {
1253                 ERROR("%p: queue index out of range (%u >= %u)",
1254                       (void *)dev, idx, priv->rxqs_n);
1255                 priv_unlock(priv);
1256                 return -EOVERFLOW;
1257         }
1258         if (rxq != NULL) {
1259                 DEBUG("%p: reusing already allocated queue index %u (%p)",
1260                       (void *)dev, idx, (void *)rxq);
1261                 if (priv->started) {
1262                         priv_unlock(priv);
1263                         return -EEXIST;
1264                 }
1265                 (*priv->rxqs)[idx] = NULL;
1266                 rxq_cleanup(rxq_ctrl);
1267                 /* Resize if rxq size is changed. */
1268                 if (rxq_ctrl->rxq.elts_n != log2above(desc)) {
1269                         rxq_ctrl = rte_realloc(rxq_ctrl,
1270                                                sizeof(*rxq_ctrl) +
1271                                                desc * sizeof(struct rte_mbuf *),
1272                                                RTE_CACHE_LINE_SIZE);
1273                         if (!rxq_ctrl) {
1274                                 ERROR("%p: unable to reallocate queue index %u",
1275                                         (void *)dev, idx);
1276                                 priv_unlock(priv);
1277                                 return -ENOMEM;
1278                         }
1279                 }
1280         } else {
1281                 rxq_ctrl = rte_calloc_socket("RXQ", 1, sizeof(*rxq_ctrl) +
1282                                              desc * sizeof(struct rte_mbuf *),
1283                                              0, socket);
1284                 if (rxq_ctrl == NULL) {
1285                         ERROR("%p: unable to allocate queue index %u",
1286                               (void *)dev, idx);
1287                         priv_unlock(priv);
1288                         return -ENOMEM;
1289                 }
1290         }
1291         ret = rxq_ctrl_setup(dev, rxq_ctrl, desc, socket, conf, mp);
1292         if (ret)
1293                 rte_free(rxq_ctrl);
1294         else {
1295                 rxq_ctrl->rxq.stats.idx = idx;
1296                 DEBUG("%p: adding RX queue %p to list",
1297                       (void *)dev, (void *)rxq_ctrl);
1298                 (*priv->rxqs)[idx] = &rxq_ctrl->rxq;
1299                 /* Update receive callback. */
1300                 priv_select_rx_function(priv);
1301         }
1302         priv_unlock(priv);
1303         return -ret;
1304 }
1305
1306 /**
1307  * DPDK callback to release a RX queue.
1308  *
1309  * @param dpdk_rxq
1310  *   Generic RX queue pointer.
1311  */
1312 void
1313 mlx5_rx_queue_release(void *dpdk_rxq)
1314 {
1315         struct rxq *rxq = (struct rxq *)dpdk_rxq;
1316         struct rxq_ctrl *rxq_ctrl;
1317         struct priv *priv;
1318         unsigned int i;
1319
1320         if (mlx5_is_secondary())
1321                 return;
1322
1323         if (rxq == NULL)
1324                 return;
1325         rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
1326         priv = rxq_ctrl->priv;
1327         priv_lock(priv);
1328         for (i = 0; (i != priv->rxqs_n); ++i)
1329                 if ((*priv->rxqs)[i] == rxq) {
1330                         DEBUG("%p: removing RX queue %p from list",
1331                               (void *)priv->dev, (void *)rxq_ctrl);
1332                         (*priv->rxqs)[i] = NULL;
1333                         break;
1334                 }
1335         rxq_cleanup(rxq_ctrl);
1336         rte_free(rxq_ctrl);
1337         priv_unlock(priv);
1338 }
1339
1340 /**
1341  * DPDK callback for RX in secondary processes.
1342  *
1343  * This function configures all queues from primary process information
1344  * if necessary before reverting to the normal RX burst callback.
1345  *
1346  * @param dpdk_rxq
1347  *   Generic pointer to RX queue structure.
1348  * @param[out] pkts
1349  *   Array to store received packets.
1350  * @param pkts_n
1351  *   Maximum number of packets in array.
1352  *
1353  * @return
1354  *   Number of packets successfully received (<= pkts_n).
1355  */
1356 uint16_t
1357 mlx5_rx_burst_secondary_setup(void *dpdk_rxq, struct rte_mbuf **pkts,
1358                               uint16_t pkts_n)
1359 {
1360         struct rxq *rxq = dpdk_rxq;
1361         struct rxq_ctrl *rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
1362         struct priv *priv = mlx5_secondary_data_setup(rxq_ctrl->priv);
1363         struct priv *primary_priv;
1364         unsigned int index;
1365
1366         if (priv == NULL)
1367                 return 0;
1368         primary_priv =
1369                 mlx5_secondary_data[priv->dev->data->port_id].primary_priv;
1370         /* Look for queue index in both private structures. */
1371         for (index = 0; index != priv->rxqs_n; ++index)
1372                 if (((*primary_priv->rxqs)[index] == rxq) ||
1373                     ((*priv->rxqs)[index] == rxq))
1374                         break;
1375         if (index == priv->rxqs_n)
1376                 return 0;
1377         rxq = (*priv->rxqs)[index];
1378         return priv->dev->rx_pkt_burst(rxq, pkts, pkts_n);
1379 }
1380
1381 /**
1382  * Fill epoll fd list for rxq interrupts.
1383  *
1384  * @param priv
1385  *   Private structure.
1386  *
1387  * @return
1388  *   0 on success, negative on failure.
1389  */
1390 int
1391 priv_intr_efd_enable(struct priv *priv)
1392 {
1393         unsigned int i;
1394         unsigned int rxqs_n = priv->rxqs_n;
1395         unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
1396         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
1397
1398         if (n == 0)
1399                 return 0;
1400         if (n < rxqs_n) {
1401                 WARN("rxqs num is larger than EAL max interrupt vector "
1402                      "%u > %u unable to supprt rxq interrupts",
1403                      rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
1404                 return -EINVAL;
1405         }
1406         intr_handle->type = RTE_INTR_HANDLE_EXT;
1407         for (i = 0; i != n; ++i) {
1408                 struct rxq *rxq = (*priv->rxqs)[i];
1409                 struct rxq_ctrl *rxq_ctrl =
1410                         container_of(rxq, struct rxq_ctrl, rxq);
1411                 int fd = rxq_ctrl->channel->fd;
1412                 int flags;
1413                 int rc;
1414
1415                 flags = fcntl(fd, F_GETFL);
1416                 rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1417                 if (rc < 0) {
1418                         WARN("failed to change rxq interrupt file "
1419                              "descriptor %d for queue index %d", fd, i);
1420                         return -1;
1421                 }
1422                 intr_handle->efds[i] = fd;
1423         }
1424         intr_handle->nb_efd = n;
1425         return 0;
1426 }
1427
1428 /**
1429  * Clean epoll fd list for rxq interrupts.
1430  *
1431  * @param priv
1432  *   Private structure.
1433  */
1434 void
1435 priv_intr_efd_disable(struct priv *priv)
1436 {
1437         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
1438
1439         rte_intr_free_epoll_fd(intr_handle);
1440 }
1441
1442 /**
1443  * Create and init interrupt vector array.
1444  *
1445  * @param priv
1446  *   Private structure.
1447  *
1448  * @return
1449  *   0 on success, negative on failure.
1450  */
1451 int
1452 priv_create_intr_vec(struct priv *priv)
1453 {
1454         unsigned int rxqs_n = priv->rxqs_n;
1455         unsigned int i;
1456         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
1457
1458         if (rxqs_n == 0)
1459                 return 0;
1460         intr_handle->intr_vec = (int *)
1461                 rte_malloc("intr_vec", rxqs_n * sizeof(int), 0);
1462         if (intr_handle->intr_vec == NULL) {
1463                 WARN("Failed to allocate memory for intr_vec "
1464                      "rxq interrupt will not be supported");
1465                 return -ENOMEM;
1466         }
1467         for (i = 0; i != rxqs_n; ++i) {
1468                 /* 1:1 mapping between rxq and interrupt. */
1469                 intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + i;
1470         }
1471         return 0;
1472 }
1473
1474 /**
1475  * Destroy init interrupt vector array.
1476  *
1477  * @param priv
1478  *   Private structure.
1479  *
1480  * @return
1481  *   0 on success, negative on failure.
1482  */
1483 void
1484 priv_destroy_intr_vec(struct priv *priv)
1485 {
1486         struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
1487
1488         rte_free(intr_handle->intr_vec);
1489 }