From: alvinx.zhang@intel.com
To: dev@dpdk.org
Cc: xiaolong.ye@intel.com, Alvin Zhang <alvinx.zhang@intel.com>
Subject: [dpdk-dev] [PATCH v3 08/11] net/igc: implement RSS API
Date: Mon, 13 Apr 2020 14:30:34 +0800 [thread overview]
Message-ID: <20200413063037.13728-9-alvinx.zhang@intel.com> (raw)
In-Reply-To: <20200413063037.13728-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>
---
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 a135176..554c809 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 906fbcb..03998c0 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -845,7 +845,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 00ef512..82ca95e 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
next prev parent reply other threads:[~2020-04-13 6:33 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 ` [dpdk-dev] [PATCH v4 08/11] net/igc: implement RSS API alvinx.zhang
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 ` alvinx.zhang [this message]
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=20200413063037.13728-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 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).