DPDK patches and discussions
 help / color / mirror / Atom feed
From: alvinx.zhang@intel.com
To: dev@dpdk.org, xiaolong.ye@intel.com, haiyue.wang@intel.com,
	qi.z.zhang@intel.com, beilei.xing@intel.com
Subject: [dpdk-dev] [PATCH v2 08/14] net/igc: implement RSS API
Date: Fri, 20 Mar 2020 10:46:09 +0800	[thread overview]
Message-ID: <1584672375-376187-9-git-send-email-alvinx.zhang@intel.com> (raw)
In-Reply-To: <1584672375-376187-1-git-send-email-alvinx.zhang@intel.com>

From: Alvin Zhang <alvinx.zhang@intel.com>

Below ops are added:
reta_update
reta_query
rss_hash_update
rss_hash_conf_get

Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
---
 doc/guides/nics/features/igc.ini |   2 +
 drivers/net/igc/igc_ethdev.c     | 171 +++++++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h     |   9 +++
 drivers/net/igc/igc_txrx.c       |   2 +-
 drivers/net/igc/igc_txrx.h       |   2 +
 5 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/igc.ini b/doc/guides/nics/features/igc.ini
index 6e21c5f..81d2a3b 100644
--- a/doc/guides/nics/features/igc.ini
+++ b/doc/guides/nics/features/igc.ini
@@ -27,6 +27,8 @@ Extended stats       = Y
 Stats per queue      = Y
 Rx interrupt         = Y
 Flow control         = Y
+RSS key update       = Y
+RSS reta update      = Y
 Linux UIO            = Y
 Linux VFIO           = Y
 x86-64               = Y
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index d2cb845..33bef51 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -210,6 +210,16 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 eth_igc_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
 static int
 eth_igc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
