patches for DPDK stable branches
 help / color / mirror / Atom feed
* [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue
@ 2018-02-09  7:41 Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 1/5] net/i40e: warn when writing global registers Beilei Xing
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

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 17.11 LTS.
Commit id: 3d2804be6e883ed31fe41dc79a840dbee96eb29a

Beilei Xing (5):
  net/i40e: warn when writing global registers
  net/i40e: add debug logs when writing global registers
  net/i40e: fix multiple driver support
  net/i40e: fix interrupt conflict with multi-driver
  net/i40e: fix Rx interrupt

 doc/guides/nics/i40e.rst          |  23 ++
 drivers/net/i40e/i40e_ethdev.c    | 470 +++++++++++++++++++++++++++++---------
 drivers/net/i40e/i40e_ethdev.h    |  61 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c |   4 +-
 drivers/net/i40e/i40e_fdir.c      |  39 ++--
 drivers/net/i40e/i40e_flow.c      |   8 +
 6 files changed, 476 insertions(+), 129 deletions(-)

-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [dpdk-stable] [BACKPORT 1/5] net/i40e: warn when writing global registers
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
@ 2018-02-09  7:41 ` Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 2/5] net/i40e: add debug logs " Beilei Xing
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

[ upstream commit 399c635c390121e8c7a7d6df72ef97a75ad8ee44 ]

Add warnings when writing global registers.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/nics/i40e.rst       | 12 ++++++++++++
 drivers/net/i40e/i40e_ethdev.c | 25 ++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h | 43 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index cd46874..efbc431 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -483,6 +483,18 @@ Vlan strip of VF
 
 The VF vlan strip function is only supported in the i40e kernel driver >= 2.1.26.
 
+Global configuration warning
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I40E PMD will set some global registers to enable some function or set some
+configure. Then when using different ports of the same NIC with Linux kernel
+and DPDK, the port with Linux kernel will be impacted by the port with DPDK.
+For example, register I40E_GL_SWT_L2TAGCTRL is used to control L2 tag, i40e
+PMD uses I40E_GL_SWT_L2TAGCTRL to set vlan TPID. If setting TPID in port A
+with DPDK, then the configuration will also impact port B in the NIC with
+kernel driver, which don't want to use the TPID.
+So PMD reports warning to clarify what is changed by writing global register.
+
 High Performance of Small Packets on 40G NIC
 --------------------------------------------
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f2c504..799cb16 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -710,6 +710,7 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	I40E_WRITE_REG(hw, I40E_GLQF_ORT(33), 0x000000E0);
 	I40E_WRITE_REG(hw, I40E_GLQF_ORT(34), 0x000000E3);
 	I40E_WRITE_REG(hw, I40E_GLQF_ORT(35), 0x000000E6);
+	i40e_global_cfg_warning(I40E_WARNING_ENA_FLX_PLD);
 
 	/*
 	 * Initialize registers for parsing packet type of QinQ
@@ -719,6 +720,7 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	 */
 	I40E_WRITE_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
 	I40E_WRITE_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
+	i40e_global_cfg_warning(I40E_WARNING_QINQ_PARSER);
 }
 
 #define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
@@ -1173,6 +1175,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 				   0x00000028,	NULL);
 	if (ret)
 		PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d", ret);
+	i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
 
 	/* Need the special FW version to support floating VEB */
 	config_floating_veb(dev);
@@ -3267,6 +3270,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
 		/* If NVM API < 1.7, keep the register setting */
 		ret = i40e_vlan_tpid_set_by_registers(dev, vlan_type,
 						      tpid, qinq);
+	i40e_global_cfg_warning(I40E_WARNING_TPID);
 
 	return ret;
 }
@@ -3509,6 +3513,7 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	I40E_WRITE_REG(hw, I40E_GLRPB_GLW,
 		       pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
 		       << I40E_KILOSHIFT);
+	i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
 
 	I40E_WRITE_FLUSH(hw);
 
@@ -7183,6 +7188,8 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
+	if (!status)
+		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
 	return status;
 }
 
@@ -7237,6 +7244,8 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
+	if (!status)
+		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
 	return status;
 }
 
@@ -7304,6 +7313,8 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
+	if (!status)
+		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
 	return status;
 }
 
@@ -7356,6 +7367,8 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
+	if (!status)
+		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
 	return status;
 }
 
@@ -7905,6 +7918,7 @@ i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
 						   reg, NULL);
 		if (ret != 0)
 			return ret;
+		i40e_global_cfg_warning(I40E_WARNING_GRE_KEY_LEN);
 	} else {
 		ret = 0;
 	}
@@ -8164,6 +8178,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 							  I40E_GLQF_HSYM(j),
 							  reg);
 			}
+			i40e_global_cfg_warning(I40E_WARNING_HSYM);
 		}
 	}
 
@@ -8189,6 +8204,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 		goto out;
 
 	i40e_write_rx_ctl(hw, I40E_GLQF_CTL, reg);
+	i40e_global_cfg_warning(I40E_WARNING_QF_CTL);
 
 out:
 	I40E_WRITE_FLUSH(hw);
@@ -8833,6 +8849,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 		pf->hash_input_set[pctype] = input_set;
 		pf->fdir.input_set[pctype] = input_set;
 	}
+
+	i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
+	i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+	i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
 }
 
 int
@@ -8893,6 +8913,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
 			     (uint32_t)((inset_reg >>
 			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+	i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
 
 	for (i = 0; i < num; i++)
 		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
@@ -8901,6 +8922,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
 		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
 				     0);
+	i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
 	I40E_WRITE_FLUSH(hw);
 
 	pf->hash_input_set[pctype] = input_set;
@@ -8974,6 +8996,7 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
 		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
 				     0);
+	i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
 	I40E_WRITE_FLUSH(hw);
 
 	pf->fdir.input_set[pctype] = input_set;
@@ -11476,6 +11499,8 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
 	ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 			&filter_replace_buf);
+	if (!ret)
+		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
 	return ret;
 }
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cd67453..f24555d 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -1084,6 +1084,22 @@ struct i40e_valid_pattern {
 	parse_filter_t parse_filter;
 };
 
+enum I40E_WARNING_IDX {
+	I40E_WARNING_DIS_FLX_PLD,
+	I40E_WARNING_ENA_FLX_PLD,
+	I40E_WARNING_QINQ_PARSER,
+	I40E_WARNING_QINQ_CLOUD_FILTER,
+	I40E_WARNING_TPID,
+	I40E_WARNING_FLOW_CTL,
+	I40E_WARNING_GRE_KEY_LEN,
+	I40E_WARNING_QF_CTL,
+	I40E_WARNING_HASH_INSET,
+	I40E_WARNING_HSYM,
+	I40E_WARNING_HASH_MSK,
+	I40E_WARNING_FD_MSK,
+	I40E_WARNING_RPL_CLD_FILTER,
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
@@ -1283,6 +1299,33 @@ i40e_calc_itr_interval(int16_t interval)
 	return interval / 2;
 }
 
+static inline void
+i40e_global_cfg_warning(enum I40E_WARNING_IDX idx)
+{
+	const char *warning;
+	static const char *const warning_list[] = {
+		[I40E_WARNING_DIS_FLX_PLD] = "disable FDIR flexible payload",
+		[I40E_WARNING_ENA_FLX_PLD] = "enable FDIR flexible payload",
+		[I40E_WARNING_QINQ_PARSER] = "support QinQ parser",
+		[I40E_WARNING_QINQ_CLOUD_FILTER] = "support QinQ cloud filter",
+		[I40E_WARNING_TPID] = "support TPID configuration",
+		[I40E_WARNING_FLOW_CTL] = "configure water marker",
+		[I40E_WARNING_GRE_KEY_LEN] = "support GRE key length setting",
+		[I40E_WARNING_QF_CTL] = "support hash function setting",
+		[I40E_WARNING_HASH_INSET] = "configure hash input set",
+		[I40E_WARNING_HSYM] = "set symmetric hash",
+		[I40E_WARNING_HASH_MSK] = "configure hash mask",
+		[I40E_WARNING_FD_MSK] = "configure fdir mask",
+		[I40E_WARNING_RPL_CLD_FILTER] = "replace cloud filter",
+	};
+
+	warning = warning_list[idx];
+
+	RTE_LOG(WARNING, PMD,
+		"Global register is changed during %s\n",
+		warning);
+}
+
 #define I40E_VALID_FLOW(flow_type) \
 	((flow_type) == RTE_ETH_FLOW_FRAG_IPV4 || \
 	(flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP || \
-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [dpdk-stable] [BACKPORT 2/5] net/i40e: add debug logs when writing global registers
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 1/5] net/i40e: warn when writing global registers Beilei Xing
@ 2018-02-09  7:41 ` Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 3/5] net/i40e: fix multiple driver support Beilei Xing
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

