[dpdk-dev] net/i40e: add device args to disable global configuration

Message ID 1516702905-131472-1-git-send-email-beilei.xing@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Helin Zhang
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation fail apply patch file failure

Commit Message

Xing, Beilei Jan. 23, 2018, 10:21 a.m. UTC
  DPDK i40e PMD will modify some global registers during initialization
and post initialization, there'll be impact during use of 700 series
Ethernet Adapter with both Linux kernel and DPDK PMD.
This patch is to add device parameters to disable global configuration.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---

This patch is based on 16.11.4 LTS version.

 drivers/net/i40e/i40e_ethdev.c | 208 ++++++++++++++++++++++++++++++++---------
 drivers/net/i40e/i40e_ethdev.h |   2 +
 2 files changed, 165 insertions(+), 45 deletions(-)
  

Comments

Xing, Beilei Feb. 1, 2018, 11:59 a.m. UTC | #1
DPDK i40e PMD will modify some global registers during initialization
and post initialization, there'll be impact during use of 700 series
Ethernet Adapter with both Linux kernel and DPDK PMD.
This patchset adds logs for global configuration and adds device args
to disable global configuration.

This patchset is based on 16.11.4 LTS.
Commit id: 516447a5056c093e4d020011a69216b453576782

v2 changes:
 - Add warning logs and debug logs.

Beilei Xing (3):
  net/i40e: add warnings when writing global registers
  net/i40e: add debug logs when writing global registers
  net/i40e: fix multiple driver support issue

 doc/guides/nics/i40e.rst       |  12 ++
 drivers/net/i40e/i40e_ethdev.c | 319 +++++++++++++++++++++++++++++++----------
 drivers/net/i40e/i40e_ethdev.h |  54 +++++++
 3 files changed, 309 insertions(+), 76 deletions(-)
  
Xing, Beilei Feb. 2, 2018, 12:25 p.m. UTC | #2
DPDK i40e PMD will modify some global registers during initialization
and post initialization, there'll be impact during use of 700 series
Ethernet Adapter with both Linux kernel and DPDK PMD.
This patchset adds logs for global configuration and adds device args
to disable global configuration and change interrupt for PF.

This patchset is based on 16.11.4 LTS.
Commit id: 516447a5056c093e4d020011a69216b453576782

v3 changes:
 - Fix interrupt conflict when using multiple driver.

v2 changes:
 - Add warning logs and debug logs.
 

Beilei Xing (4):
  net/i40e: add warnings when writing global registers
  net/i40e: add debug logs when writing global registers
  net/i40e: fix multiple driver support issue
  net/i40e: fix interrupt conflict when using multi-driver

 doc/guides/nics/i40e.rst          |  12 ++
 drivers/net/i40e/i40e_ethdev.c    | 412 ++++++++++++++++++++++++++++----------
 drivers/net/i40e/i40e_ethdev.h    |  63 +++++-
 drivers/net/i40e/i40e_ethdev_vf.c |   4 +-
 4 files changed, 377 insertions(+), 114 deletions(-)
  
Xing, Beilei Feb. 5, 2018, 8:31 a.m. UTC | #3
DPDK i40e PMD will modify some global registers during initialization
and post initialization, there'll be impact during use of 700 series
Ethernet Adapter with both Linux kernel and DPDK PMD.
This patchset adds logs for global configuration and adds device args
to disable global configuration and change interrupt for PF.

This patchset is based on 16.11.4 LTS.
Commit id: 516447a5056c093e4d020011a69216b453576782

v4 changes:
 - Add doc for new parameter.
 - Fix logical error.

v3 changes:
 - Fix interrupt conflict when using multiple driver.

v2 changes:
 - Add warning logs and debug logs.

