DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes
       [not found] <1503569908-104074-1-git-send-email-kirill.rybalchenko@intel.com>
@ 2017-09-01 15:02 ` Kirill Rybalchenko
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
                     ` (5 more replies)
  0 siblings, 6 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-01 15:02 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to map new flow types to pctypes without changing
API of the driver.

v2:
Remove unnecessary check for new flow types.
Re-arrange patchset to avoid compillation errors.
Remove unnecessary usage of statically defined flow types and pctypes.

Kirill Rybalchenko (4):
  net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  net/i40e: add new functions to manipulate with pctype mapping table
  app/testpmd: add new commands to manipulate with pctype mapping
  ethdev: remove unnecessary check for new flow type

 app/test-pmd/cmdline.c                      | 311 ++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  21 ++
 drivers/net/i40e/i40e_ethdev.c              | 347 +++++++---------------------
 drivers/net/i40e/i40e_ethdev.h              |  16 +-
 drivers/net/i40e/i40e_ethdev_vf.c           |  36 +--
 drivers/net/i40e/i40e_fdir.c                |  51 ++--
 drivers/net/i40e/i40e_flow.c                |   2 +-
 drivers/net/i40e/i40e_rxtx.c                |  57 +++++
 drivers/net/i40e/i40e_rxtx.h                |   1 +
 drivers/net/i40e/rte_pmd_i40e.c             |  98 ++++++++
 drivers/net/i40e/rte_pmd_i40e.h             |  61 +++++
 lib/librte_ether/rte_ethdev.c               |   8 -
 12 files changed, 671 insertions(+), 338 deletions(-)

-- 
2.5.5

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

* [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
@ 2017-09-01 15:02   ` Kirill Rybalchenko
  2017-09-04 16:49     ` Ananyev, Konstantin
  2017-09-08 16:58     ` Ferruh Yigit
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
                     ` (4 subsequent siblings)
  5 siblings, 2 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-01 15:02 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to add new flow types and pctypes for DDP without changing
API of the driver. The mapping table is located in private
data area for particular network adapter and can be individually
modified with set of appropriate functions.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
v2
Re-arrange patchset to avoid compillation errors.
Remove usage of statically defined flow types and pctypes.
---
 drivers/net/i40e/i40e_ethdev.c    | 347 ++++++++++----------------------------
 drivers/net/i40e/i40e_ethdev.h    |  16 +-
 drivers/net/i40e/i40e_ethdev_vf.c |  36 ++--
 drivers/net/i40e/i40e_fdir.c      |  51 +++---
 drivers/net/i40e/i40e_flow.c      |   2 +-
 drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
 drivers/net/i40e/i40e_rxtx.h      |   1 +
 7 files changed, 190 insertions(+), 320 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8e0580c..56a96f5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1062,6 +1062,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(dev);
+	i40e_set_default_pctype_table(dev);
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	intr_handle = &pci_dev->intr_handle;
 
@@ -2971,7 +2972,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
 						sizeof(uint32_t);
 	dev_info->reta_size = pf->hash_lut_size;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_msk;
 
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
@@ -6562,104 +6563,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
 
 /* Configure hash enable flags for RSS */
 uint64_t
-i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
+i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter)
 {
 	uint64_t hena = 0;
+	int i;
 
 	if (!flags)
 		return hena;
 
-	if (flags & ETH_RSS_FRAG_IPV4)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-	if (flags & ETH_RSS_FRAG_IPV6)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
-	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & (1ULL << i))
+			hena |= adapter->pcypes_tbl[i];
 	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-	if (flags & ETH_RSS_L2_PAYLOAD)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
 	return hena;
 }
 
 /* Parse the hash enable flags */
 uint64_t
-i40e_parse_hena(uint64_t flags)
+i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter)
 {
 	uint64_t rss_hf = 0;
 
 	if (!flags)
 		return rss_hf;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-		rss_hf |= ETH_RSS_FRAG_IPV4;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-		rss_hf |= ETH_RSS_FRAG_IPV6;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
-		rss_hf |= ETH_RSS_L2_PAYLOAD;
+	int i;
 
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & adapter->pcypes_tbl[i])
+			rss_hf |= (1ULL << i);
+	}
 	return rss_hf;
 }
 
@@ -6668,16 +6601,9 @@ static void
 i40e_pf_disable_rss(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -6749,23 +6675,14 @@ static int
 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t rss_hf;
 	uint64_t hena;
 	int ret;
 
-	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key,
-			       rss_conf->rss_key_len);
+	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, rss_conf->rss_key_len);
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, pf->adapter);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
@@ -6779,14 +6696,13 @@ i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_msk;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & pf->adapter->pctypes_msk)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0; /* Nothing to do */
@@ -6811,7 +6727,7 @@ i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(hena, pf->adapter);
 
 	return 0;
 }
@@ -7586,7 +7502,7 @@ i40e_pf_config_rss(struct i40e_pf *pf)
 	}
 
 	rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & pf->adapter->flow_types_msk) == 0) {
 		i40e_pf_disable_rss(pf);
 		return 0;
 	}
@@ -7807,9 +7723,9 @@ static int
 i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
-	uint32_t reg, mask = I40E_FLOW_TYPES;
-	uint16_t i;
-	enum i40e_filter_pctype pctype;
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	uint32_t reg;
+	uint16_t i, j;
 
 	memset(g_cfg, 0, sizeof(*g_cfg));
 	reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
@@ -7820,29 +7736,31 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 	PMD_DRV_LOG(DEBUG, "Hash function is %s",
 		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
-	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
-		if (!(mask & (1UL << i)))
-			continue;
-		mask &= ~(1UL << i);
-		/* Bit set indicats the coresponding flow type is supported */
-		g_cfg->valid_bit_mask[0] |= (1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
-		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
-			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
+	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_msk;
+
+	for (i = 0; i < UINT32_BIT; i++) {
+		if (adapter->pcypes_tbl[i]) {
+			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
+				if (adapter->pcypes_tbl[i] & (1ULL << j)) {
+					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
+					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
+						g_cfg->sym_hash_enable_mask[0] |=
+									(1UL << i);
+					}
+				}
+			}
+		}
 	}
 
 	return 0;
 }
 
 static int
-i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
+i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg,
+			      struct i40e_adapter *adapter)
 {
 	uint32_t i;
-	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
+	uint32_t mask0, i40e_mask = adapter->flow_types_msk;
 
 	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
 		g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -7885,64 +7803,26 @@ static int
 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;
 	int ret;
-	uint16_t i;
+	uint16_t i, j;
 	uint32_t reg;
-	uint32_t mask0 = g_cfg->valid_bit_mask[0];
-	enum i40e_filter_pctype pctype;
+	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_msk;
 
 	/* Check the input parameters */
-	ret = i40e_hash_global_config_check(g_cfg);
+	ret = i40e_hash_global_config_check(g_cfg, adapter);
 	if (ret < 0)
 		return ret;
 
-	for (i = 0; mask0 && i < UINT32_BIT; i++) {
-		if (!(mask0 & (1UL << i)))
-			continue;
-		mask0 &= ~(1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
-				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK),
-				  reg);
-			} else {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
-				  reg);
+	for (i = 0; i < UINT32_BIT; i++) {
+		if (mask0 & (1UL << i)) {
+			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+					I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+
+			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
+				if (adapter->pcypes_tbl[i] & (1ULL << j))
+					i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(j), reg);
 			}
-		} else {
-			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
 		}
 	}
 
@@ -8567,13 +8447,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pctype, pf->adapter);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 
 		input_set = i40e_get_default_input_set(pctype);
 
@@ -8636,7 +8513,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -8644,10 +8522,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	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(
-			conf->flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(conf->flow_type);
+			I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
@@ -8655,11 +8531,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
+
 	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
 		/* get inset value in register */
 		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
@@ -8713,24 +8585,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
+
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
 
-	pctype = i40e_flowtype_to_pctype(conf->flow_type);
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
 
 	/* get inset value in register */
 	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
@@ -9169,72 +9036,34 @@ i40e_hw_init(struct rte_eth_dev *dev)
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
 }
 
-enum i40e_filter_pctype
-i40e_flowtype_to_pctype(uint16_t flow_type)
-{
-	static const enum i40e_filter_pctype pctype_table[] = {
-		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
-		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
-		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
-	};
+uint16_t
+i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
+{
+	int i;
+	uint64_t pctype_mask;
 
-	return pctype_table[flow_type];
+	if (flow_type < I40E_FLOW_TYPE_MAX) {
+		pctype_mask = adapter->pcypes_tbl[flow_type];
+		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
+			if (pctype_mask & (1ULL << i))
+				return (uint16_t)i;
+		}
+	}
+	return 0;
 }
 
 uint16_t
-i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
+i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter)
 {
-	static const uint16_t flowtype_table[] = {
-		[I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_OTHER,
-		[I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_OTHER,
-		[I40E_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_FLOW_L2_PAYLOAD,
-	};
+	uint16_t flowtype = RTE_ETH_FLOW_UNKNOWN;
+	uint64_t pctype_mask = 1ULL << pctype;
+
+	for (; flowtype < I40E_FLOW_TYPE_MAX; flowtype++) {
+		if (adapter->pcypes_tbl[flowtype] & pctype_mask)
+			return flowtype;
+	}
 
-	return flowtype_table[pctype];
+	return flowtype;
 }
 
 /*
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index ad80f0f..a8fdad3 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -852,7 +852,9 @@ struct i40e_vf {
 	uint64_t flags;
 };
 
-#define I40E_MAX_PKT_TYPE 256
+#define I40E_MAX_PKT_TYPE  256
+#define I40E_FLOW_TYPE_MAX 64
+#define I40E_PCTYPE_MAX    64
 
 /*
  * Structure to store private data for each PF/VF instance.
@@ -881,6 +883,10 @@ struct i40e_adapter {
 
 	/* ptype mapping table */
 	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
+	/* flow type to pctype mapping table */
+	uint64_t pcypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;
+	uint64_t flow_types_msk;
+	uint64_t pctypes_msk;
 };
 
 extern const struct rte_flow_ops i40e_flow_ops;
@@ -925,8 +931,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
 			   struct i40e_vsi_vlan_pvid_info *info);
 int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
 int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
-uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
-uint64_t i40e_parse_hena(uint64_t flags);
+uint64_t i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter);
+uint64_t i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter);
 enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
 enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
 int i40e_fdir_setup(struct i40e_pf *pf);
@@ -935,8 +941,8 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
 					int socket_id);
 int i40e_fdir_configure(struct rte_eth_dev *dev);
 void i40e_fdir_teardown(struct i40e_pf *pf);
-enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
-uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
+uint16_t i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter);
+uint16_t i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter);
 int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 			  enum rte_filter_op filter_op,
 			  void *arg);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 7c5c16b..9fc82b7 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1393,6 +1393,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(eth_dev);
+	i40e_set_default_pctype_table(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
@@ -2128,7 +2129,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = vf->adapter->flow_types_msk;
 	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -2413,7 +2414,7 @@ static int
 i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t rss_hf, hena;
+	uint64_t hena;
 	int ret;
 
 	ret = i40evf_set_rss_key(&vf->vsi, rss_conf->rss_key,
@@ -2421,14 +2422,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, vf->adapter);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2440,16 +2434,9 @@ static void
 i40evf_disable_rss(struct i40e_vf *vf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), 0);
 	I40EVF_WRITE_FLUSH(hw);
 }
 
@@ -2478,7 +2465,7 @@ i40evf_config_rss(struct i40e_vf *vf)
 	}
 
 	rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & vf->adapter->flow_types_msk) == 0) {
 		i40evf_disable_rss(vf);
 		PMD_DRV_LOG(DEBUG, "No hash flag is set");
 		return 0;
@@ -2503,14 +2490,13 @@ i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & vf->adapter->flow_types_msk;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & vf->adapter->pctypes_msk)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0;
@@ -2536,7 +2522,7 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(hena, vf->adapter);
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 8013add..fbee050 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -344,15 +344,10 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	/* initialize the masks */
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pctype, pf->adapter);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 		pf->fdir.flex_mask[pctype].word_mask = 0;
 		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
 		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) {
@@ -449,7 +444,8 @@ i40e_check_fdir_flex_payload(const struct rte_eth_flex_payload_cfg *flex_cfg)
  * arguments are valid
  */
 static int
-i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
+i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf,
+			  struct i40e_adapter *adapter)
 {
 	const struct rte_eth_flex_payload_cfg *flex_cfg;
 	const struct rte_eth_fdir_flex_mask *flex_mask;
@@ -486,8 +482,11 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 		return -EINVAL;
 	}
 	for (i = 0; i < conf->nb_flexmasks; i++) {
+		enum i40e_filter_pctype pctype;
+
 		flex_mask = &conf->flex_mask[i];
-		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
+		pctype = i40e_flowtype_to_pctype(flex_mask->flow_type, adapter);
+		if (!pctype) {
 			PMD_DRV_LOG(WARNING, "invalid flow type.");
 			return -EINVAL;
 		}
@@ -650,7 +649,7 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	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);
+	ret = i40e_check_fdir_flex_conf(conf, pf->adapter);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, " invalid configuration arguments.");
 		return -EINVAL;
@@ -665,10 +664,10 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 			pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
 				hw, I40E_GLQF_FD_PCTYPES(
 				(int)i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type)));
+				conf->flex_mask[i].flow_type, pf->adapter)));
 		} else
 			pctype = i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type);
+				conf->flex_mask[i].flow_type, pf->adapter);
 
 		i40e_set_flex_mask_on_pctype(pf, pctype, &conf->flex_mask[i]);
 	}
@@ -1100,7 +1099,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		return -ENOTSUP;
 	}
 
-	if (!I40E_VALID_FLOW(filter->input.flow_type)) {
+	pctype = i40e_flowtype_to_pctype(filter->input.flow_type, pf->adapter);
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -1141,12 +1141,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 	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(
-			filter->input.flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
-
+			hw, I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "fdir programming fails for PCTYPE(%u).",
@@ -1384,7 +1380,6 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 {
 	struct i40e_fdir_flex_mask *mask;
 	struct rte_eth_fdir_flex_mask *ptr = flex_mask;
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t flow_type;
 	uint8_t i, j;
 	uint16_t off_bytes, mask_tmp;
@@ -1393,14 +1388,10 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 	     i <= I40E_FILTER_PCTYPE_L2_PAYLOAD;
 	     i++) {
 		mask =  &pf->fdir.flex_mask[i];
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722((enum i40e_filter_pctype)i))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE((enum i40e_filter_pctype)i))
-				continue;
-		}
-		flow_type = i40e_pctype_to_flowtype((enum i40e_filter_pctype)i);
+		flow_type = i40e_pctype_to_flowtype(i, pf->adapter);
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
+
 		for (j = 0; j < I40E_FDIR_MAX_FLEXWORD_NUM; j++) {
 			if (mask->word_mask & I40E_FLEX_WORD_MASK(j)) {
 				ptr->mask[j * sizeof(uint16_t)] = UINT8_MAX;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b92719a..4db771c 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2776,7 +2776,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		}
 	}
 
-	pctype = i40e_flowtype_to_pctype(flow_type);
+	pctype = i40e_flowtype_to_pctype(flow_type, pf->adapter);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..5e75567 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2941,6 +2941,63 @@ i40e_set_default_ptype_table(struct rte_eth_dev *dev)
 		ad->ptype_tbl[i] = i40e_get_default_pkt_type(i);
 }
 
+void __attribute__((cold))
+i40e_set_default_pctype_table(struct rte_eth_dev *dev)
+{
+	struct i40e_adapter *ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int i;
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pcypes_tbl[i] = 0ULL;
+	ad->flow_types_msk = 0ULL;
+	ad->pctypes_msk = 0ULL;
+
+	ad->pcypes_tbl[RTE_ETH_FLOW_FRAG_IPV4] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+	ad->pcypes_tbl[RTE_ETH_FLOW_FRAG_IPV6] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+	ad->pcypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
+				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+
+	if (hw->mac.type == I40E_MAC_X722) {
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+	}
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (ad->pcypes_tbl[i])
+			ad->flow_types_msk |= (1ULL << i);
+		ad->pctypes_msk |= ad->pcypes_tbl[i];
+	}
+}
+
 /* Stubs needed for linkage when CONFIG_RTE_I40E_INC_VECTOR is set to 'n' */
 int __attribute__((weak))
 i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..2a58ced 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -255,6 +255,7 @@ void i40e_set_tx_function_flag(struct rte_eth_dev *dev,
 			       struct i40e_tx_queue *txq);
 void i40e_set_tx_function(struct rte_eth_dev *dev);
 void i40e_set_default_ptype_table(struct rte_eth_dev *dev);
+void i40e_set_default_pctype_table(struct rte_eth_dev *dev);
 
 /* For each value it means, datasheet of hardware can tell more details
  *
-- 
2.5.5

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

* [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-09-01 15:02   ` Kirill Rybalchenko
  2017-09-04 17:24     ` Iremonger, Bernard
  2017-09-08 17:01     ` Ferruh Yigit
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
                     ` (3 subsequent siblings)
  5 siblings, 2 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-01 15:02 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new functions which allow modify, return or reset to default
the contents of flow type to pctype dynamic mapping table.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c | 98 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h | 61 +++++++++++++++++++++++++
 2 files changed, 159 insertions(+)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index d69a472..3f844e6 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -2161,3 +2161,101 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 
 	return 0;
 }
+
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	i40e_set_default_pctype_table(dev);
+
+	return 0;
+}
+
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t size,
+			uint16_t *count,
+			uint8_t valid_only)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	int n = 0;
+	uint16_t i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (n >= size)
+			break;
+		if (valid_only && ad->pcypes_tbl[i] == 0ULL)
+			continue;
+		mapping_items[n].flow_type = i;
+		mapping_items[n].pctype = ad->pcypes_tbl[i];
+		n++;
+	}
+
+	*count = n;
+	return 0;
+}
+
+int
+rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	int i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	if (count > I40E_FLOW_TYPE_MAX)
+		return -EINVAL;
+
+	for (i = 0; i < count; i++)
+		if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX)
+			return -EINVAL;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	if (exclusive) {
+		for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+			ad->pcypes_tbl[i] = 0ULL;
+		ad->flow_types_msk = 0ULL;
+	}
+
+	for (i = 0; i < count; i++) {
+		ad->pcypes_tbl[mapping_items[i].flow_type] = mapping_items[i].pctype;
+		if (mapping_items[i].pctype)
+			ad->flow_types_msk |= (1ULL << mapping_items[i].flow_type);
+		else
+			ad->flow_types_msk &= ~(1ULL << mapping_items[i].flow_type);
+	}
+
+	for (i = 0, ad->pctypes_msk = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_msk |= ad->pcypes_tbl[i];
+
+	return 0;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 155b7e8..66de588 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -657,4 +657,65 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,
 int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+
+struct rte_pmd_i40e_flow_type_mapping {
+	uint8_t flow_type; /**< software defined flow type*/
+	uint64_t pctype; /**< hardware defined pctype */
+};
+
+/**
+ * Update hardware defined pctype to software defined flow type
+ * mapping table.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the mapping items array.
+ * @param count
+ *    number of mapping items.
+ * @param exclusive
+ *    the flag indicate different ptype mapping update method.
+ *    -(0) only overwrite referred PTYPE mapping,
+ *	keep other PTYPEs mapping unchanged.
+ *    -(!0) overwrite referred PTYPE mapping,
+ *	set other PTYPEs maps to PTYPE_UNKNOWN.
+ */
+int rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive);
+
+/**
+ * Get software defined flow type to hardware defined pctype
+ * mapping items.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the array to store returned items.
+ * @param size
+ *    the size of the input array.
+ * @param count
+ *    the place to store the number of returned items.
+ * @param valid_only
+ *    -(0) return full mapping table.
+ *    -(!0) only return mapping items which flow_type != RTE_ETH_FLOW_UNKNOWN.
+ */
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t size,
+			uint16_t *count,
+			uint8_t valid_only);
+
+/**
+ * Reset hardware defined pctype to software defined flow type
+ * mapping table to default.
+ *
+ * @param port
+ *    pointer to port identifier of the device
+ */
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port);
+
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-09-01 15:02   ` Kirill Rybalchenko
  2017-09-04 17:29     ` Iremonger, Bernard
  2017-09-08 17:02     ` Ferruh Yigit
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
                     ` (2 subsequent siblings)
  5 siblings, 2 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-01 15:02 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new commands to manipulate with dynamic flow type to
pctype mapping table in i40e PMD.
Commands allow to print table, modify it and reset to default value.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 app/test-pmd/cmdline.c                      | 311 +++++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  21 ++
 2 files changed, 322 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0144191..f7d0733 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -637,6 +637,16 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"ptype mapping update (port_id) (hw_ptype) (sw_ptype)\n"
 			"    Update a ptype mapping item on a port\n\n"
 
+			"pctype mapping reset (port_id)\n"
+			"    Reset flow type to pctype mapping on a port\n\n"
+
+			"pctype mapping get (port_id)\n"
+			"    Get flow ptype to pctype mapping on a port\n\n"
+
+			"pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*)"
+			" (flow_type_id)\n"
+			"    Update a flow type to pctype mapping item on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -681,7 +691,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
 			" for ports.\n\n"
 
-			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
+			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|"
+			"geneve|nvgre|none|<flowtype_id>)\n"
 			"    Set the RSS mode.\n\n"
 
 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
@@ -878,8 +889,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
 			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
-			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
+			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-ipv4|dst-ipv4|"
+			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
 			"ipv6-next-header|udp-src-port|udp-dst-port|"
 			"tcp-src-port|tcp-dst-port|sctp-src-port|"
 			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
@@ -1716,6 +1727,8 @@ cmd_config_rss_parsed(void *parsed_result,
 		rss_conf.rss_hf = ETH_RSS_NVGRE;
 	else if (!strcmp(res->value, "none"))
 		rss_conf.rss_hf = 0;
+	else if (isdigit(res->value[0]) && atoi(res->value) > 0 && atoi(res->value) < 64)
+		rss_conf.rss_hf = 1ULL << atoi(res->value);
 	else {
 		printf("Unknown parameter\n");
 		return;
@@ -1739,14 +1752,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
 cmdline_parse_token_string_t cmd_config_rss_name =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
 cmdline_parse_token_string_t cmd_config_rss_value =
-	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
-		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
 
 cmdline_parse_inst_t cmd_config_rss = {
 	.f = cmd_config_rss_parsed,
 	.data = NULL,
 	.help_str = "port config all rss "
-		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
+		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|<flowtype_id>",
 	.tokens = {
 		(void *)&cmd_config_rss_port,
 		(void *)&cmd_config_rss_keyword,
@@ -8987,6 +8999,10 @@ str2flowtype(char *string)
 		if (!strcmp(flowtype_str[i].str, string))
 			return flowtype_str[i].type;
 	}
+
+	if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64)
+		return (uint16_t)atoi(string);
+
 	return RTE_ETH_FLOW_UNKNOWN;
 }
 
@@ -10463,9 +10479,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 		port_id, UINT8);
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
-		flow_type,
-		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
-		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+		flow_type, NULL);
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		inset_field,
@@ -10484,7 +10498,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
-	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload|<flowtype_id> "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -13806,6 +13820,279 @@ cmdline_parse_inst_t cmd_clear_vf_stats = {
 	},
 };
 
