* [PATCH 21.11 01/17] net/hns3: separate Tx prepare from getting Tx function
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 02/17] net/hns3: make getting Tx function static Huisong Li
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 6a934ba4c6c48691b119a878981a4e3748766518 ]
Separate getting tx prepare from hns3_get_tx_function by extracting
an independent function.
Fixes: d7ec2c076579 ("net/hns3: select Tx prepare based on Tx offload")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_rxtx.c | 32 ++++++++++++++------------------
drivers/net/hns3/hns3_rxtx.h | 3 +--
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 5c7de80e7b..18f96f3055 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -4327,26 +4327,30 @@ hns3_get_tx_prep_needed(struct rte_eth_dev *dev)
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO)
uint64_t tx_offload = dev->data->dev_conf.txmode.offloads;
+
if (tx_offload & HNS3_DEV_TX_CSKUM_TSO_OFFLOAD_MASK)
return true;
return false;
}
+static eth_tx_prep_t
+hns3_get_tx_prepare(struct rte_eth_dev *dev)
+{
+ return hns3_get_tx_prep_needed(dev) ? hns3_prep_pkts : NULL;
+}
+
eth_tx_burst_t
-hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep)
+hns3_get_tx_function(struct rte_eth_dev *dev)
{
struct hns3_adapter *hns = dev->data->dev_private;
bool vec_allowed, sve_allowed, simple_allowed;
- bool vec_support, tx_prepare_needed;
+ bool vec_support;
vec_support = hns3_tx_check_vec_support(dev) == 0;
vec_allowed = vec_support && hns3_get_default_vec_support();
sve_allowed = vec_support && hns3_get_sve_support();
simple_allowed = hns3_tx_check_simple_support(dev);
- tx_prepare_needed = hns3_get_tx_prep_needed(dev);
-
- *prep = NULL;
if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed)
return hns3_xmit_pkts_vec;
@@ -4354,19 +4358,14 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep)
return hns3_xmit_pkts_vec_sve;
if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed)
return hns3_xmit_pkts_simple;
- if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON) {
- if (tx_prepare_needed)
- *prep = hns3_prep_pkts;
+ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON)
return hns3_xmit_pkts;
- }
if (vec_allowed)
return hns3_xmit_pkts_vec;
if (simple_allowed)
return hns3_xmit_pkts_simple;
- if (tx_prepare_needed)
- *prep = hns3_prep_pkts;
return hns3_xmit_pkts;
}
@@ -4414,7 +4413,6 @@ hns3_set_rxtx_function(struct rte_eth_dev *eth_dev)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
struct hns3_adapter *hns = eth_dev->data->dev_private;
- eth_tx_prep_t prep = NULL;
if (hns->hw.adapter_state == HNS3_NIC_STARTED &&
__atomic_load_n(&hns->hw.reset.resetting, __ATOMIC_RELAXED) == 0) {
@@ -4422,8 +4420,8 @@ hns3_set_rxtx_function(struct rte_eth_dev *eth_dev)
eth_dev->rx_descriptor_status = hns3_dev_rx_descriptor_status;
eth_dev->tx_pkt_burst = hw->set_link_down ?
hns3_dummy_rxtx_burst :
- hns3_get_tx_function(eth_dev, &prep);
- eth_dev->tx_pkt_prepare = prep;
+ hns3_get_tx_function(eth_dev);
+ eth_dev->tx_pkt_prepare = hns3_get_tx_prepare(eth_dev);
eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status;
} else {
eth_dev->rx_pkt_burst = hns3_dummy_rxtx_burst;
@@ -4769,10 +4767,8 @@ hns3_stop_tx_datapath(struct rte_eth_dev *dev)
void
hns3_start_tx_datapath(struct rte_eth_dev *dev)
{
- eth_tx_prep_t prep = NULL;
-
- dev->tx_pkt_burst = hns3_get_tx_function(dev, &prep);
- dev->tx_pkt_prepare = prep;
+ dev->tx_pkt_burst = hns3_get_tx_function(dev);
+ dev->tx_pkt_prepare = hns3_get_tx_prepare(dev);
hns3_eth_dev_fp_ops_config(dev);
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index 0e412d07b3..b24a0f31bb 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -729,8 +729,7 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev,
const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev);
void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev);
-eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev,
- eth_tx_prep_t *prep);
+eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev);
uint16_t hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused,
struct rte_mbuf **pkts __rte_unused,
uint16_t pkts_n __rte_unused);
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 02/17] net/hns3: make getting Tx function static
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 01/17] net/hns3: separate Tx prepare from getting Tx function Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 03/17] net/hns3: fix RSS key size compatibility Huisong Li
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 2aec7beaba05cd82cd951f0c6bbaecb82d533ce0 ]
The hns3_get_tx_function() is an intrinsic function now and should
not be open to other files.
Fixes: 96c33cfb06cf ("net/hns3: fix Rx/Tx functions update")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_rxtx.c | 2 +-
drivers/net/hns3/hns3_rxtx.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 18f96f3055..f596d435b6 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -4340,7 +4340,7 @@ hns3_get_tx_prepare(struct rte_eth_dev *dev)
return hns3_get_tx_prep_needed(dev) ? hns3_prep_pkts : NULL;
}
-eth_tx_burst_t
+static eth_tx_burst_t
hns3_get_tx_function(struct rte_eth_dev *dev)
{
struct hns3_adapter *hns = dev->data->dev_private;
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index b24a0f31bb..c2876b3a11 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -729,7 +729,6 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev,
const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev);
void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev);
-eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev);
uint16_t hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused,
struct rte_mbuf **pkts __rte_unused,
uint16_t pkts_n __rte_unused);
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 03/17] net/hns3: fix RSS key size compatibility
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 01/17] net/hns3: separate Tx prepare from getting Tx function Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 02/17] net/hns3: make getting Tx function static Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 04/17] net/hns3: fix burst mode query with dummy function Huisong Li
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 5172f9c464aa315a9d45b9177af71b4f99d55cdb ]
For better compatibility, the RSS key size of PF and VF are obtained
from firmware. However, the outdated HNS3_RSS_KEY_SIZE macro is still
utilized in many locations as the key size.
Fixes: 9c740336f024 ("net/hns3: get device specifications from firmware")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_common.c | 12 +++++++++++-
drivers/net/hns3/hns3_flow.c | 26 ++++++++++++--------------
| 25 ++++++++++++-------------
| 5 +++--
4 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c
index 2532c3b770..07e9b3f979 100644
--- a/drivers/net/hns3/hns3_common.c
+++ b/drivers/net/hns3/hns3_common.c
@@ -130,7 +130,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
};
info->reta_size = hw->rss_ind_tbl_size;
- info->hash_key_size = HNS3_RSS_KEY_SIZE;
+ info->hash_key_size = hw->rss_key_size;
info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT;
info->default_rxportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE;
@@ -827,6 +827,16 @@ hns3_check_dev_specifications(struct hns3_hw *hw)
return -EINVAL;
}
+ if (hw->rss_key_size == 0 || hw->rss_key_size > HNS3_RSS_KEY_SIZE_MAX) {
+ hns3_err(hw, "the RSS key size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)",
+ hw->rss_key_size, HNS3_RSS_KEY_SIZE_MAX);
+ return -EINVAL;
+ }
+
+ if (hw->rss_key_size > HNS3_RSS_KEY_SIZE)
+ hns3_warn(hw, "the RSS key size obtained (%u) is greater than the default key size (%u)",
+ hw->rss_key_size, HNS3_RSS_KEY_SIZE);
+
return 0;
}
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 617a6e5a71..97ea4e4de7 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1355,10 +1355,10 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
"a nonzero RSS encapsulation level is not supported");
- if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
+ if (rss->key_len && rss->key_len != hw->rss_key_size)
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "RSS hash key must be exactly 40 bytes");
+ "invalid RSS key length");
if (!hns3_rss_input_tuple_supported(hw, rss))
return rte_flow_error_set(error, EINVAL,
@@ -1390,16 +1390,6 @@ hns3_disable_rss(struct hns3_hw *hw)
return 0;
}
-static void
-hns3_parse_rss_key(struct hns3_hw *hw, struct rte_flow_action_rss *rss_conf)
-{
- if (rss_conf->key == NULL || rss_conf->key_len < HNS3_RSS_KEY_SIZE) {
- hns3_warn(hw, "Default RSS hash key to be set");
- rss_conf->key = hns3_hash_key;
- rss_conf->key_len = HNS3_RSS_KEY_SIZE;
- }
-}
-
static int
hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func,
uint8_t *hash_algo)
@@ -1432,9 +1422,16 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func,
static int
hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
{
+ uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
+ bool use_default_key = false;
int ret;
- hns3_parse_rss_key(hw, rss_config);
+ if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) {
+ hns3_warn(hw, "Default RSS hash key to be set");
+ memcpy(rss_key, hns3_hash_key,
+ RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
+ use_default_key = true;
+ }
ret = hns3_parse_rss_algorithm(hw, &rss_config->func,
&hw->rss_info.hash_algo);
@@ -1442,7 +1439,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
return ret;
ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo,
- rss_config->key, HNS3_RSS_KEY_SIZE);
+ use_default_key ? rss_key : rss_config->key,
+ hw->rss_key_size);
if (ret)
return ret;
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index 67e33a2765..bf031e6ad7 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -10,7 +10,7 @@
#include "hns3_logs.h"
/* Default hash keys */
-const uint8_t hns3_hash_key[] = {
+const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = {
0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
@@ -317,7 +317,7 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
}
}
/* Update the shadow RSS key with user specified */
- memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE);
+ memcpy(hw->rss_info.key, key, hw->rss_key_size);
return 0;
}
@@ -553,9 +553,9 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
uint8_t *key = rss_conf->rss_key;
int ret;
- if (key && key_len != HNS3_RSS_KEY_SIZE) {
+ if (key && key_len != hw->rss_key_size) {
hns3_err(hw, "the hash key len(%u) is invalid, must be %u",
- key_len, HNS3_RSS_KEY_SIZE);
+ key_len, hw->rss_key_size);
return -EINVAL;
}
@@ -566,7 +566,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
if (key) {
ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo,
- key, HNS3_RSS_KEY_SIZE);
+ key, hw->rss_key_size);
if (ret)
goto set_algo_key_fail;
}
@@ -602,9 +602,9 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
rss_conf->rss_hf = rss_cfg->conf.types;
/* Get the RSS Key required by the user */
- if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) {
- memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE);
- rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE;
+ if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
+ memcpy(rss_conf->rss_key, rss_cfg->key, hw->rss_key_size);
+ rss_conf->rss_key_len = hw->rss_key_size;
}
rte_spinlock_unlock(&hw->lock);
@@ -824,8 +824,8 @@ hns3_rss_set_default_args(struct hns3_hw *hw)
/* Default hash algorithm */
rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
- /* Default RSS key */
- memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
+ memcpy(rss_cfg->key, hns3_hash_key,
+ RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
/* Initialize RSS indirection table */
for (i = 0; i < hw->rss_ind_tbl_size; i++)
@@ -858,9 +858,8 @@ hns3_config_rss(struct hns3_adapter *hns)
break;
}
- /* Configure RSS hash algorithm and hash key */
- ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, hash_key,
- HNS3_RSS_KEY_SIZE);
+ ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
+ hash_key, hw->rss_key_size);
if (ret)
return ret;
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index bc5b14e17b..68069d6120 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -28,6 +28,7 @@
#define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */
#define HNS3_RSS_IND_TBL_SIZE_MAX 2048
#define HNS3_RSS_KEY_SIZE 40
+#define HNS3_RSS_KEY_SIZE_MAX 128
#define HNS3_RSS_SET_BITMAP_MSK 0xffff
#define HNS3_RSS_HASH_ALGO_TOEPLITZ 0
@@ -44,7 +45,7 @@ struct hns3_rss_conf {
/* RSS parameters :algorithm, flow_types, key, queue */
struct rte_flow_action_rss conf;
uint8_t hash_algo; /* hash function type defined by hardware */
- uint8_t key[HNS3_RSS_KEY_SIZE]; /* Hash key */
+ uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */
bool valid; /* check if RSS rule is valid */
@@ -90,7 +91,7 @@ static inline uint32_t roundup_pow_of_two(uint32_t x)
return 1UL << fls(x - 1);
}
-extern const uint8_t hns3_hash_key[];
+extern const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE];
struct hns3_adapter;
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 04/17] net/hns3: fix burst mode query with dummy function
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (2 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 03/17] net/hns3: fix RSS key size compatibility Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 05/17] net/hns3: extract common functions to set Rx/Tx Huisong Li
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 10f91af5a5b370df922f888826a4387abebe1cde ]
The rte_eth_rx/tx_burst_mode_get API will fail when Rx/Tx
function is dummy.
Fixes: 7ef933908f04 ("net/hns3: add simple Tx path")
Fixes: 521ab3e93361 ("net/hns3: add simple Rx path")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_rxtx.c | 38 ++++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index f596d435b6..305d8f3744 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2797,6 +2797,7 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
{ hns3_recv_scattered_pkts, "Scalar Scattered" },
{ hns3_recv_pkts_vec, "Vector Neon" },
{ hns3_recv_pkts_vec_sve, "Vector Sve" },
+ { hns3_dummy_rxtx_burst, "Dummy" },
};
eth_rx_burst_t pkt_burst = dev->rx_pkt_burst;
@@ -4283,24 +4284,31 @@ int
hns3_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
struct rte_eth_burst_mode *mode)
{
+ static const struct {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+ } burst_infos[] = {
+ { hns3_xmit_pkts_simple, "Scalar Simple" },
+ { hns3_xmit_pkts, "Scalar" },
+ { hns3_xmit_pkts_vec, "Vector Neon" },
+ { hns3_xmit_pkts_vec_sve, "Vector Sve" },
+ { hns3_dummy_rxtx_burst, "Dummy" },
+ };
+
eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
- const char *info = NULL;
-
- if (pkt_burst == hns3_xmit_pkts_simple)
- info = "Scalar Simple";
- else if (pkt_burst == hns3_xmit_pkts)
- info = "Scalar";
- else if (pkt_burst == hns3_xmit_pkts_vec)
- info = "Vector Neon";
- else if (pkt_burst == hns3_xmit_pkts_vec_sve)
- info = "Vector Sve";
-
- if (info == NULL)
- return -EINVAL;
+ int ret = -EINVAL;
+ unsigned int i;
- snprintf(mode->info, sizeof(mode->info), "%s", info);
+ for (i = 0; i < RTE_DIM(burst_infos); i++) {
+ if (pkt_burst == burst_infos[i].pkt_burst) {
+ snprintf(mode->info, sizeof(mode->info), "%s",
+ burst_infos[i].info);
+ ret = 0;
+ break;
+ }
+ }
- return 0;
+ return ret;
}
static bool
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 05/17] net/hns3: extract common functions to set Rx/Tx
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (3 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 04/17] net/hns3: fix burst mode query with dummy function Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 06/17] net/hns3: use hardware config to report hash key Huisong Li
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 4ba28c957a16bbfe5b2a8d49dfda1c85387d7602 ]
Extract two common functions to set Rx/Tx function in order to
reduce duplicate codes.
Fixes: 23d4b61fee5d ("net/hns3: support multiple process")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_ethdev.c | 20 ++++----------------
drivers/net/hns3/hns3_ethdev_vf.c | 19 ++++---------------
drivers/net/hns3/hns3_mp.c | 4 ++--
drivers/net/hns3/hns3_rxtx.c | 28 ++++++++++++++++++++++++++++
drivers/net/hns3/hns3_rxtx.h | 2 ++
5 files changed, 40 insertions(+), 33 deletions(-)
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index be6a92a313..fd82e98693 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -5077,8 +5077,7 @@ hns3_dev_start(struct rte_eth_dev *dev)
rte_spinlock_unlock(&hw->lock);
hns3_rx_scattered_calc(dev);
- hns3_set_rxtx_function(dev);
- hns3_mp_req_start_rxtx(dev);
+ hns3_start_rxtx_datapath(dev);
/* Enable interrupt of all rx queues before enabling queues */
hns3_dev_all_rx_queue_intr_enable(hw, true);
@@ -5156,12 +5155,7 @@ hns3_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
hw->adapter_state = HNS3_NIC_STOPPING;
- hns3_set_rxtx_function(dev);
- rte_wmb();
- /* Disable datapath on secondary process. */
- hns3_mp_req_stop_rxtx(dev);
- /* Prevent crashes when queues are still in use. */
- rte_delay_ms(hw->cfg_max_queues);
+ hns3_stop_rxtx_datapath(dev);
rte_spinlock_lock(&hw->lock);
if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) {
@@ -5777,12 +5771,7 @@ hns3_stop_service(struct hns3_adapter *hns)
rte_eal_alarm_cancel(hns3_service_handler, eth_dev);
hns3_update_linkstatus_and_event(hw, false);
}
-
- hns3_set_rxtx_function(eth_dev);
- rte_wmb();
- /* Disable datapath on secondary process. */
- hns3_mp_req_stop_rxtx(eth_dev);
- rte_delay_ms(hw->cfg_max_queues);
+ hns3_stop_rxtx_datapath(eth_dev);
rte_spinlock_lock(&hw->lock);
if (hns->hw.adapter_state == HNS3_NIC_STARTED ||
@@ -5815,8 +5804,7 @@ hns3_start_service(struct hns3_adapter *hns)
hw->reset.level == HNS3_GLOBAL_RESET)
hns3_set_rst_done(hw);
eth_dev = &rte_eth_devices[hw->data->port_id];
- hns3_set_rxtx_function(eth_dev);
- hns3_mp_req_start_rxtx(eth_dev);
+ hns3_start_rxtx_datapath(eth_dev);
if (hw->adapter_state == HNS3_NIC_STARTED) {
/*
* This API parent function already hold the hns3_hw.lock, the
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 0e66a82178..729c1477cc 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -1619,12 +1619,7 @@ hns3vf_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
hw->adapter_state = HNS3_NIC_STOPPING;
- hns3_set_rxtx_function(dev);
- rte_wmb();
- /* Disable datapath on secondary process. */
- hns3_mp_req_stop_rxtx(dev);
- /* Prevent crashes when queues are still in use. */
- rte_delay_ms(hw->cfg_max_queues);
+ hns3_stop_rxtx_datapath(dev);
rte_spinlock_lock(&hw->lock);
if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) {
@@ -1778,8 +1773,7 @@ hns3vf_dev_start(struct rte_eth_dev *dev)
rte_spinlock_unlock(&hw->lock);
hns3_rx_scattered_calc(dev);
- hns3_set_rxtx_function(dev);
- hns3_mp_req_start_rxtx(dev);
+ hns3_start_rxtx_datapath(dev);
/* Enable interrupt of all rx queues before enabling queues */
hns3_dev_all_rx_queue_intr_enable(hw, true);
@@ -1949,11 +1943,7 @@ hns3vf_stop_service(struct hns3_adapter *hns)
}
hw->mac.link_status = RTE_ETH_LINK_DOWN;
- hns3_set_rxtx_function(eth_dev);
- rte_wmb();
- /* Disable datapath on secondary process. */
- hns3_mp_req_stop_rxtx(eth_dev);
- rte_delay_ms(hw->cfg_max_queues);
+ hns3_stop_rxtx_datapath(eth_dev);
rte_spinlock_lock(&hw->lock);
if (hw->adapter_state == HNS3_NIC_STARTED ||
@@ -1983,8 +1973,7 @@ hns3vf_start_service(struct hns3_adapter *hns)
struct rte_eth_dev *eth_dev;
eth_dev = &rte_eth_devices[hw->data->port_id];
- hns3_set_rxtx_function(eth_dev);
- hns3_mp_req_start_rxtx(eth_dev);
+ hns3_start_rxtx_datapath(eth_dev);
if (hw->adapter_state == HNS3_NIC_STARTED) {
hns3vf_start_poll_job(eth_dev);
diff --git a/drivers/net/hns3/hns3_mp.c b/drivers/net/hns3/hns3_mp.c
index e74ddea195..c3005b943f 100644
--- a/drivers/net/hns3/hns3_mp.c
+++ b/drivers/net/hns3/hns3_mp.c
@@ -87,12 +87,12 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
case HNS3_MP_REQ_START_RXTX:
PMD_INIT_LOG(INFO, "port %u starting datapath",
dev->data->port_id);
- hns3_set_rxtx_function(dev);
+ hns3_start_rxtx_datapath(dev);
break;
case HNS3_MP_REQ_STOP_RXTX:
PMD_INIT_LOG(INFO, "port %u stopping datapath",
dev->data->port_id);
- hns3_set_rxtx_function(dev);
+ hns3_stop_rxtx_datapath(dev);
break;
case HNS3_MP_REQ_START_TX:
PMD_INIT_LOG(INFO, "port %u starting Tx datapath",
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 305d8f3744..bf091a7500 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -4784,3 +4784,31 @@ hns3_start_tx_datapath(struct rte_eth_dev *dev)
hns3_mp_req_start_tx(dev);
}
+
+void
+hns3_stop_rxtx_datapath(struct rte_eth_dev *dev)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ hns3_set_rxtx_function(dev);
+
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ return;
+
+ rte_wmb();
+ /* Disable datapath on secondary process. */
+ hns3_mp_req_stop_rxtx(dev);
+ /* Prevent crashes when queues are still in use. */
+ rte_delay_ms(hw->cfg_max_queues);
+}
+
+void
+hns3_start_rxtx_datapath(struct rte_eth_dev *dev)
+{
+ hns3_set_rxtx_function(dev);
+
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ return;
+
+ hns3_mp_req_start_rxtx(dev);
+}
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index c2876b3a11..a5260e8850 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -766,5 +766,7 @@ int hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset);
void hns3_tx_push_init(struct rte_eth_dev *dev);
void hns3_stop_tx_datapath(struct rte_eth_dev *dev);
void hns3_start_tx_datapath(struct rte_eth_dev *dev);
+void hns3_stop_rxtx_datapath(struct rte_eth_dev *dev);
+void hns3_start_rxtx_datapath(struct rte_eth_dev *dev);
#endif /* _HNS3_RXTX_H_ */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 06/17] net/hns3: use hardware config to report hash key
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (4 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 05/17] net/hns3: extract common functions to set Rx/Tx Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 07/17] net/hns3: use hardware config to report hash types Huisong Li
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 7da415d27d8872a45a2d0cf9b5e66a8027c8f53c ]
Currently, hns3_dev_rss_hash_conf_get() interface reports RSS key from
the key maintained by driver. It's better to report the key from
hardware, which is more realistic.
Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
| 53 ++++++++++++++++++++++++++++++++++++-
| 3 ++-
2 files changed, 54 insertions(+), 2 deletions(-)
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index bf031e6ad7..7c0ca04400 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -321,6 +321,48 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
return 0;
}
+int
+hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
+ uint8_t *key, uint8_t key_len)
+{
+ struct hns3_rss_generic_config_cmd *req;
+ struct hns3_cmd_desc desc;
+ uint16_t cur_key_size;
+ uint16_t max_bd_num;
+ uint8_t *cur_key;
+ uint16_t idx;
+ int ret;
+
+ req = (struct hns3_rss_generic_config_cmd *)desc.data;
+ max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM);
+ for (idx = 0; idx < max_bd_num; idx++) {
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
+ true);
+
+ req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B);
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret) {
+ hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d",
+ ret);
+ return ret;
+ }
+
+ if (idx == 0)
+ *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK;
+
+ if (idx == max_bd_num - 1 &&
+ (key_len % HNS3_RSS_HASH_KEY_NUM) != 0)
+ cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM;
+ else
+ cur_key_size = HNS3_RSS_HASH_KEY_NUM;
+
+ cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM;
+ memcpy(cur_key, req->hash_key, cur_key_size);
+ }
+
+ return 0;
+}
+
/*
* rss_indirection_table command function, opcode:0x0D07.
* Used to configure the indirection table of rss.
@@ -597,13 +639,22 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
struct hns3_rss_conf *rss_cfg = &hw->rss_info;
+ uint8_t hash_algo;
+ int ret;
rte_spinlock_lock(&hw->lock);
rss_conf->rss_hf = rss_cfg->conf.types;
/* Get the RSS Key required by the user */
if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
- memcpy(rss_conf->rss_key, rss_cfg->key, hw->rss_key_size);
+ ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_conf->rss_key,
+ hw->rss_key_size);
+ if (ret != 0) {
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "obtain hash algo and key failed, ret = %d",
+ ret);
+ return ret;
+ }
rss_conf->rss_key_len = hw->rss_key_size;
}
rte_spinlock_unlock(&hw->lock);
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 68069d6120..598381df84 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -114,6 +114,7 @@ void hns3_rss_uninit(struct hns3_adapter *hns);
int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf);
int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
const uint8_t *key, uint8_t key_len);
-
+int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
+ uint8_t *key, uint8_t key_len);
#endif /* _HNS3_RSS_H_ */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 07/17] net/hns3: use hardware config to report hash types
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (5 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 06/17] net/hns3: use hardware config to report hash key Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 08/17] net/hns3: separate setting hash algorithm Huisong Li
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 406b25c7ffd2d84b1e09665872f69755c75e7d89 ]
Use the configuration in hardware to report hash types instead
of data maintained in software.
Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
| 260 ++++++++++++++++++++++++++++--------
| 1 +
2 files changed, 208 insertions(+), 53 deletions(-)
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index 7c0ca04400..f535161e77 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -70,6 +70,17 @@ enum hns3_tuple_field {
HNS3_RSS_FIELD_IPV6_FRAG_IP_S
};
+#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0)
+#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8)
+#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16)
+#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24)
+#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26)
+#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32)
+#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40)
+#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48)
+#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56)
+#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58)
+
enum hns3_rss_tuple_type {
HNS3_RSS_IP_TUPLE,
HNS3_RSS_IP_L4_TUPLE,
@@ -79,200 +90,249 @@ static const struct {
uint64_t rss_types;
uint16_t tuple_type;
uint64_t rss_field;
+ uint64_t tuple_mask;
} hns3_set_tuple_table[] = {
/* IPV4-FRAG */
{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV4_FLAG_M },
{ RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_FLAG_M },
{ RTE_ETH_RSS_FRAG_IPV4,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_FLAG_M },
/* IPV4 */
{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
{ RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
{ RTE_ETH_RSS_IPV4,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
/* IPV4-OTHER */
{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV4_NONF_M },
/* IPV4-TCP */
{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV4_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV4_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S),
+ HNS3_RSS_TUPLE_IPV4_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
+ HNS3_RSS_TUPLE_IPV4_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_TCP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D),
+ HNS3_RSS_TUPLE_IPV4_TCP_M },
/* IPV4-UDP */
{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV4_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV4_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S),
+ HNS3_RSS_TUPLE_IPV4_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
+ HNS3_RSS_TUPLE_IPV4_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_UDP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D),
+ HNS3_RSS_TUPLE_IPV4_UDP_M },
/* IPV4-SCTP */
{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV4_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV4_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S),
+ HNS3_RSS_TUPLE_IPV4_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D),
+ HNS3_RSS_TUPLE_IPV4_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) |
- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER),
+ HNS3_RSS_TUPLE_IPV4_SCTP_M },
/* IPV6-FRAG */
{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV6_FLAG_M },
{ RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_FLAG_M },
{ RTE_ETH_RSS_FRAG_IPV6,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_FLAG_M },
/* IPV6 */
{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
{ RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
{ RTE_ETH_RSS_IPV6,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
/* IPV6-OTHER */
{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
HNS3_RSS_IP_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D),
+ HNS3_RSS_TUPLE_IPV6_NONF_M },
/* IPV6-TCP */
{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV6_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV6_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S),
+ HNS3_RSS_TUPLE_IPV6_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
+ HNS3_RSS_TUPLE_IPV6_TCP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_TCP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D),
+ HNS3_RSS_TUPLE_IPV6_TCP_M },
/* IPV6-UDP */
{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV6_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV6_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S),
+ HNS3_RSS_TUPLE_IPV6_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
+ HNS3_RSS_TUPLE_IPV6_UDP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_UDP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D),
+ HNS3_RSS_TUPLE_IPV6_UDP_M },
/* IPV6-SCTP */
{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S),
+ HNS3_RSS_TUPLE_IPV6_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D),
+ HNS3_RSS_TUPLE_IPV6_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S),
+ HNS3_RSS_TUPLE_IPV6_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY,
HNS3_RSS_IP_L4_TUPLE,
- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D),
+ HNS3_RSS_TUPLE_IPV6_SCTP_M },
{ RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
HNS3_RSS_IP_L4_TUPLE,
BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) |
- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) },
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER),
+ HNS3_RSS_TUPLE_IPV6_SCTP_M },
};
/*
@@ -623,6 +683,96 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
return ret;
}
+int
+hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields)
+{
+ struct hns3_rss_input_tuple_cmd *req;
+ struct hns3_cmd_desc desc;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true);
+ req = (struct hns3_rss_input_tuple_cmd *)desc.data;
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret != 0) {
+ hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d",
+ ret);
+ return ret;
+ }
+
+ *tuple_fields = rte_le_to_cpu_64(req->tuple_field);
+
+ return 0;
+}
+
+static uint64_t
+hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields)
+{
+ uint64_t ipv6_sctp_l4_mask =
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) |
+ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S);
+ uint64_t rss_hf = 0;
+ uint64_t tuple_mask;
+ uint32_t i;
+
+ for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) {
+ tuple_mask = hns3_set_tuple_table[i].tuple_mask;
+ /*
+ * The RSS hash of the packet type is disabled if its tuples is
+ * zero.
+ */
+ if ((tuple_fields & tuple_mask) == 0)
+ continue;
+
+ /*
+ * Some hardware don't support to use src/dst port fields to
+ * hash for IPV6-SCTP packet.
+ */
+ if ((hns3_set_tuple_table[i].rss_types &
+ RTE_ETH_RSS_NONFRAG_IPV6_SCTP) &&
+ !hw->rss_info.ipv6_sctp_offload_supported)
+ tuple_mask &= ~ipv6_sctp_l4_mask;
+
+ /*
+ * The framework (ethdev ops) or driver (rte flow API) ensure
+ * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set
+ * to driver at the same time. But if user doesn't specify
+ * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields.
+ * In this case, driver should not report L3/L4_SRC/DST_ONLY.
+ */
+ if ((tuple_fields & tuple_mask) == tuple_mask) {
+ /* Skip the item enabled part tuples. */
+ if ((tuple_fields & hns3_set_tuple_table[i].rss_field) !=
+ tuple_mask)
+ continue;
+
+ rss_hf |= hns3_set_tuple_table[i].rss_types;
+ continue;
+ }
+
+ /* Match the item enabled part tuples.*/
+ if ((tuple_fields & hns3_set_tuple_table[i].rss_field) ==
+ hns3_set_tuple_table[i].rss_field)
+ rss_hf |= hns3_set_tuple_table[i].rss_types;
+ }
+
+ return rss_hf;
+}
+
+static int
+hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf)
+{
+ uint64_t tuple_fields;
+ int ret;
+
+ ret = hns3_get_rss_tuple_field(hw, &tuple_fields);
+ if (ret != 0)
+ return ret;
+
+ *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields);
+
+ return 0;
+}
+
/*
* Get rss key and rss_hf types set of RSS hash configuration.
* @param dev
@@ -638,28 +788,32 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
{
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
- struct hns3_rss_conf *rss_cfg = &hw->rss_info;
uint8_t hash_algo;
int ret;
rte_spinlock_lock(&hw->lock);
- rss_conf->rss_hf = rss_cfg->conf.types;
+ ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf);
+ if (ret != 0) {
+ hns3_err(hw, "obtain hash tuples failed, ret = %d", ret);
+ goto out;
+ }
/* Get the RSS Key required by the user */
if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) {
ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_conf->rss_key,
hw->rss_key_size);
if (ret != 0) {
- rte_spinlock_unlock(&hw->lock);
hns3_err(hw, "obtain hash algo and key failed, ret = %d",
ret);
- return ret;
+ goto out;
}
rss_conf->rss_key_len = hw->rss_key_size;
}
+
+out:
rte_spinlock_unlock(&hw->lock);
- return 0;
+ return ret;
}
/*
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 598381df84..cc53f363ae 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -112,6 +112,7 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw);
int hns3_config_rss(struct hns3_adapter *hns);
void hns3_rss_uninit(struct hns3_adapter *hns);
int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf);
+int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields);
int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
const uint8_t *key, uint8_t key_len);
int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 08/17] net/hns3: separate setting hash algorithm
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (6 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 07/17] net/hns3: use hardware config to report hash types Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 09/17] net/hns3: separate setting hash key Huisong Li
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 1fcbef5ccb993b6028a3f8a68a7b01f9b8c67413 ]
Currently, the setting of hash algorithm comes from the
default configuration in driver and the rte_flow interface.
The hash algorithm that is set to hardware in both ways is
saved in hw->rss_info.conf.func.
But the 'func' in struct rte_flow_action_rss is usually used
in rte flow interface. And the ethdev ops interface may also
set hash algorithm in the future. It is not appropriate and
is a little messy for ethdev ops interface and driver default
configuration to use struct rte_flow_action_rss. So we have
to separate the RSS configuration from ethdev ops and rte
flow interface to make codes more easier to maintain.
This patch separates hash algorithm by following ways:
1) 'hash_algo' in struct hns3_rss_conf is used for ethdev ops
interface or default configuration in driver.
2) Add a 'rte_flow_hash_algo' field in struct hns3_rss_conf
to save algorithm from rte flow interface. The main reasons
are as follows:
Currently, only the last rule is used to restore the rte
flow rule. If 'func' in RSS action is 'DEFAULT', it means
that this rule doesn't modify algorithm and driver need to
save current algorithm for restoring algorithm during reset
phase.
Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 60 +++++++++++++++++++++---------------
| 14 +--------
| 1 +
3 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 97ea4e4de7..2ead9b3a48 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1391,30 +1391,40 @@ hns3_disable_rss(struct hns3_hw *hw)
}
static int
-hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func,
+hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func,
uint8_t *hash_algo)
{
- enum rte_eth_hash_function algo_func = *func;
- switch (algo_func) {
- case RTE_ETH_HASH_FUNCTION_DEFAULT:
- /* Keep *hash_algo as what it used to be */
- algo_func = hw->rss_info.conf.func;
- break;
- case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
- *hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
- break;
- case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
- *hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
- break;
- case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
- *hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
- break;
- default:
- hns3_err(hw, "Invalid RSS algorithm configuration(%d)",
- algo_func);
- return -EINVAL;
+ const uint8_t hash_func_map[] = {
+ [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
+ [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
+ [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE,
+ [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP,
+ };
+ uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0};
+ int ret;
+
+ if (func == RTE_ETH_HASH_FUNCTION_DEFAULT) {
+ ret = hns3_rss_get_algo_key(hw, hash_algo, key,
+ hw->rss_key_size);
+ if (ret != 0) {
+ hns3_err(hw, "fail to get current RSS hash algorithm, ret = %d",
+ ret);
+ return ret;
+ }
+
+ /*
+ * During the phase of reset recovery, the hash algorithm
+ * obtained from hardware may not be the one used(saved in
+ * rte_flow_hash_algo) when this rule is delivered.
+ */
+ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) &&
+ *hash_algo != hw->rss_info.rte_flow_hash_algo)
+ *hash_algo = hw->rss_info.rte_flow_hash_algo;
+
+ return 0;
}
- *func = algo_func;
+
+ *hash_algo = hash_func_map[func];
return 0;
}
@@ -1424,6 +1434,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
{
uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
bool use_default_key = false;
+ uint8_t hash_algo;
int ret;
if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) {
@@ -1433,18 +1444,17 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
use_default_key = true;
}
- ret = hns3_parse_rss_algorithm(hw, &rss_config->func,
- &hw->rss_info.hash_algo);
+ ret = hns3_parse_rss_algorithm(hw, rss_config->func, &hash_algo);
if (ret)
return ret;
- ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo,
+ ret = hns3_rss_set_algo_key(hw, hash_algo,
use_default_key ? rss_key : rss_config->key,
hw->rss_key_size);
if (ret)
return ret;
- hw->rss_info.conf.func = rss_config->func;
+ hw->rss_info.rte_flow_hash_algo = hash_algo;
ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_config->types);
if (ret)
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index f535161e77..417082acf2 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -1027,7 +1027,7 @@ hns3_rss_set_default_args(struct hns3_hw *hw)
int i;
/* Default hash algorithm */
- rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+ rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
memcpy(rss_cfg->key, hns3_hash_key,
RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
@@ -1051,18 +1051,6 @@ hns3_config_rss(struct hns3_adapter *hns)
enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
- switch (hw->rss_info.conf.func) {
- case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
- break;
- case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
- break;
- default:
- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
- break;
- }
-
ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo,
hash_key, hw->rss_key_size);
if (ret)
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index cc53f363ae..7f47cc243c 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -45,6 +45,7 @@ struct hns3_rss_conf {
/* RSS parameters :algorithm, flow_types, key, queue */
struct rte_flow_action_rss conf;
uint8_t hash_algo; /* hash function type defined by hardware */
+ uint8_t rte_flow_hash_algo;
uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 09/17] net/hns3: separate setting hash key
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (7 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 08/17] net/hns3: separate setting hash algorithm Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:22 ` [PATCH 21.11 10/17] net/hns3: separate setting RSS types Huisong Li
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit fe9cc8b88babd0911d91dc194b35c7c352e2bf7b ]
The settings of hash key comes from the ethdev ops (like, dev_configure
and rss_hash_update) and rte_flow API. For the ethdev ops, driver has
to save it to rss_info::key in hns3_hw structure so as to it can be
restored when reset is triggered. While rte_flow API no need to use
this field to save, they has a global flow_rss_list to maintain all
rules which save hash key. And hash key can be restored by this rule
information during the reset phase.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
| 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index 417082acf2..bc78bcbb94 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -376,8 +376,7 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
return ret;
}
}
- /* Update the shadow RSS key with user specified */
- memcpy(hw->rss_info.key, key, hw->rss_key_size);
+
return 0;
}
@@ -671,6 +670,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
key, hw->rss_key_size);
if (ret)
goto set_algo_key_fail;
+ /* Update the shadow RSS key with user specified */
+ memcpy(hw->rss_info.key, key, hw->rss_key_size);
}
rte_spinlock_unlock(&hw->lock);
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 10/17] net/hns3: separate setting RSS types
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (8 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 09/17] net/hns3: separate setting hash key Huisong Li
@ 2023-03-21 9:22 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 11/17] net/hns3: use new RSS rule to configure hardware Huisong Li
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:22 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 791e56935e488b8154a83daaf3952e1901ed7552 ]
The settings of RSS types comes from the ethdev ops (like, dev_configure
and rss_hash_update) and rte_flow API. For the ethdev ops, driver has to
save it so as to it can be restored when reset is triggered.
While rte_flow API no need to maintain this field, it can be restored by
the saved rule.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 3 ++-
| 22 ++++++++++++++--------
| 1 +
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 2ead9b3a48..512ad6066d 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1386,6 +1386,7 @@ hns3_disable_rss(struct hns3_hw *hw)
ret = hns3_set_rss_tuple_by_rss_hf(hw, 0);
if (ret)
return ret;
+ hw->rss_info.rss_hf = 0;
return 0;
}
@@ -1534,7 +1535,7 @@ hns3_config_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf)
/* Filter the unsupported flow types */
flow_types = conf->conf.types ?
rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT :
- hw->rss_info.conf.types;
+ hw->rss_info.rss_hf;
if (flow_types != rss_flow_conf.types)
hns3_warn(hw, "modified RSS types based on hardware support,"
" requested:0x%" PRIx64 " configured:0x%" PRIx64,
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index bc78bcbb94..f140a6a2ca 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -628,9 +628,6 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
return ret;
}
- /* Update supported flow types when set tuple success */
- hw->rss_info.conf.types = rss_hf;
-
return 0;
}
@@ -648,7 +645,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint64_t rss_hf_bk = hw->rss_info.conf.types;
+ uint64_t rss_hf_bk = hw->rss_info.rss_hf;
uint8_t key_len = rss_conf->rss_key_len;
uint64_t rss_hf = rss_conf->rss_hf;
uint8_t *key = rss_conf->rss_key;
@@ -673,6 +670,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
/* Update the shadow RSS key with user specified */
memcpy(hw->rss_info.key, key, hw->rss_key_size);
}
+ hw->rss_info.rss_hf = rss_hf;
rte_spinlock_unlock(&hw->lock);
return 0;
@@ -1030,6 +1028,7 @@ hns3_rss_set_default_args(struct hns3_hw *hw)
/* Default hash algorithm */
rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
+ hw->rss_info.rss_hf = 0;
memcpy(rss_cfg->key, hns3_hash_key,
RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
@@ -1067,15 +1066,22 @@ hns3_config_rss(struct hns3_adapter *hns)
return ret;
/*
- * When muli-queue RSS mode flag is not set or unsupported tuples are
+ * When multi-queue RSS mode flag is not set or unsupported tuples are
* set, disable all tuples.
*/
- rss_hf = hw->rss_info.conf.types;
+ rss_hf = hw->rss_info.rss_hf;
if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) ||
!(rss_hf & HNS3_ETH_RSS_SUPPORT))
rss_hf = 0;
- return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
+ ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
+ if (ret != 0) {
+ hns3_err(hw, "set RSS tuples failed, ret = %d.", ret);
+ return ret;
+ }
+ hw->rss_info.rss_hf = rss_hf;
+
+ return 0;
}
/*
@@ -1093,5 +1099,5 @@ hns3_rss_uninit(struct hns3_adapter *hns)
return;
/* Disable RSS */
- hw->rss_info.conf.types = 0;
+ hw->rss_info.rss_hf = 0;
}
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 7f47cc243c..48c535ed3f 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -44,6 +44,7 @@ struct hns3_rss_tuple_cfg {
struct hns3_rss_conf {
/* RSS parameters :algorithm, flow_types, key, queue */
struct rte_flow_action_rss conf;
+ uint64_t rss_hf;
uint8_t hash_algo; /* hash function type defined by hardware */
uint8_t rte_flow_hash_algo;
uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 11/17] net/hns3: use new RSS rule to configure hardware
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (9 preceding siblings ...)
2023-03-21 9:22 ` [PATCH 21.11 10/17] net/hns3: separate setting RSS types Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 12/17] net/hns3: save hash algo to RSS filter list node Huisong Li
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 218a119a08e01f203f92b46334b6b2f03ff9765d ]
Remove redundant assignment and directly use new RSS rule to configure
hardware. Additionally, considering that the new rule configuration may
need to be modified, the 'const' of input parameter about it is removed.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 52 ++++++++++++++----------------------
1 file changed, 20 insertions(+), 32 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 512ad6066d..f51e1439eb 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1435,6 +1435,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
{
uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
bool use_default_key = false;
+ uint64_t flow_types;
uint8_t hash_algo;
int ret;
@@ -1454,10 +1455,18 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
hw->rss_key_size);
if (ret)
return ret;
-
hw->rss_info.rte_flow_hash_algo = hash_algo;
- ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_config->types);
+ /* Filter the unsupported flow types */
+ flow_types = rss_config->types ?
+ rss_config->types & HNS3_ETH_RSS_SUPPORT :
+ hw->rss_info.rss_hf;
+ if (flow_types != rss_config->types)
+ hns3_warn(hw, "modified RSS types based on hardware support,"
+ " requested:0x%" PRIx64 " configured:0x%" PRIx64,
+ rss_config->types, flow_types);
+
+ ret = hns3_set_rss_tuple_by_rss_hf(hw, flow_types);
if (ret)
hns3_err(hw, "Update RSS tuples by rss hf failed %d", ret);
@@ -1503,48 +1512,27 @@ hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf)
}
static int
-hns3_config_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf)
+hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf)
{
- uint64_t flow_types;
+ struct rte_flow_action_rss *rss_act;
uint16_t num;
int ret;
- struct rte_flow_action_rss rss_flow_conf = {
- .func = conf->conf.func,
- .level = conf->conf.level,
- .types = conf->conf.types,
- .key_len = conf->conf.key_len,
- .queue_num = conf->conf.queue_num,
- .key = conf->conf.key_len ?
- (void *)(uintptr_t)conf->conf.key : NULL,
- .queue = conf->conf.queue,
- };
-
+ rss_act = &conf->conf;
/* Set rx queues to use */
- num = RTE_MIN(hw->data->nb_rx_queues, rss_flow_conf.queue_num);
- if (rss_flow_conf.queue_num > num)
+ num = RTE_MIN(hw->data->nb_rx_queues, rss_act->queue_num);
+ if (rss_act->queue_num > num)
hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated",
- rss_flow_conf.queue_num);
+ rss_act->queue_num);
hns3_info(hw, "Max of contiguous %u PF queues are configured", num);
if (num) {
- ret = hns3_update_indir_table(hw, &rss_flow_conf, num);
+ ret = hns3_update_indir_table(hw, rss_act, num);
if (ret)
return ret;
}
- /* Filter the unsupported flow types */
- flow_types = conf->conf.types ?
- rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT :
- hw->rss_info.rss_hf;
- if (flow_types != rss_flow_conf.types)
- hns3_warn(hw, "modified RSS types based on hardware support,"
- " requested:0x%" PRIx64 " configured:0x%" PRIx64,
- rss_flow_conf.types, flow_types);
- /* Update the useful flow types */
- rss_flow_conf.types = flow_types;
-
/* Set hash algorithm and flow types by the user's config */
- return hns3_hw_rss_hash_set(hw, &rss_flow_conf);
+ return hns3_hw_rss_hash_set(hw, rss_act);
}
static int
@@ -1634,7 +1622,7 @@ hns3_rss_action_is_dup(struct hns3_hw *hw,
}
static int
-hns3_flow_parse_rss(struct rte_eth_dev *dev, const struct hns3_rss_conf *conf)
+hns3_flow_parse_rss(struct rte_eth_dev *dev, struct hns3_rss_conf *conf)
{
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 12/17] net/hns3: save hash algo to RSS filter list node
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (10 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 11/17] net/hns3: use new RSS rule to configure hardware Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 13/17] net/hns3: remove unused structures Huisong Li
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 9d34b8a181bf022fe3a3a3ae8511f3d921fc5c67 ]
Save hash algo from rte flow RSS rule to RSS filter list node
instead of struct hns3_rss_conf.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index f51e1439eb..ce5e39b694 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1392,7 +1392,7 @@ hns3_disable_rss(struct hns3_hw *hw)
}
static int
-hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func,
+hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf,
uint8_t *hash_algo)
{
const uint8_t hash_func_map[] = {
@@ -1404,7 +1404,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func,
uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0};
int ret;
- if (func == RTE_ETH_HASH_FUNCTION_DEFAULT) {
+ if (rss_conf->conf.func == RTE_ETH_HASH_FUNCTION_DEFAULT) {
ret = hns3_rss_get_algo_key(hw, hash_algo, key,
hw->rss_key_size);
if (ret != 0) {
@@ -1419,20 +1419,21 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func,
* rte_flow_hash_algo) when this rule is delivered.
*/
if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) &&
- *hash_algo != hw->rss_info.rte_flow_hash_algo)
- *hash_algo = hw->rss_info.rte_flow_hash_algo;
+ *hash_algo != rss_conf->rte_flow_hash_algo)
+ *hash_algo = rss_conf->rte_flow_hash_algo;
return 0;
}
- *hash_algo = hash_func_map[func];
+ *hash_algo = hash_func_map[rss_conf->conf.func];
return 0;
}
static int
-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
+hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf)
{
+ struct rte_flow_action_rss *rss_config = &conf->conf;
uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
bool use_default_key = false;
uint64_t flow_types;
@@ -1446,7 +1447,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
use_default_key = true;
}
- ret = hns3_parse_rss_algorithm(hw, rss_config->func, &hash_algo);
+ ret = hns3_parse_rss_algorithm(hw, conf, &hash_algo);
if (ret)
return ret;
@@ -1455,7 +1456,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
hw->rss_key_size);
if (ret)
return ret;
- hw->rss_info.rte_flow_hash_algo = hash_algo;
+ conf->rte_flow_hash_algo = hash_algo;
/* Filter the unsupported flow types */
flow_types = rss_config->types ?
@@ -1532,7 +1533,7 @@ hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf)
}
/* Set hash algorithm and flow types by the user's config */
- return hns3_hw_rss_hash_set(hw, rss_act);
+ return hns3_hw_rss_hash_set(hw, conf);
}
static int
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 13/17] net/hns3: remove unused structures
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (11 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 12/17] net/hns3: save hash algo to RSS filter list node Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 14/17] net/hns3: allow adding queue buffer size hash rule Huisong Li
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
From: Chengwen Feng <fengchengwen@huawei.com>
[ upstream commit f5a46128fbd84a34e63d05135cf124f12eb414c5 ]
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_cmd.h | 19 -------------------
| 4 ----
2 files changed, 23 deletions(-)
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index c5ca494135..ebe1a657d6 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -56,11 +56,6 @@ enum hns3_cmd_return_status {
HNS3_CMD_ROH_CHECK_FAIL = 12
};
-struct hns3_misc_vector {
- uint8_t *addr;
- int vector_irq;
-};
-
struct hns3_cmq {
struct hns3_cmq_ring csq;
struct hns3_cmq_ring crq;
@@ -394,20 +389,6 @@ struct hns3_pkt_buf_alloc {
struct hns3_shared_buf s_buf;
};
-#define HNS3_RX_COM_WL_EN_B 15
-struct hns3_rx_com_wl_buf_cmd {
- uint16_t high_wl;
- uint16_t low_wl;
- uint8_t rsv[20];
-};
-
-#define HNS3_RX_PKT_EN_B 15
-struct hns3_rx_pkt_buf_cmd {
- uint16_t high_pkt;
- uint16_t low_pkt;
- uint8_t rsv[20];
-};
-
#define HNS3_PF_STATE_DONE_B 0
#define HNS3_PF_STATE_MAIN_B 1
#define HNS3_PF_STATE_BOND_B 2
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 48c535ed3f..63b1d0d944 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -36,10 +36,6 @@
#define HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP 2
#define HNS3_RSS_HASH_ALGO_MASK 0xf
-struct hns3_rss_tuple_cfg {
- uint64_t rss_tuple_fields;
-};
-
#define HNS3_RSS_QUEUES_BUFFER_NUM 64 /* Same as the Max rx/tx queue num */
struct hns3_rss_conf {
/* RSS parameters :algorithm, flow_types, key, queue */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 14/17] net/hns3: allow adding queue buffer size hash rule
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (12 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 13/17] net/hns3: remove unused structures Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 15/17] net/hns3: separate flow RSS config from RSS conf Huisong Li
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit 8095bf3e6d8ca7349e0a15f95407acd2063e7be0 ]
The maximum queue number from RSS flow rule allowed depends on
the maximum queue number (512) under one TC instead of the one
of Rx/Tx queue so as to eliminate restrictions on user usage.
Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
| 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 63b1d0d944..5af2eb21b5 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -36,7 +36,8 @@
#define HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP 2
#define HNS3_RSS_HASH_ALGO_MASK 0xf
-#define HNS3_RSS_QUEUES_BUFFER_NUM 64 /* Same as the Max rx/tx queue num */
+/* Same as the Max queue num under TC */
+#define HNS3_RSS_QUEUES_BUFFER_NUM 512
struct hns3_rss_conf {
/* RSS parameters :algorithm, flow_types, key, queue */
struct rte_flow_action_rss conf;
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 15/17] net/hns3: separate flow RSS config from RSS conf
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (13 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 14/17] net/hns3: allow adding queue buffer size hash rule Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 16/17] net/hns3: reimplement hash flow function Huisong Li
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit b93ad0cc7677881911e5fc3baa89e0a0bbd73c48 ]
Some RSS fields in struct hns3_rss_conf (e.g. conf, queue,
valid) are only used when create RSS flow rule, which is
unnecessary for RSS configuration information from ethdev
ops. This patch removes these fields from hns3_rss_conf
and add a new struct hns3_flow_rss_conf as rte flow
RSS filter list node element.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 23 ++++++++++++-----------
drivers/net/hns3/hns3_flow.h | 10 +++++++++-
| 5 -----
3 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index ce5e39b694..af5d2a5767 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1312,7 +1312,6 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
{
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
- struct hns3_rss_conf *rss_conf = &hw->rss_info;
const struct rte_flow_action_rss *rss;
const struct rte_flow_action *act;
uint32_t act_index = 0;
@@ -1327,7 +1326,7 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
act, "no valid queues");
}
- if (rss->queue_num > RTE_DIM(rss_conf->queue))
+ if (rss->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM)
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
"queue number configured exceeds "
@@ -1392,7 +1391,7 @@ hns3_disable_rss(struct hns3_hw *hw)
}
static int
-hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf,
+hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_flow_rss_conf *rss_conf,
uint8_t *hash_algo)
{
const uint8_t hash_func_map[] = {
@@ -1419,8 +1418,8 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf,
* rte_flow_hash_algo) when this rule is delivered.
*/
if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) &&
- *hash_algo != rss_conf->rte_flow_hash_algo)
- *hash_algo = rss_conf->rte_flow_hash_algo;
+ *hash_algo != rss_conf->hash_algo)
+ *hash_algo = rss_conf->hash_algo;
return 0;
}
@@ -1431,7 +1430,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf,
}
static int
-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf)
+hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf)
{
struct rte_flow_action_rss *rss_config = &conf->conf;
uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
@@ -1456,7 +1455,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf)
hw->rss_key_size);
if (ret)
return ret;
- conf->rte_flow_hash_algo = hash_algo;
+ conf->hash_algo = hash_algo;
/* Filter the unsupported flow types */
flow_types = rss_config->types ?
@@ -1498,7 +1497,8 @@ hns3_update_indir_table(struct hns3_hw *hw,
}
static int
-hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf)
+hns3_reset_rss_filter(struct hns3_hw *hw,
+ const struct hns3_flow_rss_conf *conf)
{
int ret;
@@ -1513,7 +1513,7 @@ hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf)
}
static int
-hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf)
+hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf)
{
struct rte_flow_action_rss *rss_act;
uint16_t num;
@@ -1623,7 +1623,8 @@ hns3_rss_action_is_dup(struct hns3_hw *hw,
}
static int
-hns3_flow_parse_rss(struct rte_eth_dev *dev, struct hns3_rss_conf *conf)
+hns3_flow_parse_rss(struct rte_eth_dev *dev,
+ struct hns3_flow_rss_conf *conf)
{
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
@@ -1693,8 +1694,8 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev,
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
const struct rte_flow_action_rss *rss_act;
struct hns3_rss_conf_ele *rss_filter_ptr;
+ struct hns3_flow_rss_conf *new_conf;
struct hns3_rss_conf_ele *filter_ptr;
- struct hns3_rss_conf *new_conf;
int ret;
rss_filter_ptr = rte_zmalloc("hns3 rss filter",
diff --git a/drivers/net/hns3/hns3_flow.h b/drivers/net/hns3/hns3_flow.h
index e90d2211e4..e6a8a425d8 100644
--- a/drivers/net/hns3/hns3_flow.h
+++ b/drivers/net/hns3/hns3_flow.h
@@ -21,10 +21,18 @@ struct rte_flow {
uint32_t counter_id;
};
+struct hns3_flow_rss_conf {
+ struct rte_flow_action_rss conf;
+ uint8_t hash_algo;
+ uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
+ uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */
+ bool valid; /* check if RSS rule is valid */
+};
+
/* rss filter list structure */
struct hns3_rss_conf_ele {
TAILQ_ENTRY(hns3_rss_conf_ele) entries;
- struct hns3_rss_conf filter_info;
+ struct hns3_flow_rss_conf filter_info;
};
/* hns3_flow memory list structure */
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 5af2eb21b5..07f6db2652 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -39,15 +39,10 @@
/* Same as the Max queue num under TC */
#define HNS3_RSS_QUEUES_BUFFER_NUM 512
struct hns3_rss_conf {
- /* RSS parameters :algorithm, flow_types, key, queue */
- struct rte_flow_action_rss conf;
uint64_t rss_hf;
uint8_t hash_algo; /* hash function type defined by hardware */
- uint8_t rte_flow_hash_algo;
uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
- uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */
- bool valid; /* check if RSS rule is valid */
/*
* For IPv6 SCTP packets type, check whether the NIC hardware support
* RSS hash using the src/dst port as the input tuple. For Kunpeng920
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 16/17] net/hns3: reimplement hash flow function
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (14 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 15/17] net/hns3: separate flow RSS config from RSS conf Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 9:23 ` [PATCH 21.11 17/17] net/hns3: add verification of RSS types Huisong Li
2023-03-21 16:21 ` [PATCH 21.11 00/17] backport some patches for hns3 Kevin Traynor
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit e3069658da9ffb6f83a0d972ff2776c405eb6a8f ]
Currently, hns3 driver supports setting multiple rte flow RSS rule,
but only the last is valid. This implementation is different from
the mainstream usage of rte flow hash in the community. Please see
the discussion threads [1] and [2].
This patch sets RSS hash feature completely based on the request of
the flow rule so that multiple hash rules can take effect at the same
time. Please notice that:
1. For hns3, 'func' has only one hardware. 'key' and 'queue' have only
one entry in hardware.
2. the overlapping part of the old rule will be overridden if the
configuration items of a new rule overlap with those of an old rule.
The hns3_flow_validate() verifies and parses RSS or Fdir rules from
user, and saves them to a local variable at the same time. The local
variable is directly used to create RSS or Fdir rules. In this way,
we save one parsing and saving process.
[1] https://lore.kernel.org/all/DM5PR12MB46648085D7CABF1AFF2D75CDD60A9@DM5PR12MB4664.namprd12.prod.outlook.com/
[2] https://lore.kernel.org/all/f7de4db4-1b88-622f-4e03-acd3eee8a72c@oktetlabs.ru/
Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_ethdev.h | 9 -
drivers/net/hns3/hns3_flow.c | 965 +++++++++++++++++++++++----------
drivers/net/hns3/hns3_flow.h | 17 +-
| 144 ++---
| 117 +++-
5 files changed, 856 insertions(+), 396 deletions(-)
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index d188cd17d6..0881d26516 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -1001,15 +1001,6 @@ static inline uint32_t hns3_read_reg(void *base, uint32_t reg)
#define hns3_read_dev(a, reg) \
hns3_read_reg((a)->io_base, (reg))
-#define NEXT_ITEM_OF_ACTION(act, actions, index) \
- do { \
- act = (actions) + (index); \
- while (act->type == RTE_FLOW_ACTION_TYPE_VOID) { \
- (index)++; \
- act = actions + index; \
- } \
- } while (0)
-
static inline uint64_t
hns3_atomic_test_bit(unsigned int nr, volatile uint64_t *addr)
{
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index af5d2a5767..ff7a8a6dc0 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -10,6 +10,125 @@
#include "hns3_logs.h"
#include "hns3_flow.h"
+#define NEXT_ITEM_OF_ACTION(act, actions, index) \
+ do { \
+ (act) = (actions) + (index); \
+ while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \
+ (index)++; \
+ (act) = (actions) + (index); \
+ } \
+ } while (0)
+
+#define NEXT_ITEM_OF_PATTERN(item, pattern, index) \
+ do { \
+ (item) = (pattern) + (index); \
+ while ((item)->type == RTE_FLOW_ITEM_TYPE_VOID) { \
+ (index)++; \
+ (item) = (pattern) + (index); \
+ } \
+ } while (0)
+
+#define HNS3_HASH_HDR_ETH RTE_BIT64(0)
+#define HNS3_HASH_HDR_IPV4 RTE_BIT64(1)
+#define HNS3_HASH_HDR_IPV6 RTE_BIT64(2)
+#define HNS3_HASH_HDR_TCP RTE_BIT64(3)
+#define HNS3_HASH_HDR_UDP RTE_BIT64(4)
+#define HNS3_HASH_HDR_SCTP RTE_BIT64(5)
+
+#define HNS3_HASH_VOID_NEXT_ALLOW BIT_ULL(RTE_FLOW_ITEM_TYPE_ETH)
+
+#define HNS3_HASH_ETH_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \
+ BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6))
+
+#define HNS3_HASH_IP_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_TCP) | \
+ BIT_ULL(RTE_FLOW_ITEM_TYPE_UDP) | \
+ BIT_ULL(RTE_FLOW_ITEM_TYPE_SCTP))
+
+static const uint64_t hash_pattern_next_allow_items[] = {
+ [RTE_FLOW_ITEM_TYPE_VOID] = HNS3_HASH_VOID_NEXT_ALLOW,
+ [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_ETH_NEXT_ALLOW,
+ [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_IP_NEXT_ALLOW,
+ [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_IP_NEXT_ALLOW,
+};
+
+static const uint64_t hash_pattern_item_header[] = {
+ [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_HDR_ETH,
+ [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_HDR_IPV4,
+ [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_HDR_IPV6,
+ [RTE_FLOW_ITEM_TYPE_TCP] = HNS3_HASH_HDR_TCP,
+ [RTE_FLOW_ITEM_TYPE_UDP] = HNS3_HASH_HDR_UDP,
+ [RTE_FLOW_ITEM_TYPE_SCTP] = HNS3_HASH_HDR_SCTP,
+};
+
+#define HNS3_HASH_IPV4 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV4)
+#define HNS3_HASH_IPV4_TCP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV4 | \
+ HNS3_HASH_HDR_TCP)
+#define HNS3_HASH_IPV4_UDP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV4 | \
+ HNS3_HASH_HDR_UDP)
+#define HNS3_HASH_IPV4_SCTP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV4 | \
+ HNS3_HASH_HDR_SCTP)
+#define HNS3_HASH_IPV6 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV6)
+#define HNS3_HASH_IPV6_TCP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV6 | \
+ HNS3_HASH_HDR_TCP)
+#define HNS3_HASH_IPV6_UDP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV6 | \
+ HNS3_HASH_HDR_UDP)
+#define HNS3_HASH_IPV6_SCTP (HNS3_HASH_HDR_ETH | \
+ HNS3_HASH_HDR_IPV6 | \
+ HNS3_HASH_HDR_SCTP)
+
+static const struct hns3_hash_map_info {
+ /* flow type specified, zero means action works for all flow types. */
+ uint64_t pattern_type;
+ uint64_t rss_pctype; /* packet type with prefix RTE_ETH_RSS_xxx */
+ uint64_t l3l4_types; /* Supported L3/L4 RSS types for this packet type */
+ uint64_t hw_pctype; /* packet type in driver */
+ uint64_t tuple_mask; /* full tuples of the hw_pctype */
+} hash_map_table[] = {
+ /* IPV4 */
+ { HNS3_HASH_IPV4,
+ RTE_ETH_RSS_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M },
+ { HNS3_HASH_IPV4,
+ RTE_ETH_RSS_NONFRAG_IPV4_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M },
+ { HNS3_HASH_IPV4,
+ RTE_ETH_RSS_FRAG_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV4_FLAG, HNS3_RSS_TUPLE_IPV4_FLAG_M },
+ { HNS3_HASH_IPV4_TCP,
+ RTE_ETH_RSS_NONFRAG_IPV4_TCP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV4_TCP, HNS3_RSS_TUPLE_IPV4_TCP_M },
+ { HNS3_HASH_IPV4_UDP,
+ RTE_ETH_RSS_NONFRAG_IPV4_UDP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV4_UDP, HNS3_RSS_TUPLE_IPV4_UDP_M },
+ { HNS3_HASH_IPV4_SCTP,
+ RTE_ETH_RSS_NONFRAG_IPV4_SCTP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV4_SCTP, HNS3_RSS_TUPLE_IPV4_SCTP_M },
+ /* IPV6 */
+ { HNS3_HASH_IPV6,
+ RTE_ETH_RSS_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M },
+ { HNS3_HASH_IPV6,
+ RTE_ETH_RSS_NONFRAG_IPV6_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M },
+ { HNS3_HASH_IPV6,
+ RTE_ETH_RSS_FRAG_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST,
+ HNS3_RSS_PCTYPE_IPV6_FLAG, HNS3_RSS_TUPLE_IPV6_FLAG_M },
+ { HNS3_HASH_IPV6_TCP,
+ RTE_ETH_RSS_NONFRAG_IPV6_TCP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV6_TCP, HNS3_RSS_TUPLE_IPV6_TCP_M },
+ { HNS3_HASH_IPV6_UDP,
+ RTE_ETH_RSS_NONFRAG_IPV6_UDP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV6_UDP, HNS3_RSS_TUPLE_IPV6_UDP_M },
+ { HNS3_HASH_IPV6_SCTP,
+ RTE_ETH_RSS_NONFRAG_IPV6_SCTP, HNS3_RSS_SUPPORT_L3L4,
+ HNS3_RSS_PCTYPE_IPV6_SCTP, HNS3_RSS_TUPLE_IPV6_SCTP_M },
+};
+
static const uint8_t full_mask[VNI_OR_TNI_LEN] = { 0xFF, 0xFF, 0xFF };
static const uint8_t zero_mask[VNI_OR_TNI_LEN] = { 0x00, 0x00, 0x00 };
@@ -79,7 +198,7 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len)
}
/*
- * This function is used to find rss general action.
+ * This function is used to parse filter type.
* 1. As we know RSS is used to spread packets among several queues, the flow
* API provide the struct rte_flow_action_rss, user could config its field
* sush as: func/level/types/key/queue to control RSS function.
@@ -87,16 +206,18 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len)
* implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule
* which action is RSS queues region.
* 3. When action is RSS, we use the following rule to distinguish:
- * Case 1: pattern have ETH and action's queue_num > 0, indicate it is queue
- * region configuration.
+ * Case 1: pattern has ETH and all fields in RSS action except 'queues' are
+ * zero or default, indicate it is queue region configuration.
* Case other: an rss general action.
*/
-static const struct rte_flow_action *
-hns3_find_rss_general_action(const struct rte_flow_item pattern[],
- const struct rte_flow_action actions[])
+static void
+hns3_parse_filter_type(const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct hns3_filter_info *filter_info)
{
const struct rte_flow_action_rss *rss_act;
const struct rte_flow_action *act = NULL;
+ bool only_has_queues = false;
bool have_eth = false;
for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
@@ -105,8 +226,10 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[],
break;
}
}
- if (!act)
- return NULL;
+ if (act == NULL) {
+ filter_info->type = RTE_ETH_FILTER_FDIR;
+ return;
+ }
for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
if (pattern->type == RTE_FLOW_ITEM_TYPE_ETH) {
@@ -116,18 +239,20 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[],
}
rss_act = act->conf;
- if (have_eth && rss_act->queue_num) {
+ only_has_queues = (rss_act->queue_num > 0) &&
+ (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT &&
+ rss_act->types == 0 && rss_act->key_len == 0);
+ if (have_eth && only_has_queues) {
/*
- * Pattern have ETH and action's queue_num > 0, indicate this is
- * queue region configuration.
- * Because queue region is implemented by FDIR + RSS in hns3
- * hardware, it needs to enter FDIR process, so here return NULL
- * to avoid enter RSS process.
+ * Pattern has ETH and all fields in RSS action except 'queues'
+ * are zero or default, which indicates this is queue region
+ * configuration.
*/
- return NULL;
+ filter_info->type = RTE_ETH_FILTER_FDIR;
+ return;
}
- return act;
+ filter_info->type = RTE_ETH_FILTER_HASH;
}
static inline struct hns3_flow_counter *
@@ -1199,7 +1324,6 @@ hns3_filterlist_flush(struct rte_eth_dev *dev)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct hns3_fdir_rule_ele *fdir_rule_ptr;
- struct hns3_rss_conf_ele *rss_filter_ptr;
struct hns3_flow_mem *flow_node;
fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list);
@@ -1209,13 +1333,6 @@ hns3_filterlist_flush(struct rte_eth_dev *dev)
fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list);
}
- rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
- while (rss_filter_ptr) {
- TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries);
- rte_free(rss_filter_ptr);
- rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
- }
-
flow_node = TAILQ_FIRST(&hw->flow_list);
while (flow_node) {
TAILQ_REMOVE(&hw->flow_list, flow_node, entries);
@@ -1281,196 +1398,422 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp,
}
static bool
-hns3_rss_input_tuple_supported(struct hns3_hw *hw,
- const struct rte_flow_action_rss *rss)
+hns3_valid_ipv6_sctp_rss_types(struct hns3_hw *hw, uint64_t types)
{
/*
- * For IP packet, it is not supported to use src/dst port fields to RSS
- * hash for the following packet types.
- * - IPV4 FRAG | IPV4 NONFRAG | IPV6 FRAG | IPV6 NONFRAG
- * Besides, for Kunpeng920, the NIC HW is not supported to use src/dst
- * port fields to RSS hash for IPV6 SCTP packet type. However, the
- * Kunpeng930 and future kunpeng series support to use src/dst port
- * fields to RSS hash for IPv6 SCTP packet type.
+ * Some hardware don't support to use src/dst port fields to hash
+ * for IPV6 SCTP packet type.
*/
- if (rss->types & (RTE_ETH_RSS_L4_DST_ONLY | RTE_ETH_RSS_L4_SRC_ONLY) &&
- (rss->types & RTE_ETH_RSS_IP ||
- (!hw->rss_info.ipv6_sctp_offload_supported &&
- rss->types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
+ if (types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP &&
+ types & HNS3_RSS_SUPPORT_L4_SRC_DST &&
+ !hw->rss_info.ipv6_sctp_offload_supported)
return false;
return true;
}
-/*
- * This function is used to parse rss action validation.
- */
static int
-hns3_parse_rss_filter(struct rte_eth_dev *dev,
- const struct rte_flow_action *actions,
- struct rte_flow_error *error)
+hns3_flow_parse_hash_func(const struct rte_flow_action_rss *rss_act,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
{
- struct hns3_adapter *hns = dev->data->dev_private;
- struct hns3_hw *hw = &hns->hw;
- const struct rte_flow_action_rss *rss;
- const struct rte_flow_action *act;
- uint32_t act_index = 0;
- uint16_t n;
+ if (rss_act->func >= RTE_ETH_HASH_FUNCTION_MAX)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL, "RSS hash func are not supported");
- NEXT_ITEM_OF_ACTION(act, actions, act_index);
- rss = act->conf;
+ rss_conf->conf.func = rss_act->func;
+ return 0;
+}
- if (rss == NULL) {
+static int
+hns3_flow_parse_hash_key(struct hns3_hw *hw,
+ const struct rte_flow_action_rss *rss_act,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ if (rss_act->key_len != hw->rss_key_size)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION_CONF,
- act, "no valid queues");
- }
+ NULL, "invalid RSS key length");
+
+ if (rss_act->key != NULL)
+ memcpy(rss_conf->key, rss_act->key, rss_act->key_len);
+ else
+ memcpy(rss_conf->key, hns3_hash_key,
+ RTE_MIN(sizeof(hns3_hash_key), rss_act->key_len));
+ /* Need to record if user sets hash key. */
+ rss_conf->conf.key = rss_act->key;
+ rss_conf->conf.key_len = rss_act->key_len;
+
+ return 0;
+}
+
+static int
+hns3_flow_parse_queues(struct hns3_hw *hw,
+ const struct rte_flow_action_rss *rss_act,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ uint16_t i;
- if (rss->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM)
+ if (rss_act->queue_num > hw->rss_ind_tbl_size)
return rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "queue number configured exceeds "
- "queue buffer size driver supported");
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL,
+ "queue number can not exceed RSS indirection table.");
- for (n = 0; n < rss->queue_num; n++) {
- if (rss->queue[n] < hw->alloc_rss_size)
- continue;
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "queue id must be less than queue number allocated to a TC");
+ if (rss_act->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL,
+ "queue number configured exceeds queue buffer size driver supported");
+
+ for (i = 0; i < rss_act->queue_num; i++) {
+ if (rss_act->queue[i] >= hw->alloc_rss_size)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL,
+ "queue id must be less than queue number allocated to a TC");
}
- if (!(rss->types & HNS3_ETH_RSS_SUPPORT) && rss->types)
+ memcpy(rss_conf->queue, rss_act->queue,
+ rss_act->queue_num * sizeof(rss_conf->queue[0]));
+ rss_conf->conf.queue = rss_conf->queue;
+ rss_conf->conf.queue_num = rss_act->queue_num;
+
+ return 0;
+}
+
+static int
+hns3_flow_get_hw_pctype(struct hns3_hw *hw,
+ const struct rte_flow_action_rss *rss_act,
+ const struct hns3_hash_map_info *map,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ uint64_t l3l4_src_dst, l3l4_refine, left_types;
+
+ if (rss_act->types == 0) {
+ /* Disable RSS hash of this packet type if types is zero. */
+ rss_conf->hw_pctypes |= map->hw_pctype;
+ return 0;
+ }
+
+ /*
+ * Can not have extra types except rss_pctype and l3l4_type in this map.
+ */
+ left_types = ~map->rss_pctype & rss_act->types;
+ if (left_types & ~map->l3l4_types)
return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF,
- act,
- "Flow types is unsupported by "
- "hns3's RSS");
- if (rss->func >= RTE_ETH_HASH_FUNCTION_MAX)
- return rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "RSS hash func are not supported");
- if (rss->level)
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "cannot set extra types.");
+
+ l3l4_src_dst = left_types;
+ /* L3/L4 SRC and DST shouldn't be specified at the same time. */
+ l3l4_refine = rte_eth_rss_hf_refine(l3l4_src_dst);
+ if (l3l4_refine != l3l4_src_dst)
return rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "a nonzero RSS encapsulation level is not supported");
- if (rss->key_len && rss->key_len != hw->rss_key_size)
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "cannot specify L3_SRC/DST_ONLY or L4_SRC/DST_ONLY at the same.");
+
+ if (!hns3_valid_ipv6_sctp_rss_types(hw, rss_act->types))
return rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
- "invalid RSS key length");
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "hardware doesn't support to use L4 src/dst to hash for IPV6-SCTP.");
- if (!hns3_rss_input_tuple_supported(hw, rss))
- return rte_flow_error_set(error, EINVAL,
+ rss_conf->hw_pctypes |= map->hw_pctype;
+
+ return 0;
+}
+
+static int
+hns3_flow_parse_rss_types_by_ptype(struct hns3_hw *hw,
+ const struct rte_flow_action_rss *rss_act,
+ uint64_t pattern_type,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ const struct hns3_hash_map_info *map;
+ bool matched = false;
+ uint16_t i;
+ int ret;
+
+ for (i = 0; i < RTE_DIM(hash_map_table); i++) {
+ map = &hash_map_table[i];
+ if (map->pattern_type != pattern_type) {
+ /*
+ * If the target pattern type is already matched with
+ * the one before this pattern in the hash map table,
+ * no need to continue walk.
+ */
+ if (matched)
+ break;
+ continue;
+ }
+ matched = true;
+
+ /*
+ * If pattern type is matched and the 'types' is zero, all packet flow
+ * types related to this pattern type disable RSS hash.
+ * Otherwise, RSS types must match the pattern type and cannot have no
+ * extra or unsupported types.
+ */
+ if (rss_act->types != 0 && !(map->rss_pctype & rss_act->types))
+ continue;
+
+ ret = hns3_flow_get_hw_pctype(hw, rss_act, map, rss_conf, error);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (rss_conf->hw_pctypes != 0)
+ return 0;
+
+ if (matched)
+ return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION_CONF,
- &rss->types,
- "input RSS types are not supported");
+ NULL, "RSS types are unsupported");
- act_index++;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL, "Pattern specified is unsupported");
+}
- /* Check if the next not void action is END */
- NEXT_ITEM_OF_ACTION(act, actions, act_index);
- if (act->type != RTE_FLOW_ACTION_TYPE_END)
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Not supported action.");
+static uint64_t
+hns3_flow_get_all_hw_pctypes(uint64_t types)
+{
+ uint64_t hw_pctypes = 0;
+ uint16_t i;
- return 0;
+ for (i = 0; i < RTE_DIM(hash_map_table); i++) {
+ if (types & hash_map_table[i].rss_pctype)
+ hw_pctypes |= hash_map_table[i].hw_pctype;
+ }
+
+ return hw_pctypes;
}
static int
-hns3_disable_rss(struct hns3_hw *hw)
+hns3_flow_parse_rss_types(struct hns3_hw *hw,
+ const struct rte_flow_action_rss *rss_act,
+ uint64_t pattern_type,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
{
+ rss_conf->conf.types = rss_act->types;
+
+ /* no pattern specified to set global RSS types. */
+ if (pattern_type == 0) {
+ if (rss_act->types & ~HNS3_ETH_RSS_SUPPORT)
+ hns3_warn(hw, "some types in the requested RSS types (0x%" PRIx64 ") aren't supported, they are ignored.",
+ rss_act->types);
+ rss_conf->hw_pctypes =
+ hns3_flow_get_all_hw_pctypes(rss_act->types);
+ return 0;
+ }
+
+ return hns3_flow_parse_rss_types_by_ptype(hw, rss_act, pattern_type,
+ rss_conf, error);
+}
+
+static int
+hns3_flow_parse_hash_global_conf(struct rte_eth_dev *dev,
+ const struct rte_flow_action_rss *rss_act,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int ret;
- ret = hns3_set_rss_tuple_by_rss_hf(hw, 0);
- if (ret)
+ ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error);
+ if (ret != 0)
return ret;
- hw->rss_info.rss_hf = 0;
- return 0;
+ if (rss_act->queue_num > 0) {
+ ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (rss_act->key_len > 0) {
+ ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error);
+ if (ret != 0)
+ return ret;
+ }
+
+ return hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type,
+ rss_conf, error);
}
static int
-hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_flow_rss_conf *rss_conf,
- uint8_t *hash_algo)
-{
- const uint8_t hash_func_map[] = {
- [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
- [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
- [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE,
- [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP,
- };
- uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0};
- int ret;
+hns3_flow_parse_pattern_type(const struct rte_flow_item pattern[],
+ uint64_t *ptype, struct rte_flow_error *error)
+{
+ enum rte_flow_item_type pre_type = RTE_FLOW_ITEM_TYPE_VOID;
+ const char *message = "Pattern specified isn't supported";
+ uint64_t item_hdr, pattern_hdrs = 0;
+ enum rte_flow_item_type cur_type;
- if (rss_conf->conf.func == RTE_ETH_HASH_FUNCTION_DEFAULT) {
- ret = hns3_rss_get_algo_key(hw, hash_algo, key,
- hw->rss_key_size);
- if (ret != 0) {
- hns3_err(hw, "fail to get current RSS hash algorithm, ret = %d",
- ret);
- return ret;
+ for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
+ if (pattern->type == RTE_FLOW_ITEM_TYPE_VOID)
+ continue;
+ if (pattern->mask || pattern->spec || pattern->last) {
+ message = "Header info shouldn't be specified";
+ goto unsup;
}
- /*
- * During the phase of reset recovery, the hash algorithm
- * obtained from hardware may not be the one used(saved in
- * rte_flow_hash_algo) when this rule is delivered.
- */
- if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) &&
- *hash_algo != rss_conf->hash_algo)
- *hash_algo = rss_conf->hash_algo;
+ /* Check the sub-item allowed by the previous item . */
+ if (pre_type >= RTE_DIM(hash_pattern_next_allow_items) ||
+ !(hash_pattern_next_allow_items[pre_type] &
+ BIT_ULL(pattern->type)))
+ goto unsup;
+
+ cur_type = pattern->type;
+ /* Unsupported for current type being greater than array size. */
+ if (cur_type >= RTE_DIM(hash_pattern_item_header))
+ goto unsup;
+
+ /* The value is zero, which means unsupported current header. */
+ item_hdr = hash_pattern_item_header[cur_type];
+ if (item_hdr == 0)
+ goto unsup;
+
+ /* Have duplicate pattern header. */
+ if (item_hdr & pattern_hdrs)
+ goto unsup;
+ pre_type = cur_type;
+ pattern_hdrs |= item_hdr;
+ }
+ if (pattern_hdrs != 0) {
+ *ptype = pattern_hdrs;
return 0;
}
- *hash_algo = hash_func_map[rss_conf->conf.func];
+unsup:
+ return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+ pattern, message);
+}
+
+static int
+hns3_flow_parse_pattern_act(struct rte_eth_dev *dev,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action_rss *rss_act,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
+
+ ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error);
+ if (ret != 0)
+ return ret;
+
+ if (rss_act->key_len > 0) {
+ ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (rss_act->queue_num > 0) {
+ ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error);
+ if (ret != 0)
+ return ret;
+ }
+
+ ret = hns3_flow_parse_pattern_type(pattern, &rss_conf->pattern_type,
+ error);
+ if (ret != 0)
+ return ret;
+
+ ret = hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type,
+ rss_conf, error);
+ if (ret != 0)
+ return ret;
+
+ if (rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT ||
+ rss_act->key_len > 0 || rss_act->queue_num > 0)
+ hns3_warn(hw, "hash func, key and queues are global config, which work for all flow types. "
+ "Recommend: don't set them together with pattern.");
return 0;
}
+static bool
+hns3_rss_action_is_dup(struct hns3_hw *hw,
+ const struct hns3_flow_rss_conf *conf)
+{
+ struct hns3_rss_conf_ele *filter;
+
+ TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) {
+ if (conf->pattern_type != filter->filter_info.pattern_type)
+ continue;
+
+ if (hns3_action_rss_same(&filter->filter_info.conf, &conf->conf))
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * This function is used to parse rss action validation.
+ */
static int
-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf)
+hns3_parse_rss_filter(struct rte_eth_dev *dev,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action *actions,
+ struct hns3_flow_rss_conf *rss_conf,
+ struct rte_flow_error *error)
{
- struct rte_flow_action_rss *rss_config = &conf->conf;
- uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
- bool use_default_key = false;
- uint64_t flow_types;
- uint8_t hash_algo;
+ struct hns3_adapter *hns = dev->data->dev_private;
+ const struct rte_flow_action_rss *rss_act;
+ const struct rte_flow_action *act;
+ const struct rte_flow_item *pat;
+ struct hns3_hw *hw = &hns->hw;
+ uint32_t index = 0;
int ret;
- if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) {
- hns3_warn(hw, "Default RSS hash key to be set");
- memcpy(rss_key, hns3_hash_key,
- RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size));
- use_default_key = true;
+ NEXT_ITEM_OF_ACTION(act, actions, index);
+ if (actions[1].type != RTE_FLOW_ACTION_TYPE_END)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ &actions[1],
+ "Only support one action for RSS.");
+
+ rss_act = (const struct rte_flow_action_rss *)act->conf;
+ if (rss_act == NULL) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ act, "lost RSS action configuration");
}
- ret = hns3_parse_rss_algorithm(hw, conf, &hash_algo);
- if (ret)
+ if (rss_act->level != 0)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ act,
+ "RSS level is not supported");
+
+ index = 0;
+ NEXT_ITEM_OF_PATTERN(pat, pattern, index);
+ if (pat[0].type == RTE_FLOW_ITEM_TYPE_END) {
+ rss_conf->pattern_type = 0;
+ ret = hns3_flow_parse_hash_global_conf(dev, rss_act,
+ rss_conf, error);
+ } else {
+ ret = hns3_flow_parse_pattern_act(dev, pat, rss_act,
+ rss_conf, error);
+ }
+ if (ret != 0)
return ret;
- ret = hns3_rss_set_algo_key(hw, hash_algo,
- use_default_key ? rss_key : rss_config->key,
- hw->rss_key_size);
- if (ret)
- return ret;
- conf->hash_algo = hash_algo;
-
- /* Filter the unsupported flow types */
- flow_types = rss_config->types ?
- rss_config->types & HNS3_ETH_RSS_SUPPORT :
- hw->rss_info.rss_hf;
- if (flow_types != rss_config->types)
- hns3_warn(hw, "modified RSS types based on hardware support,"
- " requested:0x%" PRIx64 " configured:0x%" PRIx64,
- rss_config->types, flow_types);
-
- ret = hns3_set_rss_tuple_by_rss_hf(hw, flow_types);
- if (ret)
- hns3_err(hw, "Update RSS tuples by rss hf failed %d", ret);
+ if (hns3_rss_action_is_dup(hw, rss_conf))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ act, "duplicate RSS rule");
- return ret;
+ return 0;
}
static int
@@ -1496,44 +1839,106 @@ hns3_update_indir_table(struct hns3_hw *hw,
return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size);
}
+static uint64_t
+hns3_flow_get_pctype_tuple_mask(uint64_t hw_pctype)
+{
+ uint64_t tuple_mask = 0;
+ uint16_t i;
+
+ for (i = 0; i < RTE_DIM(hash_map_table); i++) {
+ if (hw_pctype == hash_map_table[i].hw_pctype) {
+ tuple_mask = hash_map_table[i].tuple_mask;
+ break;
+ }
+ }
+
+ return tuple_mask;
+}
+
static int
-hns3_reset_rss_filter(struct hns3_hw *hw,
- const struct hns3_flow_rss_conf *conf)
+hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw,
+ struct hns3_flow_rss_conf *rss_conf)
{
+ uint64_t old_tuple_fields, new_tuple_fields;
+ uint64_t hw_pctypes, tuples, tuple_mask = 0;
+ bool cfg_global_tuple;
int ret;
- if (!conf->valid)
- return 0;
+ cfg_global_tuple = (rss_conf->pattern_type == 0);
+ if (!cfg_global_tuple) {
+ /*
+ * To ensure that different packets do not affect each other,
+ * we have to first read all tuple fields, and then only modify
+ * the tuples for the specified packet type.
+ */
+ ret = hns3_get_rss_tuple_field(hw, &old_tuple_fields);
+ if (ret != 0)
+ return ret;
- ret = hns3_disable_rss(hw);
- if (ret)
- hns3_err(hw, "RSS disable failed(%d)", ret);
+ new_tuple_fields = old_tuple_fields;
+ hw_pctypes = rss_conf->hw_pctypes;
+ while (hw_pctypes > 0) {
+ uint32_t idx = rte_bsf64(hw_pctypes);
+ uint64_t pctype = BIT_ULL(idx);
+
+ tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype);
+ tuples = hns3_rss_calc_tuple_filed(hw,
+ rss_conf->conf.types);
+ new_tuple_fields &= ~tuple_mask;
+ new_tuple_fields |= tuples;
+ hw_pctypes &= ~pctype;
+ }
+ } else {
+ new_tuple_fields =
+ hns3_rss_calc_tuple_filed(hw, rss_conf->conf.types);
+ }
- return ret;
+ ret = hns3_set_rss_tuple_field(hw, new_tuple_fields);
+ if (ret != 0)
+ return ret;
+
+ hns3_info(hw, "RSS tuple fields changed from 0x%" PRIx64 " to 0x%" PRIx64,
+ old_tuple_fields, new_tuple_fields);
+
+ return 0;
}
static int
-hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf)
+hns3_config_rss_filter(struct hns3_hw *hw,
+ struct hns3_flow_rss_conf *rss_conf)
{
struct rte_flow_action_rss *rss_act;
- uint16_t num;
int ret;
- rss_act = &conf->conf;
- /* Set rx queues to use */
- num = RTE_MIN(hw->data->nb_rx_queues, rss_act->queue_num);
- if (rss_act->queue_num > num)
- hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated",
- rss_act->queue_num);
- hns3_info(hw, "Max of contiguous %u PF queues are configured", num);
- if (num) {
- ret = hns3_update_indir_table(hw, rss_act, num);
- if (ret)
+ rss_act = &rss_conf->conf;
+ if (rss_act->queue_num > 0) {
+ ret = hns3_update_indir_table(hw, rss_act, rss_act->queue_num);
+ if (ret) {
+ hns3_err(hw, "set queues action failed, ret = %d", ret);
+ return ret;
+ }
+ }
+
+ if (rss_act->key_len > 0 ||
+ rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
+ ret = hns3_update_rss_algo_key(hw, rss_act->func, rss_conf->key,
+ rss_act->key_len);
+ if (ret != 0) {
+ hns3_err(hw, "set func or hash key action failed, ret = %d",
+ ret);
return ret;
+ }
+ }
+
+ if (rss_conf->hw_pctypes > 0) {
+ ret = hns3_flow_set_rss_ptype_tuple(hw, rss_conf);
+ if (ret != 0) {
+ hns3_err(hw, "set types action failed, ret = %d", ret);
+ return ret;
+ }
}
- /* Set hash algorithm and flow types by the user's config */
- return hns3_hw_rss_hash_set(hw, conf);
+ return 0;
}
static int
@@ -1542,51 +1947,44 @@ hns3_clear_rss_filter(struct rte_eth_dev *dev)
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_rss_conf_ele *rss_filter_ptr;
struct hns3_hw *hw = &hns->hw;
- int rss_rule_succ_cnt = 0; /* count for success of clearing RSS rules */
- int rss_rule_fail_cnt = 0; /* count for failure of clearing RSS rules */
- int ret = 0;
rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
while (rss_filter_ptr) {
TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries);
- ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info);
- if (ret)
- rss_rule_fail_cnt++;
- else
- rss_rule_succ_cnt++;
rte_free(rss_filter_ptr);
rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
}
- if (rss_rule_fail_cnt) {
- hns3_err(hw, "fail to delete all RSS filters, success num = %d "
- "fail num = %d", rss_rule_succ_cnt,
- rss_rule_fail_cnt);
- ret = -EIO;
- }
-
- return ret;
+ return hns3_config_rss(hns);
}
static int
-hns3_restore_rss_filter(struct hns3_hw *hw)
+hns3_reconfig_all_rss_filter(struct hns3_hw *hw)
{
struct hns3_rss_conf_ele *filter;
- int ret = 0;
+ uint32_t rule_no = 0;
+ int ret;
- pthread_mutex_lock(&hw->flows_lock);
TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) {
- if (!filter->filter_info.valid)
- continue;
-
ret = hns3_config_rss_filter(hw, &filter->filter_info);
if (ret != 0) {
- hns3_err(hw, "restore RSS filter failed, ret=%d", ret);
- goto out;
+ hns3_err(hw, "config %uth RSS filter failed, ret = %d",
+ rule_no, ret);
+ return ret;
}
+ rule_no++;
}
-out:
+ return 0;
+}
+
+static int
+hns3_restore_rss_filter(struct hns3_hw *hw)
+{
+ int ret;
+
+ pthread_mutex_lock(&hw->flows_lock);
+ ret = hns3_reconfig_all_rss_filter(hw);
pthread_mutex_unlock(&hw->flows_lock);
return ret;
@@ -1605,38 +2003,6 @@ hns3_restore_filter(struct hns3_adapter *hns)
return hns3_restore_rss_filter(hw);
}
-static bool
-hns3_rss_action_is_dup(struct hns3_hw *hw,
- const struct rte_flow_action_rss *act)
-{
- struct hns3_rss_conf_ele *filter;
-
- TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) {
- if (!filter->filter_info.valid)
- continue;
-
- if (hns3_action_rss_same(&filter->filter_info.conf, act))
- return true;
- }
-
- return false;
-}
-
-static int
-hns3_flow_parse_rss(struct rte_eth_dev *dev,
- struct hns3_flow_rss_conf *conf)
-{
- struct hns3_adapter *hns = dev->data->dev_private;
- struct hns3_hw *hw = &hns->hw;
-
- if (hns3_rss_action_is_dup(hw, &conf->conf)) {
- hns3_err(hw, "duplicate RSS configuration");
- return -EINVAL;
- }
-
- return hns3_config_rss_filter(hw, conf);
-}
-
static int
hns3_flow_args_check(const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
@@ -1670,32 +2036,55 @@ static int
hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
- struct rte_flow_error *error)
+ struct rte_flow_error *error,
+ struct hns3_filter_info *filter_info)
{
- struct hns3_fdir_rule fdir_rule;
+ union hns3_filter_conf *conf;
int ret;
ret = hns3_flow_args_check(attr, pattern, actions, error);
if (ret)
return ret;
- if (hns3_find_rss_general_action(pattern, actions))
- return hns3_parse_rss_filter(dev, actions, error);
+ hns3_parse_filter_type(pattern, actions, filter_info);
+ conf = &filter_info->conf;
+ if (filter_info->type == RTE_ETH_FILTER_HASH)
+ return hns3_parse_rss_filter(dev, pattern, actions,
+ &conf->rss_conf, error);
+
+ return hns3_parse_fdir_filter(dev, pattern, actions,
+ &conf->fdir_conf, error);
+}
+
+static int
+hns3_flow_rebuild_all_rss_filter(struct hns3_adapter *hns)
+{
+ struct hns3_hw *hw = &hns->hw;
+ int ret;
+
+ ret = hns3_config_rss(hns);
+ if (ret != 0) {
+ hns3_err(hw, "restore original RSS configuration failed, ret = %d.",
+ ret);
+ return ret;
+ }
+ ret = hns3_reconfig_all_rss_filter(hw);
+ if (ret != 0)
+ hns3_err(hw, "rebuild all RSS filter failed, ret = %d.", ret);
- memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule));
- return hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error);
+ return ret;
}
static int
hns3_flow_create_rss_rule(struct rte_eth_dev *dev,
- const struct rte_flow_action *act,
+ struct hns3_flow_rss_conf *rss_conf,
struct rte_flow *flow)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- const struct rte_flow_action_rss *rss_act;
+ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
struct hns3_rss_conf_ele *rss_filter_ptr;
struct hns3_flow_rss_conf *new_conf;
- struct hns3_rss_conf_ele *filter_ptr;
+ struct rte_flow_action_rss *rss_act;
int ret;
rss_filter_ptr = rte_zmalloc("hns3 rss filter",
@@ -1705,35 +2094,28 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev,
return -ENOMEM;
}
- rss_act = (const struct rte_flow_action_rss *)act->conf;
new_conf = &rss_filter_ptr->filter_info;
- memcpy(&new_conf->conf, rss_act, sizeof(*rss_act));
- if (rss_act->queue_num > 0) {
- memcpy(new_conf->queue, rss_act->queue,
- rss_act->queue_num * sizeof(new_conf->queue[0]));
+ memcpy(new_conf, rss_conf, sizeof(*new_conf));
+ rss_act = &new_conf->conf;
+ if (rss_act->queue_num > 0)
new_conf->conf.queue = new_conf->queue;
- }
- if (rss_act->key_len > 0) {
- if (rss_act->key != NULL) {
- memcpy(new_conf->key, rss_act->key,
- rss_act->key_len * sizeof(new_conf->key[0]));
- new_conf->conf.key = new_conf->key;
- }
- }
+ /*
+ * There are two ways to deliver hash key action:
+ * 1> 'key_len' is greater than zero and 'key' isn't NULL.
+ * 2> 'key_len' is greater than zero, but 'key' is NULL.
+ * For case 2, we need to keep 'key' of the new_conf is NULL so as to
+ * inherit the configuration from user in case of failing to verify
+ * duplicate rule later.
+ */
+ if (rss_act->key_len > 0 && rss_act->key != NULL)
+ new_conf->conf.key = new_conf->key;
- ret = hns3_flow_parse_rss(dev, new_conf);
+ ret = hns3_config_rss_filter(hw, new_conf);
if (ret != 0) {
rte_free(rss_filter_ptr);
+ (void)hns3_flow_rebuild_all_rss_filter(hns);
return ret;
}
- rss_filter_ptr->filter_info.valid = true;
-
- /*
- * When create a new RSS rule, the old rule will be overlaid and set
- * invalid.
- */
- TAILQ_FOREACH(filter_ptr, &hw->flow_rss_list, entries)
- filter_ptr->filter_info.valid = false;
TAILQ_INSERT_TAIL(&hw->flow_rss_list, rss_filter_ptr, entries);
flow->rule = rss_filter_ptr;
@@ -1744,29 +2126,22 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev,
static int
hns3_flow_create_fdir_rule(struct rte_eth_dev *dev,
- const struct rte_flow_item pattern[],
- const struct rte_flow_action actions[],
+ struct hns3_fdir_rule *fdir_rule,
struct rte_flow_error *error,
struct rte_flow *flow)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
struct hns3_fdir_rule_ele *fdir_rule_ptr;
- struct hns3_fdir_rule fdir_rule;
int ret;
- memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule));
- ret = hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error);
- if (ret != 0)
- return ret;
-
- if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) {
+ if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) {
ret = hns3_counter_new(dev, 0,
- fdir_rule.act_cnt.id, error);
+ fdir_rule->act_cnt.id, error);
if (ret != 0)
return ret;
- flow->counter_id = fdir_rule.act_cnt.id;
+ flow->counter_id = fdir_rule->act_cnt.id;
}
fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
@@ -1782,11 +2157,11 @@ hns3_flow_create_fdir_rule(struct rte_eth_dev *dev,
* rules to the hardware to simplify the rollback of rules in the
* hardware.
*/
- ret = hns3_fdir_filter_program(hns, &fdir_rule, false);
+ ret = hns3_fdir_filter_program(hns, fdir_rule, false);
if (ret != 0)
goto err_fdir_filter;
- memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule,
+ memcpy(&fdir_rule_ptr->fdir_conf, fdir_rule,
sizeof(struct hns3_fdir_rule));
TAILQ_INSERT_TAIL(&hw->flow_fdir_list, fdir_rule_ptr, entries);
flow->rule = fdir_rule_ptr;
@@ -1797,8 +2172,8 @@ hns3_flow_create_fdir_rule(struct rte_eth_dev *dev,
err_fdir_filter:
rte_free(fdir_rule_ptr);
err_malloc:
- if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER)
- hns3_counter_release(dev, fdir_rule.act_cnt.id);
+ if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER)
+ hns3_counter_release(dev, fdir_rule->act_cnt.id);
return ret;
}
@@ -1816,13 +2191,15 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
struct rte_flow_error *error)
{
struct hns3_adapter *hns = dev->data->dev_private;
- struct hns3_hw *hw = &hns->hw;
+ struct hns3_filter_info filter_info = {0};
struct hns3_flow_mem *flow_node;
- const struct rte_flow_action *act;
+ struct hns3_hw *hw = &hns->hw;
+ union hns3_filter_conf *conf;
struct rte_flow *flow;
int ret;
- ret = hns3_flow_validate(dev, attr, pattern, actions, error);
+ ret = hns3_flow_validate(dev, attr, pattern, actions, error,
+ &filter_info);
if (ret)
return NULL;
@@ -1842,13 +2219,12 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
}
flow_node->flow = flow;
+ conf = &filter_info.conf;
TAILQ_INSERT_TAIL(&hw->flow_list, flow_node, entries);
-
- act = hns3_find_rss_general_action(pattern, actions);
- if (act)
- ret = hns3_flow_create_rss_rule(dev, act, flow);
+ if (filter_info.type == RTE_ETH_FILTER_HASH)
+ ret = hns3_flow_create_rss_rule(dev, &conf->rss_conf, flow);
else
- ret = hns3_flow_create_fdir_rule(dev, pattern, actions,
+ ret = hns3_flow_create_fdir_rule(dev, &conf->fdir_conf,
error, flow);
if (ret == 0)
return flow;
@@ -1902,15 +2278,10 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
break;
case RTE_ETH_FILTER_HASH:
rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule;
- ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info);
- if (ret)
- return rte_flow_error_set(error, EIO,
- RTE_FLOW_ERROR_TYPE_HANDLE,
- flow,
- "Destroy RSS fail.Try again");
TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries);
rte_free(rss_filter_ptr);
rss_filter_ptr = NULL;
+ (void)hns3_flow_rebuild_all_rss_filter(hns);
break;
default:
return rte_flow_error_set(error, EINVAL,
@@ -2017,10 +2388,12 @@ hns3_flow_validate_wrap(struct rte_eth_dev *dev,
struct rte_flow_error *error)
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct hns3_filter_info filter_info = {0};
int ret;
pthread_mutex_lock(&hw->flows_lock);
- ret = hns3_flow_validate(dev, attr, pattern, actions, error);
+ ret = hns3_flow_validate(dev, attr, pattern, actions, error,
+ &filter_info);
pthread_mutex_unlock(&hw->flows_lock);
return ret;
diff --git a/drivers/net/hns3/hns3_flow.h b/drivers/net/hns3/hns3_flow.h
index e6a8a425d8..a700de73c7 100644
--- a/drivers/net/hns3/hns3_flow.h
+++ b/drivers/net/hns3/hns3_flow.h
@@ -7,6 +7,8 @@
#include <rte_flow.h>
+#include "hns3_fdir.h"
+
struct hns3_flow_counter {
LIST_ENTRY(hns3_flow_counter) next; /* Pointer to the next counter. */
uint32_t shared:1; /* Share counter ID with other flow rules. */
@@ -23,10 +25,10 @@ struct rte_flow {
struct hns3_flow_rss_conf {
struct rte_flow_action_rss conf;
- uint8_t hash_algo;
uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */
uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */
- bool valid; /* check if RSS rule is valid */
+ uint64_t pattern_type;
+ uint64_t hw_pctypes; /* packet types in driver */
};
/* rss filter list structure */
@@ -41,6 +43,17 @@ struct hns3_flow_mem {
struct rte_flow *flow;
};
+
+union hns3_filter_conf {
+ struct hns3_fdir_rule fdir_conf;
+ struct hns3_flow_rss_conf rss_conf;
+};
+
+struct hns3_filter_info {
+ enum rte_filter_type type;
+ union hns3_filter_conf conf;
+};
+
TAILQ_HEAD(hns3_rss_filter_list, hns3_rss_conf_ele);
TAILQ_HEAD(hns3_flow_mem_list, hns3_flow_mem);
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index f140a6a2ca..246b96dd9b 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -18,69 +18,13 @@ const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = {
0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
};
-enum hns3_tuple_field {
- /* IPV4_TCP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0,
- HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S,
- HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D,
- HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S,
-
- /* IPV4_UDP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8,
- HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S,
- HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D,
- HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S,
-
- /* IPV4_SCTP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16,
- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S,
- HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D,
- HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S,
- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER,
-
- /* IPV4 ENABLE FIELD */
- HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24,
- HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S,
- HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D,
- HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S,
-
- /* IPV6_TCP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32,
- HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S,
- HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D,
- HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S,
-
- /* IPV6_UDP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40,
- HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S,
- HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D,
- HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S,
-
- /* IPV6_SCTP ENABLE FIELD */
- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48,
- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S,
- HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D,
- HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S,
- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER,
-
- /* IPV6 ENABLE FIELD */
- HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56,
- HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S,
- HNS3_RSS_FIELD_IPV6_FRAG_IP_D,
- HNS3_RSS_FIELD_IPV6_FRAG_IP_S
+const uint8_t hns3_hash_func_map[] = {
+ [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
+ [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ,
+ [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE,
+ [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP,
};
-#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0)
-#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8)
-#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16)
-#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24)
-#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26)
-#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32)
-#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40)
-#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48)
-#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56)
-#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58)
-
enum hns3_rss_tuple_type {
HNS3_RSS_IP_TUPLE,
HNS3_RSS_IP_L4_TUPLE,
@@ -574,7 +518,7 @@ hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf)
hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored.");
}
-static uint64_t
+uint64_t
hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
{
uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
@@ -610,25 +554,35 @@ hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
}
int
-hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
+hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields)
{
struct hns3_rss_input_tuple_cmd *req;
struct hns3_cmd_desc desc;
- uint64_t tuple_field;
int ret;
hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false);
req = (struct hns3_rss_input_tuple_cmd *)desc.data;
-
- tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf);
- req->tuple_field = rte_cpu_to_le_64(tuple_field);
+ req->tuple_field = rte_cpu_to_le_64(tuple_fields);
ret = hns3_cmd_send(hw, &desc, 1);
- if (ret) {
- hns3_err(hw, "Update RSS flow types tuples failed %d", ret);
- return ret;
- }
+ if (ret != 0)
+ hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret);
- return 0;
+ return ret;
+}
+
+int
+hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
+{
+ uint64_t tuple_fields;
+ int ret;
+
+ tuple_fields = hns3_rss_calc_tuple_filed(hw, rss_hf);
+ ret = hns3_set_rss_tuple_field(hw, tuple_fields);
+ if (ret != 0)
+ hns3_err(hw, "Update RSS flow types tuples failed, ret = %d",
+ ret);
+
+ return ret;
}
/*
@@ -1000,6 +954,52 @@ hns3_set_rss_tc_mode(struct hns3_hw *hw)
return ret;
}
+/*
+ * Note: the 'hash_algo' is defined by enum rte_eth_hash_function.
+ */
+int
+hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func,
+ uint8_t *key, uint8_t key_len)
+{
+ uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0};
+ bool modify_key, modify_algo;
+ uint8_t hash_algo;
+ int ret;
+
+ modify_key = (key != NULL && key_len > 0);
+ modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT;
+ if (!modify_key && !modify_algo)
+ return 0;
+
+ if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) {
+ hns3_err(hw, "hash func (%u) is unsupported.", hash_func);
+ return -ENOTSUP;
+ }
+ if (modify_key && key_len != hw->rss_key_size) {
+ hns3_err(hw, "hash key length (%u) is invalid.", key_len);
+ return -EINVAL;
+ }
+
+ ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size);
+ if (ret != 0) {
+ hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d",
+ ret);
+ return ret;
+ }
+
+ if (modify_algo)
+ hash_algo = hns3_hash_func_map[hash_func];
+ if (modify_key)
+ memcpy(rss_key, key, key_len);
+
+ ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size);
+ if (ret != 0)
+ hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d",
+ ret);
+
+ return ret;
+}
+
static void
hns3_rss_tuple_uninit(struct hns3_hw *hw)
{
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 07f6db2652..76c10afdde 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -7,23 +7,102 @@
#include <rte_ethdev.h>
#include <rte_flow.h>
-#define HNS3_ETH_RSS_SUPPORT ( \
- RTE_ETH_RSS_IPV4 | \
- RTE_ETH_RSS_FRAG_IPV4 | \
- RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
- RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
- RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
- RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \
- RTE_ETH_RSS_IPV6 | \
- RTE_ETH_RSS_FRAG_IPV6 | \
- RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
- RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
- RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
- RTE_ETH_RSS_NONFRAG_IPV6_OTHER | \
- RTE_ETH_RSS_L3_SRC_ONLY | \
- RTE_ETH_RSS_L3_DST_ONLY | \
- RTE_ETH_RSS_L4_SRC_ONLY | \
- RTE_ETH_RSS_L4_DST_ONLY)
+#define HNS3_RSS_SUPPORT_L3_SRC_DST (RTE_ETH_RSS_L3_SRC_ONLY | \
+ RTE_ETH_RSS_L3_DST_ONLY)
+#define HNS3_RSS_SUPPORT_L4_SRC_DST (RTE_ETH_RSS_L4_SRC_ONLY | \
+ RTE_ETH_RSS_L4_DST_ONLY)
+#define HNS3_RSS_SUPPORT_L3L4 (HNS3_RSS_SUPPORT_L3_SRC_DST | \
+ HNS3_RSS_SUPPORT_L4_SRC_DST)
+
+#define HNS3_RSS_SUPPORT_FLOW_TYPE (RTE_ETH_RSS_IPV4 | \
+ RTE_ETH_RSS_FRAG_IPV4 | \
+ RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
+ RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
+ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
+ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \
+ RTE_ETH_RSS_IPV6 | \
+ RTE_ETH_RSS_FRAG_IPV6 | \
+ RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
+ RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
+ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
+ RTE_ETH_RSS_NONFRAG_IPV6_OTHER)
+
+#define HNS3_ETH_RSS_SUPPORT (HNS3_RSS_SUPPORT_FLOW_TYPE | \
+ HNS3_RSS_SUPPORT_L3L4)
+
+enum hns3_tuple_field {
+ /* IPV4_TCP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0,
+ HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S,
+ HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S,
+
+ /* IPV4_UDP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8,
+ HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S,
+ HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S,
+
+ /* IPV4_SCTP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16,
+ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S,
+ HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S,
+ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER,
+
+ /* IPV4 ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24,
+ HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S,
+ HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D,
+ HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S,
+
+ /* IPV6_TCP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32,
+ HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S,
+ HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S,
+
+ /* IPV6_UDP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40,
+ HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S,
+ HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S,
+
+ /* IPV6_SCTP ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48,
+ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S,
+ HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D,
+ HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S,
+ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER,
+
+ /* IPV6 ENABLE FIELD */
+ HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56,
+ HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S,
+ HNS3_RSS_FIELD_IPV6_FRAG_IP_D,
+ HNS3_RSS_FIELD_IPV6_FRAG_IP_S
+};
+
+#define HNS3_RSS_PCTYPE_IPV4_TCP BIT_ULL(0)
+#define HNS3_RSS_PCTYPE_IPV4_UDP BIT_ULL(8)
+#define HNS3_RSS_PCTYPE_IPV4_SCTP BIT_ULL(16)
+#define HNS3_RSS_PCTYPE_IPV4_NONF BIT_ULL(24)
+#define HNS3_RSS_PCTYPE_IPV4_FLAG BIT_ULL(26)
+#define HNS3_RSS_PCTYPE_IPV6_TCP BIT_ULL(32)
+#define HNS3_RSS_PCTYPE_IPV6_UDP BIT_ULL(40)
+#define HNS3_RSS_PCTYPE_IPV6_SCTP BIT_ULL(48)
+#define HNS3_RSS_PCTYPE_IPV6_NONF BIT_ULL(56)
+#define HNS3_RSS_PCTYPE_IPV6_FLAG BIT_ULL(58)
+
+#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0)
+#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8)
+#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16)
+#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24)
+#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26)
+#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32)
+#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40)
+#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48)
+#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56)
+#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58)
#define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */
#define HNS3_RSS_IND_TBL_SIZE_MAX 2048
@@ -106,10 +185,14 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw);
int hns3_config_rss(struct hns3_adapter *hns);
void hns3_rss_uninit(struct hns3_adapter *hns);
int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf);
+int hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields);
int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields);
int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
const uint8_t *key, uint8_t key_len);
int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
uint8_t *key, uint8_t key_len);
+uint64_t hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
+int hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
+ uint8_t *key, uint8_t key_len);
#endif /* _HNS3_RSS_H_ */
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 21.11 17/17] net/hns3: add verification of RSS types
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (15 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 16/17] net/hns3: reimplement hash flow function Huisong Li
@ 2023-03-21 9:23 ` Huisong Li
2023-03-21 16:21 ` [PATCH 21.11 00/17] backport some patches for hns3 Kevin Traynor
17 siblings, 0 replies; 19+ messages in thread
From: Huisong Li @ 2023-03-21 9:23 UTC (permalink / raw)
To: stable, ktraynor; +Cc: liudongdong3, huangdaode, liuyonglong, lihuisong
[ upstream commit eb3ef9e0d7eb54b47ab58d3d14f9f5fff3f4120b ]
Add the verification of RSS types from ethdev ops and rte flow without
pattern attribute. The following cases are invalid:
1. types contains unsupported RSS type but hasn't type driver support.
2. types has L3 src/dst but hasn't supported packet type.
3. types has L4 src/dst but hasn't supported packet type and hasn't IP
packet type.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
---
drivers/net/hns3/hns3_flow.c | 12 +++---
| 74 +++++++++++++++++++++++++-----------
| 3 +-
3 files changed, 60 insertions(+), 29 deletions(-)
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index ff7a8a6dc0..8b37c17b40 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1605,9 +1605,10 @@ hns3_flow_parse_rss_types(struct hns3_hw *hw,
/* no pattern specified to set global RSS types. */
if (pattern_type == 0) {
- if (rss_act->types & ~HNS3_ETH_RSS_SUPPORT)
- hns3_warn(hw, "some types in the requested RSS types (0x%" PRIx64 ") aren't supported, they are ignored.",
- rss_act->types);
+ if (!hns3_check_rss_types_valid(hw, rss_act->types))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+ NULL, "RSS types is invalid.");
rss_conf->hw_pctypes =
hns3_flow_get_all_hw_pctypes(rss_act->types);
return 0;
@@ -1882,15 +1883,14 @@ hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw,
uint64_t pctype = BIT_ULL(idx);
tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype);
- tuples = hns3_rss_calc_tuple_filed(hw,
- rss_conf->conf.types);
+ tuples = hns3_rss_calc_tuple_filed(rss_conf->conf.types);
new_tuple_fields &= ~tuple_mask;
new_tuple_fields |= tuples;
hw_pctypes &= ~pctype;
}
} else {
new_tuple_fields =
- hns3_rss_calc_tuple_filed(hw, rss_conf->conf.types);
+ hns3_rss_calc_tuple_filed(rss_conf->conf.types);
}
ret = hns3_set_rss_tuple_field(hw, new_tuple_fields);
--git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index 246b96dd9b..8bcc906e45 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -492,34 +492,62 @@ hns3_rss_reset_indir_table(struct hns3_hw *hw)
return ret;
}
-static void
-hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf)
+bool
+hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types)
{
uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
RTE_ETH_RSS_NONFRAG_IPV6_OTHER;
- uint64_t l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
- RTE_ETH_RSS_NONFRAG_IPV4_UDP |
- RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
- RTE_ETH_RSS_NONFRAG_IPV6_TCP |
- RTE_ETH_RSS_NONFRAG_IPV6_UDP |
- RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
- uint64_t l3_src_dst_mask = RTE_ETH_RSS_L3_SRC_ONLY |
- RTE_ETH_RSS_L3_DST_ONLY;
- uint64_t l4_src_dst_mask = RTE_ETH_RSS_L4_SRC_ONLY |
- RTE_ETH_RSS_L4_DST_ONLY;
-
- if (rss_hf & l3_src_dst_mask &&
- !(rss_hf & ip_mask || rss_hf & l4_mask))
- hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored.");
-
- if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask))
- hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored.");
+ uint64_t ip_l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP |
+ RTE_ETH_RSS_NONFRAG_IPV4_UDP |
+ RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
+ RTE_ETH_RSS_NONFRAG_IPV6_TCP |
+ RTE_ETH_RSS_NONFRAG_IPV6_UDP |
+ RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
+ bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST);
+ bool has_ip_pkt = !!(types & ip_mask);
+ uint64_t final_types;
+
+ if (types == 0)
+ return true;
+
+ if ((types & HNS3_ETH_RSS_SUPPORT) == 0) {
+ hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.",
+ types);
+ return false;
+ }
+
+ if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 &&
+ (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) {
+ hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set.");
+ return false;
+ }
+
+ if (has_l4_src_dst && (types & ip_l4_mask) == 0) {
+ if (!has_ip_pkt) {
+ hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set.");
+ return false;
+ }
+ /*
+ * For the case that the types has L4_SRC/DST_ONLY but hasn't
+ * IP-TCP/UDP/SCTP packet type, this types is considered valid
+ * if it also has IP packet type.
+ */
+ hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet.");
+ }
+
+ if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) {
+ final_types = types & HNS3_ETH_RSS_SUPPORT;
+ hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "",
+ types, final_types);
+ }
+
+ return true;
}
uint64_t
-hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
+hns3_rss_calc_tuple_filed(uint64_t rss_hf)
{
uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY |
RTE_ETH_RSS_L3_DST_ONLY;
@@ -548,7 +576,6 @@ hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
!has_l3_l4_only)
tuple |= hns3_set_tuple_table[i].rss_field;
}
- hns3_rss_check_l3l4_types(hw, rss_hf);
return tuple;
}
@@ -576,7 +603,7 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf)
uint64_t tuple_fields;
int ret;
- tuple_fields = hns3_rss_calc_tuple_filed(hw, rss_hf);
+ tuple_fields = hns3_rss_calc_tuple_filed(rss_hf);
ret = hns3_set_rss_tuple_field(hw, tuple_fields);
if (ret != 0)
hns3_err(hw, "Update RSS flow types tuples failed, ret = %d",
@@ -611,6 +638,9 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
return -EINVAL;
}
+ if (!hns3_check_rss_types_valid(hw, rss_hf))
+ return -EINVAL;
+
rte_spinlock_lock(&hw->lock);
ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf);
if (ret)
--git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 76c10afdde..931dacb813 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -184,6 +184,7 @@ int hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir,
int hns3_rss_reset_indir_table(struct hns3_hw *hw);
int hns3_config_rss(struct hns3_adapter *hns);
void hns3_rss_uninit(struct hns3_adapter *hns);
+bool hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types);
int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf);
int hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields);
int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields);
@@ -191,7 +192,7 @@ int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
const uint8_t *key, uint8_t key_len);
int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo,
uint8_t *key, uint8_t key_len);
-uint64_t hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf)
+uint64_t hns3_rss_calc_tuple_filed(uint64_t rss_hf);
int hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
uint8_t *key, uint8_t key_len);
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 21.11 00/17] backport some patches for hns3
2023-03-21 9:22 [PATCH 21.11 00/17] backport some patches for hns3 Huisong Li
` (16 preceding siblings ...)
2023-03-21 9:23 ` [PATCH 21.11 17/17] net/hns3: add verification of RSS types Huisong Li
@ 2023-03-21 16:21 ` Kevin Traynor
17 siblings, 0 replies; 19+ messages in thread
From: Kevin Traynor @ 2023-03-21 16:21 UTC (permalink / raw)
To: Huisong Li, stable; +Cc: liudongdong3, huangdaode, liuyonglong
On 21/03/2023 09:22, Huisong Li wrote:
> Some patches depends on the patch 13/17. So we also backport patch 13/17.
>
> Chengwen Feng (1):
> net/hns3: remove unused structures
>
> Huisong Li (16):
> net/hns3: separate Tx prepare from getting Tx function
> net/hns3: make getting Tx function static
> net/hns3: fix RSS key size compatibility
> net/hns3: fix burst mode query with dummy function
> net/hns3: extract common functions to set Rx/Tx
> net/hns3: use hardware config to report hash key
> net/hns3: use hardware config to report hash types
> net/hns3: separate setting hash algorithm
> net/hns3: separate setting hash key
> net/hns3: separate setting RSS types
> net/hns3: use new RSS rule to configure hardware
> net/hns3: save hash algo to RSS filter list node
> net/hns3: allow adding queue buffer size hash rule
> net/hns3: separate flow RSS config from RSS conf
> net/hns3: reimplement hash flow function
> net/hns3: add verification of RSS types
>
> drivers/net/hns3/hns3_cmd.h | 19 -
> drivers/net/hns3/hns3_common.c | 12 +-
> drivers/net/hns3/hns3_ethdev.c | 20 +-
> drivers/net/hns3/hns3_ethdev.h | 9 -
> drivers/net/hns3/hns3_ethdev_vf.c | 19 +-
> drivers/net/hns3/hns3_flow.c | 972 +++++++++++++++++++++---------
> drivers/net/hns3/hns3_flow.h | 23 +-
> drivers/net/hns3/hns3_mp.c | 4 +-
> drivers/net/hns3/hns3_rss.c | 563 ++++++++++++-----
> drivers/net/hns3/hns3_rss.h | 139 ++++-
> drivers/net/hns3/hns3_rxtx.c | 100 +--
> drivers/net/hns3/hns3_rxtx.h | 4 +-
> 12 files changed, 1289 insertions(+), 595 deletions(-)
>
Thanks Huisong. These are queued for 21.11 branch pending CI pass.
Kevin.
^ permalink raw reply [flat|nested] 19+ messages in thread