DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/5] Support configuring hash functions
@ 2014-07-24  6:42 Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type Helin Zhang
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

These pathches mainly support configuring hash functions.
In detail, it can select Toeplitz and simple XOR hash
functions. It can configure symmetric hash function. Also
'ethdev' level interfaces are implemented in i40e, which
provides commands for application invoking, and to check
if specific capability (command) is supported on a port.

Helin Zhang (5):
  ethdev: Rename macros of packet classification type
  ethdev: add new ops of 'check_command_supported' and    
    'rx_classification_filter_ctl'
  i40e: support selecting hash functions
  i40e: support configuring symmetric hash function
  app/testpmd: new commands for configuring hash functions

 app/test-pmd/cmdline.c              | 455 ++++++++++++++++++++++++++++++++++++
 config/common_bsdapp                |   1 +
 config/common_linuxapp              |   1 +
 lib/librte_ether/Makefile           |   1 +
 lib/librte_ether/rte_eth_features.h |  65 ++++++
 lib/librte_ether/rte_ethdev.c       |  31 +++
 lib/librte_ether/rte_ethdev.h       | 126 +++++++---
 lib/librte_pmd_i40e/Makefile        |   6 +
 lib/librte_pmd_i40e/i40e_ethdev.c   | 439 ++++++++++++++++++++++++++++++++++
 lib/librte_pmd_i40e/rte_i40e.h      |  95 ++++++++
 10 files changed, 1183 insertions(+), 37 deletions(-)
 create mode 100644 lib/librte_ether/rte_eth_features.h
 create mode 100644 lib/librte_pmd_i40e/rte_i40e.h

-- 
1.8.1.4

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

* [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type
  2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
@ 2014-07-24  6:42 ` Helin Zhang
  2014-07-24  7:48   ` Thomas Monjalon
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl' Helin Zhang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

For better understanding, 'PCTYPE' was added to the name of i40e
RSS shift macros.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 lib/librte_ether/rte_ethdev.h | 74 +++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 50df654..a262463 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -346,46 +346,46 @@ struct rte_eth_rss_conf {
 #define ETH_RSS_IPV6_UDP_SHIFT                7
 #define ETH_RSS_IPV6_UDP_EX_SHIFT             8
 /* for 40G only */
-#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
-#define ETH_RSS_NONF_IPV4_TCP_SHIFT           33
-#define ETH_RSS_NONF_IPV4_SCTP_SHIFT          34
-#define ETH_RSS_NONF_IPV4_OTHER_SHIFT         35
-#define ETH_RSS_FRAG_IPV4_SHIFT               36
-#define ETH_RSS_NONF_IPV6_UDP_SHIFT           41
-#define ETH_RSS_NONF_IPV6_TCP_SHIFT           43
-#define ETH_RSS_NONF_IPV6_SCTP_SHIFT          44
-#define ETH_RSS_NONF_IPV6_OTHER_SHIFT         45
-#define ETH_RSS_FRAG_IPV6_SHIFT               46
-#define ETH_RSS_FCOE_OX_SHIFT                 48
-#define ETH_RSS_FCOE_RX_SHIFT                 49
-#define ETH_RSS_FCOE_OTHER_SHIFT              50
-#define ETH_RSS_L2_PAYLOAD_SHIFT              63
+#define ETH_PCTYPE_NONF_IPV4_UDP              31
+#define ETH_PCTYPE_NONF_IPV4_TCP              33
+#define ETH_PCTYPE_NONF_IPV4_SCTP             34
+#define ETH_PCTYPE_NONF_IPV4_OTHER            35
+#define ETH_PCTYPE_FRAG_IPV4                  36
+#define ETH_PCTYPE_NONF_IPV6_UDP              41
+#define ETH_PCTYPE_NONF_IPV6_TCP              43
+#define ETH_PCTYPE_NONF_IPV6_SCTP             44
+#define ETH_PCTYPE_NONF_IPV6_OTHER            45
+#define ETH_PCTYPE_FRAG_IPV6                  46
+#define ETH_PCTYPE_FCOE_OX                    48 /* not used */
+#define ETH_PCTYPE_FCOE_RX                    49 /* not used */
+#define ETH_PCTYPE_FCOE_OTHER                 50 /* not used */
+#define ETH_PCTYPE_L2_PAYLOAD                 63
 
 /* for 1G & 10G */
-#define ETH_RSS_IPV4                    ((uint16_t)1 << ETH_RSS_IPV4_SHIFT)
-#define ETH_RSS_IPV4_TCP                ((uint16_t)1 << ETH_RSS_IPV4_TCP_SHIFT)
-#define ETH_RSS_IPV6                    ((uint16_t)1 << ETH_RSS_IPV6_SHIFT)
-#define ETH_RSS_IPV6_EX                 ((uint16_t)1 << ETH_RSS_IPV6_EX_SHIFT)
-#define ETH_RSS_IPV6_TCP                ((uint16_t)1 << ETH_RSS_IPV6_TCP_SHIFT)
-#define ETH_RSS_IPV6_TCP_EX             ((uint16_t)1 << ETH_RSS_IPV6_TCP_EX_SHIFT)
-#define ETH_RSS_IPV4_UDP                ((uint16_t)1 << ETH_RSS_IPV4_UDP_SHIFT)
-#define ETH_RSS_IPV6_UDP                ((uint16_t)1 << ETH_RSS_IPV6_UDP_SHIFT)
-#define ETH_RSS_IPV6_UDP_EX             ((uint16_t)1 << ETH_RSS_IPV6_UDP_EX_SHIFT)
+#define ETH_RSS_IPV4                    (1 << ETH_RSS_IPV4_SHIFT)
+#define ETH_RSS_IPV4_TCP                (1 << ETH_RSS_IPV4_TCP_SHIFT)
+#define ETH_RSS_IPV6                    (1 << ETH_RSS_IPV6_SHIFT)
+#define ETH_RSS_IPV6_EX                 (1 << ETH_RSS_IPV6_EX_SHIFT)
+#define ETH_RSS_IPV6_TCP                (1 << ETH_RSS_IPV6_TCP_SHIFT)
+#define ETH_RSS_IPV6_TCP_EX             (1 << ETH_RSS_IPV6_TCP_EX_SHIFT)
+#define ETH_RSS_IPV4_UDP                (1 << ETH_RSS_IPV4_UDP_SHIFT)
+#define ETH_RSS_IPV6_UDP                (1 << ETH_RSS_IPV6_UDP_SHIFT)
+#define ETH_RSS_IPV6_UDP_EX             (1 << ETH_RSS_IPV6_UDP_EX_SHIFT)
 /* for 40G only */
-#define ETH_RSS_NONF_IPV4_UDP           ((uint64_t)1 << ETH_RSS_NONF_IPV4_UDP_SHIFT)
-#define ETH_RSS_NONF_IPV4_TCP           ((uint64_t)1 << ETH_RSS_NONF_IPV4_TCP_SHIFT)
-#define ETH_RSS_NONF_IPV4_SCTP          ((uint64_t)1 << ETH_RSS_NONF_IPV4_SCTP_SHIFT)
-#define ETH_RSS_NONF_IPV4_OTHER         ((uint64_t)1 << ETH_RSS_NONF_IPV4_OTHER_SHIFT)
-#define ETH_RSS_FRAG_IPV4               ((uint64_t)1 << ETH_RSS_FRAG_IPV4_SHIFT)
-#define ETH_RSS_NONF_IPV6_UDP           ((uint64_t)1 << ETH_RSS_NONF_IPV6_UDP_SHIFT)
-#define ETH_RSS_NONF_IPV6_TCP           ((uint64_t)1 << ETH_RSS_NONF_IPV6_TCP_SHIFT)
-#define ETH_RSS_NONF_IPV6_SCTP          ((uint64_t)1 << ETH_RSS_NONF_IPV6_SCTP_SHIFT)
-#define ETH_RSS_NONF_IPV6_OTHER         ((uint64_t)1 << ETH_RSS_NONF_IPV6_OTHER_SHIFT)
-#define ETH_RSS_FRAG_IPV6               ((uint64_t)1 << ETH_RSS_FRAG_IPV6_SHIFT)
-#define ETH_RSS_FCOE_OX                 ((uint64_t)1 << ETH_RSS_FCOE_OX_SHIFT) /* not used */
-#define ETH_RSS_FCOE_RX                 ((uint64_t)1 << ETH_RSS_FCOE_RX_SHIFT) /* not used */
-#define ETH_RSS_FCOE_OTHER              ((uint64_t)1 << ETH_RSS_FCOE_OTHER_SHIFT) /* not used */
-#define ETH_RSS_L2_PAYLOAD              ((uint64_t)1 << ETH_RSS_L2_PAYLOAD_SHIFT)
+#define ETH_RSS_NONF_IPV4_UDP           (1ULL << ETH_PCTYPE_NONF_IPV4_UDP)
+#define ETH_RSS_NONF_IPV4_TCP           (1ULL << ETH_PCTYPE_NONF_IPV4_TCP)
+#define ETH_RSS_NONF_IPV4_SCTP          (1ULL << ETH_PCTYPE_NONF_IPV4_SCTP)
+#define ETH_RSS_NONF_IPV4_OTHER         (1ULL << ETH_PCTYPE_NONF_IPV4_OTHER)
+#define ETH_RSS_FRAG_IPV4               (1ULL << ETH_PCTYPE_FRAG_IPV4)
+#define ETH_RSS_NONF_IPV6_UDP           (1ULL << ETH_PCTYPE_NONF_IPV6_UDP)
+#define ETH_RSS_NONF_IPV6_TCP           (1ULL << ETH_PCTYPE_NONF_IPV6_TCP)
+#define ETH_RSS_NONF_IPV6_SCTP          (1ULL << ETH_PCTYPE_NONF_IPV6_SCTP)
+#define ETH_RSS_NONF_IPV6_OTHER         (1ULL << ETH_PCTYPE_NONF_IPV6_OTHER)
+#define ETH_RSS_FRAG_IPV6               (1ULL << ETH_PCTYPE_FRAG_IPV6)
+#define ETH_RSS_FCOE_OX                 (1ULL << ETH_PCTYPE_FCOE_OX)
+#define ETH_RSS_FCOE_RX                 (1ULL << ETH_PCTYPE_FCOE_RX)
+#define ETH_RSS_FCOE_OTHER              (1ULL << ETH_PCTYPE_FCOE_OTHER)
+#define ETH_RSS_L2_PAYLOAD              (1ULL << ETH_PCTYPE_L2_PAYLOAD)
 
 #define ETH_RSS_IP ( \
 		ETH_RSS_IPV4 | \
-- 
1.8.1.4

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

* [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl'
  2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type Helin Zhang
@ 2014-07-24  6:42 ` Helin Zhang
  2014-07-24  7:56   ` Thomas Monjalon
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions Helin Zhang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

Two ops of 'check_command_supported' and 'rx_classification_filter_ctl'
are added.
* 'check_command_supported' is for capability discovery. In anothoer
  word, it is to check if specific feature/command is supported by
  the specific port.
* 'rx_classification_filter_ctl' is for receive classifcation filter
  configuring. e.g. hash function configuration, flow director
  configuration. It is a common API where a lot of commands can
  be implemented for different sub features.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 31 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 52 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fd1010a..7afffb4 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3002,3 +3002,34 @@ rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
 	return (*dev->dev_ops->get_flex_filter)(dev, index, filter,
 						rx_queue);
 }
+
+int
+rte_eth_dev_check_command_supported(uint8_t port_id, uint32_t cmd)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return -ENODEV;
+	}
+	dev = &rte_eth_devices[port_id];
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->check_command_supported, -ENOTSUP);
+	return (*dev->dev_ops->check_command_supported)(dev, cmd);
+}
+
+int
+rte_eth_dev_rx_classification_filter_ctl(uint8_t port_id,
+					 uint32_t cmd,
+					 void *args)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return -ENODEV;
+	}
+	dev = &rte_eth_devices[port_id];
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_classification_filter_ctl,
+								-ENOTSUP);
+	return (*dev->dev_ops->rx_classification_filter_ctl)(dev, cmd, args);
+}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index a262463..482e64d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1240,6 +1240,15 @@ typedef int (*eth_mirror_rule_reset_t)(struct rte_eth_dev *dev,
 				  uint8_t rule_id);
 /**< @internal Remove a traffic mirroring rule on an Ethernet device */
 
