[dpdk-dev] [PATCH v4 3/4] net/i40e: fix multiple driver support issue

2018-02-05 Thread Beilei Xing
This patch provides the option to disable writing some global registers
in PMD, in order to avoid affecting other drivers, when multiple drivers
run on the same NIC and control different physical ports. Because there
are few global resources shared among different physical ports.

Fixes: ec246eeb5da1 ("i40e: use default filter input set on init")
Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")
Fixes: f05ec7d77e41 ("i40e: initialize flow director flexible payload setting")
Fixes: e536c2e32883 ("net/i40e: fix parsing QinQ packets type")
Fixes: 19b16e2f6442 ("ethdev: add vlan type when setting ether type")
Cc: sta...@dpdk.org

Signed-off-by: Beilei Xing 
---
 drivers/net/i40e/i40e_ethdev.c | 215 -
 drivers/net/i40e/i40e_ethdev.h |   2 +
 2 files changed, 171 insertions(+), 46 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef23241..ae0f31a 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -944,6 +944,67 @@ config_floating_veb(struct rte_eth_dev *dev)
 #define I40E_L2_TAGS_S_TAG_SHIFT 1
 #define I40E_L2_TAGS_S_TAG_MASK I40E_MASK(0x1, I40E_L2_TAGS_S_TAG_SHIFT)
 
+#define ETH_I40E_SUPPORT_MULTI_DRIVER  "support-multi-driver"
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
+ ETH_I40E_SUPPORT_MULTI_DRIVER "=0|1");
+
+static int
+i40e_parse_multi_drv_handler(__rte_unused const char *key,
+ const char *value,
+ void *opaque)
+{
+   struct i40e_pf *pf;
+   unsigned long support_multi_driver;
+   char *end;
+
+   pf = (struct i40e_pf *)opaque;
+
+   errno = 0;
+   support_multi_driver = strtoul(value, &end, 10);
+   if (errno != 0 || end == value || *end != 0) {
+   PMD_DRV_LOG(WARNING, "Wrong global configuration");
+   return -(EINVAL);
+   }
+
+   if (support_multi_driver == 1 || support_multi_driver == 0)
+   pf->support_multi_driver = (bool)support_multi_driver;
+   else
+   PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
+   "enable global configuration by default."
+   ETH_I40E_SUPPORT_MULTI_DRIVER);
+   return 0;
+}
+
+static int
+i40e_support_multi_driver(struct rte_eth_dev *dev)
+{
+   struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   struct rte_pci_device *pci_dev = dev->pci_dev;
+   static const char *valid_keys[] = {
+   ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
+   struct rte_kvargs *kvlist;
+
+   /* Enable global configuration by default */
+   pf->support_multi_driver = false;
+
+   if (!pci_dev->device.devargs)
+   return 0;
+
+   kvlist = rte_kvargs_parse(pci_dev->device.devargs->args, valid_keys);
+   if (!kvlist)
+   return -EINVAL;
+
+   if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER) > 1)
+   PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+   "the first invalid or last valid one is used !",
+   ETH_I40E_SUPPORT_MULTI_DRIVER);
+
+   rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
+  i40e_parse_multi_drv_handler, pf);
+   rte_kvargs_free(kvlist);
+   return 0;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -993,6 +1054,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
hw->bus.func = pci_dev->addr.function;
hw->adapter_stopped = 0;
 
+   /* Check if need to support multi-driver */
+   i40e_support_multi_driver(dev);
+
/* Make sure all is clean before doing PF reset */
i40e_clear_hw(hw);
 
@@ -1019,7 +1083,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 * software. It should be removed once issues are fixed
 * in NVM.
 */
-   i40e_GLQF_reg_init(hw);
+   if (!pf->support_multi_driver)
+   i40e_GLQF_reg_init(hw);
 
/* Initialize the input set for filters (hash and fd) to default value 
*/
i40e_filter_input_set_init(pf);
@@ -1115,11 +1180,14 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
i40e_set_fc(hw, &aq_fail, TRUE);
 