+/* pctype mapping reset */
+
+/* Common result structure for pctype mapping reset */
+struct cmd_pctype_mapping_reset_result {
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t reset;
+	uint8_t port_id;
+};
+
+/* Common CLI fields for pctype mapping reset*/
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 reset, "reset");
+cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port_id, UINT8);
+
+static void
+cmd_pctype_mapping_reset_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_reset_result *res = parsed_result;
+	int ret = -ENOTSUP;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_reset = {
+	.f = cmd_pctype_mapping_reset_parsed,
+	.data = NULL,
+	.help_str = "pctype mapping reset <port_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_reset_pctype,
+		(void *)&cmd_pctype_mapping_reset_mapping,
+		(void *)&cmd_pctype_mapping_reset_reset,
+		(void *)&cmd_pctype_mapping_reset_port_id,
+		NULL,
+	},
+};
+
+/* pctype mapping get */
+
+#define FLOW_TYPE_MAX 64
+#define PCTYPE_MAX    64
+
+/* Common result structure for pctype mapping get */
+struct cmd_pctype_mapping_get_result {
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t get;
+	uint8_t port_id;
+};
+
+/* Common CLI fields for pctype mapping get */
+cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_get =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 get, "get");
+cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port_id, UINT8);
+
+static void
+cmd_pctype_mapping_get_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_get_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping[FLOW_TYPE_MAX];
+	uint16_t count;
+	int i, j;
+#endif
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id,
+					mapping,
+					FLOW_TYPE_MAX,
+					&count,
+					1);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (!ret) {
+		for (i = 0; i < count; i++) {
+			int first_pctype = 1;
+
+			printf("pctype: ");
+			for (j = 0; j < PCTYPE_MAX; j++) {
+				if (mapping[i].pctype & (1ULL << j)) {
+					printf(first_pctype ? "%02d" : ",%02d", j);
+					first_pctype = 0;
+				}
+			}
+			printf("  ->  flowtype: %02d\n", mapping[i].flow_type);
+		}
+	}
+#endif
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_get = {
+	.f = cmd_pctype_mapping_get_parsed,
+	.data = NULL,
+	.help_str = "pctype mapping get <port_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_get_pctype,
+		(void *)&cmd_pctype_mapping_get_mapping,
+		(void *)&cmd_pctype_mapping_get_get,
+		(void *)&cmd_pctype_mapping_get_port_id,
+		NULL,
+	},
+};
+
+/* pctype mapping update */
+
+/* Common result structure for pctype mapping update */
+struct cmd_pctype_mapping_update_result {
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t update;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype_list;
+	uint16_t flow_type;
+};
+
+/* Common CLI fields for pctype mapping update*/
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_update =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 update, "update");
+cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype_list, NULL);
+cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 flow_type, UINT16);
+
+static void
+cmd_pctype_mapping_update_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_update_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping;
+#endif
+	unsigned int nb_item, i;
+	unsigned int pctype_list[PCTYPE_MAX];
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	nb_item = parse_item_list(res->pctype_list, "pctypes", PCTYPE_MAX,
+				  pctype_list, 1);
+
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	mapping.flow_type = res->flow_type;
+	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
+		mapping.pctype |= (1ULL << pctype_list[i]);
+	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
+						&mapping,
+						1,
+						0);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid pctype or flow type\n");
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_update = {
+	.f = cmd_pctype_mapping_update_parsed,
+	.data = NULL,
+	.help_str = "pctype mapping update <port_id> <pctype_id_0,[pctype_id_1]*>"
+	" <flowtype_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_update_pctype,
+		(void *)&cmd_pctype_mapping_update_mapping,
+		(void *)&cmd_pctype_mapping_update_update,
+		(void *)&cmd_pctype_mapping_update_port_id,
+		(void *)&cmd_pctype_mapping_update_pc_type,
+		(void *)&cmd_pctype_mapping_update_flow_type,
+		NULL,
+	},
+};
+
 /* ptype mapping get */
 
 /* Common result structure for ptype mapping get */
@@ -14387,6 +14674,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_replace,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_reset,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_update,
+
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_get,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_reset,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_update,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2ed62f5..f5913b7 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1310,6 +1310,27 @@ Reset ptype mapping table::
 
    testpmd> ptype mapping reset (port_id)
 
+pctype mapping
+~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> pctype mapping get (port_id)
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*) (flow_type_d)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
+Reset pctype mapping table::
+
+   testpmd> pctype mapping reset (port_id)
+
 Port Functions
 --------------
 
-- 
2.5.5

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

* [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                     ` (2 preceding siblings ...)
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-09-01 15:02   ` Kirill Rybalchenko
  2017-09-08 17:01     ` Ferruh Yigit
  2017-09-04 17:16   ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Iremonger, Bernard
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
  5 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-01 15:02 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary check for new flow type for rss hash
filter update.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..c470997 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2263,16 +2263,8 @@ int
 rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
 {
 	struct rte_eth_dev *dev;
-	uint16_t rss_hash_protos;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rss_hash_protos = rss_conf->rss_hf;
-	if ((rss_hash_protos != 0) &&
-	    ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {
-		RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
-				rss_hash_protos);
-		return -EINVAL;
-	}
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
 	return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
-- 
2.5.5

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

* Re: [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-09-04 16:49     ` Ananyev, Konstantin
  2017-09-08 16:58     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Ananyev, Konstantin @ 2017-09-04 16:49 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev
  Cc: Rybalchenko, Kirill, Chilikin, Andrey, Xing, Beilei, Wu, Jingjing

Hi Kirill,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Friday, September 1, 2017 4:03 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>;
> Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
> 
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to add new flow types and pctypes for DDP without changing
> API of the driver. The mapping table is located in private
> data area for particular network adapter and can be individually
> modified with set of appropriate functions.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
> v2
> Re-arrange patchset to avoid compillation errors.
> Remove usage of statically defined flow types and pctypes.
> ---
>  drivers/net/i40e/i40e_ethdev.c    | 347 ++++++++++----------------------------
>  drivers/net/i40e/i40e_ethdev.h    |  16 +-
>  drivers/net/i40e/i40e_ethdev_vf.c |  36 ++--
>  drivers/net/i40e/i40e_fdir.c      |  51 +++---
>  drivers/net/i40e/i40e_flow.c      |   2 +-
>  drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
>  drivers/net/i40e/i40e_rxtx.h      |   1 +
>  7 files changed, 190 insertions(+), 320 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 8e0580c..56a96f5 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1062,6 +1062,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>  		return 0;
>  	}
>  	i40e_set_default_ptype_table(dev);
> +	i40e_set_default_pctype_table(dev);
>  	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
>  	intr_handle = &pci_dev->intr_handle;
> 
> @@ -2971,7 +2972,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
>  						sizeof(uint32_t);
>  	dev_info->reta_size = pf->hash_lut_size;
> -	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
> +	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_msk;
> 
>  	dev_info->default_rxconf = (struct rte_eth_rxconf) {
>  		.rx_thresh = {
> @@ -6562,104 +6563,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
> 
>  /* Configure hash enable flags for RSS */
>  uint64_t
> -i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
> +i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter)
>  {

As a nit here and in few other functions below, to keep more conventional order of parameters:
i40e_config_hena(struct i40e_adapter *adapter, ....)

probably even better: 'const struct i40e_adapter *adapter' whenever possible.

>  	uint64_t hena = 0;
> +	int i;
> 
>  	if (!flags)
>  		return hena;
> 
> -	if (flags & ETH_RSS_FRAG_IPV4)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
> -	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
> -	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
> -	if (flags & ETH_RSS_FRAG_IPV6)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
> -	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (flags & (1ULL << i))
> +			hena |= adapter->pcypes_tbl[i];
>  	}
> -	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
> -	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
> -	if (flags & ETH_RSS_L2_PAYLOAD)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
> 
>  	return hena;
>  }
> 

...

> 
> -enum i40e_filter_pctype
> -i40e_flowtype_to_pctype(uint16_t flow_type)
> -{
> -	static const enum i40e_filter_pctype pctype_table[] = {
> -		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
> -		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
> -		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
> -	};
> +uint16_t
> +i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
> +{
> +	int i;
> +	uint64_t pctype_mask;
> 
> -	return pctype_table[flow_type];
> +	if (flow_type < I40E_FLOW_TYPE_MAX) {
> +		pctype_mask = adapter->pcypes_tbl[flow_type];
> +		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
> +			if (pctype_mask & (1ULL << i))
> +				return (uint16_t)i;

So, each pcypes_tbl[] would always have only one bit set?
If so, wouldn't it  be more convenient to store only bit index?


> +		}
> +	}
> +	return 0;

As I can see, that function would return 0 for both
adapter->pcypes_tbl[flow_type] == 0 and adapter->pcypes_tbl[flow_type] == 1
Is that intended?
Konstantin

>  }
> 

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

* Re: [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                     ` (3 preceding siblings ...)
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
@ 2017-09-04 17:16   ` Iremonger, Bernard
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
  5 siblings, 0 replies; 40+ messages in thread
From: Iremonger, Bernard @ 2017-09-04 17:16 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev
  Cc: Rybalchenko, Kirill, Chilikin, Andrey, Xing, Beilei, Wu, Jingjing

Hi Kirill,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Friday, September 1, 2017 4:03 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping
> of flow types to pctypes
> 
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to map new flow types to pctypes without changing API of the
> driver.
> 
> v2:
> Remove unnecessary check for new flow types.
> Re-arrange patchset to avoid compillation errors.
> Remove unnecessary usage of statically defined flow types and pctypes.
> 
> Kirill Rybalchenko (4):
>   net/i40e: implement dynamic mapping of sw flow types to hw pctypes
>   net/i40e: add new functions to manipulate with pctype mapping table
>   app/testpmd: add new commands to manipulate with pctype mapping
>   ethdev: remove unnecessary check for new flow type
> 
>  app/test-pmd/cmdline.c                      | 311 ++++++++++++++++++++++++-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  21 ++
>  drivers/net/i40e/i40e_ethdev.c              | 347 +++++++---------------------
>  drivers/net/i40e/i40e_ethdev.h              |  16 +-
>  drivers/net/i40e/i40e_ethdev_vf.c           |  36 +--
>  drivers/net/i40e/i40e_fdir.c                |  51 ++--
>  drivers/net/i40e/i40e_flow.c                |   2 +-
>  drivers/net/i40e/i40e_rxtx.c                |  57 +++++
>  drivers/net/i40e/i40e_rxtx.h                |   1 +
>  drivers/net/i40e/rte_pmd_i40e.c             |  98 ++++++++
>  drivers/net/i40e/rte_pmd_i40e.h             |  61 +++++
>  lib/librte_ether/rte_ethdev.c               |   8 -
>  12 files changed, 671 insertions(+), 338 deletions(-)
> 
> --
> 2.5.5
The rte_pmd_i40e_version.map file needs to be updated for the new rte_pmd_i40e_*  API's.

Regards,

Bernard.

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

* Re: [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-09-04 17:24     ` Iremonger, Bernard
  2017-09-08 17:01     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Iremonger, Bernard @ 2017-09-04 17:24 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev
  Cc: Rybalchenko, Kirill, Chilikin, Andrey, Xing, Beilei, Wu, Jingjing

Hi Kirill,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Friday, September 1, 2017 4:03 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to
> manipulate with pctype mapping table
> 
> Add new functions which allow modify, return or reset to default the
> contents of flow type to pctype dynamic mapping table.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  drivers/net/i40e/rte_pmd_i40e.c | 98
> +++++++++++++++++++++++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h | 61 +++++++++++++++++++++++++
>  2 files changed, 159 insertions(+)
> 
> diff --git a/drivers/net/i40e/rte_pmd_i40e.c
> b/drivers/net/i40e/rte_pmd_i40e.c index d69a472..3f844e6 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.c
> +++ b/drivers/net/i40e/rte_pmd_i40e.c
> @@ -2161,3 +2161,101 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port,
> uint16_t vf_id,
> 
>  	return 0;
>  }
> +
> +int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port) {
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_i40e_supported(dev))
> +		return -ENOTSUP;
> +
> +	i40e_set_default_pctype_table(dev);
> +
> +	return 0;
> +}
> +
> +int rte_pmd_i40e_flow_type_mapping_get(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping
> *mapping_items,
> +			uint16_t size,
> +			uint16_t *count,
> +			uint8_t valid_only)
> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_adapter *ad;
> +	int n = 0;
> +	uint16_t i;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_i40e_supported(dev))
> +		return -ENOTSUP;
> +
> +	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (n >= size)
> +			break;
> +		if (valid_only && ad->pcypes_tbl[i] == 0ULL)
> +			continue;
> +		mapping_items[n].flow_type = i;
> +		mapping_items[n].pctype = ad->pcypes_tbl[i];
> +		n++;
> +	}
> +
> +	*count = n;
> +	return 0;
> +}
> +
> +int
> +rte_pmd_i40e_flow_type_mapping_update(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping
> *mapping_items,
> +			uint16_t count,
> +			uint8_t exclusive)
> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_adapter *ad;
> +	int i;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_i40e_supported(dev))
> +		return -ENOTSUP;
> +
> +	if (count > I40E_FLOW_TYPE_MAX)
> +		return -EINVAL;
> +
> +	for (i = 0; i < count; i++)
> +		if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX)
> +			return -EINVAL;
> +
> +	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> +	if (exclusive) {
> +		for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
> +			ad->pcypes_tbl[i] = 0ULL;
> +		ad->flow_types_msk = 0ULL;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		ad->pcypes_tbl[mapping_items[i].flow_type] =
> mapping_items[i].pctype;
> +		if (mapping_items[i].pctype)
> +			ad->flow_types_msk |= (1ULL <<
> mapping_items[i].flow_type);
> +		else
> +			ad->flow_types_msk &= ~(1ULL <<
> mapping_items[i].flow_type);
> +	}
> +
> +	for (i = 0, ad->pctypes_msk = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
> +		ad->pctypes_msk |= ad->pcypes_tbl[i];
> +
> +	return 0;
> +}
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> b/drivers/net/i40e/rte_pmd_i40e.h index 155b7e8..66de588 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -657,4 +657,65 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t
> port,  int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
>  				 struct ether_addr *mac_addr);
> 
> +
> +struct rte_pmd_i40e_flow_type_mapping {
> +	uint8_t flow_type; /**< software defined flow type*/
> +	uint64_t pctype; /**< hardware defined pctype */ };
> +
> +/**
> + * Update hardware defined pctype to software defined flow type
> + * mapping table.
> + *
> + * @param port
> + *    pointer to port identifier of the device.
> + * @param mapping_items
> + *    the base address of the mapping items array.
> + * @param count
> + *    number of mapping items.
> + * @param exclusive
> + *    the flag indicate different ptype mapping update method.
> + *    -(0) only overwrite referred PTYPE mapping,
> + *	keep other PTYPEs mapping unchanged.
> + *    -(!0) overwrite referred PTYPE mapping,
> + *	set other PTYPEs maps to PTYPE_UNKNOWN.
> + */
> +int rte_pmd_i40e_flow_type_mapping_update(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping
> *mapping_items,
> +			uint16_t count,
> +			uint8_t exclusive);
> +
> +/**
> + * Get software defined flow type to hardware defined pctype
> + * mapping items.
> + *
> + * @param port
> + *    pointer to port identifier of the device.
> + * @param mapping_items
> + *    the base address of the array to store returned items.
> + * @param size
> + *    the size of the input array.
> + * @param count
> + *    the place to store the number of returned items.
> + * @param valid_only
> + *    -(0) return full mapping table.
> + *    -(!0) only return mapping items which flow_type !=
> RTE_ETH_FLOW_UNKNOWN.
> + */
> +int rte_pmd_i40e_flow_type_mapping_get(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping
> *mapping_items,
> +			uint16_t size,
> +			uint16_t *count,
> +			uint8_t valid_only);
> +
> +/**
> + * Reset hardware defined pctype to software defined flow type
> + * mapping table to default.
> + *
> + * @param port
> + *    pointer to port identifier of the device
> + */
> +int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port);
> +
>  #endif /* _PMD_I40E_H_ */
> --
> 2.5.5

There are 3 checkpatch warnings in rte_pmd_i40e.c file at lines 2250, 2252 and 2254.

Regards,

Bernard.

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

* Re: [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-09-04 17:29     ` Iremonger, Bernard
  2017-09-08 17:02     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Iremonger, Bernard @ 2017-09-04 17:29 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev
  Cc: Rybalchenko, Kirill, Chilikin, Andrey, Xing, Beilei, Wu, Jingjing

Hi Kirill,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Friday, September 1, 2017 4:03 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to
> manipulate with pctype mapping
> 
> Add new commands to manipulate with dynamic flow type to pctype
> mapping table in i40e PMD.
> Commands allow to print table, modify it and reset to default value.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  app/test-pmd/cmdline.c                      | 311
> +++++++++++++++++++++++++++-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  21 ++
>  2 files changed, 322 insertions(+), 10 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 0144191..f7d0733 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -637,6 +637,16 @@ static void cmd_help_long_parsed(void
> *parsed_result,
>  			"ptype mapping update (port_id) (hw_ptype)
> (sw_ptype)\n"
>  			"    Update a ptype mapping item on a port\n\n"
> 
> +			"pctype mapping reset (port_id)\n"
> +			"    Reset flow type to pctype mapping on a port\n\n"
> +
> +			"pctype mapping get (port_id)\n"
> +			"    Get flow ptype to pctype mapping on a port\n\n"
> +
> +			"pctype mapping update (port_id)
> (pctype_id_0[,pctype_id_1]*)"
> +			" (flow_type_id)\n"
> +			"    Update a flow type to pctype mapping item on a
> port\n\n"
> +
>  			, list_pkt_forwarding_modes()
>  		);
>  	}
> @@ -681,7 +691,8 @@ static void cmd_help_long_parsed(void
> *parsed_result,
>  			"    Set crc-strip/scatter/rx-checksum/hardware-
> vlan/drop_en"
>  			" for ports.\n\n"
> 
> -			"port config all rss
> (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
> +			"port config all rss
> (all|ip|tcp|udp|sctp|ether|port|vxlan|"
> +			"geneve|nvgre|none|<flowtype_id>)\n"
>  			"    Set the RSS mode.\n\n"
> 
>  			"port config port-id rss reta
> (hash,queue)[,(hash,queue)]\n"
> @@ -878,8 +889,8 @@ static void cmd_help_long_parsed(void
> *parsed_result,
>  			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
>  			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
>  			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
> -			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-
> ipv6|"
> -			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
> +			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-
> ipv4|dst-ipv4|"
> +			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
>  			"ipv6-next-header|udp-src-port|udp-dst-port|"
>  			"tcp-src-port|tcp-dst-port|sctp-src-port|"
>  			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-
> 1st|"
> @@ -1716,6 +1727,8 @@ cmd_config_rss_parsed(void *parsed_result,
>  		rss_conf.rss_hf = ETH_RSS_NVGRE;
>  	else if (!strcmp(res->value, "none"))
>  		rss_conf.rss_hf = 0;
> +	else if (isdigit(res->value[0]) && atoi(res->value) > 0 && atoi(res-
> >value) < 64)
> +		rss_conf.rss_hf = 1ULL << atoi(res->value);
>  	else {
>  		printf("Unknown parameter\n");
>  		return;
> @@ -1739,14 +1752,13 @@ cmdline_parse_token_string_t
> cmd_config_rss_all =  cmdline_parse_token_string_t cmd_config_rss_name
> =
>  	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
> cmdline_parse_token_string_t cmd_config_rss_value =
> -	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
> -
> 	"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
> +	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
> 
>  cmdline_parse_inst_t cmd_config_rss = {
>  	.f = cmd_config_rss_parsed,
>  	.data = NULL,
>  	.help_str = "port config all rss "
> -
> 	"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
> +
> +"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|<flowtype_id
> >",
>  	.tokens = {
>  		(void *)&cmd_config_rss_port,
>  		(void *)&cmd_config_rss_keyword,
> @@ -8987,6 +8999,10 @@ str2flowtype(char *string)
>  		if (!strcmp(flowtype_str[i].str, string))
>  			return flowtype_str[i].type;
>  	}
> +
> +	if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64)
> +		return (uint16_t)atoi(string);
> +
>  	return RTE_ETH_FLOW_UNKNOWN;
>  }
> 
> @@ -10463,9 +10479,7 @@ cmdline_parse_token_num_t
> cmd_set_hash_input_set_port_id =
>  		port_id, UINT8);
>  cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
>  	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
> -		flow_type,
> -		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
> -		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-
> other#l2_payload");
> +		flow_type, NULL);
>  cmdline_parse_token_string_t cmd_set_hash_input_set_field =
>  	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
>  		inset_field,
> @@ -10484,7 +10498,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set
> = {
>  	.data = NULL,
>  	.help_str = "set_hash_input_set <port_id> "
>  	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
> -	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
> +	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-
> other|l2_payload|<flowtype_id> "
>  	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-
> proto|"
>  	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-
> port|"
>  	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
> @@ -13806,6 +13820,279 @@ cmdline_parse_inst_t cmd_clear_vf_stats = {
>  	},
>  };
> 
> +/* pctype mapping reset */
> +
> +/* Common result structure for pctype mapping reset */ struct
> +cmd_pctype_mapping_reset_result {
> +	cmdline_fixed_string_t pctype;
> +	cmdline_fixed_string_t mapping;
> +	cmdline_fixed_string_t reset;
> +	uint8_t port_id;
> +};
> +
> +/* Common CLI fields for pctype mapping reset*/
> +cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_reset_result,
> +		 pctype, "pctype");
> +cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_reset_result,
> +		 mapping, "mapping");
> +cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_reset_result,
> +		 reset, "reset");
> +cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id =
> +	TOKEN_NUM_INITIALIZER
> +		(struct cmd_pctype_mapping_reset_result,
> +		 port_id, UINT8);
> +
> +static void
> +cmd_pctype_mapping_reset_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_reset_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id);
> +#endif
> +
> +	switch (ret) {
> +	case 0:
> +		break;
> +	case -ENODEV:
> +		printf("invalid port_id %d\n", res->port_id);
> +		break;
> +	case -ENOTSUP:
> +		printf("function not implemented\n");
> +		break;
> +	default:
> +		printf("programming error: (%s)\n", strerror(-ret));
> +	}
> +}
> +
> +cmdline_parse_inst_t cmd_pctype_mapping_reset = {
> +	.f = cmd_pctype_mapping_reset_parsed,
> +	.data = NULL,
> +	.help_str = "pctype mapping reset <port_id>",
> +	.tokens = {
> +		(void *)&cmd_pctype_mapping_reset_pctype,
> +		(void *)&cmd_pctype_mapping_reset_mapping,
> +		(void *)&cmd_pctype_mapping_reset_reset,
> +		(void *)&cmd_pctype_mapping_reset_port_id,
> +		NULL,
> +	},
> +};
> +
> +/* pctype mapping get */
> +
> +#define FLOW_TYPE_MAX 64
> +#define PCTYPE_MAX    64
> +
> +/* Common result structure for pctype mapping get */ struct
> +cmd_pctype_mapping_get_result {
> +	cmdline_fixed_string_t pctype;
> +	cmdline_fixed_string_t mapping;
> +	cmdline_fixed_string_t get;
> +	uint8_t port_id;
> +};
> +
> +/* Common CLI fields for pctype mapping get */
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 pctype, "pctype");
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 mapping, "mapping");
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_get =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 get, "get");
> +cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
> +	TOKEN_NUM_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 port_id, UINT8);
> +
> +static void
> +cmd_pctype_mapping_get_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_get_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	struct rte_pmd_i40e_flow_type_mapping
> mapping[FLOW_TYPE_MAX];
> +	uint16_t count;
> +	int i, j;
> +#endif
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id,
> +					mapping,
> +					FLOW_TYPE_MAX,
> +					&count,
> +					1);
> +#endif
> +
> +	switch (ret) {
> +	case 0:
> +		break;
> +	case -ENODEV:
> +		printf("invalid port_id %d\n", res->port_id);
> +		break;
> +	case -ENOTSUP:
> +		printf("function not implemented\n");
> +		break;
> +	default:
> +		printf("programming error: (%s)\n", strerror(-ret));
> +	}
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	if (!ret) {
> +		for (i = 0; i < count; i++) {
> +			int first_pctype = 1;
> +
> +			printf("pctype: ");
> +			for (j = 0; j < PCTYPE_MAX; j++) {
> +				if (mapping[i].pctype & (1ULL << j)) {
> +					printf(first_pctype ? "%02d" :
> ",%02d", j);
> +					first_pctype = 0;
> +				}
> +			}
> +			printf("  ->  flowtype: %02d\n",
> mapping[i].flow_type);
> +		}
> +	}
> +#endif
> +}
> +
> +cmdline_parse_inst_t cmd_pctype_mapping_get = {
> +	.f = cmd_pctype_mapping_get_parsed,
> +	.data = NULL,
> +	.help_str = "pctype mapping get <port_id>",
> +	.tokens = {
> +		(void *)&cmd_pctype_mapping_get_pctype,
> +		(void *)&cmd_pctype_mapping_get_mapping,
> +		(void *)&cmd_pctype_mapping_get_get,
> +		(void *)&cmd_pctype_mapping_get_port_id,
> +		NULL,
> +	},
> +};
> +
> +/* pctype mapping update */
> +
> +/* Common result structure for pctype mapping update */ struct
> +cmd_pctype_mapping_update_result {
> +	cmdline_fixed_string_t pctype;
> +	cmdline_fixed_string_t mapping;
> +	cmdline_fixed_string_t update;
> +	uint8_t port_id;
> +	cmdline_fixed_string_t pctype_list;
> +	uint16_t flow_type;
> +};
> +
> +/* Common CLI fields for pctype mapping update*/
> +cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 pctype, "pctype");
> +cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 mapping, "mapping");
> +cmdline_parse_token_string_t cmd_pctype_mapping_update_update =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 update, "update");
> +cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id =
> +	TOKEN_NUM_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 port_id, UINT8);
> +cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 pctype_list, NULL);
> +cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type =
> +	TOKEN_NUM_INITIALIZER
> +		(struct cmd_pctype_mapping_update_result,
> +		 flow_type, UINT16);
> +
> +static void
> +cmd_pctype_mapping_update_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_update_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	struct rte_pmd_i40e_flow_type_mapping mapping; #endif
> +	unsigned int nb_item, i;
> +	unsigned int pctype_list[PCTYPE_MAX];
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +	nb_item = parse_item_list(res->pctype_list, "pctypes",
> PCTYPE_MAX,
> +				  pctype_list, 1);
> +
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	mapping.flow_type = res->flow_type;
> +	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
> +		mapping.pctype |= (1ULL << pctype_list[i]);
> +	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
> +						&mapping,
> +						1,
> +						0);
> +#endif
> +
> +	switch (ret) {
> +	case 0:
> +		break;
> +	case -EINVAL:
> +		printf("invalid pctype or flow type\n");
> +		break;
> +	case -ENODEV:
> +		printf("invalid port_id %d\n", res->port_id);
> +		break;
> +	case -ENOTSUP:
> +		printf("function not implemented\n");
> +		break;
> +	default:
> +		printf("programming error: (%s)\n", strerror(-ret));
> +	}
> +}
> +
> +cmdline_parse_inst_t cmd_pctype_mapping_update = {
> +	.f = cmd_pctype_mapping_update_parsed,
> +	.data = NULL,
> +	.help_str = "pctype mapping update <port_id>
> <pctype_id_0,[pctype_id_1]*>"
> +	" <flowtype_id>",
> +	.tokens = {
> +		(void *)&cmd_pctype_mapping_update_pctype,
> +		(void *)&cmd_pctype_mapping_update_mapping,
> +		(void *)&cmd_pctype_mapping_update_update,
> +		(void *)&cmd_pctype_mapping_update_port_id,
> +		(void *)&cmd_pctype_mapping_update_pc_type,
> +		(void *)&cmd_pctype_mapping_update_flow_type,
> +		NULL,
> +	},
> +};
> +
>  /* ptype mapping get */
> 
>  /* Common result structure for ptype mapping get */ @@ -14387,6
> +14674,10 @@ cmdline_parse_ctx_t main_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_ptype_mapping_replace,
>  	(cmdline_parse_inst_t *)&cmd_ptype_mapping_reset,
>  	(cmdline_parse_inst_t *)&cmd_ptype_mapping_update,
> +
> +	(cmdline_parse_inst_t *)&cmd_pctype_mapping_get,
> +	(cmdline_parse_inst_t *)&cmd_pctype_mapping_reset,
> +	(cmdline_parse_inst_t *)&cmd_pctype_mapping_update,
>  	NULL,
>  };
> 
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 2ed62f5..f5913b7 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -1310,6 +1310,27 @@ Reset ptype mapping table::
> 
>     testpmd> ptype mapping reset (port_id)
> 
> +pctype mapping
> +~~~~~~~~~~~~~
> +
> +List all items from the pctype mapping table::
> +
> +   testpmd> pctype mapping get (port_id)
> +
> +Update hardware defined pctype to software defined flow type mapping
> table::
> +
> +   testpmd> pctype mapping update (port_id)
> + (pctype_id_0[,pctype_id_1]*) (flow_type_d)
> +
> +where:
> +
> +* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the
> pctype mapping table.
> +
> +* ``flow_type_id``: software flow type id as the index of the pctype
> mapping table.
> +
> +Reset pctype mapping table::
> +
> +   testpmd> pctype mapping reset (port_id)
> +
>  Port Functions
>  --------------
> 
> --
> 2.5.5

