15129044dSC.J. Collier/*-
25129044dSC.J. Collier *   BSD LICENSE
35129044dSC.J. Collier *
45129044dSC.J. Collier *   Copyright 2015 6WIND S.A.
55129044dSC.J. Collier *   Copyright 2015 Mellanox.
65129044dSC.J. Collier *
75129044dSC.J. Collier *   Redistribution and use in source and binary forms, with or without
85129044dSC.J. Collier *   modification, are permitted provided that the following conditions
95129044dSC.J. Collier *   are met:
105129044dSC.J. Collier *
115129044dSC.J. Collier *     * Redistributions of source code must retain the above copyright
125129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer.
135129044dSC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
145129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer in
155129044dSC.J. Collier *       the documentation and/or other materials provided with the
165129044dSC.J. Collier *       distribution.
175129044dSC.J. Collier *     * Neither the name of 6WIND S.A. nor the names of its
185129044dSC.J. Collier *       contributors may be used to endorse or promote products derived
195129044dSC.J. Collier *       from this software without specific prior written permission.
205129044dSC.J. Collier *
215129044dSC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
225129044dSC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235129044dSC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
245129044dSC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
255129044dSC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
265129044dSC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
275129044dSC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
285129044dSC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
295129044dSC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
305129044dSC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
315129044dSC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325129044dSC.J. Collier */
335129044dSC.J. Collier
345129044dSC.J. Collier#include <stddef.h>
355129044dSC.J. Collier#include <errno.h>
365129044dSC.J. Collier#include <string.h>
375129044dSC.J. Collier
385129044dSC.J. Collier/* Verbs header. */
395129044dSC.J. Collier/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
405129044dSC.J. Collier#ifdef PEDANTIC
41c300e355SChristian Ehrhardt#pragma GCC diagnostic ignored "-Wpedantic"
425129044dSC.J. Collier#endif
435129044dSC.J. Collier#include <infiniband/verbs.h>
445129044dSC.J. Collier#ifdef PEDANTIC
45c300e355SChristian Ehrhardt#pragma GCC diagnostic error "-Wpedantic"
465129044dSC.J. Collier#endif
475129044dSC.J. Collier
485129044dSC.J. Collier/* DPDK headers don't like -pedantic. */
495129044dSC.J. Collier#ifdef PEDANTIC
50c300e355SChristian Ehrhardt#pragma GCC diagnostic ignored "-Wpedantic"
515129044dSC.J. Collier#endif
525129044dSC.J. Collier#include <rte_ethdev.h>
535129044dSC.J. Collier#ifdef PEDANTIC
54c300e355SChristian Ehrhardt#pragma GCC diagnostic error "-Wpedantic"
555129044dSC.J. Collier#endif
565129044dSC.J. Collier
575129044dSC.J. Collier#include "mlx5.h"
585129044dSC.J. Collier#include "mlx5_rxtx.h"
595129044dSC.J. Collier#include "mlx5_utils.h"
605129044dSC.J. Collier
615129044dSC.J. Collier/* Initialization data for special flows. */
625129044dSC.J. Collierstatic const struct special_flow_init special_flow_init[] = {
635129044dSC.J. Collier	[HASH_RXQ_FLOW_TYPE_PROMISC] = {
645129044dSC.J. Collier		.dst_mac_val = "\x00\x00\x00\x00\x00\x00",
655129044dSC.J. Collier		.dst_mac_mask = "\x00\x00\x00\x00\x00\x00",
665129044dSC.J. Collier		.hash_types =
675129044dSC.J. Collier			1 << HASH_RXQ_TCPV4 |
685129044dSC.J. Collier			1 << HASH_RXQ_UDPV4 |
695129044dSC.J. Collier			1 << HASH_RXQ_IPV4 |
705129044dSC.J. Collier			1 << HASH_RXQ_TCPV6 |
715129044dSC.J. Collier			1 << HASH_RXQ_UDPV6 |
725129044dSC.J. Collier			1 << HASH_RXQ_IPV6 |
735129044dSC.J. Collier			1 << HASH_RXQ_ETH |
745129044dSC.J. Collier			0,
755129044dSC.J. Collier		.per_vlan = 0,
765129044dSC.J. Collier	},
775129044dSC.J. Collier	[HASH_RXQ_FLOW_TYPE_ALLMULTI] = {
785129044dSC.J. Collier		.dst_mac_val = "\x01\x00\x00\x00\x00\x00",
795129044dSC.J. Collier		.dst_mac_mask = "\x01\x00\x00\x00\x00\x00",
805129044dSC.J. Collier		.hash_types =
815129044dSC.J. Collier			1 << HASH_RXQ_UDPV4 |
825129044dSC.J. Collier			1 << HASH_RXQ_IPV4 |
835129044dSC.J. Collier			1 << HASH_RXQ_UDPV6 |
845129044dSC.J. Collier			1 << HASH_RXQ_IPV6 |
855129044dSC.J. Collier			1 << HASH_RXQ_ETH |
865129044dSC.J. Collier			0,
875129044dSC.J. Collier		.per_vlan = 0,
885129044dSC.J. Collier	},
895129044dSC.J. Collier	[HASH_RXQ_FLOW_TYPE_BROADCAST] = {
905129044dSC.J. Collier		.dst_mac_val = "\xff\xff\xff\xff\xff\xff",
915129044dSC.J. Collier		.dst_mac_mask = "\xff\xff\xff\xff\xff\xff",
925129044dSC.J. Collier		.hash_types =
935129044dSC.J. Collier			1 << HASH_RXQ_UDPV4 |
945129044dSC.J. Collier			1 << HASH_RXQ_IPV4 |
955129044dSC.J. Collier			1 << HASH_RXQ_UDPV6 |
965129044dSC.J. Collier			1 << HASH_RXQ_IPV6 |
975129044dSC.J. Collier			1 << HASH_RXQ_ETH |
985129044dSC.J. Collier			0,
995129044dSC.J. Collier		.per_vlan = 1,
1005129044dSC.J. Collier	},
1015129044dSC.J. Collier	[HASH_RXQ_FLOW_TYPE_IPV6MULTI] = {
1025129044dSC.J. Collier		.dst_mac_val = "\x33\x33\x00\x00\x00\x00",
1035129044dSC.J. Collier		.dst_mac_mask = "\xff\xff\x00\x00\x00\x00",
1045129044dSC.J. Collier		.hash_types =
1055129044dSC.J. Collier			1 << HASH_RXQ_UDPV6 |
1065129044dSC.J. Collier			1 << HASH_RXQ_IPV6 |
1075129044dSC.J. Collier			1 << HASH_RXQ_ETH |
1085129044dSC.J. Collier			0,
1095129044dSC.J. Collier		.per_vlan = 1,
1105129044dSC.J. Collier	},
1115129044dSC.J. Collier};
1125129044dSC.J. Collier
1135129044dSC.J. Collier/**
1145129044dSC.J. Collier * Enable a special flow in a hash RX queue for a given VLAN index.
1155129044dSC.J. Collier *
1165129044dSC.J. Collier * @param hash_rxq
1175129044dSC.J. Collier *   Pointer to hash RX queue structure.
1185129044dSC.J. Collier * @param flow_type
1195129044dSC.J. Collier *   Special flow type.
1205129044dSC.J. Collier * @param vlan_index
1215129044dSC.J. Collier *   VLAN index to use.
1225129044dSC.J. Collier *
1235129044dSC.J. Collier * @return
1245129044dSC.J. Collier *   0 on success, errno value on failure.
1255129044dSC.J. Collier */
1265129044dSC.J. Collierstatic int
1275129044dSC.J. Collierhash_rxq_special_flow_enable_vlan(struct hash_rxq *hash_rxq,
1285129044dSC.J. Collier				  enum hash_rxq_flow_type flow_type,
1295129044dSC.J. Collier				  unsigned int vlan_index)
1305129044dSC.J. Collier{
1315129044dSC.J. Collier	struct priv *priv = hash_rxq->priv;
1325129044dSC.J. Collier	struct ibv_exp_flow *flow;
1335129044dSC.J. Collier	FLOW_ATTR_SPEC_ETH(data, priv_flow_attr(priv, NULL, 0, hash_rxq->type));
1345129044dSC.J. Collier	struct ibv_exp_flow_attr *attr = &data->attr;
1355129044dSC.J. Collier	struct ibv_exp_flow_spec_eth *spec = &data->spec;
1365129044dSC.J. Collier	const uint8_t *mac;
1375129044dSC.J. Collier	const uint8_t *mask;
1385129044dSC.J. Collier	unsigned int vlan_enabled = (priv->vlan_filter_n &&
1395129044dSC.J. Collier				     special_flow_init[flow_type].per_vlan);
1405129044dSC.J. Collier	unsigned int vlan_id = priv->vlan_filter[vlan_index];
1415129044dSC.J. Collier
1425129044dSC.J. Collier	/* Check if flow is relevant for this hash_rxq. */
1435129044dSC.J. Collier	if (!(special_flow_init[flow_type].hash_types & (1 << hash_rxq->type)))
1445129044dSC.J. Collier		return 0;
1455129044dSC.J. Collier	/* Check if flow already exists. */
1465129044dSC.J. Collier	if (hash_rxq->special_flow[flow_type][vlan_index] != NULL)
1475129044dSC.J. Collier		return 0;
1485129044dSC.J. Collier
1495129044dSC.J. Collier	/*
1505129044dSC.J. Collier	 * No padding must be inserted by the compiler between attr and spec.
1515129044dSC.J. Collier	 * This layout is expected by libibverbs.
1525129044dSC.J. Collier	 */
1535129044dSC.J. Collier	assert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec);
1545129044dSC.J. Collier	priv_flow_attr(priv, attr, sizeof(data), hash_rxq->type);
1555129044dSC.J. Collier	/* The first specification must be Ethernet. */
1565129044dSC.J. Collier	assert(spec->type == IBV_EXP_FLOW_SPEC_ETH);
1575129044dSC.J. Collier	assert(spec->size == sizeof(*spec));
1585129044dSC.J. Collier
1595129044dSC.J. Collier	mac = special_flow_init[flow_type].dst_mac_val;
1605129044dSC.J. Collier	mask = special_flow_init[flow_type].dst_mac_mask;
1615129044dSC.J. Collier	*spec = (struct ibv_exp_flow_spec_eth){
1625129044dSC.J. Collier		.type = IBV_EXP_FLOW_SPEC_ETH,
1635129044dSC.J. Collier		.size = sizeof(*spec),
1645129044dSC.J. Collier		.val = {
1655129044dSC.J. Collier			.dst_mac = {
1665129044dSC.J. Collier				mac[0], mac[1], mac[2],
1675129044dSC.J. Collier				mac[3], mac[4], mac[5],
1685129044dSC.J. Collier			},
1695129044dSC.J. Collier			.vlan_tag = (vlan_enabled ? htons(vlan_id) : 0),
1705129044dSC.J. Collier		},
1715129044dSC.J. Collier		.mask = {
1725129044dSC.J. Collier			.dst_mac = {
1735129044dSC.J. Collier				mask[0], mask[1], mask[2],
1745129044dSC.J. Collier				mask[3], mask[4], mask[5],
1755129044dSC.J. Collier			},
1765129044dSC.J. Collier			.vlan_tag = (vlan_enabled ? htons(0xfff) : 0),
1775129044dSC.J. Collier		},
1785129044dSC.J. Collier	};
1795129044dSC.J. Collier
1805129044dSC.J. Collier	errno = 0;
1815129044dSC.J. Collier	flow = ibv_exp_create_flow(hash_rxq->qp, attr);
1825129044dSC.J. Collier	if (flow == NULL) {
1835129044dSC.J. Collier		/* It's not clear whether errno is always set in this case. */
1845129044dSC.J. Collier		ERROR("%p: flow configuration failed, errno=%d: %s",
1855129044dSC.J. Collier		      (void *)hash_rxq, errno,
1865129044dSC.J. Collier		      (errno ? strerror(errno) : "Unknown error"));
1875129044dSC.J. Collier		if (errno)
1885129044dSC.J. Collier			return errno;
1895129044dSC.J. Collier		return EINVAL;
1905129044dSC.J. Collier	}
1915129044dSC.J. Collier	hash_rxq->special_flow[flow_type][vlan_index] = flow;
1925129044dSC.J. Collier	DEBUG("%p: special flow %s (index %d) VLAN %u (index %u) enabled",
1935129044dSC.J. Collier	      (void *)hash_rxq, hash_rxq_flow_type_str(flow_type), flow_type,
1945129044dSC.J. Collier	      vlan_id, vlan_index);
1955129044dSC.J. Collier	return 0;
1965129044dSC.J. Collier}
1975129044dSC.J. Collier
1985129044dSC.J. Collier/**
1995129044dSC.J. Collier * Disable a special flow in a hash RX queue for a given VLAN index.
2005129044dSC.J. Collier *
2015129044dSC.J. Collier * @param hash_rxq
2025129044dSC.J. Collier *   Pointer to hash RX queue structure.
2035129044dSC.J. Collier * @param flow_type
2045129044dSC.J. Collier *   Special flow type.
2055129044dSC.J. Collier * @param vlan_index
2065129044dSC.J. Collier *   VLAN index to use.
2075129044dSC.J. Collier */
2085129044dSC.J. Collierstatic void
2095129044dSC.J. Collierhash_rxq_special_flow_disable_vlan(struct hash_rxq *hash_rxq,
2105129044dSC.J. Collier				   enum hash_rxq_flow_type flow_type,
2115129044dSC.J. Collier				   unsigned int vlan_index)
2125129044dSC.J. Collier{
2135129044dSC.J. Collier	struct ibv_exp_flow *flow =
2145129044dSC.J. Collier		hash_rxq->special_flow[flow_type][vlan_index];
2155129044dSC.J. Collier
2165129044dSC.J. Collier	if (flow == NULL)
2175129044dSC.J. Collier		return;
2185129044dSC.J. Collier	claim_zero(ibv_exp_destroy_flow(flow));
2195129044dSC.J. Collier	hash_rxq->special_flow[flow_type][vlan_index] = NULL;
2205129044dSC.J. Collier	DEBUG("%p: special flow %s (index %d) VLAN %u (index %u) disabled",
2215129044dSC.J. Collier	      (void *)hash_rxq, hash_rxq_flow_type_str(flow_type), flow_type,
2225129044dSC.J. Collier	      hash_rxq->priv->vlan_filter[vlan_index], vlan_index);
2235129044dSC.J. Collier}
2245129044dSC.J. Collier
2255129044dSC.J. Collier/**
2265129044dSC.J. Collier * Enable a special flow in a hash RX queue.
2275129044dSC.J. Collier *
2285129044dSC.J. Collier * @param hash_rxq
2295129044dSC.J. Collier *   Pointer to hash RX queue structure.
2305129044dSC.J. Collier * @param flow_type
2315129044dSC.J. Collier *   Special flow type.
2325129044dSC.J. Collier * @param vlan_index
2335129044dSC.J. Collier *   VLAN index to use.
2345129044dSC.J. Collier *
2355129044dSC.J. Collier * @return
2365129044dSC.J. Collier *   0 on success, errno value on failure.
2375129044dSC.J. Collier */
2385129044dSC.J. Collierstatic int
2395129044dSC.J. Collierhash_rxq_special_flow_enable(struct hash_rxq *hash_rxq,
2405129044dSC.J. Collier			     enum hash_rxq_flow_type flow_type)
2415129044dSC.J. Collier{
2425129044dSC.J. Collier	struct priv *priv = hash_rxq->priv;
2435129044dSC.J. Collier	unsigned int i = 0;
2445129044dSC.J. Collier	int ret;
2455129044dSC.J. Collier
2465129044dSC.J. Collier	assert((unsigned int)flow_type < RTE_DIM(hash_rxq->special_flow));
2475129044dSC.J. Collier	assert(RTE_DIM(hash_rxq->special_flow[flow_type]) ==
2485129044dSC.J. Collier	       RTE_DIM(priv->vlan_filter));
2495129044dSC.J. Collier	/* Add a special flow for each VLAN filter when relevant. */
2505129044dSC.J. Collier	do {
2515129044dSC.J. Collier		ret = hash_rxq_special_flow_enable_vlan(hash_rxq, flow_type, i);
2525129044dSC.J. Collier		if (ret) {
2535129044dSC.J. Collier			/* Failure, rollback. */
2545129044dSC.J. Collier			while (i != 0)
2555129044dSC.J. Collier				hash_rxq_special_flow_disable_vlan(hash_rxq,
2565129044dSC.J. Collier								   flow_type,
2575129044dSC.J. Collier								   --i);
2585129044dSC.J. Collier			return ret;
2595129044dSC.J. Collier		}
2605129044dSC.J. Collier	} while (special_flow_init[flow_type].per_vlan &&
2615129044dSC.J. Collier		 ++i < priv->vlan_filter_n);
2625129044dSC.J. Collier	return 0;
2635129044dSC.J. Collier}
2645129044dSC.J. Collier
2655129044dSC.J. Collier/**
2665129044dSC.J. Collier * Disable a special flow in a hash RX queue.
2675129044dSC.J. Collier *
2685129044dSC.J. Collier * @param hash_rxq
2695129044dSC.J. Collier *   Pointer to hash RX queue structure.
2705129044dSC.J. Collier * @param flow_type
2715129044dSC.J. Collier *   Special flow type.
2725129044dSC.J. Collier */
2735129044dSC.J. Collierstatic void
2745129044dSC.J. Collierhash_rxq_special_flow_disable(struct hash_rxq *hash_rxq,
2755129044dSC.J. Collier			      enum hash_rxq_flow_type flow_type)
2765129044dSC.J. Collier{
2775129044dSC.J. Collier	unsigned int i;
2785129044dSC.J. Collier
2795129044dSC.J. Collier	assert((unsigned int)flow_type < RTE_DIM(hash_rxq->special_flow));
2805129044dSC.J. Collier	for (i = 0; (i != RTE_DIM(hash_rxq->special_flow[flow_type])); ++i)
2815129044dSC.J. Collier		hash_rxq_special_flow_disable_vlan(hash_rxq, flow_type, i);
2825129044dSC.J. Collier}
2835129044dSC.J. Collier
2845129044dSC.J. Collier/**
2855129044dSC.J. Collier * Enable a special flow in all hash RX queues.
2865129044dSC.J. Collier *
2875129044dSC.J. Collier * @param priv
2885129044dSC.J. Collier *   Private structure.
2895129044dSC.J. Collier * @param flow_type
2905129044dSC.J. Collier *   Special flow type.
2915129044dSC.J. Collier *
2925129044dSC.J. Collier * @return
2935129044dSC.J. Collier *   0 on success, errno value on failure.
2945129044dSC.J. Collier */
2955129044dSC.J. Collierint
2965129044dSC.J. Collierpriv_special_flow_enable(struct priv *priv, enum hash_rxq_flow_type flow_type)
2975129044dSC.J. Collier{
2985129044dSC.J. Collier	unsigned int i;
2995129044dSC.J. Collier
3005129044dSC.J. Collier	if (!priv_allow_flow_type(priv, flow_type))
3015129044dSC.J. Collier		return 0;
3025129044dSC.J. Collier	for (i = 0; (i != priv->hash_rxqs_n); ++i) {
3035129044dSC.J. Collier		struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
3045129044dSC.J. Collier		int ret;
3055129044dSC.J. Collier
3065129044dSC.J. Collier		ret = hash_rxq_special_flow_enable(hash_rxq, flow_type);
3075129044dSC.J. Collier		if (!ret)
3085129044dSC.J. Collier			continue;
3095129044dSC.J. Collier		/* Failure, rollback. */
3105129044dSC.J. Collier		while (i != 0) {
3115129044dSC.J. Collier			hash_rxq = &(*priv->hash_rxqs)[--i];
3125129044dSC.J. Collier			hash_rxq_special_flow_disable(hash_rxq, flow_type);
3135129044dSC.J. Collier		}
3145129044dSC.J. Collier		return ret;
3155129044dSC.J. Collier	}
3165129044dSC.J. Collier	return 0;
3175129044dSC.J. Collier}
3185129044dSC.J. Collier
3195129044dSC.J. Collier/**
3205129044dSC.J. Collier * Disable a special flow in all hash RX queues.
3215129044dSC.J. Collier *
3225129044dSC.J. Collier * @param priv
3235129044dSC.J. Collier *   Private structure.
3245129044dSC.J. Collier * @param flow_type
3255129044dSC.J. Collier *   Special flow type.
3265129044dSC.J. Collier */
3275129044dSC.J. Colliervoid
3285129044dSC.J. Collierpriv_special_flow_disable(struct priv *priv, enum hash_rxq_flow_type flow_type)
3295129044dSC.J. Collier{
3305129044dSC.J. Collier	unsigned int i;
3315129044dSC.J. Collier
3325129044dSC.J. Collier	for (i = 0; (i != priv->hash_rxqs_n); ++i) {
3335129044dSC.J. Collier		struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
3345129044dSC.J. Collier
3355129044dSC.J. Collier		hash_rxq_special_flow_disable(hash_rxq, flow_type);
3365129044dSC.J. Collier	}
3375129044dSC.J. Collier}
3385129044dSC.J. Collier
3395129044dSC.J. Collier/**
3405129044dSC.J. Collier * Enable all special flows in all hash RX queues.
3415129044dSC.J. Collier *
3425129044dSC.J. Collier * @param priv
3435129044dSC.J. Collier *   Private structure.
3445129044dSC.J. Collier */
3455129044dSC.J. Collierint
3465129044dSC.J. Collierpriv_special_flow_enable_all(struct priv *priv)
3475129044dSC.J. Collier{
3485129044dSC.J. Collier	enum hash_rxq_flow_type flow_type;
3495129044dSC.J. Collier
350809f0800SChristian Ehrhardt	for (flow_type = HASH_RXQ_FLOW_TYPE_PROMISC;
351809f0800SChristian Ehrhardt			flow_type != HASH_RXQ_FLOW_TYPE_MAC;
352809f0800SChristian Ehrhardt			++flow_type) {
3535129044dSC.J. Collier		int ret;
3545129044dSC.J. Collier
3555129044dSC.J. Collier		ret = priv_special_flow_enable(priv, flow_type);
3565129044dSC.J. Collier		if (!ret)
3575129044dSC.J. Collier			continue;
3585129044dSC.J. Collier		/* Failure, rollback. */
3595129044dSC.J. Collier		while (flow_type)
3605129044dSC.J. Collier			priv_special_flow_disable(priv, --flow_type);
3615129044dSC.J. Collier		return ret;
3625129044dSC.J. Collier	}
3635129044dSC.J. Collier	return 0;
3645129044dSC.J. Collier}
3655129044dSC.J. Collier
3665129044dSC.J. Collier/**
3675129044dSC.J. Collier * Disable all special flows in all hash RX queues.
3685129044dSC.J. Collier *
3695129044dSC.J. Collier * @param priv
3705129044dSC.J. Collier *   Private structure.
3715129044dSC.J. Collier */
3725129044dSC.J. Colliervoid
3735129044dSC.J. Collierpriv_special_flow_disable_all(struct priv *priv)
3745129044dSC.J. Collier{
3755129044dSC.J. Collier	enum hash_rxq_flow_type flow_type;
3765129044dSC.J. Collier
377809f0800SChristian Ehrhardt	for (flow_type = HASH_RXQ_FLOW_TYPE_PROMISC;
378809f0800SChristian Ehrhardt			flow_type != HASH_RXQ_FLOW_TYPE_MAC;
379809f0800SChristian Ehrhardt			++flow_type)
3805129044dSC.J. Collier		priv_special_flow_disable(priv, flow_type);
3815129044dSC.J. Collier}
3825129044dSC.J. Collier
3835129044dSC.J. Collier/**
3845129044dSC.J. Collier * DPDK callback to enable promiscuous mode.
3855129044dSC.J. Collier *
3865129044dSC.J. Collier * @param dev
3875129044dSC.J. Collier *   Pointer to Ethernet device structure.
3885129044dSC.J. Collier */
3895129044dSC.J. Colliervoid
3905129044dSC.J. Colliermlx5_promiscuous_enable(struct rte_eth_dev *dev)
3915129044dSC.J. Collier{
3925129044dSC.J. Collier	struct priv *priv = dev->data->dev_private;
3935129044dSC.J. Collier	int ret;
3945129044dSC.J. Collier
3955129044dSC.J. Collier	if (mlx5_is_secondary())
3965129044dSC.J. Collier		return;
3975129044dSC.J. Collier
3985129044dSC.J. Collier	priv_lock(priv);
3995129044dSC.J. Collier	priv->promisc_req = 1;
4005129044dSC.J. Collier	ret = priv_rehash_flows(priv);
4015129044dSC.J. Collier	if (ret)
4025129044dSC.J. Collier		ERROR("error while enabling promiscuous mode: %s",
4035129044dSC.J. Collier		      strerror(ret));
4045129044dSC.J. Collier	priv_unlock(priv);
4055129044dSC.J. Collier}
4065129044dSC.J. Collier
4075129044dSC.J. Collier/**
4085129044dSC.J. Collier * DPDK callback to disable promiscuous mode.
4095129044dSC.J. Collier *
4105129044dSC.J. Collier * @param dev
4115129044dSC.J. Collier *   Pointer to Ethernet device structure.
4125129044dSC.J. Collier */
4135129044dSC.J. Colliervoid
4145129044dSC.J. Colliermlx5_promiscuous_disable(struct rte_eth_dev *dev)
4155129044dSC.J. Collier{
4165129044dSC.J. Collier	struct priv *priv = dev->data->dev_private;
4175129044dSC.J. Collier	int ret;
4185129044dSC.J. Collier
4195129044dSC.J. Collier	if (mlx5_is_secondary())
4205129044dSC.J. Collier		return;
4215129044dSC.J. Collier
4225129044dSC.J. Collier	priv_lock(priv);
4235129044dSC.J. Collier	priv->promisc_req = 0;
4245129044dSC.J. Collier	ret = priv_rehash_flows(priv);
4255129044dSC.J. Collier	if (ret)
4265129044dSC.J. Collier		ERROR("error while disabling promiscuous mode: %s",
4275129044dSC.J. Collier		      strerror(ret));
4285129044dSC.J. Collier	priv_unlock(priv);
4295129044dSC.J. Collier}
4305129044dSC.J. Collier
4315129044dSC.J. Collier/**
4325129044dSC.J. Collier * DPDK callback to enable allmulti mode.
4335129044dSC.J. Collier *
4345129044dSC.J. Collier * @param dev
4355129044dSC.J. Collier *   Pointer to Ethernet device structure.
4365129044dSC.J. Collier */
4375129044dSC.J. Colliervoid
4385129044dSC.J. Colliermlx5_allmulticast_enable(struct rte_eth_dev *dev)
4395129044dSC.J. Collier{
4405129044dSC.J. Collier	struct priv *priv = dev->data->dev_private;
4415129044dSC.J. Collier	int ret;
4425129044dSC.J. Collier
4435129044dSC.J. Collier	if (mlx5_is_secondary())
4445129044dSC.J. Collier		return;
4455129044dSC.J. Collier
4465129044dSC.J. Collier	priv_lock(priv);
4475129044dSC.J. Collier	priv->allmulti_req = 1;
4485129044dSC.J. Collier	ret = priv_rehash_flows(priv);
4495129044dSC.J. Collier	if (ret)
4505129044dSC.J. Collier		ERROR("error while enabling allmulticast mode: %s",
4515129044dSC.J. Collier		      strerror(ret));
4525129044dSC.J. Collier	priv_unlock(priv);
4535129044dSC.J. Collier}
4545129044dSC.J. Collier
4555129044dSC.J. Collier/**
4565129044dSC.J. Collier * DPDK callback to disable allmulti mode.
4575129044dSC.J. Collier *
4585129044dSC.J. Collier * @param dev
4595129044dSC.J. Collier *   Pointer to Ethernet device structure.
4605129044dSC.J. Collier */
4615129044dSC.J. Colliervoid
4625129044dSC.J. Colliermlx5_allmulticast_disable(struct rte_eth_dev *dev)
4635129044dSC.J. Collier{
4645129044dSC.J. Collier	struct priv *priv = dev->data->dev_private;
4655129044dSC.J. Collier	int ret;
4665129044dSC.J. Collier
4675129044dSC.J. Collier	if (mlx5_is_secondary())
4685129044dSC.J. Collier		return;
4695129044dSC.J. Collier
4705129044dSC.J. Collier	priv_lock(priv);
4715129044dSC.J. Collier	priv->allmulti_req = 0;
4725129044dSC.J. Collier	ret = priv_rehash_flows(priv);
4735129044dSC.J. Collier	if (ret)
4745129044dSC.J. Collier		ERROR("error while disabling allmulticast mode: %s",
4755129044dSC.J. Collier		      strerror(ret));
4765129044dSC.J. Collier	priv_unlock(priv);
4775129044dSC.J. Collier}
478