i40e: setup flow director only if enabled
authorJingjing Wu <jingjing.wu@intel.com>
Thu, 4 Dec 2014 15:40:23 +0000 (23:40 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Fri, 5 Dec 2014 15:55:00 +0000 (16:55 +0100)
In order not to affect the FVL's performance by default setting, this
patch moves the flow director initialization from i40e_pf_setup to
i40e_dev_configure according to the mode in fdir configure info.
Then the resources used for flow director will be only setup if it is enabled.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
app/test-pmd/cmdline.c
lib/librte_pmd_i40e/i40e_ethdev.c
lib/librte_pmd_i40e/i40e_fdir.c

index c61c3a0..f79ea3e 100644 (file)
@@ -8546,7 +8546,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
        }
        flex_mask.flow_type = str2flowtype(res->flow_type);
        fdir_set_flex_mask(res->port_id, &flex_mask);
-       cmd_reconfig_device_queue(res->port_id, 1, 0);
+       cmd_reconfig_device_queue(res->port_id, 1, 1);
 }
 
 cmdline_parse_token_string_t cmd_flow_director_flexmask =
@@ -8667,7 +8667,7 @@ cmd_flow_director_flxpld_parsed(void *parsed_result,
        }
 
        fdir_set_flex_payload(res->port_id, &flex_cfg);
-       cmd_reconfig_device_queue(res->port_id, 1, 0);
+       cmd_reconfig_device_queue(res->port_id, 1, 1);
 }
 
 cmdline_parse_token_string_t cmd_flow_director_flexpayload =
index 87e750a..002d4a9 100644 (file)
@@ -546,7 +546,6 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv,
 err_mac_alloc:
        i40e_vsi_release(pf->main_vsi);
 err_setup_pf_switch:
-       i40e_fdir_teardown(pf);
 err_get_mac_addr:
 err_configure_lan_hmc:
        (void)i40e_shutdown_lan_hmc(hw);
@@ -565,8 +564,27 @@ err_get_capabilities:
 static int
 i40e_dev_configure(struct rte_eth_dev *dev)
 {
-       int ret;
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        enum rte_eth_rx_mq_mode mq_mode = dev->data->dev_conf.rxmode.mq_mode;
+       int ret;
+
+       if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) {
+               ret = i40e_fdir_setup(pf);
+               if (ret != I40E_SUCCESS) {
+                       PMD_DRV_LOG(ERR, "Failed to setup flow director.");
+                       return -ENOTSUP;
+               }
+               ret = i40e_fdir_configure(dev);
+               if (ret < 0) {
+                       PMD_DRV_LOG(ERR, "failed to configure fdir.");
+                       goto err;
+               }
+       } else
+               i40e_fdir_teardown(pf);
+
+       ret = i40e_dev_init_vlan(dev);
+       if (ret < 0)
+               goto err;
 
        /* VMDQ setup.
         *  Needs to move VMDQ setting out of i40e_pf_config_mq_rx() as VMDQ and
@@ -583,10 +601,12 @@ i40e_dev_configure(struct rte_eth_dev *dev)
        if (mq_mode & ETH_MQ_RX_VMDQ_FLAG) {
                ret = i40e_vmdq_setup(dev);
                if (ret)
-                       return ret;
+                       goto err;
        }
-
-       return i40e_dev_init_vlan(dev);
+       return 0;
+err:
+       i40e_fdir_teardown(pf);
+       return ret;
 }
 
 void
@@ -837,14 +857,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
                i40e_vsi_enable_queues_intr(pf->vmdq[i].vsi);
        }
 
-       ret = i40e_fdir_configure(dev);
-       if (ret < 0) {
-               PMD_DRV_LOG(ERR, "failed to configure fdir.");
-               goto err_up;
-       }
-
        /* enable FDIR MSIX interrupt */
-       if (pf->flags & I40E_FLAG_FDIR) {
+       if (pf->fdir.fdir_vsi) {
                i40e_vsi_queues_bind_intr(pf->fdir.fdir_vsi);
                i40e_vsi_enable_queues_intr(pf->fdir.fdir_vsi);
        }
@@ -903,7 +917,7 @@ i40e_dev_stop(struct rte_eth_dev *dev)
                i40e_vsi_queues_unbind_intr(pf->vmdq[i].vsi);
        }
 
-       if (pf->flags & I40E_FLAG_FDIR) {
+       if (pf->fdir.fdir_vsi) {
                i40e_vsi_queues_bind_intr(pf->fdir.fdir_vsi);
                i40e_vsi_enable_queues_intr(pf->fdir.fdir_vsi);
        }
@@ -3302,15 +3316,6 @@ i40e_pf_setup(struct i40e_pf *pf)
        }
        pf->main_vsi = vsi;
 
-       /* setup FDIR after main vsi created.*/
-       if (pf->flags & I40E_FLAG_FDIR) {
-               ret = i40e_fdir_setup(pf);
-               if (ret != I40E_SUCCESS) {
-                       PMD_DRV_LOG(ERR, "Failed to setup flow director.");
-                       pf->flags &= ~I40E_FLAG_FDIR;
-               }
-       }
-
        /* Configure filter control */
        memset(&settings, 0, sizeof(settings));
        if (hw->func_caps.rss_table_size == ETH_RSS_RETA_SIZE_128)
index d75b96e..ad38803 100644 (file)
@@ -196,6 +196,11 @@ i40e_fdir_setup(struct i40e_pf *pf)
        const struct rte_memzone *mz = NULL;
        struct rte_eth_dev *eth_dev = pf->adapter->eth_dev;
 
