case RTE_ETH_HASH_FUNCTION_DEFAULT:
case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
+ case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
break;
default:
return rte_flow_error_set(error, ENOTSUP,
/* Disable RSS */
hw->rss_info.conf.types = 0;
+ hw->rss_dis_flag = true;
return 0;
}
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(%u)",
algo_func);
static int
hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
{
- uint8_t hash_algo =
- (hw->rss_info.conf.func == RTE_ETH_HASH_FUNCTION_TOEPLITZ ?
- HNS3_RSS_HASH_ALGO_TOEPLITZ : HNS3_RSS_HASH_ALGO_SIMPLE);
struct hns3_rss_tuple_cfg *tuple;
int ret;
hns3_parse_rss_key(hw, rss_config);
/* Parse hash algorithm */
- ret = hns3_parse_rss_algorithm(hw, &rss_config->func, &hash_algo);
+ ret = hns3_parse_rss_algorithm(hw, &rss_config->func,
+ &hw->rss_info.hash_algo);
if (ret)
return ret;
- ret = hns3_set_rss_algo_key(hw, hash_algo, rss_config->key);
+ ret = hns3_set_rss_algo_key(hw, rss_config->key);
if (ret)
return ret;
return -EINVAL;
}
+ if (rss_flow_conf.key_len &&
+ rss_flow_conf.key_len > RTE_DIM(rss_info->key)) {
+ hns3_err(hw,
+ "input hash key(%u) greater than supported len(%zu)",
+ rss_flow_conf.key_len, RTE_DIM(rss_info->key));
+ return -EINVAL;
+ }
+
/* Filter the unsupported flow types */
- flow_types = rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT;
+ flow_types = conf->conf.types ?
+ rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT :
+ hw->rss_info.conf.types;
if (flow_types != rss_flow_conf.types)
hns3_warn(hw, "modified RSS types based on hardware support, "
"requested:%" PRIx64 " configured:%" PRIx64,
/* Update the useful flow types */
rss_flow_conf.types = flow_types;
- if ((rss_flow_conf.types & ETH_RSS_PROTO_MASK) == 0)
- return hns3_disable_rss(hw);
-
rss_info = &hw->rss_info;
if (!add) {
if (hns3_action_rss_same(&rss_info->conf, &rss_flow_conf)) {
return hns3_config_rss_filter(dev, &hw->rss_info, false);
}
+/* Restore the rss filter */
+int
+hns3_restore_rss_filter(struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+
+ if (hw->rss_info.conf.queue_num == 0)
+ return 0;
+
+ return hns3_config_rss_filter(dev, &hw->rss_info, true);
+}
+
static int
hns3_flow_parse_rss(struct rte_eth_dev *dev,
const struct hns3_rss_conf *conf, bool add)
}
ret = hns3_clear_rss_filter(dev);
- if (ret)
+ if (ret) {
+ rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE,
+ NULL, "Failed to flush rss filter");
return ret;
+ }
hns3_filterlist_flush(dev);
struct hns3_hw *hw;
int ret = 0;
- if (dev == NULL)
- return -EINVAL;
hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
switch (filter_type) {
case RTE_ETH_FILTER_GENERIC: