All of lore.kernel.org
 help / color / mirror / Atom feed
From: alvinx.zhang@intel.com
To: dev@dpdk.org
Cc: xiaolong.ye@intel.com
Subject: [dpdk-dev] [PATCH v4 08/11] net/igc: implement RSS API
Date: Wed, 15 Apr 2020 16:48:07 +0800	[thread overview]
Message-ID: <20200415084810.20816-9-alvinx.zhang@intel.com> (raw)
In-Reply-To: <20200415084810.20816-1-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>

V4: Modify codes according to comments.
---
 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 a364e04..23434af 100644
--- a/doc/guides/nics/features/igc.ini
+++ b/doc/guides/nics/features/igc.ini
@@ -28,6 +28,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 c31c3eb..baef681 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -217,6 +217,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,
@@ -265,6 +275,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,
 };
 
 /*
@@ -2188,6 +2202,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 & (1u << 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 & (1u << 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 d63890f..e8fd1b1 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 911fdd0..5ef5b0d 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -847,7 +847,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 1b66b3f..63b19f5 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-04-15  8:50 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-13  6:30 [dpdk-dev] [PATCH v3 00/11] igc pmd alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 01/11] net/igc: add igc PMD alvinx.zhang
2020-04-13 15:19   ` Stephen Hemminger
2020-04-15  8:47   ` [dpdk-dev] [PATCH v4 00/11] " alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 01/11] net/igc: add " alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 02/11] net/igc: support device initialization alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 03/11] net/igc: implement device base ops alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 04/11] net/igc: support reception and transmission of packets alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 05/11] net/igc: enable statistics alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 06/11] net/igc: enable Rx queue interrupts alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 07/11] net/igc: implement flow control ops alvinx.zhang
2020-04-15  8:48     ` alvinx.zhang [this message]
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 09/11] net/igc: implement feature of VLAN alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 10/11] net/igc: implement MAC-loopback mode alvinx.zhang
2020-04-15  8:48     ` [dpdk-dev] [PATCH v4 11/11] net/igc: implement flow API alvinx.zhang
2020-04-15 11:14     ` [dpdk-dev] [PATCH v4 00/11] igc PMD Ferruh Yigit
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 02/11] net/igc: support device initialization alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 03/11] net/igc: implement device base ops alvinx.zhang
2020-04-13 15:23   ` Stephen Hemminger
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 04/11] net/igc: support reception and transmission of packets alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 05/11] net/igc: enable statistics alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 06/11] net/igc: enable Rx queue interrupts alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 07/11] net/igc: implement flow control ops alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 08/11] net/igc: implement RSS API alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 09/11] net/igc: implement feature of VLAN alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 10/11] net/igc: implement MAC-loopback mode alvinx.zhang
2020-04-13  6:30 ` [dpdk-dev] [PATCH v3 11/11] net/igc: implement flow API alvinx.zhang

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=20200415084810.20816-9-alvinx.zhang@intel.com \
    --to=alvinx.zhang@intel.com \
    --cc=dev@dpdk.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.