+typedef int (*eth_check_command_supported_t)(struct rte_eth_dev *dev,
+					     uint32_t cmd);
+/**< @internal check if the command is supported by the Ethernet device */
+
+typedef int (*eth_rx_classification_filter_ctl_t)(struct rte_eth_dev *dev,
+						  uint32_t cmd,
+						  void *arg);
+/**< @internal receive classification filter control operations */
+
 #ifdef RTE_NIC_BYPASS
 
 enum {
@@ -1467,6 +1476,10 @@ struct eth_dev_ops {
 	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
 	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
 	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
+	eth_check_command_supported_t  check_command_supported;
+	/**< check if a command is supported. */
+	eth_rx_classification_filter_ctl_t rx_classification_filter_ctl;
+	/**< common control function of hw hash */
 };
 
 /**
@@ -3557,6 +3570,45 @@ int rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index);
 int rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
 			struct rte_flex_filter *filter, uint16_t *rx_queue);
 
+/**
+ * Check if the command is supported by an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param cmd
+ *   The command.
+ *
+ * @return
+ *   - (> 0) The command is supported.
+ *   - (0) The command is not supported.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if <port_id> is invalid.
+ */
+int rte_eth_dev_check_command_supported(uint8_t port_id, uint32_t cmd);
+
+/**
+ * Control the receive classification filter, including hash function
+ * selection. The commands are NIC specific in its exported public
+ * header file. Different types of NIC may have different commands.
+ * For example, the supported commands for i40e can be found in rte_i40e.h.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param cmd
+ *   The commands.
+ * @param args
+ *   A pointer to arguments defined specifically for the command.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if <port_id> is invalid.
+ *   - others depends on the specific command implementation.
+ */
+int rte_eth_dev_rx_classification_filter_ctl(uint8_t port_id,
+					     uint32_t cmd,
+					     void *args);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.8.1.4

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

* [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl' Helin Zhang
@ 2014-07-24  6:42 ` Helin Zhang
  2014-07-24  7:59   ` Thomas Monjalon
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 4/5] i40e: support configuring symmetric hash function Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 5/5] app/testpmd: new commands for configuring hash functions Helin Zhang
  4 siblings, 1 reply; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

Toeplitz and simple XOR hash functions are supported by
hardware, code changes are to tell the hardware which hash
function is selected according to the configuration.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 config/common_bsdapp              |  1 +
 config/common_linuxapp            |  1 +
 lib/librte_pmd_i40e/i40e_ethdev.c | 30 ++++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/config/common_bsdapp b/config/common_bsdapp
index bf6d8a0..e73629e 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -187,6 +187,7 @@ CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
 CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
 # interval up to 8160 us, aligned to 2 (or default value)
 CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
+CONFIG_RTE_LIBRTE_I40E_HASH_FUNC_TOEPLITZ=y
 
 #
 # Compile burst-oriented VIRTIO PMD driver
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9047975..9e00513 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -210,6 +210,7 @@ CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
 CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
 # interval up to 8160 us, aligned to 2 (or default value)
 CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
+CONFIG_RTE_LIBRTE_I40E_HASH_FUNC_TOEPLITZ=y
 
 #
 # Compile burst-oriented VIRTIO PMD driver
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c
index 9ed31b5..cc04c70 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev.c
@@ -203,6 +203,7 @@ static int i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 				    struct rte_eth_rss_conf *rss_conf);
 static int i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				      struct rte_eth_rss_conf *rss_conf);
+static void i40e_select_hash_function(struct i40e_hw *hw);
 
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1];
@@ -384,6 +385,9 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv,
 		return ret;
 	}
 
+	/* Select hash functions */
+	i40e_select_hash_function(hw);
+
 	/* Initialize the shared code (base driver) */
 	ret = i40e_init_shared_code(hw);
 	if (ret) {
@@ -3956,3 +3960,29 @@ i40e_pf_config_mq_rx(struct i40e_pf *pf)
 
 	return 0;
 }
+
+static void
+i40e_select_hash_function(struct i40e_hw *hw)
+{
+	uint32_t reg;
+
+	reg = I40E_READ_REG(hw, I40E_GLQF_CTL);
+#ifdef RTE_LIBRTE_I40E_HASH_FUNC_TOEPLITZ
+	if (reg & I40E_GLQF_CTL_HTOEP_MASK) {
+		PMD_DRV_LOG(DEBUG, "Hash function already set to Hoeplitz\n");
+		return;
+	}
+	reg |= I40E_GLQF_CTL_HTOEP_MASK;
+#else
+	if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) {
+		PMD_DRV_LOG(DEBUG, "Hash function already set to "
+						"Simple XOR\n");
+		return;
+	}
+	reg &= ~I40E_GLQF_CTL_HTOEP_MASK;
+#endif
+	PMD_DRV_LOG(INFO, "Hash function set to %s\n",
+		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "XOR");
+	I40E_WRITE_REG(hw, I40E_GLQF_CTL, reg);
+	I40E_WRITE_FLUSH(hw);
+}
-- 
1.8.1.4

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

* [dpdk-dev] [PATCH 4/5] i40e: support configuring symmetric hash function
  2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
                   ` (2 preceding siblings ...)
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions Helin Zhang
@ 2014-07-24  6:42 ` Helin Zhang
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 5/5] app/testpmd: new commands for configuring hash functions Helin Zhang
  4 siblings, 0 replies; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

Symmetric hash function can be configured:
* Set symmetric hash enable per port.
* Set symmetric hash enable per pctype (packet classification type).
* Set the swap configurations.
Commands are implemented for 'rx_classification_filter_ctl'
to support above operations which can be called in applications.
Also 'check_command_supported' is also implemented to check if
a specific capability(command) is supported or not.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 lib/librte_ether/Makefile           |   1 +
 lib/librte_ether/rte_eth_features.h |  65 ++++++
 lib/librte_pmd_i40e/Makefile        |   6 +
 lib/librte_pmd_i40e/i40e_ethdev.c   | 409 ++++++++++++++++++++++++++++++++++++
 lib/librte_pmd_i40e/rte_i40e.h      |  95 +++++++++
 5 files changed, 576 insertions(+)
 create mode 100644 lib/librte_ether/rte_eth_features.h
 create mode 100644 lib/librte_pmd_i40e/rte_i40e.h

diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index b310f8b..8089723 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -46,6 +46,7 @@ SRCS-y += rte_ethdev.c
 #
 SYMLINK-y-include += rte_ether.h
 SYMLINK-y-include += rte_ethdev.h
+SYMLINK-y-include += rte_eth_features.h
 
 # this lib depends upon:
 DEPDIRS-y += lib/librte_eal lib/librte_mempool lib/librte_ring lib/librte_mbuf
diff --git a/lib/librte_ether/rte_eth_features.h b/lib/librte_ether/rte_eth_features.h
new file mode 100644
index 0000000..d1790e2
--- /dev/null
+++ b/lib/librte_ether/rte_eth_features.h
@@ -0,0 +1,65 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_ETH_FEATURES_H_
+#define _RTE_ETH_FEATURES_H_
+
+/**
+ * @file
+ *
+ * Ethernet device specific features
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTE_CMD_UNKNOWN                        0
+/**< Command unknown. */
+#define RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE 1
+/**< Command to set symmetric hash enable per pctype. */
+#define RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE 2
+/**< Command to get symmetric hash enable per port. */
+#define RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT   3
+/**< Command to set symmetric hash enable per port. */
+#define RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT   4
+/**< Command to get filter swap configurations. */
+#define RTE_CMD_GET_FILTER_SWAP                5
+/**< Command to set filter swap configurations. */
+#define RTE_CMD_SET_FILTER_SWAP                6
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETH_FEATURES_H_ */
diff --git a/lib/librte_pmd_i40e/Makefile b/lib/librte_pmd_i40e/Makefile
index 4b31675..a777a76 100644
--- a/lib/librte_pmd_i40e/Makefile
+++ b/lib/librte_pmd_i40e/Makefile
@@ -87,6 +87,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c
+
+#
+# Export include file
+#
+SYMLINK-$(CONFIG_RTE_LIBRTE_I40E_PMD)-include += rte_i40e.h
+
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether
 DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_mempool lib/librte_mbuf
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c
index cc04c70..b699638 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev.c
@@ -48,7 +48,9 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_dev.h>
+#include <rte_eth_features.h>
 
+#include "rte_i40e.h"
 #include "i40e_logs.h"
 #include "i40e/i40e_register_x710_int.h"
 #include "i40e/i40e_prototype.h"
@@ -204,6 +206,13 @@ static int i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				      struct rte_eth_rss_conf *rss_conf);
 static void i40e_select_hash_function(struct i40e_hw *hw);
+static void i40e_init_hash_function(struct i40e_hw *hw);
+static int i40e_dev_check_command_supported(
+				struct rte_eth_dev *dev __rte_unused,
+				uint32_t cmd);
+static int i40e_rx_classification_filter_ctl(struct rte_eth_dev *dev,
+					     uint32_t cmd,
+					     void *args);
 
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1];
@@ -249,6 +258,8 @@ static struct eth_dev_ops i40e_eth_dev_ops = {
 	.reta_query                   = i40e_dev_rss_reta_query,
 	.rss_hash_update              = i40e_dev_rss_hash_update,
 	.rss_hash_conf_get            = i40e_dev_rss_hash_conf_get,
+	.check_command_supported      = i40e_dev_check_command_supported,
+	.rx_classification_filter_ctl = i40e_rx_classification_filter_ctl,
 };
 
 static struct eth_driver rte_i40e_pmd = {
@@ -385,6 +396,8 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv,
 		return ret;
 	}
 
+	/* Init hash functions */
+	i40e_init_hash_function(hw);
 	/* Select hash functions */
 	i40e_select_hash_function(hw);
 
@@ -3961,6 +3974,342 @@ i40e_pf_config_mq_rx(struct i40e_pf *pf)
 	return 0;
 }
 
+static int
+i40e_get_filter_swap(struct i40e_hw *hw, struct rte_i40e_filter_swap_info *info)
+{
+	uint32_t reg;
+
+	if (!hw || !info) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	switch (info->pctype) {
+	case ETH_PCTYPE_NONF_IPV4_UDP:
+	case ETH_PCTYPE_NONF_IPV4_TCP:
+	case ETH_PCTYPE_NONF_IPV4_SCTP:
+	case ETH_PCTYPE_NONF_IPV4_OTHER:
+	case ETH_PCTYPE_FRAG_IPV4:
+	case ETH_PCTYPE_NONF_IPV6_UDP:
+	case ETH_PCTYPE_NONF_IPV6_TCP:
+	case ETH_PCTYPE_NONF_IPV6_SCTP:
+	case ETH_PCTYPE_NONF_IPV6_OTHER:
+	case ETH_PCTYPE_FRAG_IPV6:
+	case ETH_PCTYPE_L2_PAYLOAD:
+		reg = I40E_READ_REG(hw, I40E_GLQF_SWAP(0, info->pctype));
+		PMD_DRV_LOG(DEBUG, "Value read from I40E_GLQF_SWAP[0,%d]: "
+					"0x%x\n", info->pctype, reg);
+
+		/**
+		 * The offset and length read from register in word unit,
+		 * which need to be converted in byte unit before being saved.
+		 */
+		info->off0_src0 =
+			(uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC0_MASK) >>
+				I40E_GLQF_SWAP_OFF0_SRC0_SHIFT) << 1;
+		info->off0_src1 =
+			(uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC1_MASK) >>
+				I40E_GLQF_SWAP_OFF0_SRC1_SHIFT) << 1;
+		info->len0 = (uint8_t)((reg & I40E_GLQF_SWAP_FLEN0_MASK) >>
+					I40E_GLQF_SWAP_FLEN0_SHIFT) << 1;
+		info->off1_src0 =
+			(uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC0_MASK) >>
+				I40E_GLQF_SWAP_OFF1_SRC0_SHIFT) << 1;
+		info->off1_src1 =
+			(uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC1_MASK) >>
+				I40E_GLQF_SWAP_OFF1_SRC1_SHIFT) << 1;
+		info->len1 = (uint8_t)((reg & I40E_GLQF_SWAP_FLEN1_MASK) >>
+					I40E_GLQF_SWAP_FLEN1_SHIFT) << 1;
+		break;
+	case ETH_PCTYPE_FCOE_OX:
+	case ETH_PCTYPE_FCOE_RX:
+	case ETH_PCTYPE_FCOE_OTHER:
+	default:
+		PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n",
+							info->pctype);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+i40e_set_filter_swap(struct i40e_hw *hw, struct rte_i40e_filter_swap_info *info)
+{
+#define I40E_FIELD_LEN_MAX 0x1f
+#define I40E_FIELD_OFFSET_MAX 0x7f
+	uint32_t reg;
+
+	if (!hw || !info) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	switch (info->pctype) {
+	case ETH_PCTYPE_NONF_IPV4_UDP:
+	case ETH_PCTYPE_NONF_IPV4_TCP:
+	case ETH_PCTYPE_NONF_IPV4_SCTP:
+	case ETH_PCTYPE_NONF_IPV4_OTHER:
+	case ETH_PCTYPE_FRAG_IPV4:
+	case ETH_PCTYPE_NONF_IPV6_UDP:
+	case ETH_PCTYPE_NONF_IPV6_TCP:
+	case ETH_PCTYPE_NONF_IPV6_SCTP:
+	case ETH_PCTYPE_NONF_IPV6_OTHER:
+	case ETH_PCTYPE_FRAG_IPV6:
+	case ETH_PCTYPE_L2_PAYLOAD:
+		if (info->off0_src0 > I40E_FIELD_OFFSET_MAX) {
+			PMD_DRV_LOG(ERR, "off0_src0 (0x%x) exceeds the "
+				"maximum of 0x%x\n", info->off0_src0,
+						I40E_FIELD_OFFSET_MAX);
+			return -1;
+		} else if (info->off0_src1 > I40E_FIELD_OFFSET_MAX) {
+			PMD_DRV_LOG(ERR, "off0_src1 (0x%x) exceeds the "
+				"maximum of 0x%x\n", info->off0_src1,
+						I40E_FIELD_OFFSET_MAX);
+			return -1;
+		} else if (info->len0 > I40E_FIELD_LEN_MAX) {
+			PMD_DRV_LOG(ERR, "len0 (0x%x) exceeds the maximum "
+				"of 0x%x\n", info->len0, I40E_FIELD_LEN_MAX);
+			return -1;
+		} else if (info->off1_src0 > I40E_FIELD_OFFSET_MAX) {
+			PMD_DRV_LOG(ERR, "off1_src0 (0x%x) exceeds the "
+				"maximum of 0x%x\n", info->off1_src0,
+						I40E_FIELD_OFFSET_MAX);
+			return -1;
+		} else if (info->off1_src1 > I40E_FIELD_OFFSET_MAX) {
+			PMD_DRV_LOG(ERR, "off1_src1 (0x%x) exceeds the "
+				"maximum of 0x%x\n", info->off1_src1,
+						I40E_FIELD_OFFSET_MAX);
+			return -1;
+		} else if (info->len1 > I40E_FIELD_LEN_MAX) {
+			PMD_DRV_LOG(ERR, "len1 (0x%x) exceeds the maximum "
+				"of 0x%x\n", info->len1, I40E_FIELD_LEN_MAX);
+			return -1;
+		}
+
+		/**
+		 * The offset and length given in byte unit, which need to be
+		 * converted in word unit before being written to the register,
+		 * as hardware requires it in word unit.
+		 */
+		reg = (info->off0_src0 >> 1) << I40E_GLQF_SWAP_OFF0_SRC0_SHIFT;
+		reg |= (info->off0_src1 >> 1) <<
+			I40E_GLQF_SWAP_OFF0_SRC1_SHIFT;
+		reg |= (info->len0 >> 1) << I40E_GLQF_SWAP_FLEN0_SHIFT;
+		reg |= (info->off1_src0 >> 1) <<
+			I40E_GLQF_SWAP_OFF1_SRC0_SHIFT;
+		reg |= (info->off1_src1 >> 1) <<
+			I40E_GLQF_SWAP_OFF1_SRC1_SHIFT;
+		reg |= (info->len1 >> 1) << I40E_GLQF_SWAP_FLEN1_SHIFT;
+		PMD_DRV_LOG(DEBUG, "Value to be written to "
+			"I40E_GLQF_SWAP[0,%d]: 0x%x\n", info->pctype, reg);
+		I40E_WRITE_REG(hw, I40E_GLQF_SWAP(0, info->pctype), reg);
+		I40E_WRITE_FLUSH(hw);
+		break;
+	case ETH_PCTYPE_FCOE_OX:
+	case ETH_PCTYPE_FCOE_RX:
+	case ETH_PCTYPE_FCOE_OTHER:
+	default:
+		PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n",
+							info->pctype);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable)
+{
+	uint32_t reg;
+
+	if (!hw || !enable) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	reg = I40E_READ_REG(hw, I40E_PRTQF_CTL_0);
+	*enable = reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK ? 1 : 0;
+
+	return 0;
+}
+
+static int
+i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable)
+{
+	uint32_t reg;
+
+	if (!hw || !enable) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	reg = I40E_READ_REG(hw, I40E_PRTQF_CTL_0);
+	if (*enable > 0) {
+		if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) {
+			PMD_DRV_LOG(INFO, "Symmetric hash has already "
+						"been enabled\n");
+			return 0;
+		}
+		reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
+	} else {
+		if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) {
+			PMD_DRV_LOG(INFO, "Symmetric hash has already "
+						"been disabled\n");
+			return 0;
+		}
+		reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
+	}
+	I40E_WRITE_REG(hw, I40E_PRTQF_CTL_0, reg);
+	I40E_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+static int
+i40e_get_symmetric_hash_enable_per_pctype(struct i40e_hw *hw,
+			struct rte_i40e_sym_hash_enable_info *info)
+{
+	uint32_t reg;
+
+	if (!hw || !info) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	switch (info->pctype) {
+	case ETH_PCTYPE_NONF_IPV4_UDP:
+	case ETH_PCTYPE_NONF_IPV4_TCP:
+	case ETH_PCTYPE_NONF_IPV4_SCTP:
+	case ETH_PCTYPE_NONF_IPV4_OTHER:
+	case ETH_PCTYPE_FRAG_IPV4:
+	case ETH_PCTYPE_NONF_IPV6_UDP:
+	case ETH_PCTYPE_NONF_IPV6_TCP:
+	case ETH_PCTYPE_NONF_IPV6_SCTP:
+	case ETH_PCTYPE_NONF_IPV6_OTHER:
+	case ETH_PCTYPE_FRAG_IPV6:
+	case ETH_PCTYPE_L2_PAYLOAD:
+		reg = I40E_READ_REG(hw, I40E_GLQF_HSYM(info->pctype));
+		break;
+	case ETH_PCTYPE_FCOE_OX:
+	case ETH_PCTYPE_FCOE_RX:
+	case ETH_PCTYPE_FCOE_OTHER:
+	default:
+		PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n",
+							info->pctype);
+		return -1;
+	}
+
+	info->enable = reg & I40E_GLQF_HSYM_SYMH_ENA_MASK ? 1 : 0;
+
+	return 0;
+}
+
+static int
+i40e_set_symmetric_hash_enable_per_pctype(struct i40e_hw *hw,
+			struct rte_i40e_sym_hash_enable_info *info)
+{
+	uint32_t reg;
+
+	if (!hw || !info) {
+		PMD_DRV_LOG(ERR, "Invalid pointer\n");
+		return -1;
+	}
+
+	switch (info->pctype) {
+	case ETH_PCTYPE_NONF_IPV4_UDP:
+	case ETH_PCTYPE_NONF_IPV4_TCP:
+	case ETH_PCTYPE_NONF_IPV4_SCTP:
+	case ETH_PCTYPE_NONF_IPV4_OTHER:
+	case ETH_PCTYPE_FRAG_IPV4:
+	case ETH_PCTYPE_NONF_IPV6_UDP:
+	case ETH_PCTYPE_NONF_IPV6_TCP:
+	case ETH_PCTYPE_NONF_IPV6_SCTP:
+	case ETH_PCTYPE_NONF_IPV6_OTHER:
+	case ETH_PCTYPE_FRAG_IPV6:
+	case ETH_PCTYPE_L2_PAYLOAD:
+		reg = info->enable ? I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+		I40E_WRITE_REG(hw, I40E_GLQF_HSYM(info->pctype), reg);
+		I40E_WRITE_FLUSH(hw);
+		break;
+	case ETH_PCTYPE_FCOE_OX:
+	case ETH_PCTYPE_FCOE_RX:
+	case ETH_PCTYPE_FCOE_OTHER:
+	default:
+		PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n",
+							info->pctype);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+i40e_dev_check_command_supported(struct rte_eth_dev *dev __rte_unused,
+				 uint32_t cmd)
+{
+	uint32_t i;
+	/* Check the commands defined for i40e only in rte_eth_features.h */
+	static const uint32_t i40e_commands[] = {
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE,
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT,
+		RTE_CMD_GET_FILTER_SWAP,
+		RTE_CMD_SET_FILTER_SWAP,
+	};
+
+	for (i = 0; i < RTE_DIM(i40e_commands); i++) {
+		if (i40e_commands[i] == cmd)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int
+i40e_rx_classification_filter_ctl(struct rte_eth_dev *dev,
+				  uint32_t cmd,
+				  void *args)
+{
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret = 0;
+
+	switch (cmd) {
+	case RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE:
+		ret = i40e_get_symmetric_hash_enable_per_pctype(hw,
+			(struct rte_i40e_sym_hash_enable_info *)args);
+		break;
+	case RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE:
+		ret = i40e_set_symmetric_hash_enable_per_pctype(hw,
+			(struct rte_i40e_sym_hash_enable_info *)args);
+		break;
+	case RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT:
+		ret = i40e_get_symmetric_hash_enable_per_port(hw,
+						(uint8_t *)args);
+		break;
+	case RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT:
+		ret = i40e_set_symmetric_hash_enable_per_port(hw,
+						(uint8_t *)args);
+		break;
+	case RTE_CMD_GET_FILTER_SWAP:
+		ret = i40e_get_filter_swap(hw,
+			(struct rte_i40e_filter_swap_info *)args);
+		break;
+	case RTE_CMD_SET_FILTER_SWAP:
+		ret = i40e_set_filter_swap(hw,
+			(struct rte_i40e_filter_swap_info *)args);
+		break;
+	default:
+		ret = -1;
+		PMD_DRV_LOG(ERR, "Unknown command which is not "
+					"supported by i40e\n");
+		break;
+	}
+
+	return ret;
+}
+
 static void
 i40e_select_hash_function(struct i40e_hw *hw)
 {
@@ -3986,3 +4335,63 @@ i40e_select_hash_function(struct i40e_hw *hw)
 	I40E_WRITE_REG(hw, I40E_GLQF_CTL, reg);
 	I40E_WRITE_FLUSH(hw);
 }
+
+/**
+ * Initialize filter swap configurations and symmetric hash control
+ * configurations, as only global reset can reload the firmware
+ * configurations.
+ */
+static void
+i40e_init_hash_function(struct i40e_hw *hw)
+{
+	static struct rte_i40e_filter_swap_info swap_info[] = {
+		{ETH_PCTYPE_NONF_IPV4_UDP,
+			0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02},
+		{ETH_PCTYPE_NONF_IPV4_TCP,
+			0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02},
+		{ETH_PCTYPE_NONF_IPV4_SCTP,
+			0x1e, 0x36, 0x04, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_NONF_IPV4_OTHER,
+			0x1e, 0x36, 0x04, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_FRAG_IPV4,
+			0x1e, 0x36, 0x04, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_NONF_IPV6_UDP,
+			0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02},
+		{ETH_PCTYPE_NONF_IPV6_TCP,
+			0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02},
+		{ETH_PCTYPE_NONF_IPV6_SCTP,
+			0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_NONF_IPV6_OTHER,
+			0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_FRAG_IPV6,
+			0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00},
+		{ETH_PCTYPE_L2_PAYLOAD,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	};
+	static struct rte_i40e_sym_hash_enable_info sym_hash_ena_info[] = {
+		{ETH_PCTYPE_NONF_IPV4_UDP, 0},
+		{ETH_PCTYPE_NONF_IPV4_TCP, 0},
+		{ETH_PCTYPE_NONF_IPV4_SCTP, 0},
+		{ETH_PCTYPE_NONF_IPV4_OTHER, 0},
+		{ETH_PCTYPE_FRAG_IPV4, 0},
+		{ETH_PCTYPE_NONF_IPV6_UDP, 0},
+		{ETH_PCTYPE_NONF_IPV6_TCP, 0},
+		{ETH_PCTYPE_NONF_IPV6_SCTP, 0},
+		{ETH_PCTYPE_NONF_IPV6_OTHER, 0},
+		{ETH_PCTYPE_FRAG_IPV6, 0},
+		{ETH_PCTYPE_L2_PAYLOAD, 0},
+	};
+	uint32_t i;
+
+	/* initialize filter swap */
+	for (i = 0; i < RTE_DIM(swap_info); i++)
+		i40e_set_filter_swap(hw, &swap_info[i]);
+
+	/* disable all symmetric hash per pctype */
+	for (i = 0; i < RTE_DIM(sym_hash_ena_info); i++)
+		i40e_set_symmetric_hash_enable_per_pctype(hw,
+					&sym_hash_ena_info[i]);
+
+	/* disable symmetric hash per port */
+	i40e_set_symmetric_hash_enable_per_port(hw, 0);
+}
diff --git a/lib/librte_pmd_i40e/rte_i40e.h b/lib/librte_pmd_i40e/rte_i40e.h
new file mode 100644
index 0000000..211e566
--- /dev/null
+++ b/lib/librte_pmd_i40e/rte_i40e.h
@@ -0,0 +1,95 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_I40E_H_
+#define _RTE_I40E_H_
+
+/**
+ * @file
+ *
+ * RTE I40E
+ *
+ * The I40E defines the commands and structures specifically for i40e hardware
+ * features. As different types of NIC hardware may have different features,
+ * they might not be common for all types of NIC hardwares. The commands and
+ * structures can be used in applications directly together with generalized
+ * APIs declared in rte_ethdev.h. The commands couldn't be supported by
+ * non-i40e PMD.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * For commands:
+ * 'RTE_CMD_GET_FILTER_SWAP'
+ * 'RTE_CMD_SET_FILTER_SWAP'
+ *
+ * A structure used to get/set filter swap. All of the offsets and
+ * length are defined in bytes.
+ */
+struct rte_i40e_filter_swap_info {
+	/**< Packet classification type, defined in rte_ethdev.h */
+	uint8_t pctype;
+	/**< Offset of the 1st field of the 1st couple to be swapped. */
+	uint8_t off0_src0;
+	/**< Offset of the 2nd field of the 1st couple to be swapped. */
+	uint8_t off0_src1;
+	/**< Field length of the first couple. */
+	uint8_t len0;
+	/**< Offset of the 1st field of the 2nd couple to be swapped. */
+	uint8_t off1_src0;
+	/**< Offset of the 2nd field of the 2nd couple to be swapped. */
+	uint8_t off1_src1;
+	/**< Field length of the second couple. */
+	uint8_t len1;
+};
+
+/**
+ * For commands:
+ * 'RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE'
+ * 'RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE'
+ *
+ * A structure used to set/get symmetric hash enable per pctype.
+ */
+struct rte_i40e_sym_hash_enable_info {
+	uint8_t pctype; /**< packet classification type */
+	uint8_t enable; /**< enable or disable flag */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif /* _RTE_I40E_H_ */
-- 
1.8.1.4

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

* [dpdk-dev] [PATCH 5/5] app/testpmd: new commands for configuring hash functions
  2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
                   ` (3 preceding siblings ...)
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 4/5] i40e: support configuring symmetric hash function Helin Zhang
@ 2014-07-24  6:42 ` Helin Zhang
  4 siblings, 0 replies; 17+ messages in thread
From: Helin Zhang @ 2014-07-24  6:42 UTC (permalink / raw)
  To: dev

Six commands are added in testpmd to support configuring
hash functions. They are,
* i40e_get_sym_hash_ena_per_port
* i40e_set_sym_hash_ena_per_port
* i40e_get_sym_hash_ena_per_pctype
* i40e_set_sym_hash_ena_per_pctype
* i40e_get_filter_swap
* i40e_set_filter_swap

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c | 455 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 455 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 345be11..0e075da 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -74,6 +74,10 @@
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
 #include <rte_devargs.h>
+#include <rte_eth_features.h>
+#ifdef RTE_LIBRTE_I40E_PMD
+#include <rte_i40e.h>
+#endif
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
@@ -655,6 +659,34 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"get_flex_filter (port_id) index (idx)\n"
 			"    get info of a flex filter.\n\n"
+
+#ifdef RTE_LIBRTE_I40E_PMD
+			"i40e_get_sym_hash_ena_per_port (port_id)\n"
+			"    get symmetric hash enable configuration per port,"
+			" on i40e only\n\n"
+
+			"i40e_set_sym_hash_ena_per_port (port_id)"
+			" enable|disable\n"
+			"    set symmetric hash enable configuration per port"
+			" to enable or disable, on i40e only\n\n"
+
+			"i40e_get_sym_hash_ena_per_pctype (port_id) (pctype)\n"
+			"    get symmetric hash enable configuration per port,"
+			" on i40e only\n\n"
+
+			"i40e_set_sym_hash_ena_per_pctype (port_id) (pctype)"
+			" enable|disable\n"
+			"    set symmetric hash enable configuration per"
+			" pctype to enable or disable, on i40e only\n\n"
+
+			"i40e_get_filter_swap (port_id) (pctype)\n"
+			"    get filter swap configurations on i40e,"
+			" on i40e only\n\n"
+
+			"i40e_set_filter_swap (port_id) (pctype) (off0_src0)"
+			" (off0_src1) (len0) (off1_src0) (off1_src1) (len1)\n"
+			"    set filter swap configurations, on i40e only\n\n"
+#endif /* RTE_LIBRTE_I40E_PMD */
 		);
 	}
 }
@@ -7304,6 +7336,421 @@ cmdline_parse_inst_t cmd_get_flex_filter = {
 	},
 };
 
+/* *** Classification Filters Control *** */
+#ifdef RTE_LIBRTE_I40E_PMD
+/* *** Get symmetric hash enable per port *** */
+struct cmd_i40e_get_sym_hash_ena_per_port_result {
+	cmdline_fixed_string_t i40e_get_sym_hash_ena_per_port;
+	uint8_t port_id;
+};
+
+static void
+cmd_i40e_get_sym_hash_per_port_parsed(void *parsed_result,
+				      __rte_unused struct cmdline *cl,
+				      __rte_unused void *data)
+{
+	struct cmd_i40e_get_sym_hash_ena_per_port_result *res = parsed_result;
+	uint8_t enable = 0;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT) <= 0) {
+		printf("Command of RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT "
+			"not supported on port: %d\n", res->port_id);
+		return;
+	}
+
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT, &enable);
+	if (ret < 0) {
+		printf("Cannot get symmetric hash enable per port "
+				"on i40e port %u\n", res->port_id);
+		return;
+	}
+
+	printf("Symmetric hash is %s on i40e port %u\n",
+		enable ? "enabled" : "disabled", res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_i40e_get_sym_hash_ena_per_port_all =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_get_sym_hash_ena_per_port_result,
+			i40e_get_sym_hash_ena_per_port,
+			"i40e_get_sym_hash_ena_per_port");
+cmdline_parse_token_num_t cmd_i40e_get_sym_hash_ena_per_port_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_get_sym_hash_ena_per_port_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_i40e_get_sym_hash_ena_per_port = {
+	.f = cmd_i40e_get_sym_hash_per_port_parsed,
+	.data = NULL,
+	.help_str = "i40e_get_sym_hash_ena_per_port port_id",
+	.tokens = {
+		(void *)&cmd_i40e_get_sym_hash_ena_per_port_all,
+		(void *)&cmd_i40e_get_sym_hash_ena_per_port_port_id,
+		NULL,
+	},
+};
+
+/* *** Set symmetric hash enable per port *** */
+struct cmd_i40e_set_sym_hash_ena_per_port_result {
+	cmdline_fixed_string_t i40e_set_sym_hash_ena_per_port;
+	cmdline_fixed_string_t enable;
+	uint8_t port_id;
+};
+
+static void
+cmd_i40e_set_sym_hash_per_port_parsed(void *parsed_result,
+				      __rte_unused struct cmdline *cl,
+				      __rte_unused void *data)
+{
+	struct cmd_i40e_set_sym_hash_ena_per_port_result *res = parsed_result;
+	uint8_t enable = 0;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT) <= 0) {
+		printf("Command of RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT "
+			"not supported on port: %d\n", res->port_id);
+		return;
+	}
+
+	if (!strcmp(res->enable, "enable"))
+		enable = 1;
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT, &enable);
+	if (ret < 0) {
+		printf("Cannot set symmetric hash enable per port "
+				"on i40e port %u\n", res->port_id);
+		return;
+	}
+
+	printf("Symmetric hash has been set to %s on i40e port %u\n",
+					res->enable, res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_i40e_set_sym_hash_ena_per_port_all =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_port_result,
+				i40e_set_sym_hash_ena_per_port,
+				"i40e_set_sym_hash_ena_per_port");
+cmdline_parse_token_num_t cmd_i40e_set_sym_hash_ena_per_port_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_sym_hash_ena_per_port_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_i40e_set_sym_hash_ena_per_port_enable =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_port_result,
+					enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_i40e_set_sym_hash_ena_per_port = {
+	.f = cmd_i40e_set_sym_hash_per_port_parsed,
+	.data = NULL,
+	.help_str = "i40e_set_sym_hash_ena_per_port port_id enable|disable",
+	.tokens = {
+		(void *)&cmd_i40e_set_sym_hash_ena_per_port_all,
+		(void *)&cmd_i40e_set_sym_hash_ena_per_port_port_id,
+		(void *)&cmd_i40e_set_sym_hash_ena_per_port_enable,
+		NULL,
+	},
+};
+
+/* *** Get symmetric hash enable per pctype *** */
+struct cmd_i40e_get_sym_hash_ena_per_pctype_result {
+	cmdline_fixed_string_t i40e_get_sym_hash_ena_per_pctype;
+	uint8_t port_id;
+	uint8_t pctype;
+};
+
+static void
+cmd_i40e_get_sym_hash_per_pctype_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					__rte_unused void *data)
+{
+	struct cmd_i40e_get_sym_hash_ena_per_pctype_result *res =
+						parsed_result;
+	struct rte_i40e_sym_hash_enable_info info;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE) <= 0) {
+		printf("Command of RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE "
+			"not supported on port: %d\n", res->port_id);
+		return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.pctype = res->pctype;
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+		RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE, &info);
+	if (ret < 0) {
+		printf("Cannot get symmetric hash enable per pctype on i40e "
+			"port %u, pctype %u\n", res->port_id, res->pctype);
+		return;
+	}
+	printf("Symmetric hash is %s on i40e port %u, pctype %u\n",
+				info.enable ? "enabled" : "disabled",
+					res->port_id, res->pctype);
+}
+
+cmdline_parse_token_string_t cmd_i40e_get_sym_hash_ena_per_pctype_all =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_get_sym_hash_ena_per_pctype_result,
+				i40e_get_sym_hash_ena_per_pctype,
+				"i40e_get_sym_hash_ena_per_pctype");
+cmdline_parse_token_num_t cmd_i40e_get_sym_hash_ena_per_pctype_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_i40e_get_sym_hash_ena_per_pctype_result,
+						port_id, UINT8);
+cmdline_parse_token_num_t cmd_i40e_get_sym_hash_ena_per_pctype_pctype =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_i40e_get_sym_hash_ena_per_pctype_result,
+						pctype, UINT8);
+
+cmdline_parse_inst_t cmd_i40e_get_sym_hash_ena_per_pctype = {
+	.f = cmd_i40e_get_sym_hash_per_pctype_parsed,
+	.data = NULL,
+	.help_str = "i40e_get_sym_hash_ena_per_pctype port_id pctype",
+	.tokens = {
+		(void *)&cmd_i40e_get_sym_hash_ena_per_pctype_all,
+		(void *)&cmd_i40e_get_sym_hash_ena_per_pctype_port_id,
+		(void *)&cmd_i40e_get_sym_hash_ena_per_pctype_pctype,
+		NULL,
+	},
+};
+
+/* *** Set symmetric hash enable per pctype *** */
+struct cmd_i40e_set_sym_hash_ena_per_pctype_result {
+	cmdline_fixed_string_t i40e_set_sym_hash_ena_per_pctype;
+	cmdline_fixed_string_t enable;
+	uint8_t port_id;
+	uint8_t pctype;
+};
+
+static void
+cmd_i40e_set_sym_hash_per_pctype_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					__rte_unused void *data)
+{
+	struct cmd_i40e_set_sym_hash_ena_per_pctype_result *res =
+						parsed_result;
+	struct rte_i40e_sym_hash_enable_info info;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE) <= 0) {
+		printf("Command of RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE "
+			"not supported on port: %d\n", res->port_id);
+		return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.pctype = res->pctype;
+	if (!strcmp(res->enable, "enable"))
+		info.enable = 1;
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+		RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE, &info);
+	if (ret < 0) {
+		printf("Cannot set symmetric hash enable per pctype to %s "
+			"on i40e port %u, pctype %u\n", res->enable ?
+			"enabled" : "disabled", res->port_id, res->pctype);
+		return;
+	}
+	printf("Symmetic hash has been set to %s on i40e port %u, pctype %u\n",
+				res->enable, res->port_id, res->pctype);
+}
+
+cmdline_parse_token_string_t cmd_i40e_set_sym_hash_ena_per_pctype_all =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_pctype_result,
+				i40e_set_sym_hash_ena_per_pctype,
+				"i40e_set_sym_hash_ena_per_pctype");
+cmdline_parse_token_num_t cmd_i40e_set_sym_hash_ena_per_pctype_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_pctype_result,
+						port_id, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_sym_hash_ena_per_pctype_pctype =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_pctype_result,
+		pctype, UINT8);
+cmdline_parse_token_string_t cmd_i40e_set_sym_hash_ena_per_pctype_enable =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_i40e_set_sym_hash_ena_per_pctype_result,
+		enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_i40e_set_sym_hash_ena_per_pctype = {
+	.f = cmd_i40e_set_sym_hash_per_pctype_parsed,
+	.data = NULL,
+	.help_str = "i40e_set_sym_hash_ena_per_pctype pord_id "
+					"pctype enable|disable",
+	.tokens = {
+		(void *)&cmd_i40e_set_sym_hash_ena_per_pctype_all,
+		(void *)&cmd_i40e_set_sym_hash_ena_per_pctype_port_id,
+		(void *)&cmd_i40e_set_sym_hash_ena_per_pctype_pctype,
+		(void *)&cmd_i40e_set_sym_hash_ena_per_pctype_enable,
+		NULL,
+	},
+};
+
+/* *** Get filter swap *** */
+struct cmd_i40e_get_filter_swap_result {
+	cmdline_fixed_string_t i40e_get_filter_swap;
+	uint8_t port_id;
+	uint8_t pctype;
+};
+
+static void
+cmd_i40e_get_filter_swap_parsed(void *parsed_result,
+				__rte_unused struct cmdline *cl,
+				__rte_unused void *data)
+{
+	struct cmd_i40e_get_filter_swap_result *res = parsed_result;
+	struct rte_i40e_filter_swap_info info;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+			RTE_CMD_GET_FILTER_SWAP) <= 0) {
+		printf("Command of RTE_CMD_GET_FILTER_SWAP not supported "
+					"on port: %d\n", res->port_id);
+		return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.pctype = res->pctype;
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+				RTE_CMD_GET_FILTER_SWAP, &info);
+	if (ret < 0) {
+		printf("Cannot get filter swap on i40e port %u, pctype %u\n",
+						res->port_id, res->pctype);
+		return;
+	}
+	printf("Filter swap of i40e port %u, pctype %u is configured as:\n"
+			"off0_src0: 0x%02x, off0_src1: 0x%02x, len0: 0x%02x\n"
+			"off1_src0: 0x%02x, off1_src1: 0x%02x, len1: 0x%02x\n",
+		res->port_id, res->pctype, info.off0_src0, info.off0_src1,
+		info.len0, info.off1_src0, info.off1_src1, info.len1);
+}
+
+cmdline_parse_token_string_t cmd_i40e_get_filter_swap_all =
+	TOKEN_STRING_INITIALIZER(struct cmd_i40e_get_filter_swap_result,
+		i40e_get_filter_swap, "i40e_get_filter_swap");
+cmdline_parse_token_num_t cmd_i40e_get_filter_swap_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_get_filter_swap_result,
+		port_id, UINT8);
+cmdline_parse_token_num_t cmd_i40e_get_filter_swap_pctype =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_get_filter_swap_result,
+		pctype, UINT8);
+
+cmdline_parse_inst_t cmd_i40e_get_filter_swap = {
+	.f = cmd_i40e_get_filter_swap_parsed,
+	.data = NULL,
+	.help_str = "i40e_get_filter_swap port_id pctype",
+	.tokens = {
+		(void *)&cmd_i40e_get_filter_swap_all,
+		(void *)&cmd_i40e_get_filter_swap_port_id,
+		(void *)&cmd_i40e_get_filter_swap_pctype,
+		NULL,
+	},
+};
+
+/* *** Set filter swap *** */
+struct cmd_i40e_set_filter_swap_result {
+	cmdline_fixed_string_t i40e_set_filter_swap;
+	uint8_t port_id;
+	uint8_t pctype;
+	uint8_t off0_src0;
+	uint8_t off0_src1;
+	uint8_t len0;
+	uint8_t off1_src0;
+	uint8_t off1_src1;
+	uint8_t len1;
+};
+
+static void
+cmd_i40e_set_filter_swap_parsed(void *parsed_result,
+				__rte_unused struct cmdline *cl,
+				__rte_unused void *data)
+{
+	struct cmd_i40e_set_filter_swap_result *res = parsed_result;
+	struct rte_i40e_filter_swap_info info;
+	int ret;
+
+	if (rte_eth_dev_check_command_supported(res->port_id,
+			RTE_CMD_SET_FILTER_SWAP) <= 0) {
+		printf("Command of RTE_CMD_SET_FILTER_SWAP not supported "
+					"on port: %d\n", res->port_id);
+		return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.pctype = res->pctype;
+	info.off0_src0 = res->off0_src0;
+	info.off0_src1 = res->off0_src1;
+	info.len0 = res->len0;
+	info.off1_src0 = res->off1_src0;
+	info.off1_src1 = res->off1_src1;
+	info.len1 = res->len1;
+	ret = rte_eth_dev_rx_classification_filter_ctl(res->port_id,
+				RTE_CMD_SET_FILTER_SWAP, &info);
+	if (ret < 0) {
+		printf("Cannot set filter swap on i40e port %u, pctype %u\n",
+						res->port_id, res->pctype);
+		return;
+	}
+	printf("Filter swap of i40e port %u, pctype %u has been set as:\n"
+			"off0_src0: 0x%02x, off0_src1: 0x%02x, len0: 0x%02x\n"
+			"off1_src0: 0x%02x, off1_src1: 0x%02x, len1: 0x%02x\n",
+		res->port_id, res->pctype, info.off0_src0, info.off0_src1,
+		info.len0, info.off1_src0, info.off1_src1, info.len1);
+}
+
+cmdline_parse_token_string_t cmd_i40e_set_filter_swap_all =
+	TOKEN_STRING_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		i40e_set_filter_swap, "i40e_set_filter_swap");
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		port_id, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_pctype =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		pctype, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_off0_src0 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		off0_src0, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_off0_src1 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		off0_src1, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_len0 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		len0, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_off1_src0 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		off1_src0, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_off1_src1 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		off1_src1, UINT8);
+cmdline_parse_token_num_t cmd_i40e_set_filter_swap_len1 =
+	TOKEN_NUM_INITIALIZER(struct cmd_i40e_set_filter_swap_result,
+		len1, UINT8);
+
+cmdline_parse_inst_t cmd_i40e_set_filter_swap = {
+	.f = cmd_i40e_set_filter_swap_parsed,
+	.data = NULL,
+	.help_str = "i40e_set_filter_swap port_id pctype off0_src0 off0_src1 "
+					"len0 off1_src0 off1_src1 len1",
+	.tokens = {
+		(void *)&cmd_i40e_set_filter_swap_all,
+		(void *)&cmd_i40e_set_filter_swap_port_id,
+		(void *)&cmd_i40e_set_filter_swap_pctype,
+		(void *)&cmd_i40e_set_filter_swap_off0_src0,
+		(void *)&cmd_i40e_set_filter_swap_off0_src1,
+		(void *)&cmd_i40e_set_filter_swap_len0,
+		(void *)&cmd_i40e_set_filter_swap_off1_src0,
+		(void *)&cmd_i40e_set_filter_swap_off1_src1,
+		(void *)&cmd_i40e_set_filter_swap_len1,
+		NULL,
+	},
+};
+#endif /* RTE_LIBRTE_I40E_PMD */
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -7429,6 +7876,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
+#ifdef RTE_LIBRTE_I40E_PMD
+	(cmdline_parse_inst_t *)&cmd_i40e_get_sym_hash_ena_per_port,
+	(cmdline_parse_inst_t *)&cmd_i40e_set_sym_hash_ena_per_port,
+	(cmdline_parse_inst_t *)&cmd_i40e_get_sym_hash_ena_per_pctype,
+	(cmdline_parse_inst_t *)&cmd_i40e_set_sym_hash_ena_per_pctype,
+	(cmdline_parse_inst_t *)&cmd_i40e_get_filter_swap,
+	(cmdline_parse_inst_t *)&cmd_i40e_set_filter_swap,
+#endif /* RTE_LIBRTE_I40E_PMD */
 	NULL,
 };
 