Beilei Xing (4):
  net/i40e: add warnings when writing global registers
  net/i40e: add debug logs when writing global registers
  net/i40e: fix multiple driver support issue
  net/i40e: fix interrupt conflict when using multi-driver

 doc/guides/nics/i40e.rst          |  27 +++
 drivers/net/i40e/i40e_ethdev.c    | 412 ++++++++++++++++++++++++++++----------
 drivers/net/i40e/i40e_ethdev.h    |  63 +++++-
 drivers/net/i40e/i40e_ethdev_vf.c |   4 +-
 4 files changed, 392 insertions(+), 114 deletions(-)
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0835c2d..0df5cba 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -933,6 +933,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_DISABLE_GLOBAL_CFG	"disable-global-cfg"
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
+			      ETH_I40E_DISABLE_GLOBAL_CFG "=0|1");
+
+static int
+i40e_parse_global_cfg_handler(__rte_unused const char *key,
+			      const char *value,
+			      void *opaque)
+{
+	struct i40e_pf *pf;
+	unsigned long dis_global_cfg;
+	char *end;
+
+	pf = (struct i40e_pf *)opaque;
+
+	errno = 0;
+	dis_global_cfg = strtoul(value, &end, 10);
+	if (errno != 0 || end == value || *end != 0) {
+		PMD_DRV_LOG(WARNING, "Wrong global configuration");
+		return -(EINVAL);
+	}
+
+	if (dis_global_cfg == 1 || dis_global_cfg == 0)
+		pf->dis_global_cfg = (bool)dis_global_cfg;
+	else
+		PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
+			    "enable global configuration by default."
+			    ETH_I40E_DISABLE_GLOBAL_CFG);
+	return 0;
+}
+
+static int
+i40e_disable_global_cfg(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_DISABLE_GLOBAL_CFG, NULL};
+	struct rte_kvargs *kvlist;
+
+	/* Enable global configuration by default */
+	pf->dis_global_cfg = 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_DISABLE_GLOBAL_CFG) > 1)
+		PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+			    "the first invalid or last valid one is used !",
+			    ETH_I40E_DISABLE_GLOBAL_CFG);
+
+	rte_kvargs_process(kvlist, ETH_I40E_DISABLE_GLOBAL_CFG,
+			   i40e_parse_global_cfg_handler, pf);
+	rte_kvargs_free(kvlist);
+	return 0;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -982,6 +1043,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 disable global registers configuration */
+	i40e_disable_global_cfg(dev);
+
 	/* Make sure all is clean before doing PF reset */
 	i40e_clear_hw(hw);
 
@@ -1008,7 +1072,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->dis_global_cfg)
+		i40e_GLQF_reg_init(hw);
 
 	/* Initialize the input set for filters (hash and fd) to default value */
 	i40e_filter_input_set_init(pf);
@@ -1104,11 +1169,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->dis_global_cfg) {
+		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;
+		}
 	}
 
 	/* PF setup, which includes VSI setup */
@@ -2743,11 +2811,17 @@  i40e_vlan_tpid_set(struct rte_eth_dev *dev,
 		   uint16_t tpid)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	uint64_t reg_r = 0, reg_w = 0;
 	uint16_t reg_id = 0;
 	int ret = 0;
 	int qinq = dev->data->dev_conf.rxmode.hw_vlan_extend;
 
+	if (pf->dis_global_cfg) {
+		PMD_DRV_LOG(ERR, "Setting TPID is not supported.");
+		return -ENOTSUP;
+	}
+
 	switch (vlan_type) {
 	case ETH_VLAN_TYPE_OUTER:
 		if (qinq)
@@ -3025,19 +3099,23 @@  i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg);
 	}
 