There are checkpatch warnings in cmdline.c  at lines 1730,  13971 and 14083.

Regards,

Bernard.

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

* Re: [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
  2017-09-04 16:49     ` Ananyev, Konstantin
@ 2017-09-08 16:58     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-09-08 16:58 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 9/1/2017 4:02 PM, Kirill Rybalchenko wrote:
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to add new flow types and pctypes for DDP without changing
> API of the driver. The mapping table is located in private
> data area for particular network adapter and can be individually
> modified with set of appropriate functions.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
> v2
> Re-arrange patchset to avoid compillation errors.
> Remove usage of statically defined flow types and pctypes.
<...>

> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (flags & (1ULL << i))
> +			hena |= adapter->pcypes_tbl[i];

s/pcypes_tbl/pctypes_tbl/ ?

<...>

> @@ -6668,16 +6601,9 @@ static void
>  i40e_pf_disable_rss(struct i40e_pf *pf)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> -	uint64_t hena;
>  
> -	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
> -	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
> -	if (hw->mac.type == I40E_MAC_X722)
> -		hena &= ~I40E_RSS_HENA_ALL_X722;
> -	else
> -		hena &= ~I40E_RSS_HENA_ALL;
> -	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
> -	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));

Above logic keeps intact bits of I40E_PFQF_HENA register that are not
supported RSS has filter. But below new code just sets all to zero.

I don't know why above prefer this logic, but would you mind separating
this decision into own its patch? I mean in this patch keep this as it
is, and make new patch to switch new register values.

> +	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
> +	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
>  	I40E_WRITE_FLUSH(hw);
>  }
>  
> @@ -6749,23 +6675,14 @@ static int
>  i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> -	uint64_t rss_hf;
>  	uint64_t hena;
>  	int ret;
>  
> -	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key,
> -			       rss_conf->rss_key_len);
> +	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, rss_conf->rss_key_len);

I think there is no change here, and original code is correct as syntax,
please keep it unchanged.

>  	if (ret)
>  		return ret;
>  
> -	rss_hf = rss_conf->rss_hf;
> -	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
> -	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
> -	if (hw->mac.type == I40E_MAC_X722)
> -		hena &= ~I40E_RSS_HENA_ALL_X722;
> -	else
> -		hena &= ~I40E_RSS_HENA_ALL;
> -	hena |= i40e_config_hena(rss_hf, hw->mac.type);

Same register comment as above one.

> +	hena = i40e_config_hena(rss_conf->rss_hf, pf->adapter);
>  	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
>  	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
>  	I40E_WRITE_FLUSH(hw);

<...>

> @@ -7820,29 +7736,31 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
>  	PMD_DRV_LOG(DEBUG, "Hash function is %s",
>  		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
>  
> -	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
> -		if (!(mask & (1UL << i)))
> -			continue;
> -		mask &= ~(1UL << i);
> -		/* Bit set indicats the coresponding flow type is supported */
> -		g_cfg->valid_bit_mask[0] |= (1UL << i);
> -		/* if flowtype is invalid, continue */
> -		if (!I40E_VALID_FLOW(i))
> -			continue;
> -		pctype = i40e_flowtype_to_pctype(i);
> -		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
> -		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
> -			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
> +	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_msk;

Loosing data here by casting to 32bit, intentional?

> +
> +	for (i = 0; i < UINT32_BIT; i++) {

Why use UINT32_BIT? not I40E_FLOW_TYPE_MAX? Is it because
sym_hash_enable_mask is 32bits? Why not increase its stroge if we need
64 flow type / pctype ?

> +		if (adapter->pcypes_tbl[i]) {
> +			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
> +				if (adapter->pcypes_tbl[i] & (1ULL << j)) {
> +					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
> +					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
> +						g_cfg->sym_hash_enable_mask[0] |=
> +									(1UL << i);
> +					}
> +				}
> +			}
> +		}
>  	}
>  
>  	return 0;
>  }

<...>

> @@ -7885,64 +7803,26 @@ static int
>  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;
>  	int ret;
> -	uint16_t i;
> +	uint16_t i, j;
>  	uint32_t reg;
> -	uint32_t mask0 = g_cfg->valid_bit_mask[0];
> -	enum i40e_filter_pctype pctype;
> +	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_msk;

Loosing data here by casting to 32bit, intentional?


<...>

> @@ -8636,7 +8513,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
>  		return -EINVAL;
>  	}
>  
> -	if (!I40E_VALID_FLOW(conf->flow_type)) {
> +	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
> +	if (!pctype) {

pctype 0 is not defined in enum, which technically possible to be
defined in the future and break this logic, it could be good to define
it now to something UNKNOWN, RESERVED etc.. to be sure it won't be used.

>  		PMD_DRV_LOG(ERR, "invalid flow_type input.");
>  		return -EINVAL;
>  	}

<...>

> @@ -8655,11 +8531,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
>  		PMD_DRV_LOG(ERR, "Failed to parse input set");
>  		return -EINVAL;
>  	}
> -	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
> -				    input_set) != 0) {
> -		PMD_DRV_LOG(ERR, "Invalid input set");
> -		return -EINVAL;
> -	}

Why removing this validation?

> +
>  	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
>  		/* get inset value in register */
>  		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
> @@ -8713,24 +8585,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
>  		return -EINVAL;
>  	}
>  
> -	if (!I40E_VALID_FLOW(conf->flow_type)) {
> +	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
> +
> +	if (!pctype) {
>  		PMD_DRV_LOG(ERR, "invalid flow_type input.");
>  		return -EINVAL;
>  	}
>  
> -	pctype = i40e_flowtype_to_pctype(conf->flow_type);
> -
>  	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
>  				   conf->inset_size);
>  	if (ret) {
>  		PMD_DRV_LOG(ERR, "Failed to parse input set");
>  		return -EINVAL;
>  	}
> -	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
> -				    input_set) != 0) {
> -		PMD_DRV_LOG(ERR, "Invalid input set");
> -		return -EINVAL;
> -	}

And why removing this part?

>  
>  	/* get inset value in register */
>  	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> @@ -9169,72 +9036,34 @@ i40e_hw_init(struct rte_eth_dev *dev)
>  	i40e_set_symmetric_hash_enable_per_port(hw, 0);
>  }
>  
> -enum i40e_filter_pctype
> -i40e_flowtype_to_pctype(uint16_t flow_type)
<...>
> +uint16_t

Why changed return type from "enum i40e_filter_pctype" to "uint16_t",
this function should be returning pctype?

> +i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
> +{
> +	int i;
> +	uint64_t pctype_mask;
>  
> -	return pctype_table[flow_type];
> +	if (flow_type < I40E_FLOW_TYPE_MAX) {
> +		pctype_mask = adapter->pcypes_tbl[flow_type];
> +		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
> +			if (pctype_mask & (1ULL << i))

pctype_mask can be having multiple pctype, why returning at first one,
this may be breaking some I40E_MAC_X722 code.

> +				return (uint16_t)i;

if you intend to cast "i" to uint16_t why not define it uint16_t at
first place.

If return type is changed to uint16_t to OR pctype values, that logic is
missing here and caller of the function should take this into account,
and function should be commented to clarify this. If this functions
intented to return single pctype as original code, it should return
"enum i40e_filter_pctype" I think.

> +		}
> +	}
> +	return 0;
>  }
>  

<...>

> +	uint16_t flowtype = RTE_ETH_FLOW_UNKNOWN;
> +	uint64_t pctype_mask = 1ULL << pctype;
> +
> +	for (; flowtype < I40E_FLOW_TYPE_MAX; flowtype++) {
> +		if (adapter->pcypes_tbl[flowtype] & pctype_mask)
> +			return flowtype;
> +	}
>  
> -	return flowtype_table[pctype];
> +	return flowtype;

If pctype is not in the table, this will return I40E_FLOW_TYPE_MAX,
which is wrong.


<...>

> @@ -881,6 +883,10 @@ struct i40e_adapter {
>  
>  	/* ptype mapping table */
>  	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
> +	/* flow type to pctype mapping table */

It can be good to note, not sure where, this is 1:N mapping, one flow
table can has multiple pctypes, bitmasked into pctype variable in the table.

> +	uint64_t pcypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;

I guess there is a typo in variable name, is intention "pctypes_tbl" ?

> +	uint64_t flow_types_msk> +	uint64_t pctypes_msk;

abbrevation is only gaining one letter, "a", I would convert this to
"flow_types_mask" and "pctypes_mask".

>  };
>  
>  extern const struct rte_flow_ops i40e_flow_ops;
> @@ -925,8 +931,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
>  			   struct i40e_vsi_vlan_pvid_info *info);
>  int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
>  int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
> -uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
> -uint64_t i40e_parse_hena(uint64_t flags);
> +uint64_t i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter);
> +uint64_t i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter);
>  enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
>  enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
>  int i40e_fdir_setup(struct i40e_pf *pf);
> @@ -935,8 +941,8 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
>  					int socket_id);
>  int i40e_fdir_configure(struct rte_eth_dev *dev);
>  void i40e_fdir_teardown(struct i40e_pf *pf);
> -enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
> -uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
> +uint16_t i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter);
> +uint16_t i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter);
>  int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
>  			  enum rte_filter_op filter_op,
>  			  void *arg);
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c

Same above comments for VF code.

<...>

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

* Re: [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
  2017-09-04 17:24     ` Iremonger, Bernard
@ 2017-09-08 17:01     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-09-08 17:01 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 9/1/2017 4:02 PM, Kirill Rybalchenko wrote:
> Add new functions which allow modify, return or reset to default
> the contents of flow type to pctype dynamic mapping table.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  drivers/net/i40e/rte_pmd_i40e.c | 98 +++++++++++++++++++++++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h | 61 +++++++++++++++++++++++++

.map file needs to be updated for shared build.

<...>

> +int rte_pmd_i40e_flow_type_mapping_get(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
> +			uint16_t size,
> +			uint16_t *count,
> +			uint8_t valid_only)> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_adapter *ad;
> +	int n = 0;
> +	uint16_t i;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_i40e_supported(dev))
> +		return -ENOTSUP;
> +
> +	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (n >= size)
> +			break;

This returns partial table and success, how caller can know if it get
full table or not?

Is returning partial table required, specially when custom offset is not
supported..

> +		if (valid_only && ad->pcypes_tbl[i] == 0ULL)
> +			continue;
> +		mapping_items[n].flow_type = i;
> +		mapping_items[n].pctype = ad->pcypes_tbl[i];
> +		n++;
> +	}
> +
> +	*count = n;
> +	return 0;
> +}
<...>

> @@ -657,4 +657,65 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,
>  int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
>  				 struct ether_addr *mac_addr);
>  
> +
> +struct rte_pmd_i40e_flow_type_mapping {
> +	uint8_t flow_type; /**< software defined flow type*/

flow_type are RTE_ETH_FLOW_* values defined in rte_eth_ctrl.h which is
public header.

> +	uint64_t pctype; /**< hardware defined pctype */

But how user can get pctype values, since this is part of public API,
and if application would like to use these values, is there any public
header list them?

> +};
> +
> +/**
> + * Update hardware defined pctype to software defined flow type
> + * mapping table.
> + *
> + * @param port
> + *    pointer to port identifier of the device.
> + * @param mapping_items
> + *    the base address of the mapping items array.
> + * @param count
> + *    number of mapping items.
> + * @param exclusive
> + *    the flag indicate different ptype mapping update method.
> + *    -(0) only overwrite referred PTYPE mapping,
> + *	keep other PTYPEs mapping unchanged.
> + *    -(!0) overwrite referred PTYPE mapping,
> + *	set other PTYPEs maps to PTYPE_UNKNOWN.
> + */
> +int rte_pmd_i40e_flow_type_mapping_update(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
> +			uint16_t count,
> +			uint8_t exclusive);

May prefer boolean here.

> +
> +/**
> + * Get software defined flow type to hardware defined pctype
> + * mapping items.
> + *
> + * @param port
> + *    pointer to port identifier of the device.
> + * @param mapping_items
> + *    the base address of the array to store returned items.
> + * @param size
> + *    the size of the input array.
> + * @param count
> + *    the place to store the number of returned items.
> + * @param valid_only
> + *    -(0) return full mapping table.
> + *    -(!0) only return mapping items which flow_type != RTE_ETH_FLOW_UNKNOWN.
> + */
> +int rte_pmd_i40e_flow_type_mapping_get(
> +			uint8_t port,
> +			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
> +			uint16_t size,
> +			uint16_t *count,
> +			uint8_t valid_only);

May prefer boolean here.

<...>

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

