X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fi40e%2Fi40e_flow.c;h=3694df255ba41239a992cd220dcf37922cf7e0b6;hb=1ccdc31793aff57d5fe34041c7fa0aa9c00c7f5c;hp=6487596dad3e26da34b26d36a679c078c7fcfc71;hpb=2f4f2af37defd1eb32d453d78a2c4cfcc3baba04;p=dpdk.git diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 6487596dad..3694df255b 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -133,8 +133,8 @@ const struct rte_flow_ops i40e_flow_ops = { .flush = i40e_flow_flush, }; -union i40e_filter_t cons_filter; -enum rte_filter_type cons_filter_type = RTE_ETH_FILTER_NONE; +static union i40e_filter_t cons_filter; +static enum rte_filter_type cons_filter_type = RTE_ETH_FILTER_NONE; /* Pattern matched ethertype filter */ static enum rte_flow_item_type pattern_ethertype[] = { @@ -3127,6 +3127,7 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, struct rte_flow_error *error, union i40e_filter_t *filter) { + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct i40e_fdir_filter_conf *fdir_filter = &filter->fdir_filter; int ret; @@ -3148,14 +3149,29 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "Check the mode in fdir_conf."); - return -rte_errno; + /* Enable fdir when fdir flow is added at first time. */ + ret = i40e_fdir_setup(pf); + if (ret != I40E_SUCCESS) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_HANDLE, + NULL, "Failed to setup fdir."); + return -rte_errno; + } + ret = i40e_fdir_configure(dev); + if (ret < 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_HANDLE, + NULL, "Failed to configure fdir."); + goto err; + } + + dev->data->dev_conf.fdir_conf.mode = RTE_FDIR_MODE_PERFECT; } return 0; +err: + i40e_fdir_teardown(pf); + return -rte_errno; } /* Parse to get the action info of a tunnel filter @@ -4708,6 +4724,13 @@ i40e_flow_destroy(struct rte_eth_dev *dev, case RTE_ETH_FILTER_FDIR: ret = i40e_flow_add_del_fdir_filter(dev, &((struct i40e_fdir_filter *)flow->rule)->fdir, 0); + + /* If the last flow is destroyed, disable fdir. */ + if (!ret && !TAILQ_EMPTY(&pf->fdir.fdir_list)) { + i40e_fdir_teardown(pf); + dev->data->dev_conf.fdir_conf.mode = + RTE_FDIR_MODE_NONE; + } break; case RTE_ETH_FILTER_HASH: ret = i40e_config_rss_filter_del(dev, @@ -4900,6 +4923,8 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf) pf->fdir.inset_flag[pctype] = 0; } + i40e_fdir_teardown(pf); + return ret; }