-- 
1.8.1.4

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

* Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type Helin Zhang
@ 2014-07-24  7:48   ` Thomas Monjalon
  2014-07-24  8:14     ` Zhang, Helin
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2014-07-24  7:48 UTC (permalink / raw)
  To: Helin Zhang; +Cc: dev

Hi Helin,

2014-07-24 14:42, Helin Zhang:
> For better understanding, 'PCTYPE' was added to the name of i40e
> RSS shift macros.
> 
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>

> -#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
> +#define ETH_PCTYPE_NONF_IPV4_UDP              31

Why is it clearer? I don't understand what means PCTYPE.

-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl'
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl' Helin Zhang
@ 2014-07-24  7:56   ` Thomas Monjalon
  2014-07-24  8:49     ` Zhang, Helin
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2014-07-24  7:56 UTC (permalink / raw)
  To: Helin Zhang; +Cc: dev

2014-07-24 14:42, Helin Zhang:
> Two ops of 'check_command_supported' and 'rx_classification_filter_ctl'
> are added.
> * 'check_command_supported' is for capability discovery. In anothoer
>   word, it is to check if specific feature/command is supported by
>   the specific port.

This generic service is really needed to add NIC-specific functions.
I'd suggest to name it "is_supported".

> * 'rx_classification_filter_ctl' is for receive classifcation filter
>   configuring. e.g. hash function configuration, flow director
>   configuration. It is a common API where a lot of commands can
>   be implemented for different sub features.

