]> git.droids-corp.org - dpdk.git/commitdiff
mlx5: add special flows for broadcast and IPv6 multicast
authorYaacov Hazan <yaacovh@mellanox.com>
Thu, 3 Mar 2016 14:26:41 +0000 (15:26 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 16 Mar 2016 17:52:17 +0000 (18:52 +0100)
Until now, broadcast frames were handled like unicast. Moving the related
flow to the special flows table frees up the related unicast MAC entry.

The same method is used to handle IPv6 multicast frames.

Signed-off-by: Yaacov Hazan <yaacovh@mellanox.com>
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5_defs.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_mac.c
drivers/net/mlx5/mlx5_rxmode.c
drivers/net/mlx5/mlx5_rxq.c
drivers/net/mlx5/mlx5_rxtx.h
drivers/net/mlx5/mlx5_trigger.c

index 52bf4b2a5217dd0e6d4269dd197776fffff79cf3..cf7c4a559e5cc17cd82799c8bdff70bec8ebadf0 100644 (file)
@@ -90,6 +90,8 @@ mlx5_dev_close(struct rte_eth_dev *dev)
        priv_dev_interrupt_handler_uninstall(priv, dev);
        priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_ALLMULTI);
        priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_PROMISC);
+       priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_BROADCAST);
+       priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_IPV6MULTI);
        priv_mac_addrs_disable(priv);
        priv_destroy_hash_rxqs(priv);
        /* Prevent crashes when queues are still in use. */
@@ -416,13 +418,10 @@ mlx5_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                     mac.addr_bytes[0], mac.addr_bytes[1],
                     mac.addr_bytes[2], mac.addr_bytes[3],
                     mac.addr_bytes[4], mac.addr_bytes[5]);
-               /* Register MAC and broadcast addresses. */
+               /* Register MAC address. */
                claim_zero(priv_mac_addr_add(priv, 0,
                                             (const uint8_t (*)[ETHER_ADDR_LEN])
                                             mac.addr_bytes));