* Re: [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
@ 2017-09-08 17:01     ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-09-08 17:01 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 9/1/2017 4:02 PM, Kirill Rybalchenko wrote:
> Remove unnecessary check for new flow type for rss hash
> filter update.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 0597641..c470997 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -2263,16 +2263,8 @@ int
>  rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
>  {
>  	struct rte_eth_dev *dev;
> -	uint16_t rss_hash_protos;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> -	rss_hash_protos = rss_conf->rss_hf;
> -	if ((rss_hash_protos != 0) &&
> -	    ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {

Can intention here be:
((rss_hash_protos & ~(ETH_RSS_PROTO_MASK)) != 0)

> -		RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
> -				rss_hash_protos);
> -		return -EINVAL;
> -	}
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
>  	return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
> 

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

* Re: [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping
  2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
  2017-09-04 17:29     ` Iremonger, Bernard
@ 2017-09-08 17:02     ` Ferruh Yigit
  1 sibling, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-09-08 17:02 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 9/1/2017 4:02 PM, Kirill Rybalchenko wrote:
> Add new commands to manipulate with dynamic flow type to
> pctype mapping table in i40e PMD.
> Commands allow to print table, modify it and reset to default value.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  app/test-pmd/cmdline.c                      | 311 +++++++++++++++++++++++++++-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  21 ++
>  2 files changed, 322 insertions(+), 10 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 0144191..f7d0733 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -637,6 +637,16 @@ static void cmd_help_long_parsed(void *parsed_result,
>  			"ptype mapping update (port_id) (hw_ptype) (sw_ptype)\n"
>  			"    Update a ptype mapping item on a port\n\n"
>  
> +			"pctype mapping reset (port_id)\n"
> +			"    Reset flow type to pctype mapping on a port\n\n"
> +
> +			"pctype mapping get (port_id)\n"
> +			"    Get flow ptype to pctype mapping on a port\n\n"
> +
> +			"pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*)"
> +			" (flow_type_id)\n"
> +			"    Update a flow type to pctype mapping item on a port\n\n"

This is another root level command for PMD specific feature, can this be
under "port" or "set" command?

> +
>  			, list_pkt_forwarding_modes()
>  		);
>  	}
> @@ -681,7 +691,8 @@ static void cmd_help_long_parsed(void *parsed_result,
>  			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
>  			" for ports.\n\n"
>  
> -			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
> +			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|"
> +			"geneve|nvgre|none|<flowtype_id>)\n"

Why not use existing defined hash functions but use custom one, is there
a missing one in ethdev?

>  			"    Set the RSS mode.\n\n"
>  
>  			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
> @@ -878,8 +889,8 @@ static void cmd_help_long_parsed(void *parsed_result,
>  			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
>  			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
>  			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
> -			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
> -			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
> +			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-ipv4|dst-ipv4|"
> +			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
>  			"ipv6-next-header|udp-src-port|udp-dst-port|"
>  			"tcp-src-port|tcp-dst-port|sctp-src-port|"
>  			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
> @@ -1716,6 +1727,8 @@ cmd_config_rss_parsed(void *parsed_result,
>  		rss_conf.rss_hf = ETH_RSS_NVGRE;
>  	else if (!strcmp(res->value, "none"))
>  		rss_conf.rss_hf = 0;
> +	else if (isdigit(res->value[0]) && atoi(res->value) > 0 && atoi(res->value) < 64)
> +		rss_conf.rss_hf = 1ULL << atoi(res->value);
>  	else {
>  		printf("Unknown parameter\n");
>  		return;
> @@ -1739,14 +1752,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
>  cmdline_parse_token_string_t cmd_config_rss_name =
>  	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
>  cmdline_parse_token_string_t cmd_config_rss_value =
> -	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
> -		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
> +	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);

I guess this will prevent auto completion.

<...>

> +/* pctype mapping get */
> +
> +#define FLOW_TYPE_MAX 64
> +#define PCTYPE_MAX    64

These should not be defined by application I believe.

<...>

> +static void
> +cmd_pctype_mapping_update_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_update_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	struct rte_pmd_i40e_flow_type_mapping mapping;
> +#endif
> +	unsigned int nb_item, i;
> +	unsigned int pctype_list[PCTYPE_MAX];
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +	nb_item = parse_item_list(res->pctype_list, "pctypes", PCTYPE_MAX,
> +				  pctype_list, 1);

How user knows which values to fill the pctype_list?

More importantly, if this is an API call instead of user defined values,
how application should know which values to use? I am trying to say
pctype values defined in i40e driver somehow needs to public to be used.


<...>

> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -1310,6 +1310,27 @@ Reset ptype mapping table::
>  
>     testpmd> ptype mapping reset (port_id)
>  
> +pctype mapping
> +~~~~~~~~~~~~~

WARNING: .../testpmd_app_ug/testpmd_funcs.rst:1314: (WARNING/2) Title
underline too short.





pctype mapping



~~~~~~~~~~~~~

<...>

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

* [dpdk-dev] [PATCH v3 0/6] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                     ` (4 preceding siblings ...)
  2017-09-04 17:16   ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Iremonger, Bernard
@ 2017-09-20 14:32   ` Kirill Rybalchenko
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 1/6] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
                       ` (6 more replies)
  5 siblings, 7 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:32 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to map new flow types to pctypes without changing
API of the driver.

v2:
Remove unnecessary check for new flow types.
Re-arrange patchset to avoid compillation errors.
Remove unnecessary usage of statically defined flow types and pctypes.

v3:
Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
Add new definition in enum i40e_filter_pctype for for invalid pctype.
Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
testpmd: changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'
Various small modifications in code style after reviewing.

Kirill Rybalchenko (6):
  net/i40e: remove unnecessary bit operations
  net/i40e: add definition for invalid pctype
  net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  net/i40e: add new functions to manipulate with pctype mapping table
  app/testpmd: add new commands to manipulate with pctype mapping
  ethdev: remove unnecessary check for new flow type

 app/test-pmd/cmdline.c                      | 335 ++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  46 ++++
 drivers/net/i40e/base/i40e_type.h           |   4 +-
 drivers/net/i40e/i40e_ethdev.c              | 362 ++++++++--------------------
 drivers/net/i40e/i40e_ethdev.h              |  17 +-
 drivers/net/i40e/i40e_ethdev_vf.c           |  36 +--
 drivers/net/i40e/i40e_fdir.c                |  54 ++---
 drivers/net/i40e/i40e_flow.c                |   5 +-
 drivers/net/i40e/i40e_rxtx.c                |  57 +++++
 drivers/net/i40e/i40e_rxtx.h                |   1 +
 drivers/net/i40e/rte_pmd_i40e.c             |  90 +++++++
 drivers/net/i40e/rte_pmd_i40e.h             |  55 +++++
 drivers/net/i40e/rte_pmd_i40e_version.map   |   3 +
 lib/librte_ether/rte_ethdev.c               |   8 -
 14 files changed, 735 insertions(+), 338 deletions(-)

-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 1/6] net/i40e: remove unnecessary bit operations
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
@ 2017-09-20 14:32     ` Kirill Rybalchenko
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype Kirill Rybalchenko
                       ` (5 subsequent siblings)
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:32 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary bit operations in I40E_PFQF_HENA
and I40E_VFQF_HENA registers

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 21 +++------------------
 drivers/net/i40e/i40e_ethdev_vf.c | 22 ++++------------------
 2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 720f067..18eac07 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6697,16 +6697,9 @@ static void
 i40e_pf_disable_rss(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -6778,7 +6771,6 @@ static int
 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t rss_hf;
 	uint64_t hena;
 	int ret;
 
@@ -6787,14 +6779,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 38c3adc..f4ee424 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2435,7 +2435,7 @@ static int
 i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t rss_hf, hena;
+	uint64_t hena;
 	int ret;
 
 	ret = i40evf_set_rss_key(&vf->vsi, rss_conf->rss_key,
@@ -2443,14 +2443,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2462,16 +2455,9 @@ static void
 i40evf_disable_rss(struct i40e_vf *vf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), 0);
 	I40EVF_WRITE_FLUSH(hw);
 }
 
-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 1/6] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
@ 2017-09-20 14:32     ` Kirill Rybalchenko
  2017-09-22  7:29       ` Xing, Beilei
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
                       ` (4 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:32 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new definition in enum i40e_filter_pctype for
for invalid pctype

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/base/i40e_type.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index dca725a..d57986e 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1245,9 +1245,11 @@ struct i40e_filter_program_desc {
 
 /* Packet Classifier Types for filters */
 enum i40e_filter_pctype {
-	/* Note: Values 0-28 are reserved for future use.
+	/* Note: Vlue 0 is not valid pctype.
+	 * Values 0-28 are reserved for future use.
 	 * Value 29, 30, 32 are not supported on XL710 and X710.
 	 */
+	I40E_FILTER_PCTYPE_INVALID			= 0,
 	I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP	= 29,
 	I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP	= 30,
 	I40E_FILTER_PCTYPE_NONF_IPV4_UDP		= 31,
-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 1/6] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype Kirill Rybalchenko
@ 2017-09-20 14:33     ` Kirill Rybalchenko
  2017-09-25  9:44       ` Xing, Beilei
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
                       ` (3 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:33 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to add new flow types and pctypes for DDP without changing
API of the driver. The mapping table is located in private
data area for particular network adapter and can be individually
modified with set of appropriate functions.

v2:
Re-arrange patchset to avoid compillation errors.
Remove usage of statically defined flow types and pctypes.

v3:
Changed prototypes of some static functions.
Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype
functions.
Various small modifications after reviewing.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 343 ++++++++++++--------------------------
 drivers/net/i40e/i40e_ethdev.h    |  17 +-
 drivers/net/i40e/i40e_ethdev_vf.c |  16 +-
 drivers/net/i40e/i40e_fdir.c      |  54 +++---
 drivers/net/i40e/i40e_flow.c      |   5 +-
 drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
 drivers/net/i40e/i40e_rxtx.h      |   1 +
 7 files changed, 208 insertions(+), 285 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 18eac07..e396f73 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1064,6 +1064,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(dev);
+	i40e_set_default_pctype_table(dev);
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	intr_handle = &pci_dev->intr_handle;
 
@@ -3000,7 +3001,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
 						sizeof(uint32_t);
 	dev_info->reta_size = pf->hash_lut_size;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask;
 
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
@@ -6591,104 +6592,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
 
 /* Configure hash enable flags for RSS */
 uint64_t
-i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
+i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t hena = 0;
+	int i;
 
 	if (!flags)
 		return hena;
 
-	if (flags & ETH_RSS_FRAG_IPV4)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-	if (flags & ETH_RSS_FRAG_IPV6)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
-	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & (1ULL << i))
+			hena |= adapter->pctypes_tbl[i];
 	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-	if (flags & ETH_RSS_L2_PAYLOAD)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
 	return hena;
 }
 
 /* Parse the hash enable flags */
 uint64_t
-i40e_parse_hena(uint64_t flags)
+i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t rss_hf = 0;
 
 	if (!flags)
 		return rss_hf;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-		rss_hf |= ETH_RSS_FRAG_IPV4;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-		rss_hf |= ETH_RSS_FRAG_IPV6;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
-		rss_hf |= ETH_RSS_L2_PAYLOAD;
+	int i;
 
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & adapter->pctypes_tbl[i])
+			rss_hf |= (1ULL << i);
+	}
 	return rss_hf;
 }
 
@@ -6779,7 +6712,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
@@ -6793,14 +6726,13 @@ i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0; /* Nothing to do */
@@ -6825,7 +6757,7 @@ i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena);
 
 	return 0;
 }
@@ -7600,7 +7532,7 @@ i40e_pf_config_rss(struct i40e_pf *pf)
 	}
 
 	rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) {
 		i40e_pf_disable_rss(pf);
 		return 0;
 	}
@@ -7821,9 +7753,9 @@ static int
 i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
-	uint32_t reg, mask = I40E_FLOW_TYPES;
-	uint16_t i;
-	enum i40e_filter_pctype pctype;
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	uint32_t reg;
+	uint16_t i, j;
 
 	memset(g_cfg, 0, sizeof(*g_cfg));
 	reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
@@ -7834,29 +7766,37 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 	PMD_DRV_LOG(DEBUG, "Hash function is %s",
 		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
-	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
-		if (!(mask & (1UL << i)))
-			continue;
-		mask &= ~(1UL << i);
-		/* Bit set indicats the coresponding flow type is supported */
-		g_cfg->valid_bit_mask[0] |= (1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
-		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
-			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next release
+	 */
+	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+		if (adapter->pctypes_tbl[i]) {
+			for (j = I40E_FILTER_PCTYPE_INVALID + 1;
+			     j < I40E_FILTER_PCTYPE_MAX; j++) {
+				if (adapter->pctypes_tbl[i] & (1ULL << j)) {
+					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
+					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
+						g_cfg->sym_hash_enable_mask[0] |=
+									(1UL << i);
+					}
+				}
+			}
+		}
 	}
 
 	return 0;
 }
 
 static int
-i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
+i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg,
+			      struct i40e_adapter *adapter)
 {
 	uint32_t i;
-	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
+	uint32_t mask0, i40e_mask = adapter->flow_types_mask;
 
 	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
 		g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -7899,64 +7839,32 @@ static int
 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;
 	int ret;
-	uint16_t i;
+	uint16_t i, j;
 	uint32_t reg;
-	uint32_t mask0 = g_cfg->valid_bit_mask[0];
-	enum i40e_filter_pctype pctype;
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next release
+	 */
+	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_mask;
 
 	/* Check the input parameters */
-	ret = i40e_hash_global_config_check(g_cfg);
+	ret = i40e_hash_global_config_check(g_cfg, adapter);
 	if (ret < 0)
 		return ret;
 
-	for (i = 0; mask0 && i < UINT32_BIT; i++) {
-		if (!(mask0 & (1UL << i)))
-			continue;
-		mask0 &= ~(1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
-				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK),
-				  reg);
-			} else {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
-				  reg);
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+		if (mask0 & (1UL << i)) {
+			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+					I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+
+			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_GLQF_HSYM(j), reg);
 			}
-		} else {
-			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
 		}
 	}
 
@@ -8581,13 +8489,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 
 		input_set = i40e_get_default_input_set(pctype);
 
@@ -8650,7 +8555,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -8658,10 +8564,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	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(
-			conf->flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(conf->flow_type);
+			I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
@@ -8669,11 +8573,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
+
 	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
 		/* get inset value in register */
 		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
@@ -8727,24 +8627,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
 
-	pctype = i40e_flowtype_to_pctype(conf->flow_type);
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
 
 	/* get inset value in register */
 	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
@@ -9183,72 +9078,42 @@ i40e_hw_init(struct rte_eth_dev *dev)
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
 }
 
+/*
+ * For X722 it is possible to have multiple pctypes mapped to the same flowtype
+ * however this function will return only one highest pctype index,
+ * which is not quite correct. This is known problem of i40e driver
+ * and needs to be fixed later.
+ */
 enum i40e_filter_pctype
-i40e_flowtype_to_pctype(uint16_t flow_type)
-{
-	static const enum i40e_filter_pctype pctype_table[] = {
-		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
-		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
-		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
-	};
+i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type)
+{
+	int i;
+	uint64_t pctype_mask;
 
-	return pctype_table[flow_type];
+	if (flow_type < I40E_FLOW_TYPE_MAX) {
+		pctype_mask = adapter->pctypes_tbl[flow_type];
+		for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) {
+			if (pctype_mask & (1ULL << i))
+				return (enum i40e_filter_pctype)i;
+		}
+	}
+	return I40E_FILTER_PCTYPE_INVALID;
 }
 
 uint16_t
-i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
+i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+			enum i40e_filter_pctype pctype)
 {
-	static const uint16_t flowtype_table[] = {
-		[I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_OTHER,
-		[I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_OTHER,
-		[I40E_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_FLOW_L2_PAYLOAD,
-	};
+	uint16_t flowtype;
+	uint64_t pctype_mask = 1ULL << pctype;
+
+	for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX;
+	     flowtype++) {
+		if (adapter->pctypes_tbl[flowtype] & pctype_mask)
+			return flowtype;
+	}
 
-	return flowtype_table[pctype];
+	return RTE_ETH_FLOW_UNKNOWN;
 }
 
 /*
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index ad80f0f..e87f846 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -852,7 +852,8 @@ struct i40e_vf {
 	uint64_t flags;
 };
 
-#define I40E_MAX_PKT_TYPE 256
+#define I40E_MAX_PKT_TYPE  256
+#define I40E_FLOW_TYPE_MAX 64
 
 /*
  * Structure to store private data for each PF/VF instance.
@@ -881,6 +882,10 @@ struct i40e_adapter {
 
 	/* ptype mapping table */
 	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
+	/* flow type to pctype mapping table */
+	uint64_t pctypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;
+	uint64_t flow_types_mask;
+	uint64_t pctypes_mask;
 };
 
 extern const struct rte_flow_ops i40e_flow_ops;
@@ -925,8 +930,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
 			   struct i40e_vsi_vlan_pvid_info *info);
 int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
 int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
-uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
-uint64_t i40e_parse_hena(uint64_t flags);
+uint64_t i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags);
+uint64_t i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags);
 enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
 enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
 int i40e_fdir_setup(struct i40e_pf *pf);
@@ -935,8 +940,10 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
 					int socket_id);
 int i40e_fdir_configure(struct rte_eth_dev *dev);
 void i40e_fdir_teardown(struct i40e_pf *pf);
-enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
-uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
+enum i40e_filter_pctype  i40e_flowtype_to_pctype(const struct i40e_adapter *adapter,
+						 uint16_t flow_type);
+uint16_t i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+				 enum i40e_filter_pctype pctype);
 int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 			  enum rte_filter_op filter_op,
 			  void *arg);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index f4ee424..1fd6f11 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1398,6 +1398,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(eth_dev);
+	i40e_set_default_pctype_table(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
@@ -2133,7 +2134,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = vf->adapter->flow_types_mask;
 	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -2443,7 +2444,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(vf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2486,7 +2487,7 @@ i40evf_config_rss(struct i40e_vf *vf)
 	}
 
 	rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & vf->adapter->flow_types_mask) == 0) {
 		i40evf_disable_rss(vf);
 		PMD_DRV_LOG(DEBUG, "No hash flag is set");
 		return 0;
@@ -2511,14 +2512,13 @@ i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & vf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & vf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0;
@@ -2544,7 +2544,7 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(vf->adapter, hena);
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 84c0a1f..810d384 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -344,15 +344,10 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	/* initialize the masks */
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 		pf->fdir.flex_mask[pctype].word_mask = 0;
 		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
 		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) {
@@ -449,7 +444,8 @@ i40e_check_fdir_flex_payload(const struct rte_eth_flex_payload_cfg *flex_cfg)
  * arguments are valid
  */
 static int
-i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
+i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf,
+			  const struct i40e_adapter *adapter)
 {
 	const struct rte_eth_flex_payload_cfg *flex_cfg;
 	const struct rte_eth_fdir_flex_mask *flex_mask;
@@ -486,8 +482,11 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 		return -EINVAL;
 	}
 	for (i = 0; i < conf->nb_flexmasks; i++) {
+		enum i40e_filter_pctype pctype;
+
 		flex_mask = &conf->flex_mask[i];
-		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
+		pctype = i40e_flowtype_to_pctype(adapter, flex_mask->flow_type);
+		if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 			PMD_DRV_LOG(WARNING, "invalid flow type.");
 			return -EINVAL;
 		}
@@ -650,7 +649,7 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	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);
+	ret = i40e_check_fdir_flex_conf(conf, pf->adapter);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, " invalid configuration arguments.");
 		return -EINVAL;
@@ -664,11 +663,11 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 			/* 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(
+				(int)i40e_flowtype_to_pctype(pf->adapter,
 				conf->flex_mask[i].flow_type)));
 		} else
-			pctype = i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type);
+			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]);
 	}
@@ -1100,7 +1099,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		return -ENOTSUP;
 	}
 
-	if (!I40E_VALID_FLOW(filter->input.flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, filter->input.flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -1141,12 +1141,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 	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(
-			filter->input.flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
-
+			hw, I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "fdir programming fails for PCTYPE(%u).",
@@ -1384,7 +1380,6 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 {
 	struct i40e_fdir_flex_mask *mask;
 	struct rte_eth_fdir_flex_mask *ptr = flex_mask;
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t flow_type;
 	uint8_t i, j;
 	uint16_t off_bytes, mask_tmp;
@@ -1393,14 +1388,11 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 	     i <= I40E_FILTER_PCTYPE_L2_PAYLOAD;
 	     i++) {
 		mask =  &pf->fdir.flex_mask[i];
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722((enum i40e_filter_pctype)i))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE((enum i40e_filter_pctype)i))
-				continue;
-		}
-		flow_type = i40e_pctype_to_flowtype((enum i40e_filter_pctype)i);
+		flow_type = i40e_pctype_to_flowtype(pf->adapter,
+						    (enum i40e_filter_pctype)i);
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
+
 		for (j = 0; j < I40E_FDIR_MAX_FLEXWORD_NUM; j++) {
 			if (mask->word_mask & I40E_FLEX_WORD_MASK(j)) {
 				ptr->mask[j * sizeof(uint16_t)] = UINT8_MAX;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b92719a..5d8afc6 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2776,8 +2776,9 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		}
 	}
 
-	pctype = i40e_flowtype_to_pctype(flow_type);
-	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID ||
+	    pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
 				   "Unsupported flow type");
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 3a7b68e..0c8ad00 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2943,6 +2943,63 @@ i40e_set_default_ptype_table(struct rte_eth_dev *dev)
 		ad->ptype_tbl[i] = i40e_get_default_pkt_type(i);
 }
 
+void __attribute__((cold))
+i40e_set_default_pctype_table(struct rte_eth_dev *dev)
+{
+	struct i40e_adapter *ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int i;
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_tbl[i] = 0ULL;
+	ad->flow_types_mask = 0ULL;
+	ad->pctypes_mask = 0ULL;
+
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV4] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV6] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
+				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+
+	if (hw->mac.type == I40E_MAC_X722) {
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+	}
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (ad->pctypes_tbl[i])
+			ad->flow_types_mask |= (1ULL << i);
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+	}
+}
+
 /* Stubs needed for linkage when CONFIG_RTE_I40E_INC_VECTOR is set to 'n' */
 int __attribute__((weak))
 i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..2a58ced 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -255,6 +255,7 @@ void i40e_set_tx_function_flag(struct rte_eth_dev *dev,
 			       struct i40e_tx_queue *txq);
 void i40e_set_tx_function(struct rte_eth_dev *dev);
 void i40e_set_default_ptype_table(struct rte_eth_dev *dev);
+void i40e_set_default_pctype_table(struct rte_eth_dev *dev);
 
 /* For each value it means, datasheet of hardware can tell more details
  *
-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
                       ` (2 preceding siblings ...)
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-09-20 14:33     ` Kirill Rybalchenko
  2017-09-22  7:27       ` Xing, Beilei
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
                       ` (2 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:33 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new functions which allow modify, return or reset to default
the contents of flow type to pctype dynamic mapping table.

v3:
function rte_pmd_i40e_flow_type_mapping_get returns now full
mapping table.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c           | 90 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 55 +++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  3 ++
 3 files changed, 148 insertions(+)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index c08e07a..7cf56db 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -2161,3 +2161,93 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 
 	return 0;
 }
+
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	i40e_set_default_pctype_table(dev);
+
+	return 0;
+}
+
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	uint16_t i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		mapping_items[i].flow_type = i;
+		mapping_items[i].pctype = ad->pctypes_tbl[i];
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	int i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	if (count > I40E_FLOW_TYPE_MAX)
+		return -EINVAL;
+
+	for (i = 0; i < count; i++)
+		if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX ||
+		    mapping_items[i].flow_type == RTE_ETH_FLOW_UNKNOWN ||
+		    (mapping_items[i].pctype & (1ULL << I40E_FILTER_PCTYPE_INVALID)))
+			return -EINVAL;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	if (exclusive) {
+		for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+			ad->pctypes_tbl[i] = 0ULL;
+		ad->flow_types_mask = 0ULL;
+	}
+
+	for (i = 0; i < count; i++) {
+		ad->pctypes_tbl[mapping_items[i].flow_type] = mapping_items[i].pctype;
+		if (mapping_items[i].pctype)
+			ad->flow_types_mask |= (1ULL << mapping_items[i].flow_type);
+		else
+			ad->flow_types_mask &= ~(1ULL << mapping_items[i].flow_type);
+	}
+
+	for (i = 0, ad->pctypes_mask = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+
+	return 0;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 155b7e8..004a8a5 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -657,4 +657,59 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,
 int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+#define RTE_PMD_I40E_PCTYPE_MAX		64
+#define RTE_PMD_I40E_FLOW_TYPE_MAX	64
+
+struct rte_pmd_i40e_flow_type_mapping {
+	uint16_t flow_type; /**< software defined flow type*/
+	uint64_t pctype;    /**< hardware defined pctype */
+};
+
+/**
+ * Update hardware defined pctype to software defined flow type
+ * mapping table.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the mapping items array.
+ * @param count
+ *    number of mapping items.
+ * @param exclusive
+ *    the flag indicate different pctype mapping update method.
+ *    -(0) only overwrite referred PCTYPE mapping,
+ *	keep other PCTYPEs mapping unchanged.
+ *    -(!0) overwrite referred PCTYPE mapping,
+ *	set other PCTYPEs maps to PCTYPE_INVALID.
+ */
+int rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive);
+
+/**
+ * Get software defined flow type to hardware defined pctype
+ * mapping items.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the array to store returned items.
+ *    array should be allocated by caller with minimum size of
+ *    RTE_PMD_I40E_FLOW_TYPE_MAX items
+ */
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items);
+
+/**
+ * Reset hardware defined pctype to software defined flow type
+ * mapping table to default.
+ *
+ * @param port
+ *    pointer to port identifier of the device
+ */
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index ef8882b..438ca81 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -50,5 +50,8 @@ DPDK_17.11 {
 	global:
 
 	rte_pmd_i40e_add_vf_mac_addr;
+	rte_pmd_i40e_flow_type_mapping_update;
+	rte_pmd_i40e_flow_type_mapping_get;
+	rte_pmd_i40e_flow_type_mapping_get;
 
 } DPDK_17.08;
-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
                       ` (3 preceding siblings ...)
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-09-20 14:33     ` Kirill Rybalchenko
  2017-09-25 11:54       ` Xing, Beilei
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 6/6] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  6 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:33 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new commands to manipulate with dynamic flow type to
pctype mapping table in i40e PMD.
Commands allow to print table, modify it and reset to default value.

v3:
changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 app/test-pmd/cmdline.c                      | 335 +++++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  46 ++++
 drivers/net/i40e/rte_pmd_i40e_version.map   |   2 +-
 3 files changed, 372 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4f2d731..4f68267 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -230,6 +230,10 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"clear vf stats (port_id) (vf_id)\n"
 			"    Reset a VF's statistics.\n\n"
+
+			"show port (port_id) pctype mapping\n"
+			"    Get flow ptype to pctype mapping on a port\n\n"
+
 		);
 	}
 
@@ -681,7 +685,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
 			" for ports.\n\n"
 
-			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
+			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|"
+			"geneve|nvgre|none|<flowtype_id>)\n"
 			"    Set the RSS mode.\n\n"
 
 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
@@ -716,6 +721,13 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"port config (port_id|all) l2-tunnel E-tag"
 			" (enable|disable)\n"
 			"    Enable/disable the E-tag support.\n\n"
+
+			"port config (port_id) pctype mapping reset\n"
+			"    Reset flow type to pctype mapping on a port\n\n"
+
+			"port config (port_id) pctype mapping update"
+			" (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n"
+			"    Update a flow type to pctype mapping item on a port\n\n"
 		);
 	}
 
@@ -878,8 +890,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
 			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
-			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
+			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-ipv4|dst-ipv4|"
+			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
 			"ipv6-next-header|udp-src-port|udp-dst-port|"
 			"tcp-src-port|tcp-dst-port|sctp-src-port|"
 			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
@@ -1720,6 +1732,8 @@ cmd_config_rss_parsed(void *parsed_result,
 		rss_conf.rss_hf = ETH_RSS_NVGRE;
 	else if (!strcmp(res->value, "none"))
 		rss_conf.rss_hf = 0;
+	else if (isdigit(res->value[0]) && atoi(res->value) > 0 && atoi(res->value) < 64)
+		rss_conf.rss_hf = 1ULL << atoi(res->value);
 	else {
 		printf("Unknown parameter\n");
 		return;
@@ -1743,14 +1757,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
 cmdline_parse_token_string_t cmd_config_rss_name =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
 cmdline_parse_token_string_t cmd_config_rss_value =
-	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
-		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
 
 cmdline_parse_inst_t cmd_config_rss = {
 	.f = cmd_config_rss_parsed,
 	.data = NULL,
 	.help_str = "port config all rss "
-		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
+		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|<flowtype_id>",
 	.tokens = {
 		(void *)&cmd_config_rss_port,
 		(void *)&cmd_config_rss_keyword,
@@ -8991,6 +9004,10 @@ str2flowtype(char *string)
 		if (!strcmp(flowtype_str[i].str, string))
 			return flowtype_str[i].type;
 	}
+
+	if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64)
+		return (uint16_t)atoi(string);
+
 	return RTE_ETH_FLOW_UNKNOWN;
 }
 
@@ -10467,9 +10484,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 		port_id, UINT8);
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
-		flow_type,
-		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
-		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+		flow_type, NULL);
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		inset_field,
@@ -10488,7 +10503,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
-	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload|<flowtype_id> "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -13810,6 +13825,302 @@ cmdline_parse_inst_t cmd_clear_vf_stats = {
 	},
 };
 