[ upstream commit bc66b9717c508c686c7b16900a588439f84d18ad ]

Add debug logs when writing global registers.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 135 +++++++++++++++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h |  11 ++++
 2 files changed, 107 insertions(+), 39 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 799cb16..f0c5710 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -684,6 +684,15 @@ rte_i40e_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static inline void
+i40e_write_global_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
+{
+	i40e_write_rx_ctl(hw, reg_addr, reg_val);
+	PMD_DRV_LOG(DEBUG, "Global register 0x%08x is modified "
+		    "with value 0x%08x",
+		    reg_addr, reg_val);
+}
+
 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci");
@@ -707,9 +716,9 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	 * configuration API is added to avoid configuration conflicts
 	 * between ports of the same device.
 	 */
-	I40E_WRITE_REG(hw, I40E_GLQF_ORT(33), 0x000000E0);
-	I40E_WRITE_REG(hw, I40E_GLQF_ORT(34), 0x000000E3);
-	I40E_WRITE_REG(hw, I40E_GLQF_ORT(35), 0x000000E6);
+	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33), 0x000000E0);
+	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(34), 0x000000E3);
+	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(35), 0x000000E6);
 	i40e_global_cfg_warning(I40E_WARNING_ENA_FLX_PLD);
 
 	/*
@@ -718,8 +727,8 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	 * configuration API is added to avoid configuration conflicts
 	 * between ports of the same device.
 	 */
