From: Jun Yang <[email protected]>

When RSS distribution is enabled, hashing on an IP source or destination
address should cover both the outermost and the innermost (last) IP
header so that tunnelled and multi-layer IP traffic is spread correctly.
The key configuration only described a single header index, so only one
IP layer contributed to the hash.

Add dpaa2_flow_dpkg_ip_addr_hdr_expand(), which copies the existing key
extracts and, for every IP source/destination address extract, inserts a
second extract with hdr_index set to LAST_HDR_INDEX. The TC table
configuration now uses this expanded key configuration on the RSS
distribution path, while the exact-match path keeps the original key.

Move dpaa2_flow_is_ip_addr_extract() earlier so the new helper can use
it, and change it to return a boolean since only the match result is
needed.

Also fix LAST_HDR_INDEX, which was defined as 0xFFFFFFFF but is written
into the 8-bit hdr_index field of the MC key extract; use 0xFF so the
"last header" marker is programmed correctly.

Signed-off-by: Jun Yang <[email protected]>
Signed-off-by: Maxime Leroy <[email protected]>
---
 drivers/net/dpaa2/dpaa2_flow.c | 68 ++++++++++++++++++++++++++--------
 drivers/net/dpaa2/mc/fsl_net.h |  4 +-
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.c
index a22af4f33b..dc2e821d75 100644
--- a/drivers/net/dpaa2/dpaa2_flow.c
+++ b/drivers/net/dpaa2/dpaa2_flow.c
@@ -2613,6 +2613,48 @@ dpaa2_flow_fs_table_set_default(struct dpaa2_dev_priv 
*priv,
        return 0;
 }
 
+static int
+dpaa2_flow_is_ip_addr_extract(const struct dpkg_extract *extract)
+{
+       enum dpkg_extract_type type = extract->type;
+       enum net_prot prot = extract->extract.from_hdr.prot;
+       uint32_t field = extract->extract.from_hdr.field;
+
+       if (type == DPKG_EXTRACT_FROM_HDR && prot == NET_PROT_IP &&
+               (field == NH_FLD_IP_SRC || field == NH_FLD_IP_DST))
+               return true;
+
+       return false;
+}
+
+static int
+dpaa2_flow_dpkg_ip_addr_hdr_expand(const struct dpkg_profile_cfg *dpkg,
+       struct dpkg_profile_cfg *rss_dpkg)
+{
+       uint8_t i;
+
+       memset(rss_dpkg, 0, sizeof(struct dpkg_profile_cfg));
+       for (i = 0; i < dpkg->num_extracts; i++) {
+               if ((rss_dpkg->num_extracts + 1) > DPKG_MAX_NUM_OF_EXTRACTS)
+                       return -ENOSPC;
+               rte_memcpy(&rss_dpkg->extracts[rss_dpkg->num_extracts],
+                       &dpkg->extracts[i], sizeof(struct dpkg_extract));
+               
rss_dpkg->extracts[rss_dpkg->num_extracts].extract.from_hdr.hdr_index = 0;
+               rss_dpkg->num_extracts++;
+               if (!dpaa2_flow_is_ip_addr_extract(&dpkg->extracts[i]))
+                       continue;
+               if ((rss_dpkg->num_extracts + 1) > DPKG_MAX_NUM_OF_EXTRACTS)
+                       return -ENOSPC;
+               rte_memcpy(&rss_dpkg->extracts[rss_dpkg->num_extracts], 
&dpkg->extracts[i],
+                       sizeof(struct dpkg_extract));
+               
rss_dpkg->extracts[rss_dpkg->num_extracts].extract.from_hdr.hdr_index =
+                       LAST_HDR_INDEX;
+               rss_dpkg->num_extracts++;
+       }
+
+       return 0;
+}
+
 static int
 dpaa2_flow_tc_table_config(struct dpaa2_dev_priv *priv,
        uint8_t tc_id, int rss_dist, int enable)
@@ -2624,6 +2666,8 @@ dpaa2_flow_tc_table_config(struct dpaa2_dev_priv *priv,
        struct fsl_mc_io *dpni = priv->hw;
        uint16_t entry_size;
        struct dpaa2_queue *queue;
+       const struct dpkg_profile_cfg *cfg;
+       struct dpkg_profile_cfg rss_extract;
 
        tbl_profile = &priv->flow_profile.tc_profile[tc_id];
        if (tbl_profile->entry_num) {
@@ -2645,7 +2689,15 @@ dpaa2_flow_tc_table_config(struct dpaa2_dev_priv *priv,
        }
 
        dpaa2_flow_extracts_log(priv, "Configure", tc_id);
-       ret = dpkg_prepare_key_cfg(&key_profile->dpkg, 
tbl_profile->extract_param);
+       if (rss_dist) {
+               ret = dpaa2_flow_dpkg_ip_addr_hdr_expand(&key_profile->dpkg, 
&rss_extract);
+               if (ret)
+                       return ret;
+               cfg = &rss_extract;
+       } else {
+               cfg = &key_profile->dpkg;
+       }
+       ret = dpkg_prepare_key_cfg(cfg, tbl_profile->extract_param);
        if (ret < 0) {
                DPAA2_PMD_ERR("TC[%d] prepare key failed", tc_id);
                return ret;
@@ -3251,20 +3303,6 @@ dpaa2_flow_validate(struct rte_eth_dev *dev,
        return ret;
 }
 
-static uint32_t
-dpaa2_flow_is_ip_addr_extract(const struct dpkg_extract *extract)
-{
-       enum dpkg_extract_type type = extract->type;
-       enum net_prot prot = extract->extract.from_hdr.prot;
-       uint32_t field = extract->extract.from_hdr.field;
-
-       if (type == DPKG_EXTRACT_FROM_HDR && prot == NET_PROT_IP &&
-               (field == NH_FLD_IP_SRC || field == NH_FLD_IP_DST))
-               return field;
-
-       return 0;
-}
-
 static void
 dpaa2_flow_key_offset_size(struct dpaa2_key_profile *key_profile,
        uint8_t idx, uint8_t *offset, uint8_t *size)
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
index 9ace8f3226..2aae0c99e2 100644
--- a/drivers/net/dpaa2/mc/fsl_net.h
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -1,14 +1,14 @@
 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  *
  * Copyright 2013-2015 Freescale Semiconductor Inc.
- * Copyright 2018-2019 NXP
+ * Copyright 2018-2019, 2026 NXP
  *
  */
 
 #ifndef __FSL_NET_H
 #define __FSL_NET_H
 
-#define LAST_HDR_INDEX 0xFFFFFFFF
+#define LAST_HDR_INDEX 0xFF
 
 /*****************************************************************************/
 /*                Protocol fields                                            */
-- 
2.43.0

Reply via email to