+/* port config pctype mapping reset */
+
+/* Common result structure for port config pctype mapping reset */
+struct cmd_pctype_mapping_reset_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t reset;
+};
+
+/* Common CLI fields for port config pctype mapping reset*/
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 reset, "reset");
+
+static void
+cmd_pctype_mapping_reset_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_reset_result *res = parsed_result;
+	int ret = -ENOTSUP;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_reset = {
+	.f = cmd_pctype_mapping_reset_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping reset",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_reset_port,
+		(void *)&cmd_pctype_mapping_reset_config,
+		(void *)&cmd_pctype_mapping_reset_port_id,
+		(void *)&cmd_pctype_mapping_reset_pctype,
+		(void *)&cmd_pctype_mapping_reset_mapping,
+		(void *)&cmd_pctype_mapping_reset_reset,
+		NULL,
+	},
+};
+
+/* show port pctype mapping get */
+
+/* Common result structure for show port pctype mapping get */
+struct cmd_pctype_mapping_get_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+};
+
+/* Common CLI fields for pctype mapping get */
+cmdline_parse_token_string_t cmd_pctype_mapping_get_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 mapping, "mapping");
+
+static void
+cmd_pctype_mapping_get_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_get_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping[RTE_PMD_I40E_FLOW_TYPE_MAX];
+	int i, j;
+#endif
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id, mapping);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		return;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		return;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	for (i = 0; i < RTE_PMD_I40E_FLOW_TYPE_MAX; i++) {
+		if (mapping[i].pctype != 0ULL) {
+			int first_pctype = 1;
+
+			printf("pctype: ");
+			for (j = 0; j < RTE_PMD_I40E_PCTYPE_MAX; j++) {
+				if (mapping[i].pctype & (1ULL << j)) {
+					printf(first_pctype ? "%02d" : ",%02d", j);
+					first_pctype = 0;
+				}
+			}
+			printf("  ->  flowtype: %02d\n", mapping[i].flow_type);
+		}
+	}
+#endif
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_get = {
+	.f = cmd_pctype_mapping_get_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> pctype mapping",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_get_show,
+		(void *)&cmd_pctype_mapping_get_port,
+		(void *)&cmd_pctype_mapping_get_port_id,
+		(void *)&cmd_pctype_mapping_get_pctype,
+		(void *)&cmd_pctype_mapping_get_mapping,
+		NULL,
+	},
+};
+
+/* port config pctype mapping update */
+
+/* Common result structure for port config pctype mapping update */
+struct cmd_pctype_mapping_update_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t update;
+	cmdline_fixed_string_t pctype_list;
+	uint16_t flow_type;
+};
+
+/* Common CLI fields for pctype mapping update*/
+cmdline_parse_token_string_t cmd_pctype_mapping_update_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_update =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 update, "update");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype_list, NULL);
+cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 flow_type, UINT16);
+
+static void
+cmd_pctype_mapping_update_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_update_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping;
+#endif
+	unsigned int nb_item, i;
+	unsigned int pctype_list[RTE_PMD_I40E_PCTYPE_MAX];
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	nb_item = parse_item_list(res->pctype_list, "pctypes", RTE_PMD_I40E_PCTYPE_MAX,
+				  pctype_list, 1);
+
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	mapping.flow_type = res->flow_type;
+	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
+		mapping.pctype |= (1ULL << pctype_list[i]);
+	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
+						&mapping,
+						1,
+						0);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid pctype or flow type\n");
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_update = {
+	.f = cmd_pctype_mapping_update_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping update"
+	" <pctype_id_0,[pctype_id_1]*> <flowtype_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_update_port,
+		(void *)&cmd_pctype_mapping_update_config,
+		(void *)&cmd_pctype_mapping_update_port_id,
+		(void *)&cmd_pctype_mapping_update_pctype,
+		(void *)&cmd_pctype_mapping_update_mapping,
+		(void *)&cmd_pctype_mapping_update_update,
+		(void *)&cmd_pctype_mapping_update_pc_type,
+		(void *)&cmd_pctype_mapping_update_flow_type,
+		NULL,
+	},
+};
+
 /* ptype mapping get */
 
 /* Common result structure for ptype mapping get */
@@ -14391,6 +14702,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_replace,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_reset,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_update,
+
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_get,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_reset,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_update,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2ed62f5..2911fe1 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -408,6 +408,14 @@ Reset VF statistics::
 
    testpmd> clear vf stats (port_id) (vf_id)
 
+show port pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> show port (port_id) pctype mapping get
+
+
 Configuration Functions
 -----------------------
 
@@ -1310,6 +1318,27 @@ Reset ptype mapping table::
 
    testpmd> ptype mapping reset (port_id)
 
+pctype mapping
+~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> pctype mapping get (port_id)
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*) (flow_type_d)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
+Reset pctype mapping table::
+
+   testpmd> pctype mapping reset (port_id)
+
 Port Functions
 --------------
 
@@ -1697,6 +1726,23 @@ Enable/disable the E-tag support::
 
    testpmd> port config (port_id|all) l2-tunnel E-tag (enable|disable)
 
+port config pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Reset pctype mapping table::
+
+   testpmd> port config (port_id) pctype mapping reset
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> port config (port_id) pctype mapping update (pctype_id_0[,pctype_id_1]*) (flow_type_id)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
 
 Link Bonding Functions
 ----------------------
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 438ca81..9292454 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -52,6 +52,6 @@ DPDK_17.11 {
 	rte_pmd_i40e_add_vf_mac_addr;
 	rte_pmd_i40e_flow_type_mapping_update;
 	rte_pmd_i40e_flow_type_mapping_get;
-	rte_pmd_i40e_flow_type_mapping_get;
+	rte_pmd_i40e_flow_type_mapping_reset;
 
 } DPDK_17.08;
-- 
2.5.5

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

* [dpdk-dev] [PATCH v3 6/6] ethdev: remove unnecessary check for new flow type
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
                       ` (4 preceding siblings ...)
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-09-20 14:33     ` Kirill Rybalchenko
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-09-20 14:33 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary check for new flow type for rss hash
filter update.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a88916f..d2279b7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2280,16 +2280,8 @@ int
 rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
 {
 	struct rte_eth_dev *dev;
-	uint16_t rss_hash_protos;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rss_hash_protos = rss_conf->rss_hf;
-	if ((rss_hash_protos != 0) &&
-	    ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {
-		RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
-				rss_hash_protos);
-		return -EINVAL;
-	}
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
 	return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
-- 
2.5.5

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

* Re: [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-09-22  7:27       ` Xing, Beilei
  0 siblings, 0 replies; 40+ messages in thread
From: Xing, Beilei @ 2017-09-22  7:27 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev; +Cc: Chilikin, Andrey, Wu, Jingjing



> -----Original Message-----
> From: Rybalchenko, Kirill
> Sent: Wednesday, September 20, 2017 10:33 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v3 4/6] net/i40e: add new functions to manipulate with
> pctype mapping table
> 
> Add new functions which allow modify, return or reset to default the
> contents of flow type to pctype dynamic mapping table.
> 
> v3:
> function rte_pmd_i40e_flow_type_mapping_get returns now full mapping
> table.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---


> diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> b/drivers/net/i40e/rte_pmd_i40e_version.map
> index ef8882b..438ca81 100644
> --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> @@ -50,5 +50,8 @@ DPDK_17.11 {
>  	global:
> 
>  	rte_pmd_i40e_add_vf_mac_addr;
> +	rte_pmd_i40e_flow_type_mapping_update;
> +	rte_pmd_i40e_flow_type_mapping_get;
> +	rte_pmd_i40e_flow_type_mapping_get;

Should it be rte_pmd_i40e_flow_type_mapping_reset here?

> 
>  } DPDK_17.08;
> --
> 2.5.5

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

* Re: [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype
  2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype Kirill Rybalchenko
@ 2017-09-22  7:29       ` Xing, Beilei
  0 siblings, 0 replies; 40+ messages in thread
From: Xing, Beilei @ 2017-09-22  7:29 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev
  Cc: Rybalchenko, Kirill, Chilikin, Andrey, Wu, Jingjing



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Wednesday, September 20, 2017 10:33 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid
> pctype
> 
> Add new definition in enum i40e_filter_pctype for for invalid pctype
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  drivers/net/i40e/base/i40e_type.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/i40e/base/i40e_type.h
> b/drivers/net/i40e/base/i40e_type.h
> index dca725a..d57986e 100644
> --- a/drivers/net/i40e/base/i40e_type.h
> +++ b/drivers/net/i40e/base/i40e_type.h
> @@ -1245,9 +1245,11 @@ struct i40e_filter_program_desc {
> 
>  /* Packet Classifier Types for filters */  enum i40e_filter_pctype {
> -	/* Note: Values 0-28 are reserved for future use.
> +	/* Note: Vlue 0 is not valid pctype.
> +	 * Values 0-28 are reserved for future use.
>  	 * Value 29, 30, 32 are not supported on XL710 and X710.
>  	 */
> +	I40E_FILTER_PCTYPE_INVALID			= 0,

We'd better not to change base code which is aligned with kernel driver.
We can add macro in i40e_ethdev.h.

>  	I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP	= 29,
>  	I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP	= 30,
>  	I40E_FILTER_PCTYPE_NONF_IPV4_UDP		= 31,
> --
> 2.5.5

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

* Re: [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-09-25  9:44       ` Xing, Beilei
  0 siblings, 0 replies; 40+ messages in thread
From: Xing, Beilei @ 2017-09-25  9:44 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev; +Cc: Chilikin, Andrey, Wu, Jingjing

> -----Original Message-----
> From: Rybalchenko, Kirill
> Sent: Wednesday, September 20, 2017 10:33 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow
> types to hw pctypes
> 
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to add new flow types and pctypes for DDP without changing API
> of the driver. The mapping table is located in private data area for particular
> network adapter and can be individually modified with set of appropriate
> functions.
> 
> v2:
> Re-arrange patchset to avoid compillation errors.
> Remove usage of statically defined flow types and pctypes.
> 
> v3:
> Changed prototypes of some static functions.
> Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype
> functions.
> Various small modifications after reviewing.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c    | 343 ++++++++++++--------------------------
>  drivers/net/i40e/i40e_ethdev.h    |  17 +-
>  drivers/net/i40e/i40e_ethdev_vf.c |  16 +-
>  drivers/net/i40e/i40e_fdir.c      |  54 +++---
>  drivers/net/i40e/i40e_flow.c      |   5 +-
>  drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
>  drivers/net/i40e/i40e_rxtx.h      |   1 +
>  7 files changed, 208 insertions(+), 285 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 18eac07..e396f73 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c

<snip>

> 
>  static int
> -i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
> +i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg,
> +			      struct i40e_adapter *adapter)

how about chaning the parameter order?
i40e_hash_global_config_check(struct i40e_adapter *adapter, struct rte_eth_hash_global_conf *g_cfg)?

>  {
>  	uint32_t i;
> -	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
> +	uint32_t mask0, i40e_mask = adapter->flow_types_mask;
> 
>  	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
>  		g_cfg->hash_func !=
> RTE_ETH_HASH_FUNCTION_SIMPLE_XOR && @@ -7899,64 +7839,32 @@
> static int  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;
>  	int ret;
> -	uint16_t i;
> +	uint16_t i, j;
>  	uint32_t reg;
> -	uint32_t mask0 = g_cfg->valid_bit_mask[0];
> -	enum i40e_filter_pctype pctype;
> +	/*
> +	 * We work only with lowest 32 bits which is not correct, but to work
> +	 * properly the valid_bit_mask size should be increased up to 64 bits
> +	 * and this will brake ABI. This modification will be done in next
> release
> +	 */
> +	uint32_t mask0 = g_cfg->valid_bit_mask[0] &
> +(uint32_t)adapter->flow_types_mask;
> 
>  	/* Check the input parameters */
> -	ret = i40e_hash_global_config_check(g_cfg);
> +	ret = i40e_hash_global_config_check(g_cfg, adapter);
>  	if (ret < 0)
>  		return ret;
> 
> -	for (i = 0; mask0 && i < UINT32_BIT; i++) {
> -		if (!(mask0 & (1UL << i)))
> -			continue;
> -		mask0 &= ~(1UL << i);
> -		/* if flowtype is invalid, continue */
> -		if (!I40E_VALID_FLOW(i))
> -			continue;
> -		pctype = i40e_flowtype_to_pctype(i);
> -		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
> -				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
> -		if (hw->mac.type == I40E_MAC_X722) {
> -			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP)
> {

<snip>

> -				  reg);
> -			} else {
> -				i40e_write_rx_ctl(hw,
> I40E_GLQF_HSYM(pctype),
> -				  reg);
> +	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {

Should it be like following?
for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {

> +		if (mask0 & (1UL << i)) {
> +			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL <<
> i)) ?
> +
> 	I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
> +
> +			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_GLQF_HSYM(j), reg);
>  			}
> -		} else {
> -			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
> reg);
>  		}
>  	}
> 
> @@ -8581,13 +8489,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
> 
>  	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
>  	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
> -		if (hw->mac.type == I40E_MAC_X722) {
> -			if (!I40E_VALID_PCTYPE_X722(pctype))
> -				continue;
> -		} else {
> -			if (!I40E_VALID_PCTYPE(pctype))
> -				continue;
> -		}
> +		uint16_t flow_type = i40e_pctype_to_flowtype(pf->adapter,
> pctype);

Move the variable to the beginning of the function according to the code style.

> +
> +		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
> +			continue;
> 
>  		input_set = i40e_get_default_input_set(pctype);
> 
> @@ -8650,7 +8555,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
>  		return -EINVAL;
>  	}
> 
> -	if (!I40E_VALID_FLOW(conf->flow_type)) {
> +	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
> +	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
>  		PMD_DRV_LOG(ERR, "invalid flow_type input.");
>  		return -EINVAL;
>  	}

<snip>

> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index
> 84c0a1f..810d384 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -344,15 +344,10 @@ i40e_init_flx_pld(struct i40e_pf *pf)
>  	/* initialize the masks */
>  	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
>  	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
> -		if (hw->mac.type == I40E_MAC_X722) {
> -			if (!I40E_VALID_PCTYPE_X722(
> -				 (enum i40e_filter_pctype)pctype))
> -				continue;
> -		} else {
> -			if (!I40E_VALID_PCTYPE(
> -				 (enum i40e_filter_pctype)pctype))
> -				continue;
> -		}
> +		uint16_t flow_type = i40e_pctype_to_flowtype(pf->adapter,
> pctype);

Same comments here, move 'uint16_t flow_type' to the beginning of the function.

> +
> +		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
> +			continue;
>  		pf->fdir.flex_mask[pctype].word_mask = 0;
>  		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
>  		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) { @@ -
> 449,7 +444,8 @@ i40e_check_fdir_flex_payload(const struct
> rte_eth_flex_payload_cfg *flex_cfg)
>   * arguments are valid
>   */
>  static int
> -i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
> +i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf,
> +			  const struct i40e_adapter *adapter)

How about i40e_check_fdir_flex_conf(const struct i40e_adapter *adapter , const struct rte_eth_fdir_flex_conf *conf)?

>  {
>  	const struct rte_eth_flex_payload_cfg *flex_cfg;
>  	const struct rte_eth_fdir_flex_mask *flex_mask; @@ -486,8 +482,11
> @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
>  		return -EINVAL;
>  	}
>  	for (i = 0; i < conf->nb_flexmasks; i++) {
> +		enum i40e_filter_pctype pctype;

Move the variable to the beginning of the function.

> +
>  		flex_mask = &conf->flex_mask[i];
> -		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
> +		pctype = i40e_flowtype_to_pctype(adapter, flex_mask-
> >flow_type);
> +		if (pctype == I40E_FILTER_PCTYPE_INVALID) {
>  			PMD_DRV_LOG(WARNING, "invalid flow type.");
>  			return -EINVAL;
>  		}

<snip>

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

* Re: [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-09-25 11:54       ` Xing, Beilei
  0 siblings, 0 replies; 40+ messages in thread
From: Xing, Beilei @ 2017-09-25 11:54 UTC (permalink / raw)
  To: Rybalchenko, Kirill, dev; +Cc: Chilikin, Andrey, Wu, Jingjing



> -----Original Message-----
> From: Rybalchenko, Kirill
> Sent: Wednesday, September 20, 2017 10:33 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v3 5/6] app/testpmd: add new commands to manipulate
> with pctype mapping
> 
> Add new commands to manipulate with dynamic flow type to pctype
> mapping table in i40e PMD.
> Commands allow to print table, modify it and reset to default value.
> 
> v3:
> changed command syntax from 'pctype mapping...' to 'port config pctype
> mapping...' and 'show port pctype mapping'
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
>  app/test-pmd/cmdline.c                      | 335
> +++++++++++++++++++++++++++-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  46 ++++
>  drivers/net/i40e/rte_pmd_i40e_version.map   |   2 +-
>  3 files changed, 372 insertions(+), 11 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 4f2d731..4f68267 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c

<snip>

> +
> +/* show port pctype mapping get */
> +
> +/* Common result structure for show port pctype mapping get */ struct

show port pctype mapping get  ->   show port pctype mapping ?

> +cmd_pctype_mapping_get_result {
> +	cmdline_fixed_string_t show;
> +	cmdline_fixed_string_t port;
> +	uint8_t port_id;
> +	cmdline_fixed_string_t pctype;
> +	cmdline_fixed_string_t mapping;
> +};
> +
> +/* Common CLI fields for pctype mapping get */

"get" should be removed.

> +cmdline_parse_token_string_t cmd_pctype_mapping_get_show =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 show, "show");
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_port =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 port, "port");
> +cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
> +	TOKEN_NUM_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 port_id, UINT8);
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 pctype, "pctype");
> +cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
> +	TOKEN_STRING_INITIALIZER
> +		(struct cmd_pctype_mapping_get_result,
> +		 mapping, "mapping");
> +
> +static void
> +cmd_pctype_mapping_get_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_get_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	struct rte_pmd_i40e_flow_type_mapping
> mapping[RTE_PMD_I40E_FLOW_TYPE_MAX];
> +	int i, j;
> +#endif
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id,
> mapping);
> +#endif
> +
> +	switch (ret) {
> +	case 0:
> +		break;
> +	case -ENODEV:
> +		printf("invalid port_id %d\n", res->port_id);
> +		return;
> +	case -ENOTSUP:
> +		printf("function not implemented\n");
> +		return;
> +	default:
> +		printf("programming error: (%s)\n", strerror(-ret));
> +		return;
> +	}
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	for (i = 0; i < RTE_PMD_I40E_FLOW_TYPE_MAX; i++) {
> +		if (mapping[i].pctype != 0ULL) {
> +			int first_pctype = 1;
> +

first_pctype should be moved to the beginning of the function.

> +			printf("pctype: ");
> +			for (j = 0; j < RTE_PMD_I40E_PCTYPE_MAX; j++) {
> +				if (mapping[i].pctype & (1ULL << j)) {
> +					printf(first_pctype ? "%02d" : ",%02d",
> j);
> +					first_pctype = 0;
> +				}
> +			}
> +			printf("  ->  flowtype: %02d\n",
> mapping[i].flow_type);
> +		}
> +	}
> +#endif
> +}
> +

<snip>


> +static void
> +cmd_pctype_mapping_update_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_pctype_mapping_update_result *res = parsed_result;
> +	int ret = -ENOTSUP;
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	struct rte_pmd_i40e_flow_type_mapping mapping; #endif
> +	unsigned int nb_item, i;

Should "i" be defined when RTE_LIBRTE_I40E_PMD is defined? otherwise 
it will be defined but not used when RTE_LIBRTE_I40E_PMD is not defined.

> +	unsigned int pctype_list[RTE_PMD_I40E_PCTYPE_MAX];
> +
> +	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
> +		return;
> +
> +	nb_item = parse_item_list(res->pctype_list, "pctypes",
> RTE_PMD_I40E_PCTYPE_MAX,
> +				  pctype_list, 1);
> +
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> +	mapping.flow_type = res->flow_type;
> +	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
> +		mapping.pctype |= (1ULL << pctype_list[i]);
> +	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
> +						&mapping,
> +						1,
> +						0);
> +#endif
> +

<snip>

> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 2ed62f5..2911fe1 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -408,6 +408,14 @@ Reset VF statistics::
> 
>     testpmd> clear vf stats (port_id) (vf_id)
> 
> +show port pctype mapping
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Length of  the wave line should be the same as length of " show port pctype mapping "?

> +
> +List all items from the pctype mapping table::
> +
> +   testpmd> show port (port_id) pctype mapping get

"get" should be removed.

> +
> +
>  Configuration Functions
>  -----------------------
> 
> @@ -1310,6 +1318,27 @@ Reset ptype mapping table::
> 
>     testpmd> ptype mapping reset (port_id)

port config <port_id> pctype mapping reset?

> 
> +pctype mapping
> +~~~~~~~~~~~~~

I think all about " pctype mapping " can be removed as you use "port config pctype mapping", right?

> +
> +List all items from the pctype mapping table::
> +
> +   testpmd> pctype mapping get (port_id)
> +
> +Update hardware defined pctype to software defined flow type mapping
> table::
> +
> +   testpmd> pctype mapping update (port_id)
> + (pctype_id_0[,pctype_id_1]*) (flow_type_d)
> +
> +where:
> +
> +* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the
> pctype mapping table.
> +
> +* ``flow_type_id``: software flow type id as the index of the pctype
> mapping table.
> +
> +Reset pctype mapping table::
> +
> +   testpmd> pctype mapping reset (port_id)
> +
>  Port Functions
>  --------------
> 
> @@ -1697,6 +1726,23 @@ Enable/disable the E-tag support::
> 
>     testpmd> port config (port_id|all) l2-tunnel E-tag (enable|disable)
> 
> +port config pctype mapping
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Pay attention to the length of the wave line.

> +
> +Reset pctype mapping table::
> +
> +   testpmd> port config (port_id) pctype mapping reset
> +
> +Update hardware defined pctype to software defined flow type mapping
> table::
> +
> +   testpmd> port config (port_id) pctype mapping update
> + (pctype_id_0[,pctype_id_1]*) (flow_type_id)
> +
> +where:
> +
> +* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the
> pctype mapping table.
> +
> +* ``flow_type_id``: software flow type id as the index of the pctype
> mapping table.
> +
> 
>  Link Bonding Functions
>  ----------------------
> diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> b/drivers/net/i40e/rte_pmd_i40e_version.map
> index 438ca81..9292454 100644
> --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> @@ -52,6 +52,6 @@ DPDK_17.11 {
>  	rte_pmd_i40e_add_vf_mac_addr;
>  	rte_pmd_i40e_flow_type_mapping_update;
>  	rte_pmd_i40e_flow_type_mapping_get;
> -	rte_pmd_i40e_flow_type_mapping_get;
> +	rte_pmd_i40e_flow_type_mapping_reset;

It should be fixed in patch 4/6.

> 
>  } DPDK_17.08;
> --
> 2.5.5

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