-	I40E_WRITE_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
-	I40E_WRITE_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
+	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
+	I40E_WRITE_GLB_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
 	i40e_global_cfg_warning(I40E_WARNING_QINQ_PARSER);
 }
 
@@ -1175,6 +1184,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 				   0x00000028,	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);
 
 	/* Need the special FW version to support floating VEB */
@@ -3226,8 +3237,8 @@ i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev,
 		return -EIO;
 	}
 	PMD_DRV_LOG(DEBUG,
-		    "Debug write 0x%08"PRIx64" to I40E_GL_SWT_L2TAGCTRL[%d]",
-		    reg_w, reg_id);
+		    "Global register 0x%08x is changed with value 0x%08x",
+		    I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w);
 
 	return 0;
 }
@@ -3501,16 +3512,16 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	}
 
 	/* config the water marker both based on the packets and bytes */
-	I40E_WRITE_REG(hw, I40E_GLRPB_PHW,
+	I40E_WRITE_GLB_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,
+	I40E_WRITE_GLB_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,
+	I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
 		       pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
 		       << I40E_KILOSHIFT);
-	I40E_WRITE_REG(hw, I40E_GLRPB_GLW,
+	I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
 		       pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
 		       << I40E_KILOSHIFT);
 	i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
@@ -7285,6 +7296,10 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 					       &filter_replace_buf);
 	if (status < 0)
 		return status;
+	PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+		    "cloud l1 type is changed from 0x%x to 0x%x",
+		    filter_replace.old_filter_type,
+		    filter_replace.new_filter_type);
 
 	/* for GTP-U */
 	memset(&filter_replace, 0,
@@ -7313,8 +7328,13 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
-	if (!status)
+	if (!status) {
 		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+		PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+			    "cloud l1 type is changed from 0x%x to 0x%x",
+			    filter_replace.old_filter_type,
+			    filter_replace.new_filter_type);
+	}
 	return status;
 }
 
@@ -7346,6 +7366,10 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 					       &filter_replace_buf);
 	if (status < 0)
 		return status;
+	PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+		    "cloud filter type is changed from 0x%x to 0x%x",
+		    filter_replace.old_filter_type,
+		    filter_replace.new_filter_type);
 
 	/* for GTP-U */
 	memset(&filter_replace, 0,
@@ -7367,8 +7391,13 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 
 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 					       &filter_replace_buf);
-	if (!status)
+	if (!status) {
 		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+		PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+			    "cloud filter type is changed from 0x%x to 0x%x",
+			    filter_replace.old_filter_type,
+			    filter_replace.new_filter_type);
+	}
 	return status;
 }
 
@@ -7918,6 +7947,9 @@ i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
 						   reg, NULL);
 		if (ret != 0)
 			return ret;
+		PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed "
+			    "with value 0x%08x",
+			    I40E_GL_PRS_FVBM(2), reg);
 		i40e_global_cfg_warning(I40E_WARNING_GRE_KEY_LEN);
 	} else {
 		ret = 0;
@@ -8174,7 +8206,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 			for (j = I40E_FILTER_PCTYPE_INVALID + 1;
 			     j < I40E_FILTER_PCTYPE_MAX; j++) {
 				if (adapter->pctypes_tbl[i] & (1ULL << j))
-					i40e_write_rx_ctl(hw,
+					i40e_write_global_rx_ctl(hw,
 							  I40E_GLQF_HSYM(j),
 							  reg);
 			}
@@ -8203,7 +8235,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 		/* Use the default, and keep it as it is */
 		goto out;
 
-	i40e_write_rx_ctl(hw, I40E_GLQF_CTL, reg);
+	i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg);
 	i40e_global_cfg_warning(I40E_WARNING_QF_CTL);
 
 out:
@@ -8793,6 +8825,18 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+void
+i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
+{
+	uint32_t reg = i40e_read_rx_ctl(hw, addr);
+
+	PMD_DRV_LOG(DEBUG, "[0x%08x] original: 0x%08x", addr, reg);
+	if (reg != val)
+		i40e_write_global_rx_ctl(hw, addr, val);
+	PMD_DRV_LOG(DEBUG, "[0x%08x] after: 0x%08x", addr,
+		    (uint32_t)i40e_read_rx_ctl(hw, addr));
+}
+
 static void
 i40e_filter_input_set_init(struct i40e_pf *pf)
 {
@@ -8824,24 +8868,28 @@ 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),
+		i40e_check_write_global_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),
+		i40e_check_write_global_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]);
+			i40e_check_write_global_reg(hw,
+						    I40E_GLQF_FD_MSK(i, pctype),
+						    mask_reg[i]);
+			i40e_check_write_global_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);
+			i40e_check_write_global_reg(hw,
+						    I40E_GLQF_FD_MSK(i, pctype),
+						    0);
+			i40e_check_write_global_reg(hw,
+						  I40E_GLQF_HASH_MSK(i, pctype),
+						  0);
 		}
 		I40E_WRITE_FLUSH(hw);
 