+static int eth_igc_rss_reta_update(struct rte_eth_dev *dev,
+			struct rte_eth_rss_reta_entry64 *reta_conf,
+			uint16_t reta_size);
+static int eth_igc_rss_reta_query(struct rte_eth_dev *dev,
+		       struct rte_eth_rss_reta_entry64 *reta_conf,
+		       uint16_t reta_size);
+static int eth_igc_rss_hash_update(struct rte_eth_dev *dev,
+			struct rte_eth_rss_conf *rss_conf);
+static int eth_igc_rss_hash_conf_get(struct rte_eth_dev *dev,
+			struct rte_eth_rss_conf *rss_conf);
 
 static const struct eth_dev_ops eth_igc_ops = {
 	.dev_configure		= eth_igc_configure,
@@ -258,6 +268,10 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 	.rx_queue_intr_disable	= eth_igc_rx_queue_intr_disable,
 	.flow_ctrl_get		= eth_igc_flow_ctrl_get,
 	.flow_ctrl_set		= eth_igc_flow_ctrl_set,
+	.reta_update		= eth_igc_rss_reta_update,
+	.reta_query		= eth_igc_rss_reta_query,
+	.rss_hash_update	= eth_igc_rss_hash_update,
+	.rss_hash_conf_get	= eth_igc_rss_hash_conf_get,
 };
 
 /*
@@ -2181,6 +2195,163 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 }
 
 static int
+eth_igc_rss_reta_update(struct rte_eth_dev *dev,
+			struct rte_eth_rss_reta_entry64 *reta_conf,
+			uint16_t reta_size)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint16_t i;
+
+	if (reta_size != ETH_RSS_RETA_SIZE_128) {
+		PMD_DRV_LOG(ERR, "The size of RSS redirection table configured "
+			"(%d) doesn't match the number hardware can supported "
+			"(%d)", reta_size, ETH_RSS_RETA_SIZE_128);
+		return -EINVAL;
+	}
+
+	/* set redirection table */
+	for (i = 0; i < ETH_RSS_RETA_SIZE_128; i += IGC_RSS_RDT_REG_SIZE) {
+		union igc_rss_reta_reg reta, reg;
+		uint16_t idx, shift;
+		uint8_t j, mask;
+
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		mask = (uint8_t)((reta_conf[idx].mask >> shift) &
+				IGC_RSS_RDT_REG_SIZE_MASK);
+
+		/* if no need to update the register */
+		if (!mask)
+			continue;
+
+		/* check mask whether need to read the register value first */
+		if (mask == IGC_RSS_RDT_REG_SIZE_MASK)
+			reg.dword = 0;
+		else
+			reg.dword = IGC_READ_REG_LE_VALUE(hw,
+					IGC_RETA(i / IGC_RSS_RDT_REG_SIZE));
+
+		/* update the register */
+		for (j = 0; j < IGC_RSS_RDT_REG_SIZE; j++) {
+			if (mask & (0x1 << j))
+				reta.bytes[j] =
+					(uint8_t)reta_conf[idx].reta[shift + j];
+			else
+				reta.bytes[j] = reg.bytes[j];
+		}
+		IGC_WRITE_REG_LE_VALUE(hw,
+			IGC_RETA(i / IGC_RSS_RDT_REG_SIZE), reta.dword);
+	}
+
+	return 0;
+}
+
+static int
+eth_igc_rss_reta_query(struct rte_eth_dev *dev,
+		       struct rte_eth_rss_reta_entry64 *reta_conf,
+		       uint16_t reta_size)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint16_t i;
+
+	if (reta_size != ETH_RSS_RETA_SIZE_128) {
+		PMD_DRV_LOG(ERR, "The size of RSS redirection table configured "
+			"(%d) doesn't match the number hardware can supported "
+			"(%d)", reta_size, ETH_RSS_RETA_SIZE_128);
+		return -EINVAL;
+	}
+
+	/* read redirection table */
+	for (i = 0; i < ETH_RSS_RETA_SIZE_128; i += IGC_RSS_RDT_REG_SIZE) {
+		union igc_rss_reta_reg reta;
+		uint16_t idx, shift;
+		uint8_t j, mask;
+
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		mask = (uint8_t)((reta_conf[idx].mask >> shift) &
+				IGC_RSS_RDT_REG_SIZE_MASK);
+
+		/* if no need to read register */
+		if (!mask)
+			continue;
+
+		/* read register and get the queue index */
+		reta.dword = IGC_READ_REG_LE_VALUE(hw,
+				IGC_RETA(i / IGC_RSS_RDT_REG_SIZE));
+		for (j = 0; j < IGC_RSS_RDT_REG_SIZE; j++) {
+			if (mask & (0x1 << j))
+				reta_conf[idx].reta[shift + j] = reta.bytes[j];
+		}
+	}
+
+	return 0;
+}
+
+static int
+eth_igc_rss_hash_update(struct rte_eth_dev *dev,
+			struct rte_eth_rss_conf *rss_conf)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	igc_hw_rss_hash_set(hw, rss_conf);
+	return 0;
+}
+
+static int
+eth_igc_rss_hash_conf_get(struct rte_eth_dev *dev,
+			struct rte_eth_rss_conf *rss_conf)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint32_t *hash_key = (uint32_t *)rss_conf->rss_key;
+	uint32_t mrqc;
+	uint64_t rss_hf;
+
+	if (hash_key != NULL) {
+		int i;
+
+		/* if not enough space for store hash key */
+		if (rss_conf->rss_key_len != IGC_HKEY_SIZE) {
+			PMD_DRV_LOG(ERR, "RSS hash key size %u in parameter "
+				"doesn't match the hardware hash key size %u",
+				rss_conf->rss_key_len, IGC_HKEY_SIZE);
+			return -EINVAL;
+		}
+
+		/* read RSS key from register */
+		for (i = 0; i < IGC_HKEY_MAX_INDEX; i++)
+			hash_key[i] = IGC_READ_REG_LE_VALUE(hw, IGC_RSSRK(i));
+	}
+
+	/* get RSS functions configured in MRQC register */
+	mrqc = IGC_READ_REG(hw, IGC_MRQC);
+	if ((mrqc & IGC_MRQC_ENABLE_RSS_4Q) == 0)
+		return 0;
+
+	rss_hf = 0;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV4)
+		rss_hf |= ETH_RSS_IPV4;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV4_TCP)
+		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6)
+		rss_hf |= ETH_RSS_IPV6;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6_EX)
+		rss_hf |= ETH_RSS_IPV6_EX;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6_TCP)
+		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6_TCP_EX)
+		rss_hf |= ETH_RSS_IPV6_TCP_EX;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV4_UDP)
+		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6_UDP)
+		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+	if (mrqc & IGC_MRQC_RSS_FIELD_IPV6_UDP_EX)
+		rss_hf |= ETH_RSS_IPV6_UDP_EX;
+
+	rss_conf->rss_hf |= rss_hf;
+	return 0;
+}
+
+static int
 eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