* [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
                       ` (5 preceding siblings ...)
  2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 6/6] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
@ 2017-10-02 15:08     ` Kirill Rybalchenko
  2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
                         ` (6 more replies)
  6 siblings, 7 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:08 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to map new flow types to pctypes without changing
API of the driver.

v2:
Remove unnecessary check for new flow types.
Re-arrange patchset to avoid compillation errors.
Remove unnecessary usage of statically defined flow types and pctypes.

v3:
Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
Add new definition in enum i40e_filter_pctype for for invalid pctype.
Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
testpmd: changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'
Various small modifications in code style after reviewing.

v4:
Change prototypes of some static functions.
Move declaration of automatic variables to beginning of function.
Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h
Fix some typos in source filea and documentation.

Kirill Rybalchenko (5):
  net/i40e: remove unnecessary bit operations
  net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  net/i40e: add new functions to manipulate with pctype      mapping
    table
  app/testpmd: add new commands to manipulate with pctype mapping
  ethdev: remove unnecessary check for new flow type

 app/test-pmd/cmdline.c                      | 336 ++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  46 ++++
 drivers/net/i40e/i40e_ethdev.c              | 363 ++++++++--------------------
 drivers/net/i40e/i40e_ethdev.h              |  22 +-
 drivers/net/i40e/i40e_ethdev_vf.c           |  36 +--
 drivers/net/i40e/i40e_fdir.c                |  54 ++---
 drivers/net/i40e/i40e_flow.c                |   5 +-
 drivers/net/i40e/i40e_rxtx.c                |  57 +++++
 drivers/net/i40e/i40e_rxtx.h                |   1 +
 drivers/net/i40e/rte_pmd_i40e.c             |  90 +++++++
 drivers/net/i40e/rte_pmd_i40e.h             |  55 +++++
 drivers/net/i40e/rte_pmd_i40e_version.map   |   3 +
 lib/librte_ether/rte_ethdev.c               |   8 -
 13 files changed, 737 insertions(+), 339 deletions(-)

-- 
2.5.5

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

* [dpdk-dev] [PATCH v4 1/5] net/i40e: remove unnecessary bit operations
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
@ 2017-10-02 15:08       ` Kirill Rybalchenko
  2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
                         ` (5 subsequent siblings)
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:08 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary bit operations in I40E_PFQF_HENA
and I40E_VFQF_HENA registers

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 21 +++------------------
 drivers/net/i40e/i40e_ethdev_vf.c | 22 ++++------------------
 2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index acdf0de..41c4033 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6717,16 +6717,9 @@ static void
 i40e_pf_disable_rss(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -6798,7 +6791,6 @@ static int
 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t rss_hf;
 	uint64_t hena;
 	int ret;
 
@@ -6807,14 +6799,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b35011a..a903deb 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2498,7 +2498,7 @@ static int
 i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t rss_hf, hena;
+	uint64_t hena;
 	int ret;
 
 	ret = i40evf_set_rss_key(&vf->vsi, rss_conf->rss_key,
@@ -2506,14 +2506,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2525,16 +2518,9 @@ static void
 i40evf_disable_rss(struct i40e_vf *vf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), 0);
 	I40EVF_WRITE_FLUSH(hw);
 }
 
-- 
2.5.5

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

* [dpdk-dev] [PATCH v4 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
@ 2017-10-02 15:08       ` Kirill Rybalchenko
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
                         ` (4 subsequent siblings)
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:08 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to add new flow types and pctypes for DDP without changing
API of the driver. The mapping table is located in private
data area for particular network adapter and can be individually
modified with set of appropriate functions.

v2:
Re-arrange patchset to avoid compillation errors.
Remove usage of statically defined flow types and pctypes.

v3:
Change prototypes of some static functions.
Fixe bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype
functions.
Various small modifications after reviewing.

v4:
Change prototypes of some static functions.
Move declaration of automatic variables to beginning of function.
Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 344 ++++++++++++--------------------------
 drivers/net/i40e/i40e_ethdev.h    |  22 ++-
 drivers/net/i40e/i40e_ethdev_vf.c |  16 +-
 drivers/net/i40e/i40e_fdir.c      |  54 +++---
 drivers/net/i40e/i40e_flow.c      |   5 +-
 drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
 drivers/net/i40e/i40e_rxtx.h      |   1 +
 7 files changed, 212 insertions(+), 287 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 41c4033..6443702 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1070,6 +1070,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(dev);
+	i40e_set_default_pctype_table(dev);
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	intr_handle = &pci_dev->intr_handle;
 
@@ -3020,7 +3021,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
 						sizeof(uint32_t);
 	dev_info->reta_size = pf->hash_lut_size;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask;
 
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
@@ -6611,104 +6612,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
 
 /* Configure hash enable flags for RSS */
 uint64_t
-i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
+i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t hena = 0;
+	int i;
 
 	if (!flags)
 		return hena;
 
-	if (flags & ETH_RSS_FRAG_IPV4)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-	if (flags & ETH_RSS_FRAG_IPV6)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
-	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & (1ULL << i))
+			hena |= adapter->pctypes_tbl[i];
 	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-	if (flags & ETH_RSS_L2_PAYLOAD)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
 	return hena;
 }
 
 /* Parse the hash enable flags */
 uint64_t
-i40e_parse_hena(uint64_t flags)
+i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t rss_hf = 0;
 
 	if (!flags)
 		return rss_hf;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-		rss_hf |= ETH_RSS_FRAG_IPV4;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-		rss_hf |= ETH_RSS_FRAG_IPV6;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
-		rss_hf |= ETH_RSS_L2_PAYLOAD;
+	int i;
 
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & adapter->pctypes_tbl[i])
+			rss_hf |= (1ULL << i);
+	}
 	return rss_hf;
 }
 
@@ -6799,7 +6732,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
@@ -6813,14 +6746,13 @@ i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0; /* Nothing to do */
@@ -6845,7 +6777,7 @@ i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena);
 
 	return 0;
 }
@@ -7620,7 +7552,7 @@ i40e_pf_config_rss(struct i40e_pf *pf)
 	}
 
 	rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) {
 		i40e_pf_disable_rss(pf);
 		return 0;
 	}
@@ -7841,9 +7773,9 @@ static int
 i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
-	uint32_t reg, mask = I40E_FLOW_TYPES;
-	uint16_t i;
-	enum i40e_filter_pctype pctype;
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	uint32_t reg;
+	uint16_t i, j;
 
 	memset(g_cfg, 0, sizeof(*g_cfg));
 	reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
@@ -7854,29 +7786,37 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 	PMD_DRV_LOG(DEBUG, "Hash function is %s",
 		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
-	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
-		if (!(mask & (1UL << i)))
-			continue;
-		mask &= ~(1UL << i);
-		/* Bit set indicats the coresponding flow type is supported */
-		g_cfg->valid_bit_mask[0] |= (1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
-		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
-			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next release
+	 */
+	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+		if (adapter->pctypes_tbl[i]) {
+			for (j = I40E_FILTER_PCTYPE_INVALID + 1;
+			     j < I40E_FILTER_PCTYPE_MAX; j++) {
+				if (adapter->pctypes_tbl[i] & (1ULL << j)) {
+					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
+					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
+						g_cfg->sym_hash_enable_mask[0] |=
+									(1UL << i);
+					}
+				}
+			}
+		}
 	}
 
 	return 0;
 }
 
 static int
-i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
+i40e_hash_global_config_check(const struct i40e_adapter *adapter,
+			      const struct rte_eth_hash_global_conf *g_cfg)
 {
 	uint32_t i;
-	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
+	uint32_t mask0, i40e_mask = adapter->flow_types_mask;
 
 	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
 		g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -7919,64 +7859,32 @@ static int
 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;
 	int ret;
-	uint16_t i;
+	uint16_t i, j;
 	uint32_t reg;
-	uint32_t mask0 = g_cfg->valid_bit_mask[0];
-	enum i40e_filter_pctype pctype;
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next release
+	 */
+	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_mask;
 
 	/* Check the input parameters */
-	ret = i40e_hash_global_config_check(g_cfg);
+	ret = i40e_hash_global_config_check(adapter, g_cfg);
 	if (ret < 0)
 		return ret;
 
-	for (i = 0; mask0 && i < UINT32_BIT; i++) {
-		if (!(mask0 & (1UL << i)))
-			continue;
-		mask0 &= ~(1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
-				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK),
-				  reg);
-			} else {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
-				  reg);
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+		if (mask0 & (1UL << i)) {
+			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+					I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+
+			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_GLQF_HSYM(j), reg);
 			}
-		} else {
-			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
 		}
 	}
 
@@ -8598,16 +8506,14 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 	uint64_t input_set, inset_reg;
 	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
 	int num, i;
+	uint16_t flow_type;
 
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(pctype))
-				continue;
-		}
+		flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 
 		input_set = i40e_get_default_input_set(pctype);
 
@@ -8670,7 +8576,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -8678,10 +8585,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	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(
-			conf->flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(conf->flow_type);
+			I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
@@ -8689,11 +8594,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
+
 	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
 		/* get inset value in register */
 		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
@@ -8747,24 +8648,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
 
-	pctype = i40e_flowtype_to_pctype(conf->flow_type);
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
 
 	/* get inset value in register */
 	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
@@ -9203,72 +9099,42 @@ i40e_hw_init(struct rte_eth_dev *dev)
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
 }
 
+/*
+ * For X722 it is possible to have multiple pctypes mapped to the same flowtype
+ * however this function will return only one highest pctype index,
+ * which is not quite correct. This is known problem of i40e driver
+ * and needs to be fixed later.
+ */
 enum i40e_filter_pctype
-i40e_flowtype_to_pctype(uint16_t flow_type)
-{
-	static const enum i40e_filter_pctype pctype_table[] = {
-		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
-		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
-		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
-	};
+i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type)
+{
+	int i;
+	uint64_t pctype_mask;
 
-	return pctype_table[flow_type];
+	if (flow_type < I40E_FLOW_TYPE_MAX) {
+		pctype_mask = adapter->pctypes_tbl[flow_type];
+		for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) {
+			if (pctype_mask & (1ULL << i))
+				return (enum i40e_filter_pctype)i;
+		}
+	}
+	return I40E_FILTER_PCTYPE_INVALID;
 }
 
 uint16_t
-i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
+i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+			enum i40e_filter_pctype pctype)
 {
-	static const uint16_t flowtype_table[] = {
-		[I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_OTHER,
-		[I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_OTHER,
-		[I40E_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_FLOW_L2_PAYLOAD,
-	};
+	uint16_t flowtype;
+	uint64_t pctype_mask = 1ULL << pctype;
+
+	for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX;
+	     flowtype++) {
+		if (adapter->pctypes_tbl[flowtype] & pctype_mask)
+			return flowtype;
+	}
 
-	return flowtype_table[pctype];
+	return RTE_ETH_FLOW_UNKNOWN;
 }
 
 /*
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index ad80f0f..66cc053 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -478,8 +478,9 @@ struct i40e_fdir_flex_mask {
 	} bitmask[I40E_FDIR_BITMASK_NUM_WORD];
 };
 
-#define I40E_FILTER_PCTYPE_MAX 64
-#define I40E_MAX_FDIR_FILTER_NUM (1024 * 8)
+#define I40E_FILTER_PCTYPE_INVALID 0
+#define I40E_FILTER_PCTYPE_MAX     64
+#define I40E_MAX_FDIR_FILTER_NUM   (1024 * 8)
 
 struct i40e_fdir_filter {
 	TAILQ_ENTRY(i40e_fdir_filter) rules;
@@ -852,7 +853,8 @@ struct i40e_vf {
 	uint64_t flags;
 };
 
-#define I40E_MAX_PKT_TYPE 256
+#define I40E_MAX_PKT_TYPE  256
+#define I40E_FLOW_TYPE_MAX 64
 
 /*
  * Structure to store private data for each PF/VF instance.
@@ -881,6 +883,10 @@ struct i40e_adapter {
 
 	/* ptype mapping table */
 	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
+	/* flow type to pctype mapping table */
+	uint64_t pctypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;
+	uint64_t flow_types_mask;
+	uint64_t pctypes_mask;
 };
 
 extern const struct rte_flow_ops i40e_flow_ops;
@@ -925,8 +931,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
 			   struct i40e_vsi_vlan_pvid_info *info);
 int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
 int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
-uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
-uint64_t i40e_parse_hena(uint64_t flags);
+uint64_t i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags);
+uint64_t i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags);
 enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
 enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
 int i40e_fdir_setup(struct i40e_pf *pf);
@@ -935,8 +941,10 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
 					int socket_id);
 int i40e_fdir_configure(struct rte_eth_dev *dev);
 void i40e_fdir_teardown(struct i40e_pf *pf);
-enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
-uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
+enum i40e_filter_pctype  i40e_flowtype_to_pctype(const struct i40e_adapter *adapter,
+						 uint16_t flow_type);
+uint16_t i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+				 enum i40e_filter_pctype pctype);
 int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 			  enum rte_filter_op filter_op,
 			  void *arg);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index a903deb..111ac39 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1443,6 +1443,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(eth_dev);
+	i40e_set_default_pctype_table(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
@@ -2178,7 +2179,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = vf->adapter->flow_types_mask;
 	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -2506,7 +2507,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(vf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2549,7 +2550,7 @@ i40evf_config_rss(struct i40e_vf *vf)
 	}
 
 	rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & vf->adapter->flow_types_mask) == 0) {
 		i40evf_disable_rss(vf);
 		PMD_DRV_LOG(DEBUG, "No hash flag is set");
 		return 0;
@@ -2574,14 +2575,13 @@ i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & vf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & vf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0;
@@ -2607,7 +2607,7 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(vf->adapter, hena);
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 84c0a1f..def2e4c 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -323,6 +323,7 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint8_t pctype;
 	int i, index;
+	uint16_t flow_type;
 
 	/*
 	 * Define the bytes stream extracted as flexible payload in
@@ -344,15 +345,10 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	/* initialize the masks */
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		}
+		flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 		pf->fdir.flex_mask[pctype].word_mask = 0;
 		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
 		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) {
@@ -449,7 +445,8 @@ i40e_check_fdir_flex_payload(const struct rte_eth_flex_payload_cfg *flex_cfg)
  * arguments are valid
  */
 static int
-i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
+i40e_check_fdir_flex_conf(const struct i40e_adapter *adapter,
+			  const struct rte_eth_fdir_flex_conf *conf)
 {
 	const struct rte_eth_flex_payload_cfg *flex_cfg;
 	const struct rte_eth_fdir_flex_mask *flex_mask;
@@ -457,6 +454,7 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 	uint8_t nb_bitmask;
 	uint16_t i, j;
 	int ret = 0;
+	enum i40e_filter_pctype pctype;
 
 	if (conf == NULL) {
 		PMD_DRV_LOG(INFO, "NULL pointer.");
@@ -487,7 +485,8 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 	}
 	for (i = 0; i < conf->nb_flexmasks; i++) {
 		flex_mask = &conf->flex_mask[i];
-		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
+		pctype = i40e_flowtype_to_pctype(adapter, flex_mask->flow_type);
+		if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 			PMD_DRV_LOG(WARNING, "invalid flow type.");
 			return -EINVAL;
 		}
@@ -650,7 +649,7 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	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);
+	ret = i40e_check_fdir_flex_conf(pf->adapter, conf);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, " invalid configuration arguments.");
 		return -EINVAL;
@@ -664,11 +663,11 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 			/* 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(
+				(int)i40e_flowtype_to_pctype(pf->adapter,
 				conf->flex_mask[i].flow_type)));
 		} else
-			pctype = i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type);
+			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]);
 	}
@@ -1100,7 +1099,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		return -ENOTSUP;
 	}
 
-	if (!I40E_VALID_FLOW(filter->input.flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, filter->input.flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -1141,12 +1141,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 	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(
-			filter->input.flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
-
+			hw, I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "fdir programming fails for PCTYPE(%u).",
@@ -1384,7 +1380,6 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 {
 	struct i40e_fdir_flex_mask *mask;
 	struct rte_eth_fdir_flex_mask *ptr = flex_mask;
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t flow_type;
 	uint8_t i, j;
 	uint16_t off_bytes, mask_tmp;
@@ -1393,14 +1388,11 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 	     i <= I40E_FILTER_PCTYPE_L2_PAYLOAD;
 	     i++) {
 		mask =  &pf->fdir.flex_mask[i];
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722((enum i40e_filter_pctype)i))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE((enum i40e_filter_pctype)i))
-				continue;
-		}
-		flow_type = i40e_pctype_to_flowtype((enum i40e_filter_pctype)i);
+		flow_type = i40e_pctype_to_flowtype(pf->adapter,
+						    (enum i40e_filter_pctype)i);
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
+
 		for (j = 0; j < I40E_FDIR_MAX_FLEXWORD_NUM; j++) {
 			if (mask->word_mask & I40E_FLEX_WORD_MASK(j)) {
 				ptr->mask[j * sizeof(uint16_t)] = UINT8_MAX;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b92719a..5d8afc6 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2776,8 +2776,9 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		}
 	}
 
-	pctype = i40e_flowtype_to_pctype(flow_type);
-	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID ||
+	    pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
 				   "Unsupported flow type");
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 3a7b68e..0c8ad00 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2943,6 +2943,63 @@ i40e_set_default_ptype_table(struct rte_eth_dev *dev)
 		ad->ptype_tbl[i] = i40e_get_default_pkt_type(i);
 }
 
+void __attribute__((cold))
+i40e_set_default_pctype_table(struct rte_eth_dev *dev)
+{
+	struct i40e_adapter *ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int i;
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_tbl[i] = 0ULL;
+	ad->flow_types_mask = 0ULL;
+	ad->pctypes_mask = 0ULL;
+
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV4] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV6] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
+				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+
+	if (hw->mac.type == I40E_MAC_X722) {
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+	}
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (ad->pctypes_tbl[i])
+			ad->flow_types_mask |= (1ULL << i);
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+	}
+}
+
 /* Stubs needed for linkage when CONFIG_RTE_I40E_INC_VECTOR is set to 'n' */
 int __attribute__((weak))
 i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..2a58ced 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -255,6 +255,7 @@ void i40e_set_tx_function_flag(struct rte_eth_dev *dev,
 			       struct i40e_tx_queue *txq);
 void i40e_set_tx_function(struct rte_eth_dev *dev);
 void i40e_set_default_ptype_table(struct rte_eth_dev *dev);
+void i40e_set_default_pctype_table(struct rte_eth_dev *dev);
 
 /* For each value it means, datasheet of hardware can tell more details
  *
-- 
2.5.5

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

* [dpdk-dev] [PATCH v4 3/5] net/i40e: add new functions to manipulate with pctype mapping table
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
  2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
  2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-10-02 15:09       ` Kirill Rybalchenko
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
                         ` (3 subsequent siblings)
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:09 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new functions which allow modify, return or reset to default
the contents of flow type to pctype dynamic mapping table.

v3:
Function rte_pmd_i40e_flow_type_mapping_get returns now full
mapping table.

v4:
Fix typo in rte_pmd_i40e_version.map file.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c           | 90 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 55 +++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  3 ++
 3 files changed, 148 insertions(+)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index c08e07a..7cf56db 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -2161,3 +2161,93 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 
 	return 0;
 }
+
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	i40e_set_default_pctype_table(dev);
+
+	return 0;
+}
+
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	uint16_t i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		mapping_items[i].flow_type = i;
+		mapping_items[i].pctype = ad->pctypes_tbl[i];
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	int i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	if (count > I40E_FLOW_TYPE_MAX)
+		return -EINVAL;
+
+	for (i = 0; i < count; i++)
+		if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX ||
+		    mapping_items[i].flow_type == RTE_ETH_FLOW_UNKNOWN ||
+		    (mapping_items[i].pctype & (1ULL << I40E_FILTER_PCTYPE_INVALID)))
+			return -EINVAL;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	if (exclusive) {
+		for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+			ad->pctypes_tbl[i] = 0ULL;
+		ad->flow_types_mask = 0ULL;
+	}
+
+	for (i = 0; i < count; i++) {
+		ad->pctypes_tbl[mapping_items[i].flow_type] = mapping_items[i].pctype;
+		if (mapping_items[i].pctype)
+			ad->flow_types_mask |= (1ULL << mapping_items[i].flow_type);
+		else
+			ad->flow_types_mask &= ~(1ULL << mapping_items[i].flow_type);
+	}
+
+	for (i = 0, ad->pctypes_mask = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+
+	return 0;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 155b7e8..004a8a5 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -657,4 +657,59 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,
 int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+#define RTE_PMD_I40E_PCTYPE_MAX		64
+#define RTE_PMD_I40E_FLOW_TYPE_MAX	64
+
+struct rte_pmd_i40e_flow_type_mapping {
+	uint16_t flow_type; /**< software defined flow type*/
+	uint64_t pctype;    /**< hardware defined pctype */
+};
+
+/**
+ * Update hardware defined pctype to software defined flow type
+ * mapping table.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the mapping items array.
+ * @param count
+ *    number of mapping items.
+ * @param exclusive
+ *    the flag indicate different pctype mapping update method.
+ *    -(0) only overwrite referred PCTYPE mapping,
+ *	keep other PCTYPEs mapping unchanged.
+ *    -(!0) overwrite referred PCTYPE mapping,
+ *	set other PCTYPEs maps to PCTYPE_INVALID.
+ */
+int rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive);
+
+/**
+ * Get software defined flow type to hardware defined pctype
+ * mapping items.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the array to store returned items.
+ *    array should be allocated by caller with minimum size of
+ *    RTE_PMD_I40E_FLOW_TYPE_MAX items
+ */
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items);
+
+/**
+ * Reset hardware defined pctype to software defined flow type
+ * mapping table to default.
+ *
+ * @param port
+ *    pointer to port identifier of the device
+ */
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index ef8882b..9292454 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -50,5 +50,8 @@ DPDK_17.11 {
 	global:
 
 	rte_pmd_i40e_add_vf_mac_addr;
+	rte_pmd_i40e_flow_type_mapping_update;
+	rte_pmd_i40e_flow_type_mapping_get;
+	rte_pmd_i40e_flow_type_mapping_reset;
 
 } DPDK_17.08;
-- 
2.5.5

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

* [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                         ` (2 preceding siblings ...)
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-10-02 15:09       ` Kirill Rybalchenko
  2017-10-03 21:42         ` Ferruh Yigit
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
                         ` (2 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:09 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new commands to manipulate with dynamic flow type to
pctype mapping table in i40e PMD.
Commands allow to print table, modify it and reset to default value.

v3:
changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'

v4:
Fix typos in cmdline.c and documentation.
Move variable declaration to the beginning of function.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 app/test-pmd/cmdline.c                      | 336 +++++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  46 ++++
 2 files changed, 372 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4f2d731..83baae3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -230,6 +230,10 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"clear vf stats (port_id) (vf_id)\n"
 			"    Reset a VF's statistics.\n\n"
+
+			"show port (port_id) pctype mapping\n"
+			"    Get flow ptype to pctype mapping on a port\n\n"
+
 		);
 	}
 
@@ -681,7 +685,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
 			" for ports.\n\n"
 
-			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
+			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|"
+			"geneve|nvgre|none|<flowtype_id>)\n"
 			"    Set the RSS mode.\n\n"
 
 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
@@ -716,6 +721,13 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"port config (port_id|all) l2-tunnel E-tag"
 			" (enable|disable)\n"
 			"    Enable/disable the E-tag support.\n\n"
+
+			"port config (port_id) pctype mapping reset\n"
+			"    Reset flow type to pctype mapping on a port\n\n"
+
+			"port config (port_id) pctype mapping update"
+			" (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n"
+			"    Update a flow type to pctype mapping item on a port\n\n"
 		);
 	}
 
@@ -878,8 +890,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
 			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
-			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
+			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-ipv4|dst-ipv4|"
+			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
 			"ipv6-next-header|udp-src-port|udp-dst-port|"
 			"tcp-src-port|tcp-dst-port|sctp-src-port|"
 			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
@@ -1720,6 +1732,8 @@ cmd_config_rss_parsed(void *parsed_result,
 		rss_conf.rss_hf = ETH_RSS_NVGRE;
 	else if (!strcmp(res->value, "none"))
 		rss_conf.rss_hf = 0;
+	else if (isdigit(res->value[0]) && atoi(res->value) > 0 && atoi(res->value) < 64)
+		rss_conf.rss_hf = 1ULL << atoi(res->value);
 	else {
 		printf("Unknown parameter\n");
 		return;
@@ -1743,14 +1757,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
 cmdline_parse_token_string_t cmd_config_rss_name =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
 cmdline_parse_token_string_t cmd_config_rss_value =
-	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
-		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
 
 cmdline_parse_inst_t cmd_config_rss = {
 	.f = cmd_config_rss_parsed,
 	.data = NULL,
 	.help_str = "port config all rss "
-		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
+		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|<flowtype_id>",
 	.tokens = {
 		(void *)&cmd_config_rss_port,
 		(void *)&cmd_config_rss_keyword,
@@ -8991,6 +9004,10 @@ str2flowtype(char *string)
 		if (!strcmp(flowtype_str[i].str, string))
 			return flowtype_str[i].type;
 	}
+
+	if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64)
+		return (uint16_t)atoi(string);
+
 	return RTE_ETH_FLOW_UNKNOWN;
 }
 
@@ -10467,9 +10484,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 		port_id, UINT8);
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
-		flow_type,
-		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
-		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+		flow_type, NULL);
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		inset_field,
@@ -10488,7 +10503,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
-	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload|<flowtype_id> "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -13810,6 +13825,303 @@ cmdline_parse_inst_t cmd_clear_vf_stats = {
 	},
 };
 
+/* port config pctype mapping reset */
+
+/* Common result structure for port config pctype mapping reset */
+struct cmd_pctype_mapping_reset_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t reset;
+};
+
+/* Common CLI fields for port config pctype mapping reset*/
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 reset, "reset");
+
+static void
+cmd_pctype_mapping_reset_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_reset_result *res = parsed_result;
+	int ret = -ENOTSUP;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_reset = {
+	.f = cmd_pctype_mapping_reset_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping reset",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_reset_port,
+		(void *)&cmd_pctype_mapping_reset_config,
+		(void *)&cmd_pctype_mapping_reset_port_id,
+		(void *)&cmd_pctype_mapping_reset_pctype,
+		(void *)&cmd_pctype_mapping_reset_mapping,
+		(void *)&cmd_pctype_mapping_reset_reset,
+		NULL,
+	},
+};
+
+/* show port pctype mapping */
+
+/* Common result structure for show port pctype mapping */
+struct cmd_pctype_mapping_get_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+};
+
+/* Common CLI fields for pctype mapping get */
+cmdline_parse_token_string_t cmd_pctype_mapping_get_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 mapping, "mapping");
+
+static void
+cmd_pctype_mapping_get_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_get_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping[RTE_PMD_I40E_FLOW_TYPE_MAX];
+	int i, j, first_pctype;
+#endif
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id, mapping);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		return;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		return;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	for (i = 0; i < RTE_PMD_I40E_FLOW_TYPE_MAX; i++) {
+		if (mapping[i].pctype != 0ULL) {
+			first_pctype = 1;
+
+			printf("pctype: ");
+			for (j = 0; j < RTE_PMD_I40E_PCTYPE_MAX; j++) {
+				if (mapping[i].pctype & (1ULL << j)) {
+					printf(first_pctype ? "%02d" : ",%02d", j);
+					first_pctype = 0;
+				}
+			}
+			printf("  ->  flowtype: %02d\n", mapping[i].flow_type);
+		}
+	}
+#endif
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_get = {
+	.f = cmd_pctype_mapping_get_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> pctype mapping",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_get_show,
+		(void *)&cmd_pctype_mapping_get_port,
+		(void *)&cmd_pctype_mapping_get_port_id,
+		(void *)&cmd_pctype_mapping_get_pctype,
+		(void *)&cmd_pctype_mapping_get_mapping,
+		NULL,
+	},
+};
+
+/* port config pctype mapping update */
+
+/* Common result structure for port config pctype mapping update */
+struct cmd_pctype_mapping_update_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t update;
+	cmdline_fixed_string_t pctype_list;
+	uint16_t flow_type;
+};
+
+/* Common CLI fields for pctype mapping update*/
+cmdline_parse_token_string_t cmd_pctype_mapping_update_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_update =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 update, "update");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype_list, NULL);
+cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 flow_type, UINT16);
+
+static void
+cmd_pctype_mapping_update_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_update_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping;
+	unsigned int i;
+#endif
+	unsigned int nb_item;
+	unsigned int pctype_list[RTE_PMD_I40E_PCTYPE_MAX];
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	nb_item = parse_item_list(res->pctype_list, "pctypes", RTE_PMD_I40E_PCTYPE_MAX,
+				  pctype_list, 1);
+
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	mapping.flow_type = res->flow_type;
+	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
+		mapping.pctype |= (1ULL << pctype_list[i]);
+	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
+						&mapping,
+						1,
+						0);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid pctype or flow type\n");
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_update = {
+	.f = cmd_pctype_mapping_update_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping update"
+	" <pctype_id_0,[pctype_id_1]*> <flowtype_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_update_port,
+		(void *)&cmd_pctype_mapping_update_config,
+		(void *)&cmd_pctype_mapping_update_port_id,
+		(void *)&cmd_pctype_mapping_update_pctype,
+		(void *)&cmd_pctype_mapping_update_mapping,
+		(void *)&cmd_pctype_mapping_update_update,
+		(void *)&cmd_pctype_mapping_update_pc_type,
+		(void *)&cmd_pctype_mapping_update_flow_type,
+		NULL,
+	},
+};
+
 /* ptype mapping get */
 
 /* Common result structure for ptype mapping get */
@@ -14391,6 +14703,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_replace,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_reset,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_update,
+
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_get,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_reset,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_update,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2ed62f5..278dfbc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -408,6 +408,14 @@ Reset VF statistics::
 
    testpmd> clear vf stats (port_id) (vf_id)
 
+show port pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> show port (port_id) pctype mapping
+
+
 Configuration Functions
 -----------------------
 
@@ -1310,6 +1318,27 @@ Reset ptype mapping table::
 
    testpmd> ptype mapping reset (port_id)
 
+pctype mapping
+~~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> pctype mapping get (port_id)
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*) (flow_type_d)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
+Reset pctype mapping table::
+
+   testpmd> pctype mapping reset (port_id)
+
 Port Functions
 --------------
 
@@ -1697,6 +1726,23 @@ Enable/disable the E-tag support::
 
    testpmd> port config (port_id|all) l2-tunnel E-tag (enable|disable)
 
+port config pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Reset pctype mapping table::
+
+   testpmd> port config (port_id) pctype mapping reset
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> port config (port_id) pctype mapping update (pctype_id_0[,pctype_id_1]*) (flow_type_id)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
 
 Link Bonding Functions
 ----------------------
-- 
2.5.5

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

* [dpdk-dev] [PATCH v4 5/5] ethdev: remove unnecessary check for new flow type
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                         ` (3 preceding siblings ...)
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-10-02 15:09       ` Kirill Rybalchenko
  2017-10-03 21:44       ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
  6 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-02 15:09 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary check for new flow type for rss hash
filter update.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1849a3b..f3bf3e5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2291,16 +2291,8 @@ int
 rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
 {
 	struct rte_eth_dev *dev;
-	uint16_t rss_hash_protos;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rss_hash_protos = rss_conf->rss_hf;
-	if ((rss_hash_protos != 0) &&
-	    ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {
-		RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
-				rss_hash_protos);
-		return -EINVAL;
-	}
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
 	return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
-- 
2.5.5

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

* Re: [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-10-03 21:42         ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-10-03 21:42 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 10/2/2017 4:09 PM, Kirill Rybalchenko wrote:
> Add new commands to manipulate with dynamic flow type to
> pctype mapping table in i40e PMD.
> Commands allow to print table, modify it and reset to default value.
> 
> v3:
> changed command syntax from 'pctype mapping...' to
> 'port config pctype mapping...' and 'show port pctype mapping'
> 
> v4:
> Fix typos in cmdline.c and documentation.
> Move variable declaration to the beginning of function.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>

<...>

>  
> @@ -1310,6 +1318,27 @@ Reset ptype mapping table::
>  
>     testpmd> ptype mapping reset (port_id)
>  
> +pctype mapping
> +~~~~~~~~~~~~~~
> +
> +List all items from the pctype mapping table::
> +
> +   testpmd> pctype mapping get (port_id)
> +
> +Update hardware defined pctype to software defined flow type mapping table::
> +
> +   testpmd> pctype mapping update (port_id) (pctype_id_0[,pctype_id_1]*) (flow_type_d)
> +
> +where:
> +
> +* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
> +
> +* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
> +
> +Reset pctype mapping table::
> +
> +   testpmd> pctype mapping reset (port_id)
> +

This part looks like outdated and coming from prev version of the patch?

>  Port Functions
>  --------------
>  

<...>

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

* Re: [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                         ` (4 preceding siblings ...)
  2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
@ 2017-10-03 21:44       ` Ferruh Yigit
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
  6 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-10-03 21:44 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 10/2/2017 4:08 PM, Kirill Rybalchenko wrote:
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to map new flow types to pctypes without changing
> API of the driver.
> 
> v2:
> Remove unnecessary check for new flow types.
> Re-arrange patchset to avoid compillation errors.
> Remove unnecessary usage of statically defined flow types and pctypes.
> 
> v3:
> Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
> Add new definition in enum i40e_filter_pctype for for invalid pctype.
> Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
> Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
> testpmd: changed command syntax from 'pctype mapping...' to
> 'port config pctype mapping...' and 'show port pctype mapping'
> Various small modifications in code style after reviewing.
> 
> v4:
> Change prototypes of some static functions.
> Move declaration of automatic variables to beginning of function.
> Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h
> Fix some typos in source filea and documentation.
> 
> Kirill Rybalchenko (5):
>   net/i40e: remove unnecessary bit operations
>   net/i40e: implement dynamic mapping of sw flow types to hw pctypes
>   net/i40e: add new functions to manipulate with pctype      mapping
>     table
>   app/testpmd: add new commands to manipulate with pctype mapping
>   ethdev: remove unnecessary check for new flow type

There is a comment related to testpmd documentation.

Also there are long line checkpatch warnings, can you please check them
and fix reasonable ones.

Other than above two overall looks good to me, so for next version you
can keep:

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

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

* [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
                         ` (5 preceding siblings ...)
  2017-10-03 21:44       ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
@ 2017-10-04 12:52       ` Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
                           ` (5 more replies)
  6 siblings, 6 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to map new flow types to pctypes without changing
API of the driver.

v2:
Remove unnecessary check for new flow types.
Re-arrange patchset to avoid compillation errors.
Remove unnecessary usage of statically defined flow types and pctypes.

v3:
Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
Add new definition in enum i40e_filter_pctype for for invalid pctype.
Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
testpmd: changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'
Various small modifications in code style after reviewing.

v4:
Change prototypes of some static functions.
Move declaration of automatic variables to beginning of function.
Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h
Fix some typos in source filea and documentation.

v5:
Fix code style warnings and documentation.
No functional changes.

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Kirill Rybalchenko (5):
  net/i40e: remove unnecessary bit operations
  net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  net/i40e: add new functions to manipulate with pctype mapping table
  app/testpmd: add new commands to manipulate with      pctype mapping
  ethdev: remove unnecessary check for new flow type

 app/test-pmd/cmdline.c                      | 338 ++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  25 ++
 drivers/net/i40e/i40e_ethdev.c              | 366 +++++++++-------------------
 drivers/net/i40e/i40e_ethdev.h              |  23 +-
 drivers/net/i40e/i40e_ethdev_vf.c           |  36 +--
 drivers/net/i40e/i40e_fdir.c                |  54 ++--
 drivers/net/i40e/i40e_flow.c                |   5 +-
 drivers/net/i40e/i40e_rxtx.c                |  58 +++++
 drivers/net/i40e/i40e_rxtx.h                |   1 +
 drivers/net/i40e/rte_pmd_i40e.c             |  94 +++++++
 drivers/net/i40e/rte_pmd_i40e.h             |  55 +++++
 drivers/net/i40e/rte_pmd_i40e_version.map   |   3 +
 lib/librte_ether/rte_ethdev.c               |   8 -
 13 files changed, 728 insertions(+), 338 deletions(-)

-- 
2.5.5

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

* [dpdk-dev] [PATCH v5 1/5] net/i40e: remove unnecessary bit operations
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
@ 2017-10-04 12:52         ` Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
                           ` (4 subsequent siblings)
  5 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary bit operations in I40E_PFQF_HENA
and I40E_VFQF_HENA registers.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 21 +++------------------
 drivers/net/i40e/i40e_ethdev_vf.c | 22 ++++------------------
 2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index acdf0de..41c4033 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6717,16 +6717,9 @@ static void
 i40e_pf_disable_rss(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -6798,7 +6791,6 @@ static int
 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t rss_hf;
 	uint64_t hena;
 	int ret;
 
@@ -6807,14 +6799,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b35011a..a903deb 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2498,7 +2498,7 @@ static int
 i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t rss_hf, hena;
+	uint64_t hena;
 	int ret;
 
 	ret = i40evf_set_rss_key(&vf->vsi, rss_conf->rss_key,
@@ -2506,14 +2506,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2525,16 +2518,9 @@ static void
 i40evf_disable_rss(struct i40e_vf *vf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), 0);
 	I40EVF_WRITE_FLUSH(hw);
 }
 
-- 
2.5.5

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

* [dpdk-dev] [PATCH v5 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
@ 2017-10-04 12:52         ` Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Implement dynamic mapping of software flow types to hardware pctypes.
This allows to add new flow types and pctypes for DDP without changing
API of the driver. The mapping table is located in private
data area for particular network adapter and can be individually
modified with set of appropriate functions.

v2:
Re-arrange patchset to avoid compillation errors.
Remove usage of statically defined flow types and pctypes.

v3:
Change prototypes of some static functions.
Fixe bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype
functions.
Various small modifications after reviewing.

v4:
Change prototypes of some static functions.
Move declaration of automatic variables to beginning of function.
Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h

v5:
Fix code style warnings.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    | 347 ++++++++++++--------------------------
 drivers/net/i40e/i40e_ethdev.h    |  23 ++-
 drivers/net/i40e/i40e_ethdev_vf.c |  16 +-
 drivers/net/i40e/i40e_fdir.c      |  54 +++---
 drivers/net/i40e/i40e_flow.c      |   5 +-
 drivers/net/i40e/i40e_rxtx.c      |  58 +++++++
 drivers/net/i40e/i40e_rxtx.h      |   1 +
 7 files changed, 218 insertions(+), 286 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 41c4033..0b151a0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1070,6 +1070,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(dev);
+	i40e_set_default_pctype_table(dev);
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	intr_handle = &pci_dev->intr_handle;
 
@@ -3020,7 +3021,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
 						sizeof(uint32_t);
 	dev_info->reta_size = pf->hash_lut_size;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask;
 
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
@@ -6611,104 +6612,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
 
 /* Configure hash enable flags for RSS */
 uint64_t
-i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
+i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t hena = 0;
+	int i;
 
 	if (!flags)
 		return hena;
 
-	if (flags & ETH_RSS_FRAG_IPV4)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-	if (flags & ETH_RSS_FRAG_IPV6)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
-	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & (1ULL << i))
+			hena |= adapter->pctypes_tbl[i];
 	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-	if (flags & ETH_RSS_L2_PAYLOAD)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
 	return hena;
 }
 
 /* Parse the hash enable flags */
 uint64_t
-i40e_parse_hena(uint64_t flags)
+i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags)
 {
 	uint64_t rss_hf = 0;
 
 	if (!flags)
 		return rss_hf;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-		rss_hf |= ETH_RSS_FRAG_IPV4;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-		rss_hf |= ETH_RSS_FRAG_IPV6;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
-		rss_hf |= ETH_RSS_L2_PAYLOAD;
+	int i;
 
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & adapter->pctypes_tbl[i])
+			rss_hf |= (1ULL << i);
+	}
 	return rss_hf;
 }
 
@@ -6799,7 +6732,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
@@ -6813,14 +6746,13 @@ i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0; /* Nothing to do */
@@ -6845,7 +6777,7 @@ i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena);
 
 	return 0;
 }
@@ -7620,7 +7552,7 @@ i40e_pf_config_rss(struct i40e_pf *pf)
 	}
 
 	rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) {
 		i40e_pf_disable_rss(pf);
 		return 0;
 	}
@@ -7841,9 +7773,9 @@ static int
 i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
-	uint32_t reg, mask = I40E_FLOW_TYPES;
-	uint16_t i;
-	enum i40e_filter_pctype pctype;
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	uint32_t reg;
+	uint16_t i, j;
 
 	memset(g_cfg, 0, sizeof(*g_cfg));
 	reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
@@ -7854,29 +7786,38 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 	PMD_DRV_LOG(DEBUG, "Hash function is %s",
 		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
-	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
-		if (!(mask & (1UL << i)))
-			continue;
-		mask &= ~(1UL << i);
-		/* Bit set indicats the coresponding flow type is supported */
-		g_cfg->valid_bit_mask[0] |= (1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next
+	 * release
+	 */
+	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+		if (!adapter->pctypes_tbl[i])
 			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
-		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
-			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
+		for (j = I40E_FILTER_PCTYPE_INVALID + 1;
+		     j < I40E_FILTER_PCTYPE_MAX; j++) {
+			if (adapter->pctypes_tbl[i] & (1ULL << j)) {
+				reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
+				if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
+					g_cfg->sym_hash_enable_mask[0] |=
+								(1UL << i);
+				}
+			}
+		}
 	}
 
 	return 0;
 }
 
 static int
-i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
+i40e_hash_global_config_check(const struct i40e_adapter *adapter,
+			      const struct rte_eth_hash_global_conf *g_cfg)
 {
 	uint32_t i;
-	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
+	uint32_t mask0, i40e_mask = adapter->flow_types_mask;
 
 	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
 		g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -7919,64 +7860,36 @@ static int
 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;
 	int ret;
-	uint16_t i;
+	uint16_t i, j;
 	uint32_t reg;
-	uint32_t mask0 = g_cfg->valid_bit_mask[0];
-	enum i40e_filter_pctype pctype;
+	/*
+	 * We work only with lowest 32 bits which is not correct, but to work
+	 * properly the valid_bit_mask size should be increased up to 64 bits
+	 * and this will brake ABI. This modification will be done in next
+	 * release
+	 */
+	uint32_t mask0 = g_cfg->valid_bit_mask[0] &
+					(uint32_t)adapter->flow_types_mask;
 
 	/* Check the input parameters */
-	ret = i40e_hash_global_config_check(g_cfg);
+	ret = i40e_hash_global_config_check(adapter, g_cfg);
 	if (ret < 0)
 		return ret;
 
-	for (i = 0; mask0 && i < UINT32_BIT; i++) {
-		if (!(mask0 & (1UL << i)))
-			continue;
-		mask0 &= ~(1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
-				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK),
-				  reg);
-			} else {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
-				  reg);
+	for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+		if (mask0 & (1UL << i)) {
+			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+					I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+
+			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_GLQF_HSYM(j),
+							  reg);
 			}
-		} else {
-			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
 		}
 	}
 
@@ -8598,16 +8511,14 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
 	uint64_t input_set, inset_reg;
 	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
 	int num, i;
+	uint16_t flow_type;
 
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(pctype))
-				continue;
-		}
+		flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 
 		input_set = i40e_get_default_input_set(pctype);
 
@@ -8670,7 +8581,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -8678,10 +8590,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	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(
-			conf->flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(conf->flow_type);
+			I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
@@ -8689,11 +8599,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
+
 	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
 		/* get inset value in register */
 		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
@@ -8747,24 +8653,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
+
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
 
-	pctype = i40e_flowtype_to_pctype(conf->flow_type);
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
 
 	/* get inset value in register */
 	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
@@ -9203,72 +9104,42 @@ i40e_hw_init(struct rte_eth_dev *dev)
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
 }
 
+/*
+ * For X722 it is possible to have multiple pctypes mapped to the same flowtype
+ * however this function will return only one highest pctype index,
+ * which is not quite correct. This is known problem of i40e driver
+ * and needs to be fixed later.
+ */
 enum i40e_filter_pctype
-i40e_flowtype_to_pctype(uint16_t flow_type)
-{
-	static const enum i40e_filter_pctype pctype_table[] = {
-		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
-		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
-		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
-	};
+i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type)
+{
+	int i;
+	uint64_t pctype_mask;
 
-	return pctype_table[flow_type];
+	if (flow_type < I40E_FLOW_TYPE_MAX) {
+		pctype_mask = adapter->pctypes_tbl[flow_type];
+		for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) {
+			if (pctype_mask & (1ULL << i))
+				return (enum i40e_filter_pctype)i;
+		}
+	}
+	return I40E_FILTER_PCTYPE_INVALID;
 }
 
 uint16_t
-i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
+i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+			enum i40e_filter_pctype pctype)
 {
-	static const uint16_t flowtype_table[] = {
-		[I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_OTHER,
-		[I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_OTHER,
-		[I40E_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_FLOW_L2_PAYLOAD,
-	};
+	uint16_t flowtype;
+	uint64_t pctype_mask = 1ULL << pctype;
+
+	for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX;
+	     flowtype++) {
+		if (adapter->pctypes_tbl[flowtype] & pctype_mask)
+			return flowtype;
+	}
 
-	return flowtype_table[pctype];
+	return RTE_ETH_FLOW_UNKNOWN;
 }
 
 /*
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index ad80f0f..5b84da2 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -478,8 +478,9 @@ struct i40e_fdir_flex_mask {
 	} bitmask[I40E_FDIR_BITMASK_NUM_WORD];
 };
 
-#define I40E_FILTER_PCTYPE_MAX 64
-#define I40E_MAX_FDIR_FILTER_NUM (1024 * 8)
+#define I40E_FILTER_PCTYPE_INVALID 0
+#define I40E_FILTER_PCTYPE_MAX     64
+#define I40E_MAX_FDIR_FILTER_NUM   (1024 * 8)
 
 struct i40e_fdir_filter {
 	TAILQ_ENTRY(i40e_fdir_filter) rules;
@@ -852,7 +853,8 @@ struct i40e_vf {
 	uint64_t flags;
 };
 
-#define I40E_MAX_PKT_TYPE 256
+#define I40E_MAX_PKT_TYPE  256
+#define I40E_FLOW_TYPE_MAX 64
 
 /*
  * Structure to store private data for each PF/VF instance.
@@ -881,6 +883,10 @@ struct i40e_adapter {
 
 	/* ptype mapping table */
 	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
+	/* flow type to pctype mapping table */
+	uint64_t pctypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;
+	uint64_t flow_types_mask;
+	uint64_t pctypes_mask;
 };
 
 extern const struct rte_flow_ops i40e_flow_ops;
@@ -925,8 +931,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
 			   struct i40e_vsi_vlan_pvid_info *info);
 int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
 int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
-uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
-uint64_t i40e_parse_hena(uint64_t flags);
+uint64_t i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags);
+uint64_t i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags);
 enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
 enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
 int i40e_fdir_setup(struct i40e_pf *pf);
@@ -935,8 +941,11 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
 					int socket_id);
 int i40e_fdir_configure(struct rte_eth_dev *dev);
 void i40e_fdir_teardown(struct i40e_pf *pf);
-enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
-uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
+enum i40e_filter_pctype
+	i40e_flowtype_to_pctype(const struct i40e_adapter *adapter,
+				uint16_t flow_type);
+uint16_t i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
+				 enum i40e_filter_pctype pctype);
 int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 			  enum rte_filter_op filter_op,
 			  void *arg);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index a903deb..111ac39 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1443,6 +1443,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(eth_dev);
+	i40e_set_default_pctype_table(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
@@ -2178,7 +2179,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = vf->adapter->flow_types_mask;
 	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -2506,7 +2507,7 @@ i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	hena = i40e_config_hena(rss_conf->rss_hf, hw->mac.type);
+	hena = i40e_config_hena(vf->adapter, rss_conf->rss_hf);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2549,7 +2550,7 @@ i40evf_config_rss(struct i40e_vf *vf)
 	}
 
 	rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & vf->adapter->flow_types_mask) == 0) {
 		i40evf_disable_rss(vf);
 		PMD_DRV_LOG(DEBUG, "No hash flag is set");
 		return 0;
@@ -2574,14 +2575,13 @@ i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & vf->adapter->flow_types_mask;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & vf->adapter->pctypes_mask)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0;
@@ -2607,7 +2607,7 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(vf->adapter, hena);
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 84c0a1f..268ada0 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -323,6 +323,7 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint8_t pctype;
 	int i, index;
+	uint16_t flow_type;
 
 	/*
 	 * Define the bytes stream extracted as flexible payload in
@@ -344,15 +345,10 @@ i40e_init_flx_pld(struct i40e_pf *pf)
 	/* initialize the masks */
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		}
+		flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 		pf->fdir.flex_mask[pctype].word_mask = 0;
 		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
 		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) {
@@ -449,7 +445,8 @@ i40e_check_fdir_flex_payload(const struct rte_eth_flex_payload_cfg *flex_cfg)
  * arguments are valid
  */
 static int
-i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
+i40e_check_fdir_flex_conf(const struct i40e_adapter *adapter,
+			  const struct rte_eth_fdir_flex_conf *conf)
 {
 	const struct rte_eth_flex_payload_cfg *flex_cfg;
 	const struct rte_eth_fdir_flex_mask *flex_mask;
@@ -457,6 +454,7 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 	uint8_t nb_bitmask;
 	uint16_t i, j;
 	int ret = 0;
+	enum i40e_filter_pctype pctype;
 
 	if (conf == NULL) {
 		PMD_DRV_LOG(INFO, "NULL pointer.");
@@ -487,7 +485,8 @@ i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 	}
 	for (i = 0; i < conf->nb_flexmasks; i++) {
 		flex_mask = &conf->flex_mask[i];
-		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
+		pctype = i40e_flowtype_to_pctype(adapter, flex_mask->flow_type);
+		if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 			PMD_DRV_LOG(WARNING, "invalid flow type.");
 			return -EINVAL;
 		}
@@ -650,7 +649,7 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	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);
+	ret = i40e_check_fdir_flex_conf(pf->adapter, conf);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, " invalid configuration arguments.");
 		return -EINVAL;
@@ -664,11 +663,11 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 			/* 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(
+				(int)i40e_flowtype_to_pctype(pf->adapter,
 				conf->flex_mask[i].flow_type)));
 		} else
-			pctype = i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type);
+			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]);
 	}
@@ -1100,7 +1099,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		return -ENOTSUP;
 	}
 
-	if (!I40E_VALID_FLOW(filter->input.flow_type)) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, filter->input.flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -1141,12 +1141,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 	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(
-			filter->input.flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
-
+			hw, I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "fdir programming fails for PCTYPE(%u).",
@@ -1384,7 +1380,6 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 {
 	struct i40e_fdir_flex_mask *mask;
 	struct rte_eth_fdir_flex_mask *ptr = flex_mask;
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t flow_type;
 	uint8_t i, j;
 	uint16_t off_bytes, mask_tmp;
@@ -1393,14 +1388,11 @@ i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 	     i <= I40E_FILTER_PCTYPE_L2_PAYLOAD;
 	     i++) {
 		mask =  &pf->fdir.flex_mask[i];
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722((enum i40e_filter_pctype)i))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE((enum i40e_filter_pctype)i))
-				continue;
-		}
-		flow_type = i40e_pctype_to_flowtype((enum i40e_filter_pctype)i);
+		flow_type = i40e_pctype_to_flowtype(pf->adapter,
+						    (enum i40e_filter_pctype)i);
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
+
 		for (j = 0; j < I40E_FDIR_MAX_FLEXWORD_NUM; j++) {
 			if (mask->word_mask & I40E_FLEX_WORD_MASK(j)) {
 				ptr->mask[j * sizeof(uint16_t)] = UINT8_MAX;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b92719a..5d8afc6 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2776,8 +2776,9 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		}
 	}
 
-	pctype = i40e_flowtype_to_pctype(flow_type);
-	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+	pctype = i40e_flowtype_to_pctype(pf->adapter, flow_type);
+	if (pctype == I40E_FILTER_PCTYPE_INVALID ||
+	    pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
 				   "Unsupported flow type");
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 3a7b68e..f69050f 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2943,6 +2943,64 @@ i40e_set_default_ptype_table(struct rte_eth_dev *dev)
 		ad->ptype_tbl[i] = i40e_get_default_pkt_type(i);
 }
 
+void __attribute__((cold))
+i40e_set_default_pctype_table(struct rte_eth_dev *dev)
+{
+	struct i40e_adapter *ad =
+			I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int i;
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_tbl[i] = 0ULL;
+	ad->flow_types_mask = 0ULL;
+	ad->pctypes_mask = 0ULL;
+
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV4] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_FRAG_IPV6] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+	ad->pctypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
+				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+
+	if (hw->mac.type == I40E_MAC_X722) {
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+		ad->pctypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] |=
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+	}
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (ad->pctypes_tbl[i])
+			ad->flow_types_mask |= (1ULL << i);
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+	}
+}
+
 /* Stubs needed for linkage when CONFIG_RTE_I40E_INC_VECTOR is set to 'n' */
 int __attribute__((weak))
 i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..2a58ced 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -255,6 +255,7 @@ void i40e_set_tx_function_flag(struct rte_eth_dev *dev,
 			       struct i40e_tx_queue *txq);
 void i40e_set_tx_function(struct rte_eth_dev *dev);
 void i40e_set_default_ptype_table(struct rte_eth_dev *dev);
+void i40e_set_default_pctype_table(struct rte_eth_dev *dev);
 
 /* For each value it means, datasheet of hardware can tell more details
  *
-- 
2.5.5

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

* [dpdk-dev] [PATCH v5 3/5] net/i40e: add new functions to manipulate with pctype mapping table
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
@ 2017-10-04 12:52         ` Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
                           ` (2 subsequent siblings)
  5 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new functions which allow modify, return or reset to default
the contents of flow type to pctype dynamic mapping table.

v3:
Function rte_pmd_i40e_flow_type_mapping_get returns now full
mapping table.

v4:
Fix typo in rte_pmd_i40e_version.map file.

v5:
Fix code style warnings.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c           | 94 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 55 ++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  3 +
 3 files changed, 152 insertions(+)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index c08e07a..3b4582d 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -2161,3 +2161,97 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 
 	return 0;
 }
+
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	i40e_set_default_pctype_table(dev);
+
+	return 0;
+}
+
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	uint16_t i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		mapping_items[i].flow_type = i;
+		mapping_items[i].pctype = ad->pctypes_tbl[i];
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_adapter *ad;
+	int i;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	if (count > I40E_FLOW_TYPE_MAX)
+		return -EINVAL;
+
+	for (i = 0; i < count; i++)
+		if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX ||
+		    mapping_items[i].flow_type == RTE_ETH_FLOW_UNKNOWN ||
+		    (mapping_items[i].pctype &
+		    (1ULL << I40E_FILTER_PCTYPE_INVALID)))
+			return -EINVAL;
+
+	ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	if (exclusive) {
+		for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+			ad->pctypes_tbl[i] = 0ULL;
+		ad->flow_types_mask = 0ULL;
+	}
+
+	for (i = 0; i < count; i++) {
+		ad->pctypes_tbl[mapping_items[i].flow_type] =
+						mapping_items[i].pctype;
+		if (mapping_items[i].pctype)
+			ad->flow_types_mask |=
+					(1ULL << mapping_items[i].flow_type);
+		else
+			ad->flow_types_mask &=
+					~(1ULL << mapping_items[i].flow_type);
+	}
+
+	for (i = 0, ad->pctypes_mask = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pctypes_mask |= ad->pctypes_tbl[i];
+
+	return 0;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 155b7e8..004a8a5 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -657,4 +657,59 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,
 int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+#define RTE_PMD_I40E_PCTYPE_MAX		64
+#define RTE_PMD_I40E_FLOW_TYPE_MAX	64
+
+struct rte_pmd_i40e_flow_type_mapping {
+	uint16_t flow_type; /**< software defined flow type*/
+	uint64_t pctype;    /**< hardware defined pctype */
+};
+
+/**
+ * Update hardware defined pctype to software defined flow type
+ * mapping table.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the mapping items array.
+ * @param count
+ *    number of mapping items.
+ * @param exclusive
+ *    the flag indicate different pctype mapping update method.
+ *    -(0) only overwrite referred PCTYPE mapping,
+ *	keep other PCTYPEs mapping unchanged.
+ *    -(!0) overwrite referred PCTYPE mapping,
+ *	set other PCTYPEs maps to PCTYPE_INVALID.
+ */
+int rte_pmd_i40e_flow_type_mapping_update(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items,
+			uint16_t count,
+			uint8_t exclusive);
+
+/**
+ * Get software defined flow type to hardware defined pctype
+ * mapping items.
+ *
+ * @param port
+ *    pointer to port identifier of the device.
+ * @param mapping_items
+ *    the base address of the array to store returned items.
+ *    array should be allocated by caller with minimum size of
+ *    RTE_PMD_I40E_FLOW_TYPE_MAX items
+ */
+int rte_pmd_i40e_flow_type_mapping_get(
+			uint8_t port,
+			struct rte_pmd_i40e_flow_type_mapping *mapping_items);
+
+/**
+ * Reset hardware defined pctype to software defined flow type
+ * mapping table to default.
+ *
+ * @param port
+ *    pointer to port identifier of the device
+ */
+int rte_pmd_i40e_flow_type_mapping_reset(uint8_t port);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index ef8882b..9292454 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -50,5 +50,8 @@ DPDK_17.11 {
 	global:
 
 	rte_pmd_i40e_add_vf_mac_addr;
+	rte_pmd_i40e_flow_type_mapping_update;
+	rte_pmd_i40e_flow_type_mapping_get;
+	rte_pmd_i40e_flow_type_mapping_reset;
 
 } DPDK_17.08;
-- 
2.5.5

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

* [dpdk-dev] [PATCH v5 4/5] app/testpmd: add new commands to manipulate with pctype mapping
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
                           ` (2 preceding siblings ...)
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
@ 2017-10-04 12:52         ` Kirill Rybalchenko
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
  2017-10-04 21:48         ` [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
  5 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Add new commands to manipulate with dynamic flow type to
pctype mapping table in i40e PMD.
Commands allow to print table, modify it and reset to default value.

v3:
changed command syntax from 'pctype mapping...' to
'port config pctype mapping...' and 'show port pctype mapping'

v4:
Fix typos in cmdline.c and documentation.
Move variable declaration to the beginning of function.

v5:
Fix code style warnings and documentation.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 app/test-pmd/cmdline.c                      | 338 +++++++++++++++++++++++++++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  25 ++
 2 files changed, 353 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4f2d731..dc9833b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -230,6 +230,10 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"clear vf stats (port_id) (vf_id)\n"
 			"    Reset a VF's statistics.\n\n"
+
+			"show port (port_id) pctype mapping\n"
+			"    Get flow ptype to pctype mapping on a port\n\n"
+
 		);
 	}
 
@@ -681,7 +685,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
 			" for ports.\n\n"
 
-			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
+			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|"
+			"geneve|nvgre|none|<flowtype_id>)\n"
 			"    Set the RSS mode.\n\n"
 
 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
@@ -716,6 +721,13 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"port config (port_id|all) l2-tunnel E-tag"
 			" (enable|disable)\n"
 			"    Enable/disable the E-tag support.\n\n"
+
+			"port config (port_id) pctype mapping reset\n"
+			"    Reset flow type to pctype mapping on a port\n\n"
+
+			"port config (port_id) pctype mapping update"
+			" (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n"
+			"    Update a flow type to pctype mapping item on a port\n\n"
 		);
 	}
 
