4 * Copyright 2015 6WIND S.A.
5 * Copyright 2015 Mellanox.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
39 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
41 #pragma GCC diagnostic ignored "-pedantic"
43 #include <infiniband/verbs.h>
45 #pragma GCC diagnostic error "-pedantic"
48 /* DPDK headers don't like -pedantic. */
50 #pragma GCC diagnostic ignored "-pedantic"
52 #include <rte_ethdev.h>
54 #pragma GCC diagnostic error "-pedantic"
58 #include "mlx5_rxtx.h"
59 #include "mlx5_utils.h"
61 static void hash_rxq_promiscuous_disable(struct hash_rxq *);
62 static void hash_rxq_allmulticast_disable(struct hash_rxq *);
65 * Enable promiscuous mode in a hash RX queue.
68 * Pointer to hash RX queue structure.
71 * 0 on success, errno value on failure.
74 hash_rxq_promiscuous_enable(struct hash_rxq *hash_rxq)
76 struct ibv_flow *flow;
77 struct ibv_flow_attr attr = {
78 .type = IBV_FLOW_ATTR_ALL_DEFAULT,
80 .port = hash_rxq->priv->port,
84 if (hash_rxq->priv->vf)
86 if (hash_rxq->promisc_flow != NULL)
88 DEBUG("%p: enabling promiscuous mode", (void *)hash_rxq);
90 flow = ibv_create_flow(hash_rxq->qp, &attr);
92 /* It's not clear whether errno is always set in this case. */
93 ERROR("%p: flow configuration failed, errno=%d: %s",
94 (void *)hash_rxq, errno,
95 (errno ? strerror(errno) : "Unknown error"));
100 hash_rxq->promisc_flow = flow;
101 DEBUG("%p: promiscuous mode enabled", (void *)hash_rxq);
106 * Enable promiscuous mode in all hash RX queues.
112 * 0 on success, errno value on failure.
115 priv_promiscuous_enable(struct priv *priv)
119 for (i = 0; (i != priv->hash_rxqs_n); ++i) {
120 struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
123 ret = hash_rxq_promiscuous_enable(hash_rxq);
126 /* Failure, rollback. */
128 hash_rxq = &(*priv->hash_rxqs)[--i];
129 hash_rxq_promiscuous_disable(hash_rxq);
137 * DPDK callback to enable promiscuous mode.
140 * Pointer to Ethernet device structure.
143 mlx5_promiscuous_enable(struct rte_eth_dev *dev)
145 struct priv *priv = dev->data->dev_private;
149 priv->promisc_req = 1;
150 ret = priv_promiscuous_enable(priv);
152 ERROR("cannot enable promiscuous mode: %s", strerror(ret));
157 * Disable promiscuous mode in a hash RX queue.
160 * Pointer to hash RX queue structure.
163 hash_rxq_promiscuous_disable(struct hash_rxq *hash_rxq)
165 if (hash_rxq->priv->vf)
167 if (hash_rxq->promisc_flow == NULL)
169 DEBUG("%p: disabling promiscuous mode", (void *)hash_rxq);
170 claim_zero(ibv_destroy_flow(hash_rxq->promisc_flow));
171 hash_rxq->promisc_flow = NULL;
172 DEBUG("%p: promiscuous mode disabled", (void *)hash_rxq);
176 * Disable promiscuous mode in all hash RX queues.
182 priv_promiscuous_disable(struct priv *priv)
186 for (i = 0; (i != priv->hash_rxqs_n); ++i)
187 hash_rxq_promiscuous_disable(&(*priv->hash_rxqs)[i]);
191 * DPDK callback to disable promiscuous mode.
194 * Pointer to Ethernet device structure.
197 mlx5_promiscuous_disable(struct rte_eth_dev *dev)
199 struct priv *priv = dev->data->dev_private;
202 priv->promisc_req = 0;
203 priv_promiscuous_disable(priv);
208 * Enable allmulti mode in a hash RX queue.
211 * Pointer to hash RX queue structure.
214 * 0 on success, errno value on failure.
217 hash_rxq_allmulticast_enable(struct hash_rxq *hash_rxq)
219 struct ibv_flow *flow;
220 struct ibv_flow_attr attr = {
221 .type = IBV_FLOW_ATTR_MC_DEFAULT,
223 .port = hash_rxq->priv->port,
227 if (hash_rxq->allmulti_flow != NULL)
229 DEBUG("%p: enabling allmulticast mode", (void *)hash_rxq);
231 flow = ibv_create_flow(hash_rxq->qp, &attr);
233 /* It's not clear whether errno is always set in this case. */
234 ERROR("%p: flow configuration failed, errno=%d: %s",
235 (void *)hash_rxq, errno,
236 (errno ? strerror(errno) : "Unknown error"));
241 hash_rxq->allmulti_flow = flow;
242 DEBUG("%p: allmulticast mode enabled", (void *)hash_rxq);
247 * Enable allmulti mode in most hash RX queues.
248 * TCP queues are exempted to save resources.
254 * 0 on success, errno value on failure.
257 priv_allmulticast_enable(struct priv *priv)
261 for (i = 0; (i != priv->hash_rxqs_n); ++i) {
262 struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
265 /* allmulticast not relevant for TCP. */
266 if (hash_rxq->type == HASH_RXQ_TCPV4)
268 ret = hash_rxq_allmulticast_enable(hash_rxq);
271 /* Failure, rollback. */
273 hash_rxq = &(*priv->hash_rxqs)[--i];
274 hash_rxq_allmulticast_disable(hash_rxq);
282 * DPDK callback to enable allmulti mode.
285 * Pointer to Ethernet device structure.
288 mlx5_allmulticast_enable(struct rte_eth_dev *dev)
290 struct priv *priv = dev->data->dev_private;
294 priv->allmulti_req = 1;
295 ret = priv_allmulticast_enable(priv);
297 ERROR("cannot enable allmulticast mode: %s", strerror(ret));
302 * Disable allmulti mode in a hash RX queue.
305 * Pointer to hash RX queue structure.
308 hash_rxq_allmulticast_disable(struct hash_rxq *hash_rxq)
310 if (hash_rxq->allmulti_flow == NULL)
312 DEBUG("%p: disabling allmulticast mode", (void *)hash_rxq);
313 claim_zero(ibv_destroy_flow(hash_rxq->allmulti_flow));
314 hash_rxq->allmulti_flow = NULL;
315 DEBUG("%p: allmulticast mode disabled", (void *)hash_rxq);
319 * Disable allmulti mode in all hash RX queues.
325 priv_allmulticast_disable(struct priv *priv)
329 for (i = 0; (i != priv->hash_rxqs_n); ++i)
330 hash_rxq_allmulticast_disable(&(*priv->hash_rxqs)[i]);
334 * DPDK callback to disable allmulti mode.
337 * Pointer to Ethernet device structure.
340 mlx5_allmulticast_disable(struct rte_eth_dev *dev)
342 struct priv *priv = dev->data->dev_private;
345 priv->allmulti_req = 0;
346 priv_allmulticast_disable(priv);