-	/* config the water marker both based on the packets and bytes */
-	I40E_WRITE_REG(hw, I40E_GLRPB_PHW,
-		       (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-	I40E_WRITE_REG(hw, I40E_GLRPB_PLW,
-		       (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-	I40E_WRITE_REG(hw, I40E_GLRPB_GHW,
-		       pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT);
-	I40E_WRITE_REG(hw, I40E_GLRPB_GLW,
-		       pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT);
+	if (!pf->dis_global_cfg) {
+		/* config water marker both based on the packets and bytes */
+		I40E_WRITE_REG(hw, I40E_GLRPB_PHW,
+			       (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+				<< I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+		I40E_WRITE_REG(hw, I40E_GLRPB_PLW,
+			       (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+				<< I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+		I40E_WRITE_REG(hw, I40E_GLRPB_GHW,
+			       pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+			       << I40E_KILOSHIFT);
+		I40E_WRITE_REG(hw, I40E_GLRPB_GLW,
+			       pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+			       << I40E_KILOSHIFT);
+	} else
+		PMD_DRV_LOG(ERR,
+			    "Water marker configuration is not supported.");
 
 	I40E_WRITE_FLUSH(hw);
 
@@ -6855,9 +6933,15 @@  i40e_tunnel_filter_param_check(struct i40e_pf *pf,
 static int
 i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
 {
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
 	uint32_t val, reg;
 	int ret = -EINVAL;
 
+	if (pf->dis_global_cfg) {
+		PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported");
+		return -ENOTSUP;
+	}
+
 	val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2));
 	PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x\n", val);
 
@@ -7095,12 +7179,18 @@  static int
 i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
 	int ret;
 	uint16_t i;
 	uint32_t reg;
 	uint32_t mask0 = g_cfg->valid_bit_mask[0];
 	enum i40e_filter_pctype pctype;
 
+	if (pf->dis_global_cfg) {
+		PMD_DRV_LOG(ERR, "Hash global configuration is not supported.");
+		return -ENOTSUP;
+	}
+
 	/* Check the input parameters */
 	ret = i40e_hash_global_config_check(g_cfg);
 	if (ret < 0)
@@ -7815,6 +7905,12 @@  i40e_filter_input_set_init(struct i40e_pf *pf)
 						   I40E_INSET_MASK_NUM_REG);
 		if (num < 0)
 			return;
+
+		if (pf->dis_global_cfg && num > 0) {
+			PMD_DRV_LOG(ERR, "Input set setting is not supported.");
+			return;
+		}
+
 		inset_reg = i40e_translate_input_set_reg(hw->mac.type,
 					input_set);
 
@@ -7823,29 +7919,38 @@  i40e_filter_input_set_init(struct i40e_pf *pf)
 		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
 				     (uint32_t)((inset_reg >>
 				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
 
-		for (i = 0; i < num; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-		/*clear unused mask registers of the pctype */
-		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-		}
+		if (!pf->dis_global_cfg) {
+			i40e_check_write_reg(hw,
+					    I40E_GLQF_HASH_INSET(0, pctype),
+					    (uint32_t)(inset_reg & UINT32_MAX));
+			i40e_check_write_reg(hw,
+					     I40E_GLQF_HASH_INSET(1, pctype),
+					     (uint32_t)((inset_reg >>
+					      I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+			for (i = 0; i < num; i++) {
+				i40e_check_write_reg(hw,
+						    I40E_GLQF_FD_MSK(i, pctype),
+						    mask_reg[i]);
+				i40e_check_write_reg(hw,
+						  I40E_GLQF_HASH_MSK(i, pctype),
+						  mask_reg[i]);
+			}
+			/*clear unused mask registers of the pctype */
+			for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+				i40e_check_write_reg(hw,
+						I40E_GLQF_FD_MSK(i, pctype), 0);
+				i40e_check_write_reg(hw,
+					      I40E_GLQF_HASH_MSK(i, pctype), 0);
+			}
+		} else
+			PMD_DRV_LOG(ERR, "Input set setting is not supported.");
 		I40E_WRITE_FLUSH(hw);
 
 		/* store the default input set */
-		pf->hash_input_set[pctype] = input_set;
+		if (!pf->dis_global_cfg)
+			pf->hash_input_set[pctype] = input_set;
 		pf->fdir.input_set[pctype] = input_set;
 	}
 }
@@ -7860,6 +7965,11 @@  i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
 	int ret, i, num;
 
+	if (pf->dis_global_cfg) {
+		PMD_DRV_LOG(ERR, "Hash input set setting is not supported.");
+		return -ENOTSUP;
+	}
+
 	if (!conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
@@ -7984,6 +8094,11 @@  i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	if (num < 0)
 		return -EINVAL;
 
+	if (pf->dis_global_cfg && num > 0) {
+		PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+		return -ENOTSUP;
+	}
+
 	inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
 
 	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
@@ -7992,13 +8107,16 @@  i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 			     (uint32_t)((inset_reg >>
 			     I40E_32_BIT_WIDTH) & UINT32_MAX));
 
-	for (i = 0; i < num; i++)
-		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-				     mask_reg[i]);
-	/*clear unused mask registers of the pctype */
-	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
-		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-				     0);
+	if (!pf->dis_global_cfg) {
+		for (i = 0; i < num; i++)
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+	} else
+		PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
 	I40E_WRITE_FLUSH(hw);
 
 	pf->fdir.input_set[pctype] = input_set;
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f283319..2c6180c 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -477,6 +477,8 @@  struct i40e_pf {
 	bool floating_veb; /* The flag to use the floating VEB */
 	/* The floating enable flag for the specific VF */
 	bool floating_veb_list[I40E_MAX_VF];
+
+	bool dis_global_cfg; /* 1 - disable changing global register */
 };
 
 enum pending_msg {