11bdbe1afSAdrien Mazarguil /*- 21bdbe1afSAdrien Mazarguil * BSD LICENSE 31bdbe1afSAdrien Mazarguil * 41bdbe1afSAdrien Mazarguil * Copyright 2015 6WIND S.A. 51bdbe1afSAdrien Mazarguil * Copyright 2015 Mellanox. 61bdbe1afSAdrien Mazarguil * 71bdbe1afSAdrien Mazarguil * Redistribution and use in source and binary forms, with or without 81bdbe1afSAdrien Mazarguil * modification, are permitted provided that the following conditions 91bdbe1afSAdrien Mazarguil * are met: 101bdbe1afSAdrien Mazarguil * 111bdbe1afSAdrien Mazarguil * * Redistributions of source code must retain the above copyright 121bdbe1afSAdrien Mazarguil * notice, this list of conditions and the following disclaimer. 131bdbe1afSAdrien Mazarguil * * Redistributions in binary form must reproduce the above copyright 141bdbe1afSAdrien Mazarguil * notice, this list of conditions and the following disclaimer in 151bdbe1afSAdrien Mazarguil * the documentation and/or other materials provided with the 161bdbe1afSAdrien Mazarguil * distribution. 171bdbe1afSAdrien Mazarguil * * Neither the name of 6WIND S.A. nor the names of its 181bdbe1afSAdrien Mazarguil * contributors may be used to endorse or promote products derived 191bdbe1afSAdrien Mazarguil * from this software without specific prior written permission. 201bdbe1afSAdrien Mazarguil * 211bdbe1afSAdrien Mazarguil * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 221bdbe1afSAdrien Mazarguil * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 231bdbe1afSAdrien Mazarguil * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 241bdbe1afSAdrien Mazarguil * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 251bdbe1afSAdrien Mazarguil * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 261bdbe1afSAdrien Mazarguil * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 271bdbe1afSAdrien Mazarguil * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 281bdbe1afSAdrien Mazarguil * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 291bdbe1afSAdrien Mazarguil * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 301bdbe1afSAdrien Mazarguil * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 311bdbe1afSAdrien Mazarguil * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321bdbe1afSAdrien Mazarguil */ 331bdbe1afSAdrien Mazarguil 341bdbe1afSAdrien Mazarguil #include <stddef.h> 351bdbe1afSAdrien Mazarguil #include <errno.h> 361bdbe1afSAdrien Mazarguil #include <string.h> 371bdbe1afSAdrien Mazarguil 381bdbe1afSAdrien Mazarguil /* Verbs header. */ 391bdbe1afSAdrien Mazarguil /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ 401bdbe1afSAdrien Mazarguil #ifdef PEDANTIC 41fc5b160fSBruce Richardson #pragma GCC diagnostic ignored "-Wpedantic" 421bdbe1afSAdrien Mazarguil #endif 431bdbe1afSAdrien Mazarguil #include <infiniband/verbs.h> 441bdbe1afSAdrien Mazarguil #ifdef PEDANTIC 45fc5b160fSBruce Richardson #pragma GCC diagnostic error "-Wpedantic" 461bdbe1afSAdrien Mazarguil #endif 471bdbe1afSAdrien Mazarguil 481bdbe1afSAdrien Mazarguil #include <rte_ethdev.h> 491bdbe1afSAdrien Mazarguil 501bdbe1afSAdrien Mazarguil #include "mlx5.h" 511bdbe1afSAdrien Mazarguil #include "mlx5_rxtx.h" 521bdbe1afSAdrien Mazarguil #include "mlx5_utils.h" 531bdbe1afSAdrien Mazarguil 54083c2dd3SYaacov Hazan /* Initialization data for special flows. */ 55083c2dd3SYaacov Hazan static const struct special_flow_init special_flow_init[] = { 56083c2dd3SYaacov Hazan [HASH_RXQ_FLOW_TYPE_ALLMULTI] = { 57083c2dd3SYaacov Hazan .dst_mac_val = "\x01\x00\x00\x00\x00\x00", 58083c2dd3SYaacov Hazan .dst_mac_mask = "\x01\x00\x00\x00\x00\x00", 59083c2dd3SYaacov Hazan .hash_types = 60083c2dd3SYaacov Hazan 1 << HASH_RXQ_UDPV4 | 61083c2dd3SYaacov Hazan 1 << HASH_RXQ_IPV4 | 62083c2dd3SYaacov Hazan 1 << HASH_RXQ_UDPV6 | 63083c2dd3SYaacov Hazan 1 << HASH_RXQ_IPV6 | 64083c2dd3SYaacov Hazan 1 << HASH_RXQ_ETH | 65083c2dd3SYaacov Hazan 0, 66188b8ccdSAdrien Mazarguil .per_vlan = 0, 67083c2dd3SYaacov Hazan }, 680497ddaaSYaacov Hazan [HASH_RXQ_FLOW_TYPE_BROADCAST] = { 690497ddaaSYaacov Hazan .dst_mac_val = "\xff\xff\xff\xff\xff\xff", 700497ddaaSYaacov Hazan .dst_mac_mask = "\xff\xff\xff\xff\xff\xff", 710497ddaaSYaacov Hazan .hash_types = 720497ddaaSYaacov Hazan 1 << HASH_RXQ_UDPV4 | 730497ddaaSYaacov Hazan 1 << HASH_RXQ_IPV4 | 740497ddaaSYaacov Hazan 1 << HASH_RXQ_UDPV6 | 750497ddaaSYaacov Hazan 1 << HASH_RXQ_IPV6 | 760497ddaaSYaacov Hazan 1 << HASH_RXQ_ETH | 770497ddaaSYaacov Hazan 0, 78188b8ccdSAdrien Mazarguil .per_vlan = 1, 790497ddaaSYaacov Hazan }, 800497ddaaSYaacov Hazan [HASH_RXQ_FLOW_TYPE_IPV6MULTI] = { 810497ddaaSYaacov Hazan .dst_mac_val = "\x33\x33\x00\x00\x00\x00", 820497ddaaSYaacov Hazan .dst_mac_mask = "\xff\xff\x00\x00\x00\x00", 830497ddaaSYaacov Hazan .hash_types = 840497ddaaSYaacov Hazan 1 << HASH_RXQ_UDPV6 | 850497ddaaSYaacov Hazan 1 << HASH_RXQ_IPV6 | 860497ddaaSYaacov Hazan 1 << HASH_RXQ_ETH | 870497ddaaSYaacov Hazan 0, 88188b8ccdSAdrien Mazarguil .per_vlan = 1, 890497ddaaSYaacov Hazan }, 90083c2dd3SYaacov Hazan }; 91ecc1c29dSAdrien Mazarguil 921bdbe1afSAdrien Mazarguil /** 93188b8ccdSAdrien Mazarguil * Enable a special flow in a hash RX queue for a given VLAN index. 941bdbe1afSAdrien Mazarguil * 95ecc1c29dSAdrien Mazarguil * @param hash_rxq 96ecc1c29dSAdrien Mazarguil * Pointer to hash RX queue structure. 97083c2dd3SYaacov Hazan * @param flow_type 98083c2dd3SYaacov Hazan * Special flow type. 99188b8ccdSAdrien Mazarguil * @param vlan_index 100188b8ccdSAdrien Mazarguil * VLAN index to use. 1011bdbe1afSAdrien Mazarguil * 1021bdbe1afSAdrien Mazarguil * @return 1031bdbe1afSAdrien Mazarguil * 0 on success, errno value on failure. 1041bdbe1afSAdrien Mazarguil */ 105ecc1c29dSAdrien Mazarguil static int 106188b8ccdSAdrien Mazarguil hash_rxq_special_flow_enable_vlan(struct hash_rxq *hash_rxq, 107188b8ccdSAdrien Mazarguil enum hash_rxq_flow_type flow_type, 108188b8ccdSAdrien Mazarguil unsigned int vlan_index) 1091bdbe1afSAdrien Mazarguil { 1101a56bdacSYaacov Hazan struct priv *priv = hash_rxq->priv; 11143e9d979SShachar Beiser struct ibv_flow *flow; 1121a56bdacSYaacov Hazan FLOW_ATTR_SPEC_ETH(data, priv_flow_attr(priv, NULL, 0, hash_rxq->type)); 11343e9d979SShachar Beiser struct ibv_flow_attr *attr = &data->attr; 11443e9d979SShachar Beiser struct ibv_flow_spec_eth *spec = &data->spec; 115083c2dd3SYaacov Hazan const uint8_t *mac; 116083c2dd3SYaacov Hazan const uint8_t *mask; 117188b8ccdSAdrien Mazarguil unsigned int vlan_enabled = (priv->vlan_filter_n && 118188b8ccdSAdrien Mazarguil special_flow_init[flow_type].per_vlan); 119188b8ccdSAdrien Mazarguil unsigned int vlan_id = priv->vlan_filter[vlan_index]; 1201bdbe1afSAdrien Mazarguil 121083c2dd3SYaacov Hazan /* Check if flow is relevant for this hash_rxq. */ 122083c2dd3SYaacov Hazan if (!(special_flow_init[flow_type].hash_types & (1 << hash_rxq->type))) 1231bdbe1afSAdrien Mazarguil return 0; 124083c2dd3SYaacov Hazan /* Check if flow already exists. */ 125188b8ccdSAdrien Mazarguil if (hash_rxq->special_flow[flow_type][vlan_index] != NULL) 126083c2dd3SYaacov Hazan return 0; 127083c2dd3SYaacov Hazan 128083c2dd3SYaacov Hazan /* 129083c2dd3SYaacov Hazan * No padding must be inserted by the compiler between attr and spec. 130083c2dd3SYaacov Hazan * This layout is expected by libibverbs. 131083c2dd3SYaacov Hazan */ 132083c2dd3SYaacov Hazan assert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec); 1331a56bdacSYaacov Hazan priv_flow_attr(priv, attr, sizeof(data), hash_rxq->type); 134083c2dd3SYaacov Hazan /* The first specification must be Ethernet. */ 13543e9d979SShachar Beiser assert(spec->type == IBV_FLOW_SPEC_ETH); 136083c2dd3SYaacov Hazan assert(spec->size == sizeof(*spec)); 137083c2dd3SYaacov Hazan 138083c2dd3SYaacov Hazan mac = special_flow_init[flow_type].dst_mac_val; 139083c2dd3SYaacov Hazan mask = special_flow_init[flow_type].dst_mac_mask; 14043e9d979SShachar Beiser *spec = (struct ibv_flow_spec_eth){ 14143e9d979SShachar Beiser .type = IBV_FLOW_SPEC_ETH, 142083c2dd3SYaacov Hazan .size = sizeof(*spec), 143083c2dd3SYaacov Hazan .val = { 144083c2dd3SYaacov Hazan .dst_mac = { 145083c2dd3SYaacov Hazan mac[0], mac[1], mac[2], 146083c2dd3SYaacov Hazan mac[3], mac[4], mac[5], 147083c2dd3SYaacov Hazan }, 1486b30a6a8SShachar Beiser .vlan_tag = (vlan_enabled ? 1496b30a6a8SShachar Beiser rte_cpu_to_be_16(vlan_id) : 1506b30a6a8SShachar Beiser 0), 151083c2dd3SYaacov Hazan }, 152083c2dd3SYaacov Hazan .mask = { 153083c2dd3SYaacov Hazan .dst_mac = { 154083c2dd3SYaacov Hazan mask[0], mask[1], mask[2], 155083c2dd3SYaacov Hazan mask[3], mask[4], mask[5], 156083c2dd3SYaacov Hazan }, 1576b30a6a8SShachar Beiser .vlan_tag = (vlan_enabled ? 1586b30a6a8SShachar Beiser rte_cpu_to_be_16(0xfff) : 1596b30a6a8SShachar Beiser 0), 160083c2dd3SYaacov Hazan }, 161083c2dd3SYaacov Hazan }; 162083c2dd3SYaacov Hazan 1631bdbe1afSAdrien Mazarguil errno = 0; 16443e9d979SShachar Beiser flow = ibv_create_flow(hash_rxq->qp, attr); 1651bdbe1afSAdrien Mazarguil if (flow == NULL) { 1661bdbe1afSAdrien Mazarguil /* It's not clear whether errno is always set in this case. */ 1671bdbe1afSAdrien Mazarguil ERROR("%p: flow configuration failed, errno=%d: %s", 168ecc1c29dSAdrien Mazarguil (void *)hash_rxq, errno, 1691bdbe1afSAdrien Mazarguil (errno ? strerror(errno) : "Unknown error")); 1701bdbe1afSAdrien Mazarguil if (errno) 1711bdbe1afSAdrien Mazarguil return errno; 1721bdbe1afSAdrien Mazarguil return EINVAL; 1731bdbe1afSAdrien Mazarguil } 174188b8ccdSAdrien Mazarguil hash_rxq->special_flow[flow_type][vlan_index] = flow; 175188b8ccdSAdrien Mazarguil DEBUG("%p: special flow %s (index %d) VLAN %u (index %u) enabled", 176188b8ccdSAdrien Mazarguil (void *)hash_rxq, hash_rxq_flow_type_str(flow_type), flow_type, 177188b8ccdSAdrien Mazarguil vlan_id, vlan_index); 178188b8ccdSAdrien Mazarguil return 0; 179188b8ccdSAdrien Mazarguil } 180188b8ccdSAdrien Mazarguil 181188b8ccdSAdrien Mazarguil /** 182188b8ccdSAdrien Mazarguil * Disable a special flow in a hash RX queue for a given VLAN index. 183188b8ccdSAdrien Mazarguil * 184188b8ccdSAdrien Mazarguil * @param hash_rxq 185188b8ccdSAdrien Mazarguil * Pointer to hash RX queue structure. 186188b8ccdSAdrien Mazarguil * @param flow_type 187188b8ccdSAdrien Mazarguil * Special flow type. 188188b8ccdSAdrien Mazarguil * @param vlan_index 189188b8ccdSAdrien Mazarguil * VLAN index to use. 190188b8ccdSAdrien Mazarguil */ 191188b8ccdSAdrien Mazarguil static void 192188b8ccdSAdrien Mazarguil hash_rxq_special_flow_disable_vlan(struct hash_rxq *hash_rxq, 193188b8ccdSAdrien Mazarguil enum hash_rxq_flow_type flow_type, 194188b8ccdSAdrien Mazarguil unsigned int vlan_index) 195188b8ccdSAdrien Mazarguil { 19643e9d979SShachar Beiser struct ibv_flow *flow = 197188b8ccdSAdrien Mazarguil hash_rxq->special_flow[flow_type][vlan_index]; 198188b8ccdSAdrien Mazarguil 199188b8ccdSAdrien Mazarguil if (flow == NULL) 200188b8ccdSAdrien Mazarguil return; 20143e9d979SShachar Beiser claim_zero(ibv_destroy_flow(flow)); 202188b8ccdSAdrien Mazarguil hash_rxq->special_flow[flow_type][vlan_index] = NULL; 203188b8ccdSAdrien Mazarguil DEBUG("%p: special flow %s (index %d) VLAN %u (index %u) disabled", 204188b8ccdSAdrien Mazarguil (void *)hash_rxq, hash_rxq_flow_type_str(flow_type), flow_type, 205188b8ccdSAdrien Mazarguil hash_rxq->priv->vlan_filter[vlan_index], vlan_index); 206188b8ccdSAdrien Mazarguil } 207188b8ccdSAdrien Mazarguil 208188b8ccdSAdrien Mazarguil /** 209188b8ccdSAdrien Mazarguil * Enable a special flow in a hash RX queue. 210188b8ccdSAdrien Mazarguil * 211188b8ccdSAdrien Mazarguil * @param hash_rxq 212188b8ccdSAdrien Mazarguil * Pointer to hash RX queue structure. 213188b8ccdSAdrien Mazarguil * @param flow_type 214188b8ccdSAdrien Mazarguil * Special flow type. 215188b8ccdSAdrien Mazarguil * @param vlan_index 216188b8ccdSAdrien Mazarguil * VLAN index to use. 217188b8ccdSAdrien Mazarguil * 218188b8ccdSAdrien Mazarguil * @return 219188b8ccdSAdrien Mazarguil * 0 on success, errno value on failure. 220188b8ccdSAdrien Mazarguil */ 221188b8ccdSAdrien Mazarguil static int 222188b8ccdSAdrien Mazarguil hash_rxq_special_flow_enable(struct hash_rxq *hash_rxq, 223188b8ccdSAdrien Mazarguil enum hash_rxq_flow_type flow_type) 224188b8ccdSAdrien Mazarguil { 225188b8ccdSAdrien Mazarguil struct priv *priv = hash_rxq->priv; 226188b8ccdSAdrien Mazarguil unsigned int i = 0; 227188b8ccdSAdrien Mazarguil int ret; 228188b8ccdSAdrien Mazarguil 229188b8ccdSAdrien Mazarguil assert((unsigned int)flow_type < RTE_DIM(hash_rxq->special_flow)); 230188b8ccdSAdrien Mazarguil assert(RTE_DIM(hash_rxq->special_flow[flow_type]) == 231188b8ccdSAdrien Mazarguil RTE_DIM(priv->vlan_filter)); 232188b8ccdSAdrien Mazarguil /* Add a special flow for each VLAN filter when relevant. */ 233188b8ccdSAdrien Mazarguil do { 234188b8ccdSAdrien Mazarguil ret = hash_rxq_special_flow_enable_vlan(hash_rxq, flow_type, i); 235188b8ccdSAdrien Mazarguil if (ret) { 236188b8ccdSAdrien Mazarguil /* Failure, rollback. */ 237188b8ccdSAdrien Mazarguil while (i != 0) 238188b8ccdSAdrien Mazarguil hash_rxq_special_flow_disable_vlan(hash_rxq, 239188b8ccdSAdrien Mazarguil flow_type, 240188b8ccdSAdrien Mazarguil --i); 241188b8ccdSAdrien Mazarguil return ret; 242188b8ccdSAdrien Mazarguil } 243188b8ccdSAdrien Mazarguil } while (special_flow_init[flow_type].per_vlan && 244188b8ccdSAdrien Mazarguil ++i < priv->vlan_filter_n); 245ecc1c29dSAdrien Mazarguil return 0; 246ecc1c29dSAdrien Mazarguil } 247ecc1c29dSAdrien Mazarguil 248ecc1c29dSAdrien Mazarguil /** 249083c2dd3SYaacov Hazan * Disable a special flow in a hash RX queue. 250083c2dd3SYaacov Hazan * 251083c2dd3SYaacov Hazan * @param hash_rxq 252083c2dd3SYaacov Hazan * Pointer to hash RX queue structure. 253083c2dd3SYaacov Hazan * @param flow_type 254083c2dd3SYaacov Hazan * Special flow type. 255083c2dd3SYaacov Hazan */ 256083c2dd3SYaacov Hazan static void 257083c2dd3SYaacov Hazan hash_rxq_special_flow_disable(struct hash_rxq *hash_rxq, 258083c2dd3SYaacov Hazan enum hash_rxq_flow_type flow_type) 259083c2dd3SYaacov Hazan { 260188b8ccdSAdrien Mazarguil unsigned int i; 261188b8ccdSAdrien Mazarguil 262188b8ccdSAdrien Mazarguil assert((unsigned int)flow_type < RTE_DIM(hash_rxq->special_flow)); 263188b8ccdSAdrien Mazarguil for (i = 0; (i != RTE_DIM(hash_rxq->special_flow[flow_type])); ++i) 264188b8ccdSAdrien Mazarguil hash_rxq_special_flow_disable_vlan(hash_rxq, flow_type, i); 265083c2dd3SYaacov Hazan } 266083c2dd3SYaacov Hazan 267083c2dd3SYaacov Hazan /** 268083c2dd3SYaacov Hazan * Enable a special flow in all hash RX queues. 269ecc1c29dSAdrien Mazarguil * 270ecc1c29dSAdrien Mazarguil * @param priv 271ecc1c29dSAdrien Mazarguil * Private structure. 272083c2dd3SYaacov Hazan * @param flow_type 273083c2dd3SYaacov Hazan * Special flow type. 274ecc1c29dSAdrien Mazarguil * 275ecc1c29dSAdrien Mazarguil * @return 276ecc1c29dSAdrien Mazarguil * 0 on success, errno value on failure. 277ecc1c29dSAdrien Mazarguil */ 278ecc1c29dSAdrien Mazarguil int 279083c2dd3SYaacov Hazan priv_special_flow_enable(struct priv *priv, enum hash_rxq_flow_type flow_type) 280ecc1c29dSAdrien Mazarguil { 281ecc1c29dSAdrien Mazarguil unsigned int i; 282ecc1c29dSAdrien Mazarguil 283083c2dd3SYaacov Hazan if (!priv_allow_flow_type(priv, flow_type)) 2845b45c208SNelio Laranjeiro return 0; 285ecc1c29dSAdrien Mazarguil for (i = 0; (i != priv->hash_rxqs_n); ++i) { 286ecc1c29dSAdrien Mazarguil struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i]; 287ecc1c29dSAdrien Mazarguil int ret; 288ecc1c29dSAdrien Mazarguil 289083c2dd3SYaacov Hazan ret = hash_rxq_special_flow_enable(hash_rxq, flow_type); 290ecc1c29dSAdrien Mazarguil if (!ret) 291ecc1c29dSAdrien Mazarguil continue; 292ecc1c29dSAdrien Mazarguil /* Failure, rollback. */ 293ecc1c29dSAdrien Mazarguil while (i != 0) { 294ecc1c29dSAdrien Mazarguil hash_rxq = &(*priv->hash_rxqs)[--i]; 295083c2dd3SYaacov Hazan hash_rxq_special_flow_disable(hash_rxq, flow_type); 296ecc1c29dSAdrien Mazarguil } 297ecc1c29dSAdrien Mazarguil return ret; 298ecc1c29dSAdrien Mazarguil } 2991bdbe1afSAdrien Mazarguil return 0; 3001bdbe1afSAdrien Mazarguil } 3011bdbe1afSAdrien Mazarguil 3021bdbe1afSAdrien Mazarguil /** 303083c2dd3SYaacov Hazan * Disable a special flow in all hash RX queues. 304083c2dd3SYaacov Hazan * 305083c2dd3SYaacov Hazan * @param priv 306083c2dd3SYaacov Hazan * Private structure. 307083c2dd3SYaacov Hazan * @param flow_type 308083c2dd3SYaacov Hazan * Special flow type. 309083c2dd3SYaacov Hazan */ 310083c2dd3SYaacov Hazan void 311083c2dd3SYaacov Hazan priv_special_flow_disable(struct priv *priv, enum hash_rxq_flow_type flow_type) 312083c2dd3SYaacov Hazan { 313083c2dd3SYaacov Hazan unsigned int i; 314083c2dd3SYaacov Hazan 315083c2dd3SYaacov Hazan for (i = 0; (i != priv->hash_rxqs_n); ++i) { 316083c2dd3SYaacov Hazan struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i]; 317083c2dd3SYaacov Hazan 318083c2dd3SYaacov Hazan hash_rxq_special_flow_disable(hash_rxq, flow_type); 319083c2dd3SYaacov Hazan } 320083c2dd3SYaacov Hazan } 321083c2dd3SYaacov Hazan 322083c2dd3SYaacov Hazan /** 3230d218674SAdrien Mazarguil * Enable all special flows in all hash RX queues. 3240d218674SAdrien Mazarguil * 3250d218674SAdrien Mazarguil * @param priv 3260d218674SAdrien Mazarguil * Private structure. 3270d218674SAdrien Mazarguil */ 3280d218674SAdrien Mazarguil int 3290d218674SAdrien Mazarguil priv_special_flow_enable_all(struct priv *priv) 3300d218674SAdrien Mazarguil { 3310d218674SAdrien Mazarguil enum hash_rxq_flow_type flow_type; 3320d218674SAdrien Mazarguil 33351d5f8ecSNélio Laranjeiro if (priv->isolated) 33451d5f8ecSNélio Laranjeiro return 0; 335*1b37f5d8SNélio Laranjeiro for (flow_type = HASH_RXQ_FLOW_TYPE_ALLMULTI; 33636351ea3SFerruh Yigit flow_type != HASH_RXQ_FLOW_TYPE_MAC; 33736351ea3SFerruh Yigit ++flow_type) { 3380d218674SAdrien Mazarguil int ret; 3390d218674SAdrien Mazarguil 3400d218674SAdrien Mazarguil ret = priv_special_flow_enable(priv, flow_type); 3410d218674SAdrien Mazarguil if (!ret) 3420d218674SAdrien Mazarguil continue; 3430d218674SAdrien Mazarguil /* Failure, rollback. */ 3440d218674SAdrien Mazarguil while (flow_type) 3450d218674SAdrien Mazarguil priv_special_flow_disable(priv, --flow_type); 3460d218674SAdrien Mazarguil return ret; 3470d218674SAdrien Mazarguil } 3480d218674SAdrien Mazarguil return 0; 3490d218674SAdrien Mazarguil } 3500d218674SAdrien Mazarguil 3510d218674SAdrien Mazarguil /** 3520d218674SAdrien Mazarguil * Disable all special flows in all hash RX queues. 3530d218674SAdrien Mazarguil * 3540d218674SAdrien Mazarguil * @param priv 3550d218674SAdrien Mazarguil * Private structure. 3560d218674SAdrien Mazarguil */ 3570d218674SAdrien Mazarguil void 3580d218674SAdrien Mazarguil priv_special_flow_disable_all(struct priv *priv) 3590d218674SAdrien Mazarguil { 3600d218674SAdrien Mazarguil enum hash_rxq_flow_type flow_type; 3610d218674SAdrien Mazarguil 362*1b37f5d8SNélio Laranjeiro for (flow_type = HASH_RXQ_FLOW_TYPE_ALLMULTI; 36336351ea3SFerruh Yigit flow_type != HASH_RXQ_FLOW_TYPE_MAC; 36436351ea3SFerruh Yigit ++flow_type) 3650d218674SAdrien Mazarguil priv_special_flow_disable(priv, flow_type); 3660d218674SAdrien Mazarguil } 3670d218674SAdrien Mazarguil 3680d218674SAdrien Mazarguil /** 3691bdbe1afSAdrien Mazarguil * DPDK callback to enable promiscuous mode. 3701bdbe1afSAdrien Mazarguil * 3711bdbe1afSAdrien Mazarguil * @param dev 3721bdbe1afSAdrien Mazarguil * Pointer to Ethernet device structure. 3731bdbe1afSAdrien Mazarguil */ 3741bdbe1afSAdrien Mazarguil void 3751bdbe1afSAdrien Mazarguil mlx5_promiscuous_enable(struct rte_eth_dev *dev) 3761bdbe1afSAdrien Mazarguil { 377*1b37f5d8SNélio Laranjeiro struct rte_flow_item_eth eth = { 378*1b37f5d8SNélio Laranjeiro .dst.addr_bytes = "\x00\x00\x00\x00\x00\x00", 379*1b37f5d8SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 380*1b37f5d8SNélio Laranjeiro .type = 0, 381*1b37f5d8SNélio Laranjeiro }; 3821bdbe1afSAdrien Mazarguil 383a48deadaSOr Ami if (mlx5_is_secondary()) 384a48deadaSOr Ami return; 385*1b37f5d8SNélio Laranjeiro dev->data->promiscuous = 1; 386*1b37f5d8SNélio Laranjeiro claim_zero(mlx5_ctrl_flow(dev, ð, ð, 1)); 3871bdbe1afSAdrien Mazarguil } 3881bdbe1afSAdrien Mazarguil 3891bdbe1afSAdrien Mazarguil /** 3901bdbe1afSAdrien Mazarguil * DPDK callback to disable promiscuous mode. 3911bdbe1afSAdrien Mazarguil * 3921bdbe1afSAdrien Mazarguil * @param dev 3931bdbe1afSAdrien Mazarguil * Pointer to Ethernet device structure. 3941bdbe1afSAdrien Mazarguil */ 3951bdbe1afSAdrien Mazarguil void 3961bdbe1afSAdrien Mazarguil mlx5_promiscuous_disable(struct rte_eth_dev *dev) 3971bdbe1afSAdrien Mazarguil { 398*1b37f5d8SNélio Laranjeiro struct rte_flow_item_eth eth = { 399*1b37f5d8SNélio Laranjeiro .dst.addr_bytes = "\x00\x00\x00\x00\x00\x00", 400*1b37f5d8SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 401*1b37f5d8SNélio Laranjeiro .type = 0, 402*1b37f5d8SNélio Laranjeiro }; 4031bdbe1afSAdrien Mazarguil 404a48deadaSOr Ami if (mlx5_is_secondary()) 405a48deadaSOr Ami return; 406*1b37f5d8SNélio Laranjeiro dev->data->promiscuous = 0; 407*1b37f5d8SNélio Laranjeiro claim_zero(mlx5_ctrl_flow(dev, ð, ð, 0)); 4081bdbe1afSAdrien Mazarguil } 4091bdbe1afSAdrien Mazarguil 4101bdbe1afSAdrien Mazarguil /** 4111bdbe1afSAdrien Mazarguil * DPDK callback to enable allmulti mode. 4121bdbe1afSAdrien Mazarguil * 4131bdbe1afSAdrien Mazarguil * @param dev 4141bdbe1afSAdrien Mazarguil * Pointer to Ethernet device structure. 4151bdbe1afSAdrien Mazarguil */ 4161bdbe1afSAdrien Mazarguil void 4171bdbe1afSAdrien Mazarguil mlx5_allmulticast_enable(struct rte_eth_dev *dev) 4181bdbe1afSAdrien Mazarguil { 4191bdbe1afSAdrien Mazarguil struct priv *priv = dev->data->dev_private; 4201bdbe1afSAdrien Mazarguil int ret; 4211bdbe1afSAdrien Mazarguil 422a48deadaSOr Ami if (mlx5_is_secondary()) 423a48deadaSOr Ami return; 424a48deadaSOr Ami 4251bdbe1afSAdrien Mazarguil priv_lock(priv); 4261bdbe1afSAdrien Mazarguil priv->allmulti_req = 1; 427083c2dd3SYaacov Hazan ret = priv_rehash_flows(priv); 428ecc1c29dSAdrien Mazarguil if (ret) 429083c2dd3SYaacov Hazan ERROR("error while enabling allmulticast mode: %s", 430083c2dd3SYaacov Hazan strerror(ret)); 4311bdbe1afSAdrien Mazarguil priv_unlock(priv); 4321bdbe1afSAdrien Mazarguil } 4331bdbe1afSAdrien Mazarguil 4341bdbe1afSAdrien Mazarguil /** 4351bdbe1afSAdrien Mazarguil * DPDK callback to disable allmulti mode. 4361bdbe1afSAdrien Mazarguil * 4371bdbe1afSAdrien Mazarguil * @param dev 4381bdbe1afSAdrien Mazarguil * Pointer to Ethernet device structure. 4391bdbe1afSAdrien Mazarguil */ 4401bdbe1afSAdrien Mazarguil void 4411bdbe1afSAdrien Mazarguil mlx5_allmulticast_disable(struct rte_eth_dev *dev) 4421bdbe1afSAdrien Mazarguil { 4431bdbe1afSAdrien Mazarguil struct priv *priv = dev->data->dev_private; 444083c2dd3SYaacov Hazan int ret; 4451bdbe1afSAdrien Mazarguil 446a48deadaSOr Ami if (mlx5_is_secondary()) 447a48deadaSOr Ami return; 448a48deadaSOr Ami 4491bdbe1afSAdrien Mazarguil priv_lock(priv); 4501bdbe1afSAdrien Mazarguil priv->allmulti_req = 0; 451083c2dd3SYaacov Hazan ret = priv_rehash_flows(priv); 452083c2dd3SYaacov Hazan if (ret) 453083c2dd3SYaacov Hazan ERROR("error while disabling allmulticast mode: %s", 454083c2dd3SYaacov Hazan strerror(ret)); 4551bdbe1afSAdrien Mazarguil priv_unlock(priv); 4561bdbe1afSAdrien Mazarguil } 457