dpaa2-eth: Update hash key composition code
authorIoana Ciocoi Radulescu <ruxandra.radulescu@nxp.com>
Tue, 16 Apr 2019 17:13:29 +0000 (17:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Apr 2019 04:46:19 +0000 (21:46 -0700)
Introduce an internal id bitfield to uniquely identify header fields
supported by the Rx distribution keys. For the hash key, add a
conversion from the RXH_* bitmask provided by ethtool to the internal
ids.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h

index b04ad06b7e5106213995d18d31bb61b8e14cd319..828bca2f32b6a02b6b786a6b9a962e12838877c0 100644 (file)
@@ -2571,10 +2571,12 @@ static const struct dpaa2_eth_dist_fields dist_fields[] = {
                .rxnfc_field = RXH_L2DA,
                .cls_prot = NET_PROT_ETH,
                .cls_field = NH_FLD_ETH_DA,
+               .id = DPAA2_ETH_DIST_ETHDST,
                .size = 6,
        }, {
                .cls_prot = NET_PROT_ETH,
                .cls_field = NH_FLD_ETH_SA,
+               .id = DPAA2_ETH_DIST_ETHSRC,
                .size = 6,
        }, {
                /* This is the last ethertype field parsed:
@@ -2583,28 +2585,33 @@ static const struct dpaa2_eth_dist_fields dist_fields[] = {
                 */
                .cls_prot = NET_PROT_ETH,
                .cls_field = NH_FLD_ETH_TYPE,
+               .id = DPAA2_ETH_DIST_ETHTYPE,
                .size = 2,
        }, {
                /* VLAN header */
                .rxnfc_field = RXH_VLAN,
                .cls_prot = NET_PROT_VLAN,
                .cls_field = NH_FLD_VLAN_TCI,
+               .id = DPAA2_ETH_DIST_VLAN,
                .size = 2,
        }, {
                /* IP header */
                .rxnfc_field = RXH_IP_SRC,
                .cls_prot = NET_PROT_IP,
                .cls_field = NH_FLD_IP_SRC,
+               .id = DPAA2_ETH_DIST_IPSRC,
                .size = 4,
        }, {
                .rxnfc_field = RXH_IP_DST,
                .cls_prot = NET_PROT_IP,
                .cls_field = NH_FLD_IP_DST,
+               .id = DPAA2_ETH_DIST_IPDST,
                .size = 4,
        }, {
                .rxnfc_field = RXH_L3_PROTO,
                .cls_prot = NET_PROT_IP,
                .cls_field = NH_FLD_IP_PROTO,
+               .id = DPAA2_ETH_DIST_IPPROTO,
                .size = 1,
        }, {
                /* Using UDP ports, this is functionally equivalent to raw
@@ -2613,11 +2620,13 @@ static const struct dpaa2_eth_dist_fields dist_fields[] = {
                .rxnfc_field = RXH_L4_B_0_1,
                .cls_prot = NET_PROT_UDP,
                .cls_field = NH_FLD_UDP_PORT_SRC,
+               .id = DPAA2_ETH_DIST_L4SRC,
                .size = 2,
        }, {
                .rxnfc_field = RXH_L4_B_2_3,
                .cls_prot = NET_PROT_UDP,
                .cls_field = NH_FLD_UDP_PORT_DST,
+               .id = DPAA2_ETH_DIST_L4DST,
                .size = 2,
        },
 };
@@ -2734,7 +2743,7 @@ static int dpaa2_eth_set_dist_key(struct net_device *net_dev,
                 * For Rx flow classification key we set all supported fields
                 */
                if (type == DPAA2_ETH_RX_DIST_HASH) {
-                       if (!(flags & dist_fields[i].rxnfc_field))
+                       if (!(flags & dist_fields[i].id))
                                continue;
                        rx_hash_fields |= dist_fields[i].rxnfc_field;
                }
@@ -2792,11 +2801,17 @@ free_key:
 int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
 {
        struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+       u64 key = 0;
+       int i;
 
        if (!dpaa2_eth_hash_enabled(priv))
                return -EOPNOTSUPP;
 
-       return dpaa2_eth_set_dist_key(net_dev, DPAA2_ETH_RX_DIST_HASH, flags);
+       for (i = 0; i < ARRAY_SIZE(dist_fields); i++)
+               if (dist_fields[i].rxnfc_field & flags)
+                       key |= dist_fields[i].id;
+
+       return dpaa2_eth_set_dist_key(net_dev, DPAA2_ETH_RX_DIST_HASH, key);
 }
 
 static int dpaa2_eth_set_cls(struct dpaa2_eth_priv *priv)
index 958955c1e322f38dcdc2a17116eefa04bc1b388d..ee9197ae28cd9be8c30768093ffa456082868f92 100644 (file)
@@ -342,6 +342,7 @@ struct dpaa2_eth_dist_fields {
        enum net_prot cls_prot;
        int cls_field;
        int size;
+       u64 id;
 };
 
 struct dpaa2_eth_cls_rule {
@@ -455,6 +456,18 @@ enum dpaa2_eth_rx_dist {
        DPAA2_ETH_RX_DIST_CLS
 };
 
+/* Unique IDs for the supported Rx classification header fields */
+#define DPAA2_ETH_DIST_ETHDST          BIT(0)
+#define DPAA2_ETH_DIST_ETHSRC          BIT(1)
+#define DPAA2_ETH_DIST_ETHTYPE         BIT(2)
+#define DPAA2_ETH_DIST_VLAN            BIT(3)
+#define DPAA2_ETH_DIST_IPSRC           BIT(4)
+#define DPAA2_ETH_DIST_IPDST           BIT(5)
+#define DPAA2_ETH_DIST_IPPROTO         BIT(6)
+#define DPAA2_ETH_DIST_L4SRC           BIT(7)
+#define DPAA2_ETH_DIST_L4DST           BIT(8)
+#define DPAA2_ETH_DIST_ALL             (~0U)
+
 static inline
 unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
                                       struct sk_buff *skb)