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