-               claim_zero(priv_mac_addr_add(priv, (RTE_DIM(priv->mac) - 1),
-                                            &(const uint8_t [ETHER_ADDR_LEN])
-                                            { "\xff\xff\xff\xff\xff\xff" }));
 #ifndef NDEBUG
                {
                        char ifname[IF_NAMESIZE];
index 1f2a010df23e1ebc8a38ccb06233c6100c28f6ec..a7440e717c82f3c4a0149d3f9c058a83a19ce28d 100644 (file)
@@ -44,7 +44,7 @@
 #define MLX5_MAX_VLAN_IDS 128
 
 /* Maximum number of special flows. */
-#define MLX5_MAX_SPECIAL_FLOWS 2
+#define MLX5_MAX_SPECIAL_FLOWS 4
 
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX5_PMD_TX_PER_COMP_REQ 64
index 1159fa3d451b0a42e6a424f854d98f96cee3bf2e..6704382b821aedf5b539df6a30f35b79c532dd01 100644 (file)
@@ -501,8 +501,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
                max = 65535;
        info->max_rx_queues = max;
        info->max_tx_queues = max;
-       /* Last array entry is reserved for broadcast. */
-       info->max_mac_addrs = (RTE_DIM(priv->mac) - 1);
+       info->max_mac_addrs = RTE_DIM(priv->mac);
        info->rx_offload_capa =
                (priv->hw_csum ?
                 (DEV_RX_OFFLOAD_IPV4_CKSUM |
index b1f34d96ecd26e0e7304914be519136a2bf484e0..a1a7ff503d195d254aa0a09a3635d043af5506dd 100644 (file)
@@ -212,8 +212,7 @@ mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
        priv_lock(priv);
        DEBUG("%p: removing MAC address from index %" PRIu32,
              (void *)dev, index);
-       /* Last array entry is reserved for broadcast. */
-       if (index >= (RTE_DIM(priv->mac) - 1))
+       if (index >= RTE_DIM(priv->mac))
                goto end;
        priv_mac_addr_del(priv, index);
 end:
@@ -479,8 +478,7 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
        priv_lock(priv);
        DEBUG("%p: adding MAC address at index %" PRIu32,
              (void *)dev, index);
-       /* Last array entry is reserved for broadcast. */
-       if (index >= (RTE_DIM(priv->mac) - 1))
+       if (index >= RTE_DIM(priv->mac))
                goto end;
        priv_mac_addr_add(priv, index,
                          (const uint8_t (*)[ETHER_ADDR_LEN])
index b2ed17e09c7f7ee7d875429d5b2cb060d1d684a0..6ee7ce323760e761d3f06b11c60f227fa75a6068 100644 (file)
@@ -88,6 +88,30 @@ static const struct special_flow_init special_flow_init[] = {
                        1 << HASH_RXQ_ETH |
                        0,
        },
+       [HASH_RXQ_FLOW_TYPE_BROADCAST] = {
+               .dst_mac_val = "\xff\xff\xff\xff\xff\xff",
+               .dst_mac_mask = "\xff\xff\xff\xff\xff\xff",
+               .hash_types =
+                       1 << HASH_RXQ_UDPV4 |
+                       1 << HASH_RXQ_IPV4 |
+#ifdef HAVE_FLOW_SPEC_IPV6
+                       1 << HASH_RXQ_UDPV6 |
+                       1 << HASH_RXQ_IPV6 |
+#endif /* HAVE_FLOW_SPEC_IPV6 */
+                       1 << HASH_RXQ_ETH |
+                       0,
+       },
+#ifdef HAVE_FLOW_SPEC_IPV6
+       [HASH_RXQ_FLOW_TYPE_IPV6MULTI] = {
+               .dst_mac_val = "\x33\x33\x00\x00\x00\x00",
+               .dst_mac_mask = "\xff\xff\x00\x00\x00\x00",
+               .hash_types =
+                       1 << HASH_RXQ_UDPV6 |
+                       1 << HASH_RXQ_IPV6 |
+                       1 << HASH_RXQ_ETH |
+                       0,
+       },
+#endif /* HAVE_FLOW_SPEC_IPV6 */
 };
 
 /**
index 166516a4e4511734325ca72381000a683c72318e..fcf192a5d74b9558153fa9dd8d9dd3c88c65bb9e 100644 (file)
@@ -579,8 +579,18 @@ priv_allow_flow_type(struct priv *priv, enum hash_rxq_flow_type type)
                return !!priv->promisc_req;
        case HASH_RXQ_FLOW_TYPE_ALLMULTI:
                return !!priv->allmulti_req;
+       case HASH_RXQ_FLOW_TYPE_BROADCAST:
+#ifdef HAVE_FLOW_SPEC_IPV6
+       case HASH_RXQ_FLOW_TYPE_IPV6MULTI:
+#endif /* HAVE_FLOW_SPEC_IPV6 */
+               /* If allmulti is enabled, broadcast and ipv6multi
+                * are unnecessary. */
+               return !priv->allmulti_req;
        case HASH_RXQ_FLOW_TYPE_MAC:
                return 1;
+       default:
+               /* Unsupported flow type is not allowed. */
+               return 0;
        }
        return 0;
 }
index 983e6a45a86cd238695197fe084d91545be4c32c..d5a5019d86f9286c2d9b40638241f50f8a07c6aa 100644 (file)
@@ -186,6 +186,8 @@ struct special_flow_init {
 enum hash_rxq_flow_type {
        HASH_RXQ_FLOW_TYPE_PROMISC,
        HASH_RXQ_FLOW_TYPE_ALLMULTI,
+       HASH_RXQ_FLOW_TYPE_BROADCAST,
+       HASH_RXQ_FLOW_TYPE_IPV6MULTI,
        HASH_RXQ_FLOW_TYPE_MAC,
 };
 
@@ -198,6 +200,10 @@ hash_rxq_flow_type_str(enum hash_rxq_flow_type flow_type)
                return "promiscuous";
        case HASH_RXQ_FLOW_TYPE_ALLMULTI:
                return "allmulticast";
+       case HASH_RXQ_FLOW_TYPE_BROADCAST:
+               return "broadcast";
+       case HASH_RXQ_FLOW_TYPE_IPV6MULTI:
+               return "IPv6 multicast";
        case HASH_RXQ_FLOW_TYPE_MAC:
                return "MAC";
        }
index d9f7d00d2f5d3f4d0b9077901f3973c6c7ff96b9..90b8068eeb6c328837e22db6a71219e41c222d65 100644 (file)
@@ -80,6 +80,8 @@ mlx5_dev_start(struct rte_eth_dev *dev)
                      " %s",
                      (void *)priv, strerror(err));
                /* Rollback. */
+               priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_IPV6MULTI);
+               priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_BROADCAST);
                priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_ALLMULTI);
                priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_PROMISC);
                priv_mac_addrs_disable(priv);
@@ -109,6 +111,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
                return;
        }
        DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev);
+       priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_IPV6MULTI);
+       priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_BROADCAST);
        priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_ALLMULTI);
        priv_special_flow_disable(priv, HASH_RXQ_FLOW_TYPE_PROMISC);
        priv_mac_addrs_disable(priv);