+       if ((pf->flags & I40E_FLAG_FDIR) == 0) {
+               PMD_INIT_LOG(ERR, "HW doesn't support FDIR");
+               return I40E_NOT_SUPPORTED;
+       }
+
        PMD_DRV_LOG(INFO, "FDIR HW Capabilities: num_filters_guaranteed = %u,"
                        " num_filters_best_effort = %u.",
                        hw->func_caps.fd_filters_guaranteed,
@@ -203,9 +208,8 @@ i40e_fdir_setup(struct i40e_pf *pf)
 
        vsi = pf->fdir.fdir_vsi;
        if (vsi) {
-               PMD_DRV_LOG(ERR, "FDIR vsi pointer needs "
-                                "to be null before creation.");
-               return I40E_ERR_BAD_PTR;
+               PMD_DRV_LOG(INFO, "FDIR initialization has been done.");
+               return I40E_SUCCESS;
        }
        /* make new FDIR VSI */
        vsi = i40e_vsi_setup(pf, I40E_VSI_FDIR, pf->main_vsi, 0);
@@ -302,6 +306,8 @@ i40e_fdir_teardown(struct i40e_pf *pf)
        struct i40e_vsi *vsi;
 
        vsi = pf->fdir.fdir_vsi;
+       if (!vsi)
+               return;
        i40e_switch_tx_queue(hw, vsi->base_queue, FALSE);
        i40e_switch_rx_queue(hw, vsi->base_queue, FALSE);
        i40e_dev_rx_queue_release(pf->fdir.rxq);
@@ -653,37 +659,29 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
                }
        }
 
+       /* enable FDIR filter */
        val = I40E_READ_REG(hw, I40E_PFQF_CTL_0);
-       if ((pf->flags & I40E_FLAG_FDIR) &&
-               dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) {
-               /* enable FDIR filter */
-               val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
-               I40E_WRITE_REG(hw, I40E_PFQF_CTL_0, val);
+       val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
+       I40E_WRITE_REG(hw, I40E_PFQF_CTL_0, val);
 
-               i40e_init_flx_pld(pf); /* set flex config to default value */
+       i40e_init_flx_pld(pf); /* set flex config to default value */
 
-               conf = &dev->data->dev_conf.fdir_conf.flex_conf;
-               ret = i40e_check_fdir_flex_conf(conf);
-               if (ret < 0) {
-                       PMD_DRV_LOG(ERR, " invalid configuration arguments.");
-                       return -EINVAL;
-               }
-               /* configure flex payload */
-               for (i = 0; i < conf->nb_payloads; i++)
-                       i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
-               /* configure flex mask*/
-               for (i = 0; i < conf->nb_flexmasks; i++) {
-                       pctype = i40e_flowtype_to_pctype(
-                               conf->flex_mask[i].flow_type);
-                       i40e_set_flex_mask_on_pctype(pf,
-                                       pctype,
-                                       &conf->flex_mask[i]);
-               }
-       } else {
-               /* disable FDIR filter */
-               val &= ~I40E_PFQF_CTL_0_FD_ENA_MASK;
-               I40E_WRITE_REG(hw, I40E_PFQF_CTL_0, val);
-               pf->flags &= ~I40E_FLAG_FDIR;
+       conf = &dev->data->dev_conf.fdir_conf.flex_conf;
+       ret = i40e_check_fdir_flex_conf(conf);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR, " invalid configuration arguments.");
+               return -EINVAL;
+       }
+       /* configure flex payload */
+       for (i = 0; i < conf->nb_payloads; i++)
+               i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
+       /* configure flex mask*/
+       for (i = 0; i < conf->nb_flexmasks; i++) {
+               pctype = i40e_flowtype_to_pctype(
+                       conf->flex_mask[i].flow_type);
+               i40e_set_flex_mask_on_pctype(pf,
+                               pctype,
+                               &conf->flex_mask[i]);
        }
 
        return ret;
@@ -982,10 +980,12 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
        enum i40e_filter_pctype pctype;
        int ret = 0;
 
-       if (!(pf->flags & I40E_FLAG_FDIR)) {
-               PMD_DRV_LOG(ERR, "FDIR is not enabled.");
+       if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
+               PMD_DRV_LOG(ERR, "FDIR is not enabled, please"
+                       " check the mode in fdir_conf.");
                return -ENOTSUP;
        }
+
        if (!I40E_VALID_FLOW_TYPE(filter->input.flow_type)) {
                PMD_DRV_LOG(ERR, "invalid flow_type input.");
                return -EINVAL;
@@ -1263,8 +1263,11 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
        uint16_t num_flex_set = 0;
        uint16_t num_flex_mask = 0;
 
-       fdir->mode = (pf->flags & I40E_FLAG_FDIR) ?
-                       RTE_FDIR_MODE_PERFECT : RTE_FDIR_MODE_NONE;
+       if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT)
+               fdir->mode = RTE_FDIR_MODE_PERFECT;
+       else
+               fdir->mode = RTE_FDIR_MODE_NONE;
+
        fdir->guarant_spc =
                (uint32_t)hw->func_caps.fd_filters_guaranteed;
        fdir->best_spc =
@@ -1324,11 +1327,11 @@ i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        int ret = 0;
 
-       if (filter_op == RTE_ETH_FILTER_NOP) {
-               if (!(pf->flags & I40E_FLAG_FDIR))
-                       ret = -ENOTSUP;
-               return ret;
-       }
+       if ((pf->flags & I40E_FLAG_FDIR) == 0)
+               return -ENOTSUP;
+
+       if (filter_op == RTE_ETH_FILTER_NOP)
+               return 0;
 
        if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH)
                return -EINVAL;