@@ -8908,20 +8956,20 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 
 	inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
 
-	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));
+	i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				    (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				    (uint32_t)((inset_reg >>
+				    I40E_32_BIT_WIDTH) & UINT32_MAX));
 	i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
 
 	for (i = 0; i < num; i++)
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-				     mask_reg[i]);
+		i40e_check_write_global_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_HASH_MSK(i, pctype),
-				     0);
+		i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					    0);
 	i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
 	I40E_WRITE_FLUSH(hw);
 
@@ -8990,12 +9038,12 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 			     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_global_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);
+		i40e_check_write_global_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					    0);
 	i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
 	I40E_WRITE_FLUSH(hw);
 
@@ -11478,6 +11526,10 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
 			&filter_replace_buf);
 	if (ret != I40E_SUCCESS)
 		return ret;
+	PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+		    "cloud l1 type is changed from 0x%x to 0x%x",
+		    filter_replace.old_filter_type,
+		    filter_replace.new_filter_type);
 
 	/* Apply the second L2 cloud filter */
 	memset(&filter_replace, 0,
@@ -11499,8 +11551,13 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
 	ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
 			&filter_replace_buf);
-	if (!ret)
+	if (!ret) {
 		i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+		PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+			    "cloud filter type is changed from 0x%x to 0x%x",
+			    filter_replace.old_filter_type,
+			    filter_replace.new_filter_type);
+	}
 	return ret;
 }
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f24555d..31d38d7 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -106,6 +106,15 @@
 	(((vf)->version_major == VIRTCHNL_VERSION_MAJOR) && \
 	((vf)->version_minor == 1))
 
+#define I40E_WRITE_GLB_REG(hw, reg, value)				\
+	do {								\
+		I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw),		\
+						     (reg)), (value));	\
+		PMD_DRV_LOG(DEBUG, "Global register 0x%08x is modified " \
+			    "with value 0x%08x",			\
+			    (reg), (value));				\
+	} while (0)
+
 /* index flex payload per layer */
 enum i40e_flxpld_layer_idx {
 	I40E_FLXPLD_L2_IDX    = 0,
@@ -1202,6 +1211,8 @@ int i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask,
 				 uint8_t nb_elem);
 uint64_t i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input);
 void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val);
+void i40e_check_write_global_reg(struct i40e_hw *hw,
+				 uint32_t addr, uint32_t val);
 
 int i40e_tm_ops_get(struct rte_eth_dev *dev, void *ops);
 void i40e_tm_conf_init(struct rte_eth_dev *dev);