Not sure about this one. You are hiding specific API in an opaque structure.
By the way, it should be in another patch.

> +/**
> + * Check if the command is supported by an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param cmd
> + *   The command.
> + *
> + * @return
> + *   - (> 0) The command is supported.
> + *   - (0) The command is not supported.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if <port_id> is invalid.
> + */
> +int rte_eth_dev_check_command_supported(uint8_t port_id, uint32_t cmd);

What are the possible commands?
You should define enum/constants here.

-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  6:42 ` [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions Helin Zhang
@ 2014-07-24  7:59   ` Thomas Monjalon
  2014-07-24  8:01     ` Matthew Hall
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2014-07-24  7:59 UTC (permalink / raw)
  To: Helin Zhang; +Cc: dev

2014-07-24 14:42, Helin Zhang:
> Toeplitz and simple XOR hash functions are supported by
> hardware, code changes are to tell the hardware which hash
> function is selected according to the configuration.
> 
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>

> +CONFIG_RTE_LIBRTE_I40E_HASH_FUNC_TOEPLITZ=y

Is it really a good idea to configure this kind of thing at build time?
Maybe yes, I'm not sure.

-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  7:59   ` Thomas Monjalon
@ 2014-07-24  8:01     ` Matthew Hall
  2014-07-24  8:07       ` Thomas Monjalon
  0 siblings, 1 reply; 17+ messages in thread