@@ -878,8 +890,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
 			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
-			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
+			"l2_payload|<flowtype_id>) (ovlan|ivlan|src-ipv4|dst-ipv4|"
+			"src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
 			"ipv6-next-header|udp-src-port|udp-dst-port|"
 			"tcp-src-port|tcp-dst-port|sctp-src-port|"
 			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
@@ -1720,6 +1732,9 @@ cmd_config_rss_parsed(void *parsed_result,
 		rss_conf.rss_hf = ETH_RSS_NVGRE;
 	else if (!strcmp(res->value, "none"))
 		rss_conf.rss_hf = 0;
+	else if (isdigit(res->value[0]) && atoi(res->value) > 0 &&
+						atoi(res->value) < 64)
+		rss_conf.rss_hf = 1ULL << atoi(res->value);
 	else {
 		printf("Unknown parameter\n");
 		return;
@@ -1743,14 +1758,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
 cmdline_parse_token_string_t cmd_config_rss_name =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
 cmdline_parse_token_string_t cmd_config_rss_value =
-	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
-		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
 
 cmdline_parse_inst_t cmd_config_rss = {
 	.f = cmd_config_rss_parsed,
 	.data = NULL,
 	.help_str = "port config all rss "
-		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
+		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|<flowtype_id>",
 	.tokens = {
 		(void *)&cmd_config_rss_port,
 		(void *)&cmd_config_rss_keyword,
@@ -8991,6 +9005,10 @@ str2flowtype(char *string)
 		if (!strcmp(flowtype_str[i].str, string))
 			return flowtype_str[i].type;
 	}
+
+	if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64)
+		return (uint16_t)atoi(string);
+
 	return RTE_ETH_FLOW_UNKNOWN;
 }
 
@@ -10467,9 +10485,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 		port_id, UINT8);
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
-		flow_type,
-		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
-		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+		flow_type, NULL);
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		inset_field,
@@ -10488,7 +10504,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
-	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload|<flowtype_id> "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -13810,6 +13826,304 @@ cmdline_parse_inst_t cmd_clear_vf_stats = {
 	},
 };
 