-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [dpdk-stable] [BACKPORT 3/5] net/i40e: fix multiple driver support
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 1/5] net/i40e: warn when writing global registers Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 2/5] net/i40e: add debug logs " Beilei Xing
@ 2018-02-09  7:41 ` Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 4/5] net/i40e: fix interrupt conflict with multi-driver Beilei Xing
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

[ upstream commit cfdfca493caebc5e8ae5708aa21a827791649456 ]

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 <beilei.xing@intel.com>
---
 doc/guides/nics/i40e.rst       |  11 ++
 drivers/net/i40e/i40e_ethdev.c | 254 ++++++++++++++++++++++++++++++++---------
 drivers/net/i40e/i40e_ethdev.h |   1 +
 drivers/net/i40e/i40e_fdir.c   |  39 ++++---
 drivers/net/i40e/i40e_flow.c   |   8 ++
 5 files changed, 246 insertions(+), 67 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index efbc431..71d9561 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -134,6 +134,17 @@ Driver compilation and testing
 Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
 for details.
 
+- ``Support multiple driver`` (default ``disable``)
+
+  There was a multiple driver support issue during use of 700 series Ethernet
+  Adapter with both Linux kernel and DPDK PMD. To fix this issue, ``devargs``
+  parameter ``support-multi-driver`` is introduced, for example::
+
+    -w 84:00.0,support-multi-driver=1
+
+  With the above configuration, DPDK PMD will not change global registers, and
+  will switch PF interrupt from IntN to Int0 to avoid interrupt conflict between
+  DPDK and Linux Kernel.
 
 SR-IOV: Prerequisites and sample Application Notes
 --------------------------------------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f0c5710..3a141b1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1079,6 +1079,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)
 {
@@ -1132,6 +1190,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);
 
@@ -1160,7 +1221,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);
@@ -1180,13 +1242,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),
-				   0x00000028,	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),
+						   0x00000028,	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 0x28",
+			     I40E_GLQF_L3_MAP(40));
+		i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
+	}
 
 	/* Need the special FW version to support floating VEB */
 	config_floating_veb(dev);
@@ -1262,11 +1328,15 @@ 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");
+			goto err_setup_pf_switch;
+		}
 	}
 
 	/* PF setup, which includes VSI setup */
@@ -3249,6 +3319,7 @@ 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);
 	int qinq = dev->data->dev_conf.rxmode.hw_vlan_extend;
 	int ret = 0;
 
@@ -3259,6 +3330,12 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
 			    "Unsupported vlan type.");
 		return -EINVAL;
 	}
+
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Setting TPID is not supported.");
+		return -ENOTSUP;
+	}
+
 	/* 802.1ad frames ability is added in NVM API 1.7*/
 	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
 		if (qinq) {
@@ -3511,20 +3588,25 @@ 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_GLB_REG(hw, I40E_GLRPB_PHW,
-		       (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-	I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
-		       (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-	I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
-		       pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT);
-	I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
-		       pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-		       << I40E_KILOSHIFT);
-	i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
+	if (!pf->support_multi_driver) {
+		/* config water marker both based on the packets and bytes */
+		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW,
+				 (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+				 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
+				  (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+				 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
+				  pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+				  << I40E_KILOSHIFT);
+		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
+				   pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+				   << I40E_KILOSHIFT);
+		i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
+	} else {
+		PMD_DRV_LOG(ERR,
+			    "Water marker configuration is not supported.");
+	}
 
 	I40E_WRITE_FLUSH(hw);
 
@@ -7163,6 +7245,11 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+		return I40E_NOT_SUPPORTED;
+	}
+
 	memset(&filter_replace, 0,
 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
 	memset(&filter_replace_buf, 0,
@@ -7212,6 +7299,11 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+		return I40E_NOT_SUPPORTED;
+	}
+
 	/* For MPLSoUDP */
 	memset(&filter_replace, 0,
 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7268,6 +7360,11 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+		return I40E_NOT_SUPPORTED;
+	}
+
 	/* For GTP-C */
 	memset(&filter_replace, 0,
 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7346,6 +7443,11 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+		return I40E_NOT_SUPPORTED;
+	}
+
 	/* for GTP-C */
 	memset(&filter_replace, 0,
 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7927,9 +8029,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->support_multi_driver) {
+		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", val);
 
@@ -8181,6 +8289,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
 	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
 	int ret;
 	uint16_t i, j;
 	uint32_t reg;
@@ -8193,6 +8302,11 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 	uint32_t mask0 = g_cfg->valid_bit_mask[0] &
 					(uint32_t)adapter->flow_types_mask;
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Hash global configuration is not supported.");
+		return -ENOTSUP;
+	}
+
 	/* Check the input parameters */
 	ret = i40e_hash_global_config_check(adapter, g_cfg);
 	if (ret < 0)
@@ -8860,6 +8974,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 						   I40E_INSET_MASK_NUM_REG);
 		if (num < 0)
 			return;
+		if (pf->support_multi_driver && 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);
 
@@ -8868,39 +8986,48 @@ 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_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-
-		for (i = 0; i < num; i++) {
+		if (!pf->support_multi_driver) {
+			i40e_check_write_global_reg(hw,
+					    I40E_GLQF_HASH_INSET(0, pctype),
+					    (uint32_t)(inset_reg & UINT32_MAX));
 			i40e_check_write_global_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_global_reg(hw,
 						    I40E_GLQF_FD_MSK(i, pctype),
 						    mask_reg[i]);
-			i40e_check_write_global_reg(hw,
+				i40e_check_write_global_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_global_reg(hw,
+			}
+			/*clear unused mask registers of the pctype */
+			for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+				i40e_check_write_global_reg(hw,
 						    I40E_GLQF_FD_MSK(i, pctype),
 						    0);
-			i40e_check_write_global_reg(hw,
+				i40e_check_write_global_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->support_multi_driver)
+			pf->hash_input_set[pctype] = input_set;
 		pf->fdir.input_set[pctype] = input_set;
 	}
 
-	i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
-	i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
-	i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
+	if (!pf->support_multi_driver) {
+		i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
+		i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+		i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
+	}
 }
 
 int
@@ -8923,6 +9050,11 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Hash input set setting is not supported.");
+		return -ENOTSUP;
+	}
+
 	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
 	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
@@ -9028,6 +9160,10 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 					   I40E_INSET_MASK_NUM_REG);
 	if (num < 0)
 		return -EINVAL;
+	if (pf->support_multi_driver && 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);
 
@@ -9037,14 +9173,20 @@ 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_global_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_global_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					    0);
-	i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+	if (!pf->support_multi_driver) {
+		for (i = 0; i < num; i++)
+			i40e_check_write_global_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_global_reg(hw,
+						    I40E_GLQF_FD_MSK(i, pctype),
+						    0);
+		i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+	} else {
+		PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+	}
 	I40E_WRITE_FLUSH(hw);
 
 	pf->fdir.input_set[pctype] = input_set;
@@ -11496,6 +11638,11 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 
+	if (pf->support_multi_driver) {
+		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+		return ret;
+	}
+
 	/* Init */
 	memset(&filter_replace, 0,
 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -11572,3 +11719,6 @@ i40e_init_log(void)
 	if (i40e_logtype_driver >= 0)
 		rte_log_set_level(i40e_logtype_driver, RTE_LOG_NOTICE);
 }
+
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
+			      ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 31d38d7..6bf427e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -966,6 +966,7 @@ struct i40e_pf {
 	bool gtp_replace_flag;   /* 1 - GTP-C/U filter replace is done */
 	bool qinq_replace_flag;  /* QINQ filter replace is done */
 	struct i40e_tm_conf tm_conf;
+	bool support_multi_driver; /* 1 - support multiple driver */
 
 	/* Dynamic Device Personalization */
 	bool gtp_support; /* 1 - support GTP-C and GTP-U */
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index bf94723..6802995 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -669,22 +669,31 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 		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++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			/* get translated pctype value in fd pctype register */
-			pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
-				hw, I40E_GLQF_FD_PCTYPES(
-				(int)i40e_flowtype_to_pctype(pf->adapter,
-				conf->flex_mask[i].flow_type)));
-		} else
-			pctype = i40e_flowtype_to_pctype(pf->adapter,
-						conf->flex_mask[i].flow_type);
 
-		i40e_set_flex_mask_on_pctype(pf, pctype, &conf->flex_mask[i]);
+	if (!pf->support_multi_driver) {
+		/* 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++) {
+			if (hw->mac.type == I40E_MAC_X722) {
+				/* get pctype value in fd pctype register */
+				pctype = (enum i40e_filter_pctype)
+					  i40e_read_rx_ctl(hw,
+						I40E_GLQF_FD_PCTYPES(
+						(int)i40e_flowtype_to_pctype(
+						pf->adapter,
+						conf->flex_mask[i].flow_type)));
+			} else {
+				pctype = i40e_flowtype_to_pctype(pf->adapter,
+						  conf->flex_mask[i].flow_type);
+			}
+
+			i40e_set_flex_mask_on_pctype(pf, pctype,
+						     &conf->flex_mask[i]);
+		}
+	} else {
+		PMD_DRV_LOG(ERR, "Not support flexible payload.");
 	}
 
 	return ret;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b935ea7..37380e6 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2877,6 +2877,14 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 				return -rte_errno;
 			}
 
+			if (pf->support_multi_driver) {
+				rte_flow_error_set(error, ENOTSUP,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Unsupported flexible payload.");
+				return -rte_errno;
+			}
+
 			ret = i40e_flow_check_raw_item(item, raw_spec, error);
 			if (ret < 0)
 				return ret;
-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [dpdk-stable] [BACKPORT 4/5] net/i40e: fix interrupt conflict with multi-driver
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
                   ` (2 preceding siblings ...)
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 3/5] net/i40e: fix multiple driver support Beilei Xing
@ 2018-02-09  7:41 ` Beilei Xing
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 5/5] net/i40e: fix Rx interrupt Beilei Xing
  2018-02-11  3:08 ` [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Yuanhan Liu
  5 siblings, 0 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

[ upstream commit 4ab831449a1cb9ff76e662fd04ce32ee585d6f85 ]

There's interrupt conflict when using DPDK and Linux i40e
on different ports of the same Ethernet controller, this
patch fixes it by switching from IntN to Int0 if multiple
drivers are used.

Fixes: be6c228d4da3 ("i40e: support Rx interrupt")

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 89 +++++++++++++++++++++++++--------------
 drivers/net/i40e/i40e_ethdev.h    |  6 ++-
 drivers/net/i40e/i40e_ethdev_vf.c |  4 +-
 3 files changed, 63 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3a141b1..5c6e3eb 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -732,6 +732,23 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	i40e_global_cfg_warning(I40E_WARNING_QINQ_PARSER);
 }
 