index 63efa9c..6d4fc33 100644
--- a/drivers/net/igc/igc_ethdev.h
+++ b/drivers/net/igc/igc_ethdev.h
@@ -16,11 +16,20 @@
 extern "C" {
 #endif
 
+#define IGC_RSS_RDT_SIZD		128
 #define IGC_QUEUE_PAIRS_NUM		4
 
 #define IGC_HKEY_MAX_INDEX		10
 #define IGC_RSS_RDT_SIZD		128
 
+#define IGC_DEFAULT_REG_SIZE		4
+#define IGC_DEFAULT_REG_SIZE_MASK	0xf
+
+#define IGC_RSS_RDT_REG_SIZE		IGC_DEFAULT_REG_SIZE
+#define IGC_RSS_RDT_REG_SIZE_MASK	IGC_DEFAULT_REG_SIZE_MASK
+#define IGC_HKEY_REG_SIZE		IGC_DEFAULT_REG_SIZE
+#define IGC_HKEY_SIZE			(IGC_HKEY_REG_SIZE * IGC_HKEY_MAX_INDEX)
+
 /*
  * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
  * multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary.
diff --git a/drivers/net/igc/igc_txrx.c b/drivers/net/igc/igc_txrx.c
index fbfe86b..1d10f75 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -846,7 +846,7 @@ int eth_igc_rx_descriptor_status(void *rx_queue, uint16_t offset)
 	IGC_WRITE_REG(hw, IGC_MRQC, mrqc);
 }
 
-static void
+void
 igc_hw_rss_hash_set(struct igc_hw *hw, struct rte_eth_rss_conf *rss_conf)
 {
 	uint32_t *hash_key = (uint32_t *)rss_conf->rss_key;
diff --git a/drivers/net/igc/igc_txrx.h b/drivers/net/igc/igc_txrx.h
index 44fb9b3..e594acc 100644
--- a/drivers/net/igc/igc_txrx.h
+++ b/drivers/net/igc/igc_txrx.h
@@ -38,6 +38,8 @@ int eth_igc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 
 int igc_rx_init(struct rte_eth_dev *dev);
 void igc_tx_init(struct rte_eth_dev *dev);
+void
+igc_hw_rss_hash_set(struct igc_hw *hw, struct rte_eth_rss_conf *rss_conf);
 void eth_igc_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
 void eth_igc_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
-- 
1.8.3.1


  parent reply	other threads:[~2020-03-20  2:52 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-09  8:23 [dpdk-dev] [PATCH v1 01/15] net/igc: add igc PMD alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 02/15] net/igc: update base share codes alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 03/15] net/igc: device initialization alvinx.zhang
2020-03-12  4:42   ` Ye Xiaolong
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 04/15] net/igc: implement device base ops alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 05/15] net/igc: support reception and transmission of packets alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 06/15] net/igc: implement status API alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 07/15] net/igc: enable Rx queue interrupts alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 08/15] net/igc: implement flow control ops alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 09/15] net/igc: implement RSS API alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 10/15] net/igc: implement feature of VLAN alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 11/15] net/igc: implement ether-type filter alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 12/15] net/igc: implement 2-tuple filter alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 13/15] net/igc: implement TCP SYN filter alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 14/15] net/igc: implement hash filter configure alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 15/15] net/igc: implement flow API alvinx.zhang
2020-03-09  8:35 ` [dpdk-dev] [PATCH v1 01/15] net/igc: add igc PMD Ye Xiaolong
2020-03-12  3:09 ` Ye Xiaolong
2020-03-20  2:46 ` [dpdk-dev] [PATCH v2 00/14] " alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 01/14] net/igc: add " alvinx.zhang
2020-04-03 12:21     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 02/14] net/igc: support device initialization alvinx.zhang
2020-04-03 12:23     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 03/14] net/igc: implement device base ops alvinx.zhang
2020-04-03 12:24     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 04/14] net/igc: support reception and transmission of packets alvinx.zhang
2020-04-03 12:27     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 05/14] net/igc: implement status API alvinx.zhang
2020-04-03 12:24     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 06/14] net/igc: enable Rx queue interrupts alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 07/14] net/igc: implement flow control ops alvinx.zhang
2020-03-20  2:46   ` alvinx.zhang [this message]
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 09/14] net/igc: implement feature of VLAN alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 10/14] net/igc: implement ether-type filter alvinx.zhang
2020-04-03 12:26     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 11/14] net/igc: implement 2-tuple filter alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 12/14] net/igc: implement TCP SYN filter alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 13/14] net/igc: implement hash filter configure alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 14/14] net/igc: implement flow API alvinx.zhang
2020-04-03 12:26     ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1584672375-376187-9-git-send-email-alvinx.zhang@intel.com \
    --to=alvinx.zhang@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=dev@dpdk.org \
    --cc=haiyue.wang@intel.com \
    --cc=qi.z.zhang@intel.com \
    --cc=xiaolong.ye@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).