From: Matthew Hall @ 2014-07-24  8:01 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Thu, Jul 24, 2014 at 09:59:23AM +0200, Thomas Monjalon wrote:
> Is it really a good idea to configure this kind of thing at build time?
> Maybe yes, I'm not sure.

Whether it's safe to set at runtime probably depends what happens to the card 
if it gets changed. Do you have to reset the card or the port? Or is it OK if 
it's more dynamic?

Matthew.

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

* Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  8:01     ` Matthew Hall
@ 2014-07-24  8:07       ` Thomas Monjalon
  2014-07-24  8:14         ` Matthew Hall
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2014-07-24  8:07 UTC (permalink / raw)
  To: Matthew Hall, Helin Zhang; +Cc: dev

2014-07-24 01:01, Matthew Hall:
> On Thu, Jul 24, 2014 at 09:59:23AM +0200, Thomas Monjalon wrote:
> > Is it really a good idea to configure this kind of thing at build time?
> > Maybe yes, I'm not sure.
> 
> Whether it's safe to set at runtime probably depends what happens to the card 
> if it gets changed. Do you have to reset the card or the port? Or is it OK if 
> it's more dynamic?

No, we can change configuration with rte_eth_dev_configure() before
initializing port. So it is truly configurable.
Requiring recompilation means it's not really configurable between 2 runs.
And it breaks binary packaging for Linux distributions.

Many things in DPDK are configured at build time. But we should wonder if
it's really a good design.

-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type
  2014-07-24  7:48   ` Thomas Monjalon
@ 2014-07-24  8:14     ` Zhang, Helin
  2014-07-24  8:19       ` Thomas Monjalon
  0 siblings, 1 reply; 17+ messages in thread
From: Zhang, Helin @ 2014-07-24  8:14 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, July 24, 2014 3:48 PM
> To: Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet
> classification type
> 
> Hi Helin,
> 
> 2014-07-24 14:42, Helin Zhang:
> > For better understanding, 'PCTYPE' was added to the name of i40e RSS
> > shift macros.
> >
> > Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> 
> > -#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
> > +#define ETH_PCTYPE_NONF_IPV4_UDP              31
> 
> Why is it clearer? I don't understand what means PCTYPE.
> 
> --
> Thomas

Hi Thomas