+static inline void i40e_config_automask(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	uint32_t val;
+
+	/* INTENA flag is not auto-cleared for interrupt */
+	val = I40E_READ_REG(hw, I40E_GLINT_CTL);
+	val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
+		I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
+
+	/* If support multi-driver, PF will use INT0. */
+	if (!pf->support_multi_driver)
+		val |= I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK;
+
+	I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
+}
+
 #define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
 
 /*
@@ -1213,6 +1230,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return ret;
 	}
 
+	i40e_config_automask(pf);
+
 	i40e_set_default_pctype_table(dev);
 
 	/*
@@ -1725,6 +1744,7 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
 	int i;
 	uint32_t val;
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
 
 	/* Bind all RX queues to allocated MSIX interrupt */
 	for (i = 0; i < nb_queue; i++) {
@@ -1743,7 +1763,8 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
 	/* Write first RX queue to Link list register as the head element */
 	if (vsi->type != I40E_VSI_SRIOV) {
 		uint16_t interval =
-			i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
+			i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL,
+					       pf->support_multi_driver);
 
 		if (msix_vect == I40E_MISC_VEC_ID) {
 			I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
@@ -1802,7 +1823,6 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
 	uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
 	uint16_t queue_idx = 0;
 	int record = 0;
-	uint32_t val;
 	int i;
 
 	for (i = 0; i < vsi->nb_qps; i++) {
@@ -1810,13 +1830,6 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
 		I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0);
 	}
 
-	/* INTENA flag is not auto-cleared for interrupt */
-	val = I40E_READ_REG(hw, I40E_GLINT_CTL);
-	val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
-		I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK |
-		I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
-	I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
-
 	/* VF bind interrupt */
 	if (vsi->type == I40E_VSI_SRIOV) {
 		__vsi_queues_bind_intr(vsi, msix_vect,
@@ -1873,27 +1886,22 @@ i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
-	uint16_t interval = i40e_calc_itr_interval(\
-		RTE_LIBRTE_I40E_ITR_INTERVAL);
+	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
 	uint16_t msix_intr, i;
 
-	if (rte_intr_allow_others(intr_handle))
+	if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
 		for (i = 0; i < vsi->nb_msix; i++) {
 			msix_intr = vsi->msix_intr + i;
 			I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
 				I40E_PFINT_DYN_CTLN_INTENA_MASK |
 				I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-				(0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-				(interval <<
-				 I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+			        I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
 		}
 	else
 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
 			       I40E_PFINT_DYN_CTL0_INTENA_MASK |
 			       I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
-			       (0 << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT) |
-			       (interval <<
-				I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT));
+			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 
 	I40E_WRITE_FLUSH(hw);
 }
@@ -1905,16 +1913,18 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
 	uint16_t msix_intr, i;
 
-	if (rte_intr_allow_others(intr_handle))
+	if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
 		for (i = 0; i < vsi->nb_msix; i++) {
 			msix_intr = vsi->msix_intr + i;
 			I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
-				       0);
+				       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
 		}
 	else
-		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 
 	I40E_WRITE_FLUSH(hw);
 }
@@ -5098,16 +5108,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 
 	/* VF has MSIX interrupt in VF range, don't allocate here */
 	if (type == I40E_VSI_MAIN) {
-		ret = i40e_res_pool_alloc(&pf->msix_pool,
-					  RTE_MIN(vsi->nb_qps,
-						  RTE_MAX_RXTX_INTR_VEC_ID));
-		if (ret < 0) {
-			PMD_DRV_LOG(ERR, "VSI MAIN %d get heap failed %d",
-				    vsi->seid, ret);
-			goto fail_queue_alloc;
+		if (pf->support_multi_driver) {
+			/* If support multi-driver, need to use INT0 instead of
+			 * allocating from msix pool. The Msix pool is init from
+			 * INT1, so it's OK just set msix_intr to 0 and nb_msix
+			 * to 1 without calling i40e_res_pool_alloc.
+			 */
+			vsi->msix_intr = 0;
+			vsi->nb_msix = 1;
+		} else {
+			ret = i40e_res_pool_alloc(&pf->msix_pool,
+						  RTE_MIN(vsi->nb_qps,
+						     RTE_MAX_RXTX_INTR_VEC_ID));
+			if (ret < 0) {
+				PMD_DRV_LOG(ERR,
+					    "VSI MAIN %d get heap failed %d",
+					    vsi->seid, ret);
+				goto fail_queue_alloc;
+			}
+			vsi->msix_intr = ret;
+			vsi->nb_msix = RTE_MIN(vsi->nb_qps,
+					       RTE_MAX_RXTX_INTR_VEC_ID);
 		}
-		vsi->msix_intr = ret;
-		vsi->nb_msix = RTE_MIN(vsi->nb_qps, RTE_MAX_RXTX_INTR_VEC_ID);
 	} else if (type != I40E_VSI_SRIOV) {
 		ret = i40e_res_pool_alloc(&pf->msix_pool, 1);
 		if (ret < 0) {
@@ -6024,7 +6046,8 @@ void
 i40e_pf_disable_irq0(struct i40e_hw *hw)
 {
 	/* Disable all interrupt types */
-	I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+	I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+		       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -10973,11 +10996,13 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
 static int
 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t interval =
-		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
+		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL,
+				       pf->support_multi_driver);
 	uint16_t msix_intr;
 
 	msix_intr = intr_handle->intr_vec[queue_id];
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 6bf427e..229c974 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -1302,9 +1302,11 @@ i40e_align_floor(int n)
 }
 
 static inline uint16_t
-i40e_calc_itr_interval(int16_t interval)
+i40e_calc_itr_interval(int16_t interval, bool is_multi_drv)
 {
-	if (interval < 0 || interval > I40E_QUEUE_ITR_INTERVAL_MAX)
+	if (is_multi_drv)
+		interval = I40E_QUEUE_ITR_INTERVAL_MAX;
+	else if (interval < 0 || interval > I40E_QUEUE_ITR_INTERVAL_MAX)
 		interval = I40E_QUEUE_ITR_INTERVAL_DEFAULT;
 
 	/* Convert to hardware count, as writing each 1 represents 2 us */
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 2d71d7c..b36ba9f 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1167,7 +1167,7 @@ i40evf_init_vf(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	uint16_t interval =
-		i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
+		i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX, 0);
 
 	vf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	vf->dev_data = dev->data;
@@ -1870,7 +1870,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t interval =
-		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
+		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 0);
 	uint16_t msix_intr;
 
 	msix_intr = intr_handle->intr_vec[queue_id];
-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [dpdk-stable] [BACKPORT 5/5] net/i40e: fix Rx interrupt
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
                   ` (3 preceding siblings ...)
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 4/5] net/i40e: fix interrupt conflict with multi-driver Beilei Xing
@ 2018-02-09  7:41 ` Beilei Xing
  2018-02-11  3:08 ` [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Yuanhan Liu
  5 siblings, 0 replies; 7+ messages in thread
From: Beilei Xing @ 2018-02-09  7:41 UTC (permalink / raw)
  To: stable

[ upstream commit 378cc7f569a678e1c8469094104b757864c4ad05 ]

This patch fixes interval error and corrects macros when
enabling Rx interrupt mode. The patch also fixes a logical
error during supporting multiple drivers.

Fixes: be6c228d4da3 ("i40e: support Rx interrupt")

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5c6e3eb..b6ee8d1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10996,32 +10996,24 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
 static int
 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint16_t interval =
-		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL,
-				       pf->support_multi_driver);
 	uint16_t msix_intr;
 
 	msix_intr = intr_handle->intr_vec[queue_id];
 	if (msix_intr == I40E_MISC_VEC_ID)
 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
-			       I40E_PFINT_DYN_CTLN_INTENA_MASK |
-			       I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-			       (0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-			       (interval <<
-				I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+			       I40E_PFINT_DYN_CTL0_INTENA_MASK |
+			       I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
+			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 	else
 		I40E_WRITE_REG(hw,
 			       I40E_PFINT_DYN_CTLN(msix_intr -
 						   I40E_RX_VEC_START),
 			       I40E_PFINT_DYN_CTLN_INTENA_MASK |
 			       I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-			       (0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-			       (interval <<
-				I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+			       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
 
 	I40E_WRITE_FLUSH(hw);
 	rte_intr_enable(&pci_dev->intr_handle);
@@ -11039,12 +11031,13 @@ i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 
 	msix_intr = intr_handle->intr_vec[queue_id];
 	if (msix_intr == I40E_MISC_VEC_ID)
-		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 	else
 		I40E_WRITE_REG(hw,
 			       I40E_PFINT_DYN_CTLN(msix_intr -
 						   I40E_RX_VEC_START),
-			       0);
+			       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
 	I40E_WRITE_FLUSH(hw);
 
 	return 0;
-- 
2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue
  2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
                   ` (4 preceding siblings ...)
  2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 5/5] net/i40e: fix Rx interrupt Beilei Xing
@ 2018-02-11  3:08 ` Yuanhan Liu
  5 siblings, 0 replies; 7+ messages in thread
From: Yuanhan Liu @ 2018-02-11  3:08 UTC (permalink / raw)
  To: Beilei Xing; +Cc: stable

On Fri, Feb 09, 2018 at 03:41:35PM +0800, Beilei Xing wrote:
> 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 17.11 LTS.
> Commit id: 3d2804be6e883ed31fe41dc79a840dbee96eb29a

Series Applied to dpdk-stable/17.11.

Thanks!

	--yliu

> 
> Beilei Xing (5):
>   net/i40e: warn when writing global registers
>   net/i40e: add debug logs when writing global registers
>   net/i40e: fix multiple driver support
>   net/i40e: fix interrupt conflict with multi-driver
>   net/i40e: fix Rx interrupt
> 
>  doc/guides/nics/i40e.rst          |  23 ++
>  drivers/net/i40e/i40e_ethdev.c    | 470 +++++++++++++++++++++++++++++---------
>  drivers/net/i40e/i40e_ethdev.h    |  61 ++++-
>  drivers/net/i40e/i40e_ethdev_vf.c |   4 +-
>  drivers/net/i40e/i40e_fdir.c      |  39 ++--
>  drivers/net/i40e/i40e_flow.c      |   8 +
>  6 files changed, 476 insertions(+), 129 deletions(-)
> 
> -- 
> 2.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-02-11  3:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09  7:41 [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Beilei Xing
2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 1/5] net/i40e: warn when writing global registers Beilei Xing
2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 2/5] net/i40e: add debug logs " Beilei Xing
2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 3/5] net/i40e: fix multiple driver support Beilei Xing
2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 4/5] net/i40e: fix interrupt conflict with multi-driver Beilei Xing
2018-02-09  7:41 ` [dpdk-stable] [BACKPORT 5/5] net/i40e: fix Rx interrupt Beilei Xing
2018-02-11  3:08 ` [dpdk-stable] [BACKPORT 0/5] net/i40e: fix multiple driver support issue Yuanhan Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).