From: Long Wu <long...@corigine.com> Add the corresponding logics to support the offload of RSS action.
Signed-off-by: Long Wu <long...@corigine.com> Reviewed-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Peng Zhang <peng.zh...@corigine.com> --- doc/guides/nics/features/nfp.ini | 1 + drivers/net/nfp/flower/nfp_flower_flow.c | 124 ++++++++++++++++++ drivers/net/nfp/flower/nfp_flower_flow.h | 8 ++ .../net/nfp/flower/nfp_flower_representor.c | 6 + .../net/nfp/flower/nfp_flower_representor.h | 1 + 5 files changed, 140 insertions(+) diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini index 3494111f86..b20049b4f5 100644 --- a/doc/guides/nics/features/nfp.ini +++ b/doc/guides/nics/features/nfp.ini @@ -59,6 +59,7 @@ queue = Y raw_decap = Y raw_encap = Y represented_port = Y +rss = Y port_id = Y set_ipv4_dscp = Y set_ipv4_dst = Y diff --git a/drivers/net/nfp/flower/nfp_flower_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c index b3a2c1cdaf..086cc8079a 100644 --- a/drivers/net/nfp/flower/nfp_flower_flow.c +++ b/drivers/net/nfp/flower/nfp_flower_flow.c @@ -1143,6 +1143,9 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[], key_ls->act_size += sizeof(struct nfp_fl_act_mark); PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_MARK detected"); break; + case RTE_FLOW_ACTION_TYPE_RSS: + PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RSS detected"); + break; default: PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type); return -ENOTSUP; @@ -3509,6 +3512,116 @@ nfp_flow_action_mark(char *act_data, fl_mark->mark = rte_cpu_to_be_32(mark->id); } +static int +nfp_flow_action_rss_add(struct nfp_flower_representor *representor, + const struct rte_flow_action *action, + struct nfp_fl_rss **rss_store) +{ + int ret; + struct nfp_net_hw *pf_hw; + struct rte_eth_rss_conf rss_conf; + struct nfp_fl_rss *rss_store_tmp; + const struct rte_flow_action_rss *rss; + uint8_t rss_key[NFP_NET_CFG_RSS_KEY_SZ]; + + if (nfp_flower_repr_is_vf(representor)) + return 0; + + rss = action->conf; + + if (rss->key_len > NFP_NET_CFG_RSS_KEY_SZ) { + PMD_DRV_LOG(ERR, "Unsupported rss key length."); + return -ENOTSUP; + } + + rss_conf.rss_hf = 0; + rss_conf.rss_key = rss_key; + pf_hw = representor->app_fw_flower->pf_hw; + ret = nfp_net_rss_hash_conf_get(pf_hw->eth_dev, &rss_conf); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Get RSS conf failed."); + return ret; + } + + rss_store_tmp = calloc(1, sizeof(struct nfp_fl_rss)); + if (rss_store_tmp == NULL) { + PMD_DRV_LOG(ERR, "Alloc memory for rss storage failed."); + return -ENOMEM; + } + + if (rss->types != 0) { + rss_conf.rss_hf |= rss->types; + + rss_store_tmp->types = rss->types; + } + + if (rss->key_len != 0 && rss->key != NULL) { + memcpy(rss_conf.rss_key, rss->key, rss->key_len); + rss_conf.rss_key_len = rss->key_len; + + memcpy(rss_store_tmp->key, rss->key, rss->key_len); + rss_store_tmp->key_len = rss->key_len; + } + + ret = nfp_net_rss_hash_update(pf_hw->eth_dev, &rss_conf); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Update RSS conf failed."); + free(rss_store_tmp); + return ret; + } + + *rss_store = rss_store_tmp; + + return 0; +} + +static int +nfp_flow_action_rss_del(struct nfp_flower_representor *representor, + struct rte_flow *nfp_flow) +{ + int ret; + struct nfp_net_hw *pf_hw; + struct nfp_fl_rss *rss_store; + struct rte_eth_rss_conf rss_conf; + uint8_t rss_key[NFP_NET_CFG_RSS_KEY_SZ]; + + if (nfp_flower_repr_is_vf(representor)) + return 0; + + rss_conf.rss_hf = 0; + rss_conf.rss_key = rss_key; + pf_hw = representor->app_fw_flower->pf_hw; + ret = nfp_net_rss_hash_conf_get(pf_hw->eth_dev, &rss_conf); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Get RSS conf failed."); + goto exit; + } + + rss_store = nfp_flow->rss; + + if ((rss_conf.rss_hf & rss_store->types) != 0) + rss_conf.rss_hf &= (~(rss_store->types)); + + /* Need default RSS configuration */ + if (rss_conf.rss_hf == 0) + rss_conf.rss_hf = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6; + + if (rss_conf.rss_key_len == rss_store->key_len && + memcmp(rss_conf.rss_key, rss_store->key, rss_store->key_len) == 0) { + rss_conf.rss_key = NULL; + rss_conf.rss_key_len = 0; + } + + ret = nfp_net_rss_hash_update(pf_hw->eth_dev, &rss_conf); + if (ret != 0) + PMD_DRV_LOG(ERR, "Update RSS conf failed."); + +exit: + free(nfp_flow->rss); + + return ret; +} + static uint32_t nfp_flow_count_output(const struct rte_flow_action actions[]) { @@ -3761,6 +3874,13 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor, nfp_flow_action_mark(position, action); position += sizeof(struct nfp_fl_act_mark); break; + case RTE_FLOW_ACTION_TYPE_RSS: + PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_RSS"); + ret = nfp_flow_action_rss_add(representor, action, &nfp_flow->rss); + if (ret != 0) + return ret; + nfp_flow->type = NFP_FLOW_RSS; + break; default: PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type); return -ENOTSUP; @@ -4099,6 +4219,10 @@ nfp_flow_destroy(struct rte_eth_dev *dev, /* Delete the entry in pre tunnel table */ ret = nfp_pre_tun_table_check_del(representor, nfp_flow); break; + case NFP_FLOW_RSS: + /* Clear corresponding RSS configuration */ + ret = nfp_flow_action_rss_del(representor, nfp_flow); + break; default: PMD_DRV_LOG(ERR, "Invalid nfp flow type %d.", nfp_flow->type); ret = -EINVAL; diff --git a/drivers/net/nfp/flower/nfp_flower_flow.h b/drivers/net/nfp/flower/nfp_flower_flow.h index 75f18c6bd5..5d927edde9 100644 --- a/drivers/net/nfp/flower/nfp_flower_flow.h +++ b/drivers/net/nfp/flower/nfp_flower_flow.h @@ -33,6 +33,7 @@ enum nfp_flow_type { NFP_FLOW_COMMON, NFP_FLOW_ENCAP, NFP_FLOW_DECAP, + NFP_FLOW_RSS, }; struct nfp_fl_key_ls { @@ -121,6 +122,12 @@ struct nfp_ipv6_addr_entry { int ref_count; }; +struct nfp_fl_rss { + uint8_t key[NFP_NET_CFG_RSS_KEY_SZ]; + uint32_t key_len; + uint64_t types; +}; + #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 struct nfp_flow_priv { @@ -166,6 +173,7 @@ struct nfp_flow_priv { struct rte_flow { struct nfp_fl_payload payload; struct nfp_fl_tun tun; + struct nfp_fl_rss *rss; size_t length; uint32_t hash_key; uint32_t mtr_id; diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c index 7284a1e84d..b2c55879ca 100644 --- a/drivers/net/nfp/flower/nfp_flower_representor.c +++ b/drivers/net/nfp/flower/nfp_flower_representor.c @@ -860,3 +860,9 @@ nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower) return ret; } + +bool +nfp_flower_repr_is_vf(struct nfp_flower_representor *repr) +{ + return repr->repr_type == NFP_REPR_TYPE_VF; +} diff --git a/drivers/net/nfp/flower/nfp_flower_representor.h b/drivers/net/nfp/flower/nfp_flower_representor.h index 8053617562..7a4e7ecfc1 100644 --- a/drivers/net/nfp/flower/nfp_flower_representor.h +++ b/drivers/net/nfp/flower/nfp_flower_representor.h @@ -24,5 +24,6 @@ struct nfp_flower_representor { }; int nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower); +bool nfp_flower_repr_is_vf(struct nfp_flower_representor *repr); #endif /* __NFP_FLOWER_REPRESENTOR_H__ */ -- 2.39.1