+/* port config pctype mapping reset */
+
+/* Common result structure for port config pctype mapping reset */
+struct cmd_pctype_mapping_reset_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t reset;
+};
+
+/* Common CLI fields for port config pctype mapping reset*/
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_reset_result,
+		 reset, "reset");
+
+static void
+cmd_pctype_mapping_reset_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_reset_result *res = parsed_result;
+	int ret = -ENOTSUP;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_reset = {
+	.f = cmd_pctype_mapping_reset_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping reset",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_reset_port,
+		(void *)&cmd_pctype_mapping_reset_config,
+		(void *)&cmd_pctype_mapping_reset_port_id,
+		(void *)&cmd_pctype_mapping_reset_pctype,
+		(void *)&cmd_pctype_mapping_reset_mapping,
+		(void *)&cmd_pctype_mapping_reset_reset,
+		NULL,
+	},
+};
+
+/* show port pctype mapping */
+
+/* Common result structure for show port pctype mapping */
+struct cmd_pctype_mapping_get_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+};
+
+/* Common CLI fields for pctype mapping get */
+cmdline_parse_token_string_t cmd_pctype_mapping_get_show =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 show, "show");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port, "port");
+cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_get_result,
+		 mapping, "mapping");
+
+static void
+cmd_pctype_mapping_get_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_get_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping
+				mapping[RTE_PMD_I40E_FLOW_TYPE_MAX];
+	int i, j, first_pctype;
+#endif
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id, mapping);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		return;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		return;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	for (i = 0; i < RTE_PMD_I40E_FLOW_TYPE_MAX; i++) {
+		if (mapping[i].pctype != 0ULL) {
+			first_pctype = 1;
+
+			printf("pctype: ");
+			for (j = 0; j < RTE_PMD_I40E_PCTYPE_MAX; j++) {
+				if (mapping[i].pctype & (1ULL << j)) {
+					printf(first_pctype ?
+					       "%02d" : ",%02d", j);
+					first_pctype = 0;
+				}
+			}
+			printf("  ->  flowtype: %02d\n", mapping[i].flow_type);
+		}
+	}
+#endif
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_get = {
+	.f = cmd_pctype_mapping_get_parsed,
+	.data = NULL,
+	.help_str = "show port <port_id> pctype mapping",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_get_show,
+		(void *)&cmd_pctype_mapping_get_port,
+		(void *)&cmd_pctype_mapping_get_port_id,
+		(void *)&cmd_pctype_mapping_get_pctype,
+		(void *)&cmd_pctype_mapping_get_mapping,
+		NULL,
+	},
+};
+
+/* port config pctype mapping update */
+
+/* Common result structure for port config pctype mapping update */
+struct cmd_pctype_mapping_update_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t pctype;
+	cmdline_fixed_string_t mapping;
+	cmdline_fixed_string_t update;
+	cmdline_fixed_string_t pctype_list;
+	uint16_t flow_type;
+};
+
+/* Common CLI fields for pctype mapping update*/
+cmdline_parse_token_string_t cmd_pctype_mapping_update_port =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port, "port");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_config =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 config, "config");
+cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype, "pctype");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 mapping, "mapping");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_update =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 update, "update");
+cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 pctype_list, NULL);
+cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_pctype_mapping_update_result,
+		 flow_type, UINT16);
+
+static void
+cmd_pctype_mapping_update_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_pctype_mapping_update_result *res = parsed_result;
+	int ret = -ENOTSUP;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_flow_type_mapping mapping;
+	unsigned int i;
+#endif
+	unsigned int nb_item;
+	unsigned int pctype_list[RTE_PMD_I40E_PCTYPE_MAX];
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	nb_item = parse_item_list(res->pctype_list, "pctypes",
+				  RTE_PMD_I40E_PCTYPE_MAX, pctype_list, 1);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	mapping.flow_type = res->flow_type;
+	for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++)
+		mapping.pctype |= (1ULL << pctype_list[i]);
+	ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id,
+						&mapping,
+						1,
+						0);
+#endif
+
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid pctype or flow type\n");
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	case -ENOTSUP:
+		printf("function not implemented\n");
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_pctype_mapping_update = {
+	.f = cmd_pctype_mapping_update_parsed,
+	.data = NULL,
+	.help_str = "port config <port_id> pctype mapping update"
+	" <pctype_id_0,[pctype_id_1]*> <flowtype_id>",
+	.tokens = {
+		(void *)&cmd_pctype_mapping_update_port,
+		(void *)&cmd_pctype_mapping_update_config,
+		(void *)&cmd_pctype_mapping_update_port_id,
+		(void *)&cmd_pctype_mapping_update_pctype,
+		(void *)&cmd_pctype_mapping_update_mapping,
+		(void *)&cmd_pctype_mapping_update_update,
+		(void *)&cmd_pctype_mapping_update_pc_type,
+		(void *)&cmd_pctype_mapping_update_flow_type,
+		NULL,
+	},
+};
+
 /* ptype mapping get */
 
 /* Common result structure for ptype mapping get */
@@ -14391,6 +14705,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_replace,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_reset,
 	(cmdline_parse_inst_t *)&cmd_ptype_mapping_update,
+
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_get,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_reset,
+	(cmdline_parse_inst_t *)&cmd_pctype_mapping_update,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2ed62f5..aeef3e1 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -408,6 +408,14 @@ Reset VF statistics::
 
    testpmd> clear vf stats (port_id) (vf_id)
 
+show port pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+List all items from the pctype mapping table::
+
+   testpmd> show port (port_id) pctype mapping
+
+
 Configuration Functions
 -----------------------
 
@@ -1697,6 +1705,23 @@ Enable/disable the E-tag support::
 
    testpmd> port config (port_id|all) l2-tunnel E-tag (enable|disable)
 
+port config pctype mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Reset pctype mapping table::
+
+   testpmd> port config (port_id) pctype mapping reset
+
+Update hardware defined pctype to software defined flow type mapping table::
+
+   testpmd> port config (port_id) pctype mapping update (pctype_id_0[,pctype_id_1]*) (flow_type_id)
+
+where:
+
+* ``pctype_id_x``: hardware pctype id as index of bit in bitmask value of the pctype mapping table.
+
+* ``flow_type_id``: software flow type id as the index of the pctype mapping table.
+
 
 Link Bonding Functions
 ----------------------
-- 
2.5.5

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

* [dpdk-dev] [PATCH v5 5/5] ethdev: remove unnecessary check for new flow type
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
                           ` (3 preceding siblings ...)
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
@ 2017-10-04 12:52         ` Kirill Rybalchenko
  2017-10-04 21:48         ` [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
  5 siblings, 0 replies; 40+ messages in thread
From: Kirill Rybalchenko @ 2017-10-04 12:52 UTC (permalink / raw)
  To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, beilei.xing, jingjing.wu

Remove unnecessary check for new flow type for rss hash
filter update.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1849a3b..f3bf3e5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2291,16 +2291,8 @@ int
 rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
 {
 	struct rte_eth_dev *dev;
-	uint16_t rss_hash_protos;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rss_hash_protos = rss_conf->rss_hf;
-	if ((rss_hash_protos != 0) &&
-	    ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {
-		RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
-				rss_hash_protos);
-		return -EINVAL;
-	}
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
 	return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
-- 
2.5.5

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

* Re: [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
                           ` (4 preceding siblings ...)
  2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
@ 2017-10-04 21:48         ` Ferruh Yigit
  2017-10-05  1:28           ` Ferruh Yigit
  5 siblings, 1 reply; 40+ messages in thread
From: Ferruh Yigit @ 2017-10-04 21:48 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 10/4/2017 1:52 PM, Kirill Rybalchenko wrote:
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to map new flow types to pctypes without changing
> API of the driver.
> 
> v2:
> Remove unnecessary check for new flow types.
> Re-arrange patchset to avoid compillation errors.
> Remove unnecessary usage of statically defined flow types and pctypes.
> 
> v3:
> Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
> Add new definition in enum i40e_filter_pctype for for invalid pctype.
> Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
> Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
> testpmd: changed command syntax from 'pctype mapping...' to
> 'port config pctype mapping...' and 'show port pctype mapping'
> Various small modifications in code style after reviewing.
> 
> v4:
> Change prototypes of some static functions.
> Move declaration of automatic variables to beginning of function.
> Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h
> Fix some typos in source filea and documentation.
> 
> v5:
> Fix code style warnings and documentation.
> No functional changes.
> 

> 
> Kirill Rybalchenko (5):
>   net/i40e: remove unnecessary bit operations
>   net/i40e: implement dynamic mapping of sw flow types to hw pctypes
>   net/i40e: add new functions to manipulate with pctype mapping table
>   app/testpmd: add new commands to manipulate with      pctype mapping
>   ethdev: remove unnecessary check for new flow type

Series Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

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

* Re: [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes
  2017-10-04 21:48         ` [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
@ 2017-10-05  1:28           ` Ferruh Yigit
  0 siblings, 0 replies; 40+ messages in thread
From: Ferruh Yigit @ 2017-10-05  1:28 UTC (permalink / raw)
  To: Kirill Rybalchenko, dev; +Cc: andrey.chilikin, beilei.xing, jingjing.wu

On 10/4/2017 10:48 PM, Ferruh Yigit wrote:
> On 10/4/2017 1:52 PM, Kirill Rybalchenko wrote:
>> Implement dynamic mapping of software flow types to hardware pctypes.
>> This allows to map new flow types to pctypes without changing
>> API of the driver.
>>
>> v2:
>> Remove unnecessary check for new flow types.
>> Re-arrange patchset to avoid compillation errors.
>> Remove unnecessary usage of statically defined flow types and pctypes.
>>
>> v3:
>> Remove unnecessary bit operations in I40E_PFQF_HENA and I40E_VFQF_HENA registers.
>> Add new definition in enum i40e_filter_pctype for for invalid pctype.
>> Fixed bugs in i40e_pctype_to_flowtype and i40e_flowtype_to_pctype functions.
>> Function rte_pmd_i40e_flow_type_mapping_get returns now full mapping table.
>> testpmd: changed command syntax from 'pctype mapping...' to
>> 'port config pctype mapping...' and 'show port pctype mapping'
>> Various small modifications in code style after reviewing.
>>
>> v4:
>> Change prototypes of some static functions.
>> Move declaration of automatic variables to beginning of function.
>> Move declaration of I40E_FILTER_PCTYPE_INVALID to i40e_ethdev.h
>> Fix some typos in source filea and documentation.
>>
>> v5:
>> Fix code style warnings and documentation.
>> No functional changes.
>>
> 
>>
>> Kirill Rybalchenko (5):
>>   net/i40e: remove unnecessary bit operations
>>   net/i40e: implement dynamic mapping of sw flow types to hw pctypes
>>   net/i40e: add new functions to manipulate with pctype mapping table
>>   app/testpmd: add new commands to manipulate with      pctype mapping
>>   ethdev: remove unnecessary check for new flow type
> 
> Series Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Series applied to dpdk-next-net/master, thanks.

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

end of thread, other threads:[~2017-10-05  1:28 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1503569908-104074-1-git-send-email-kirill.rybalchenko@intel.com>
2017-09-01 15:02 ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
2017-09-04 16:49     ` Ananyev, Konstantin
2017-09-08 16:58     ` Ferruh Yigit
2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 2/4] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
2017-09-04 17:24     ` Iremonger, Bernard
2017-09-08 17:01     ` Ferruh Yigit
2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 3/4] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
2017-09-04 17:29     ` Iremonger, Bernard
2017-09-08 17:02     ` Ferruh Yigit
2017-09-01 15:02   ` [dpdk-dev] [PATCH v2 4/4] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
2017-09-08 17:01     ` Ferruh Yigit
2017-09-04 17:16   ` [dpdk-dev] [PATCH v2 0/4] net/i40e: implement dynamic mapping of flow types to pctypes Iremonger, Bernard
2017-09-20 14:32   ` [dpdk-dev] [PATCH v3 0/6] " Kirill Rybalchenko
2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 1/6] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
2017-09-20 14:32     ` [dpdk-dev] [PATCH v3 2/6] net/i40e: add definition for invalid pctype Kirill Rybalchenko
2017-09-22  7:29       ` Xing, Beilei
2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 3/6] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
2017-09-25  9:44       ` Xing, Beilei
2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 4/6] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
2017-09-22  7:27       ` Xing, Beilei
2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 5/6] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
2017-09-25 11:54       ` Xing, Beilei
2017-09-20 14:33     ` [dpdk-dev] [PATCH v3 6/6] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
2017-10-02 15:08     ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Kirill Rybalchenko
2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
2017-10-02 15:08       ` [dpdk-dev] [PATCH v4 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
2017-10-03 21:42         ` Ferruh Yigit
2017-10-02 15:09       ` [dpdk-dev] [PATCH v4 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
2017-10-03 21:44       ` [dpdk-dev] [PATCH v4 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
2017-10-04 12:52       ` [dpdk-dev] [PATCH v5 " Kirill Rybalchenko
2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 1/5] net/i40e: remove unnecessary bit operations Kirill Rybalchenko
2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 2/5] net/i40e: implement dynamic mapping of sw flow types to hw pctypes Kirill Rybalchenko
2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 3/5] net/i40e: add new functions to manipulate with pctype mapping table Kirill Rybalchenko
2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 4/5] app/testpmd: add new commands to manipulate with pctype mapping Kirill Rybalchenko
2017-10-04 12:52         ` [dpdk-dev] [PATCH v5 5/5] ethdev: remove unnecessary check for new flow type Kirill Rybalchenko
2017-10-04 21:48         ` [dpdk-dev] [PATCH v5 0/5] net/i40e: implement dynamic mapping of flow types to pctypes Ferruh Yigit
2017-10-05  1:28           ` Ferruh Yigit

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).