It is 'packet classification type' defined in data sheet, and widely used. It is not just for RSS only, it can be used for flow director possibly. That's why I think it would be better to rename it with PCTYPE names. Thank you!

Regards,
Helin

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

* Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  8:07       ` Thomas Monjalon
@ 2014-07-24  8:14         ` Matthew Hall
  2014-07-24  8:54           ` Zhang, Helin
  0 siblings, 1 reply; 17+ messages in thread
From: Matthew Hall @ 2014-07-24  8:14 UTC (permalink / raw)
  To: Thomas Monjalon, Helin Zhang; +Cc: dev

If no reboot of the card is needed then it's probably better to add it to one of the ethtool style APIs...
-- 
Sent from my mobile device.

On July 24, 2014 1:07:37 AM PDT, Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
>2014-07-24 01:01, Matthew Hall:
>> On Thu, Jul 24, 2014 at 09:59:23AM +0200, Thomas Monjalon wrote:
>> > Is it really a good idea to configure this kind of thing at build
>time?
>> > Maybe yes, I'm not sure.
>> 
>> Whether it's safe to set at runtime probably depends what happens to
>the card 
>> if it gets changed. Do you have to reset the card or the port? Or is
>it OK if 
>> it's more dynamic?
>
>No, we can change configuration with rte_eth_dev_configure() before
>initializing port. So it is truly configurable.
>Requiring recompilation means it's not really configurable between 2
>runs.
>And it breaks binary packaging for Linux distributions.
>
>Many things in DPDK are configured at build time. But we should wonder
>if
>it's really a good design.

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

* Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type
  2014-07-24  8:14     ` Zhang, Helin
@ 2014-07-24  8:19       ` Thomas Monjalon
  2014-07-24  8:23         ` Zhang, Helin
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2014-07-24  8:19 UTC (permalink / raw)
  To: Zhang, Helin; +Cc: dev

2014-07-24 08:14, Zhang, Helin:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2014-07-24 14:42, Helin Zhang:
> > > For better understanding, 'PCTYPE' was added to the name of i40e RSS
> > > shift macros.
> > >
> > > Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> > 
> > > -#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
> > > +#define ETH_PCTYPE_NONF_IPV4_UDP              31
> > 
> > Why is it clearer? I don't understand what means PCTYPE.
> 
> It is 'packet classification type' defined in data sheet, and widely used.

Widely used? No it seems to be an i40e naming.
Which datasheet are you pointing?

> It is not just for RSS only, it can be used for flow director possibly.
> That's why I think it would be better to rename it with PCTYPE names.

At least, you should add a comment in the code to explain the meaning.

Thank you
-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type
  2014-07-24  8:19       ` Thomas Monjalon
@ 2014-07-24  8:23         ` Zhang, Helin
  0 siblings, 0 replies; 17+ messages in thread
From: Zhang, Helin @ 2014-07-24  8:23 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, July 24, 2014 4:20 PM
> To: Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet
> classification type
> 
> 2014-07-24 08:14, Zhang, Helin:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2014-07-24 14:42, Helin Zhang:
> > > > For better understanding, 'PCTYPE' was added to the name of i40e
> > > > RSS shift macros.
> > > >
> > > > Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> > >
> > > > -#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
> > > > +#define ETH_PCTYPE_NONF_IPV4_UDP              31
> > >
> > > Why is it clearer? I don't understand what means PCTYPE.
> >
> > It is 'packet classification type' defined in data sheet, and widely used.
> 
> Widely used? No it seems to be an i40e naming.
> Which datasheet are you pointing?

Sorry, it is widely used in i40e. That might not so widely for the whole DPDK.
The datasheet I mentioned is the Intel(r) 40G NIC datasheet.

> 
> > It is not just for RSS only, it can be used for flow director possibly.
> > That's why I think it would be better to rename it with PCTYPE names.
> 
> At least, you should add a comment in the code to explain the meaning.

OK, good comments!

> 
> Thank you
> --
> Thomas

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

* Re: [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl'
  2014-07-24  7:56   ` Thomas Monjalon
@ 2014-07-24  8:49     ` Zhang, Helin
  0 siblings, 0 replies; 17+ messages in thread
From: Zhang, Helin @ 2014-07-24  8:49 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, July 24, 2014 3:57 PM
> To: Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: add new ops of
> 'check_command_supported' and 'rx_classification_filter_ctl'
> 
> 2014-07-24 14:42, Helin Zhang:
> > Two ops of 'check_command_supported' and 'rx_classification_filter_ctl'
> > are added.
> > * 'check_command_supported' is for capability discovery. In anothoer
> >   word, it is to check if specific feature/command is supported by
> >   the specific port.
> 
> This generic service is really needed to add NIC-specific functions.
> I'd suggest to name it "is_supported".
> 
I tried to name it as the same style of rte_cpu_check_supported().
As you indicated, 'is_commmand_supported' might be a better name.

> > * 'rx_classification_filter_ctl' is for receive classifcation filter
> >   configuring. e.g. hash function configuration, flow director
> >   configuration. It is a common API where a lot of commands can
> >   be implemented for different sub features.
> 
> Not sure about this one. You are hiding specific API in an opaque structure.
> By the way, it should be in another patch.
> 
We want to implement several common API for NIC specific features, to avoid creating quite a lot of ops in 'struct eth_dev_ops'.
The idea came from ioctl.

> > +/**
> > + * Check if the command is supported by an Ethernet device.
> > + *
> > + * @param port_id
> > + *   The port identifier of the Ethernet device.
> > + * @param cmd
> > + *   The command.
> > + *
> > + * @return
> > + *   - (> 0) The command is supported.
> > + *   - (0) The command is not supported.
> > + *   - (-ENOTSUP) if hardware doesn't support.
> > + *   - (-ENODEV) if <port_id> is invalid.
> > + */
> > +int rte_eth_dev_check_command_supported(uint8_t port_id, uint32_t
> cmd);
> 
> What are the possible commands?
> You should define enum/constants here.
> 
The idea came from ioctl(). Enum could be a choice. The commands was defined in rte_eth_features.h. Comments should be added here for telling that.

> --
> Thomas

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

* Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
  2014-07-24  8:14         ` Matthew Hall
@ 2014-07-24  8:54           ` Zhang, Helin
  0 siblings, 0 replies; 17+ messages in thread
From: Zhang, Helin @ 2014-07-24  8:54 UTC (permalink / raw)
  To: Matthew Hall, Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Matthew Hall [mailto:mhall@mhcomputing.net]
> Sent: Thursday, July 24, 2014 4:15 PM
> To: Thomas Monjalon; Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions
> 
> If no reboot of the card is needed then it's probably better to add it to one of
> the ethtool style APIs...
> --
> Sent from my mobile device.
> 
> On July 24, 2014 1:07:37 AM PDT, Thomas Monjalon
> <thomas.monjalon@6wind.com> wrote:
> >2014-07-24 01:01, Matthew Hall:
> >> On Thu, Jul 24, 2014 at 09:59:23AM +0200, Thomas Monjalon wrote:
> >> > Is it really a good idea to configure this kind of thing at build
> >time?
> >> > Maybe yes, I'm not sure.
> >>
> >> Whether it's safe to set at runtime probably depends what happens to
> >the card
> >> if it gets changed. Do you have to reset the card or the port? Or is
> >it OK if
> >> it's more dynamic?
> >
> >No, we can change configuration with rte_eth_dev_configure() before
> >initializing port. So it is truly configurable.
> >Requiring recompilation means it's not really configurable between 2
> >runs.
> >And it breaks binary packaging for Linux distributions.
> >
> >Many things in DPDK are configured at build time. But we should wonder
> >if it's really a good design.


Hi Thomas, Matt

Good points! Thank you guys!

Regards,
Helin

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

end of thread, other threads:[~2014-07-24  8:53 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-24  6:42 [dpdk-dev] [PATCH 0/5] Support configuring hash functions Helin Zhang
2014-07-24  6:42 ` [dpdk-dev] [PATCH 1/5] ethdev: Rename macros of packet classification type Helin Zhang
2014-07-24  7:48   ` Thomas Monjalon
2014-07-24  8:14     ` Zhang, Helin
2014-07-24  8:19       ` Thomas Monjalon
2014-07-24  8:23         ` Zhang, Helin
2014-07-24  6:42 ` [dpdk-dev] [PATCH 2/5] ethdev: add new ops of 'check_command_supported' and 'rx_classification_filter_ctl' Helin Zhang
2014-07-24  7:56   ` Thomas Monjalon
2014-07-24  8:49     ` Zhang, Helin
2014-07-24  6:42 ` [dpdk-dev] [PATCH 3/5] i40e: support selecting hash functions Helin Zhang
2014-07-24  7:59   ` Thomas Monjalon
2014-07-24  8:01     ` Matthew Hall
2014-07-24  8:07       ` Thomas Monjalon
2014-07-24  8:14         ` Matthew Hall
2014-07-24  8:54           ` Zhang, Helin
2014-07-24  6:42 ` [dpdk-dev] [PATCH 4/5] i40e: support configuring symmetric hash function Helin Zhang
2014-07-24  6:42 ` [dpdk-dev] [PATCH 5/5] app/testpmd: new commands for configuring hash functions Helin Zhang

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