/* Set the global registers with default ether type value */
-   ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
-   if (ret != I40E_SUCCESS) {
-   PMD_INIT_LOG(ERR, "Failed to set the default outer "
-"VLAN ether type");
-   goto err_setup_pf_switch;
+   if (!pf->support_multi_driver) {
+   ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
+ETHER_TYPE_VLAN);
+   if (ret != I40E_SUCCESS) {
+   PMD_INIT_LOG(ERR, "Failed to set the default outer "
+"VLAN ether type");
+  

[dpdk-dev] [PATCH v4 3/4] net/i40e: fix multiple driver support issue

2018-02-02 Thread Beilei Xing
This patch provides the option to disable writing some global registers
in PMD, in order to avoid affecting other drivers, when multiple drivers
run on the same NIC and control different physical ports. Because there
are few global resources shared among different physical ports.

Fixes: ec246eeb5da1 ("i40e: use default filter input set on init")
Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")
Fixes: f05ec7d77e41 ("i40e: initialize flow director flexible payload setting")
Fixes: e536c2e32883 ("net/i40e: fix parsing QinQ packets type")
Fixes: 19b16e2f6442 ("ethdev: add vlan type when setting ether type")

Signed-off-by: Beilei Xing 
---
 drivers/net/i40e/i40e_ethdev.c | 262 -
 drivers/net/i40e/i40e_ethdev.h |   1 +
 drivers/net/i40e/i40e_fdir.c   |  39 +++---
 drivers/net/i40e/i40e_flow.c   |   8 ++
 4 files changed, 240 insertions(+), 70 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index aad00aa..bede5c5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1039,6 +1039,64 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev)
memset(info, 0, sizeof(struct i40e_queue_regions));
 }
 
+#define ETH_I40E_SUPPORT_MULTI_DRIVER  "support-multi-driver"
+
+static int
+i40e_parse_multi_drv_handler(__rte_unused const char *key,
+  const char *value,
+  void *opaque)
+{
+   struct i40e_pf *pf;
+   unsigned long support_multi_driver;
+   char *end;
+
+   pf = (struct i40e_pf *)opaque;
+
+   errno = 0;
+   support_multi_driver = strtoul(value, &end, 10);
+   if (errno != 0 || end == value || *end != 0) {
+   PMD_DRV_LOG(WARNING, "Wrong global configuration");
+   return -(EINVAL);
+   }
+
+   if (support_multi_driver == 1 || support_multi_driver == 0)
+   pf->support_multi_driver = (bool)support_multi_driver;
+   else
+   PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
+   "enable global configuration by default."
+   ETH_I40E_SUPPORT_MULTI_DRIVER);
+   return 0;
+}
+
+static int
+i40e_support_multi_driver(struct rte_eth_dev *dev)
+{
+   struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   static const char *const valid_keys[] = {
+   ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
+   struct rte_kvargs *kvlist;
+
+   /* Enable global configuration by default */
+   pf->support_multi_driver = false;
+
+   if (!dev->device->devargs)
+   return 0;
+
+   kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+   if (!kvlist)
+   return -EINVAL;
+
+   if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER) > 1)
+   PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+   "the first invalid or last valid one is used !",
+   ETH_I40E_SUPPORT_MULTI_DRIVER);
+
+   rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
+  i40e_parse_multi_drv_handler, pf);
+   rte_kvargs_free(kvlist);
+   return 0;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -1092,6 +1150,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
hw->bus.func = pci_dev->addr.function;
hw->adapter_stopped = 0;
 
+   /* Check if need to support multi-driver */
+   i40e_support_multi_driver(dev);
+
/* Make sure all is clean before doing PF reset */
i40e_clear_hw(hw);
 
@@ -1119,7 +1180,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 * for packet type of QinQ by software.
 * It should be removed once issues are fixed in NVM.
 */
-   i40e_GLQF_reg_init(hw);
+   if (!pf->support_multi_driver)
+   i40e_GLQF_reg_init(hw);
 
/* Initialize the input set for filters (hash and fd) to default value 
*/
i40e_filter_input_set_init(pf);
@@ -1139,13 +1201,17 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
/* initialise the L3_MAP register */
-   ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
-  0x0028,  NULL);
-   if (ret)
-   PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d", ret);
-   PMD_INIT_LOG(DEBUG, "Global register 0x%08x is changed with value 0x28",
-I40E_GLQF_L3_MAP(40));
-   i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
+   if (!pf->support_multi_driver) {
+   ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
+  0x0028,  NULL);
+   if (ret)
+   PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d",
+