|
|
a6040a |
From 82d2ba939b9bbd99ed25ea06d5a690cf96489ea9 Mon Sep 17 00:00:00 2001
|
|
|
a6040a |
From: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
a6040a |
Date: Fri, 24 Nov 2017 15:31:49 +0000
|
|
|
a6040a |
Subject: [PATCH] net/nfp: configure default RSS reta table
|
|
|
a6040a |
|
|
|
a6040a |
Some apps can enable RSS but not update the reta table nor the hash.
|
|
|
a6040a |
This patch adds a default reta table setup based on total number of
|
|
|
a6040a |
configured rx queues. The hash key is dependent on how the app
|
|
|
a6040a |
configures the rx_conf struct.
|
|
|
a6040a |
|
|
|
a6040a |
Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
a6040a |
(cherry picked from commit f92e94478803c2307e68bf1023e6b49106bc843d)
|
|
|
a6040a |
---
|
|
|
a6040a |
drivers/net/nfp/nfp_net.c | 154 +++++++++++++++++++++++++++++++-------
|
|
|
a6040a |
1 file changed, 125 insertions(+), 29 deletions(-)
|
|
|
a6040a |
|
|
|
a6040a |
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
index 3a63b1ca3..559230ab6 100644
|
|
|
a6040a |
--- a/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
+++ b/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
@@ -101,6 +101,15 @@ static void nfp_net_stop(struct rte_eth_dev *dev);
|
|
|
a6040a |
static uint16_t nfp_net_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
|
|
|
a6040a |
uint16_t nb_pkts);
|
|
|
a6040a |
|
|
|
a6040a |
+static int nfp_net_rss_config_default(struct rte_eth_dev *dev);
|
|
|
a6040a |
+static int nfp_net_rss_hash_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
+ struct rte_eth_rss_conf *rss_conf);
|
|
|
a6040a |
+static int nfp_net_rss_reta_write(struct rte_eth_dev *dev,
|
|
|
a6040a |
+ struct rte_eth_rss_reta_entry64 *reta_conf,
|
|
|
a6040a |
+ uint16_t reta_size);
|
|
|
a6040a |
+static int nfp_net_rss_hash_write(struct rte_eth_dev *dev,
|
|
|
a6040a |
+ struct rte_eth_rss_conf *rss_conf);
|
|
|
a6040a |
+
|
|
|
a6040a |
/* The offset of the queue controller queues in the PCIe Target */
|
|
|
a6040a |
#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff)))
|
|
|
a6040a |
|
|
|
a6040a |
@@ -721,6 +730,8 @@ nfp_net_start(struct rte_eth_dev *dev)
|
|
|
a6040a |
{
|
|
|
a6040a |
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
|
|
|
a6040a |
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
|
|
|
a6040a |
+ struct rte_eth_conf *dev_conf;
|
|
|
a6040a |
+ struct rte_eth_rxmode *rxmode;
|
|
|
a6040a |
uint32_t new_ctrl, update = 0;
|
|
|
a6040a |
struct nfp_net_hw *hw;
|
|
|
a6040a |
uint32_t intr_vector;
|
|
|
a6040a |
@@ -770,6 +781,19 @@ nfp_net_start(struct rte_eth_dev *dev)
|
|
|
a6040a |
|
|
|
a6040a |
rte_intr_enable(intr_handle);
|
|
|
a6040a |
|
|
|
a6040a |
+ dev_conf = &dev->data->dev_conf;
|
|
|
a6040a |
+ rxmode = &dev_conf->rxmode;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* Checking RX mode */
|
|
|
a6040a |
+ if (rxmode->mq_mode & ETH_MQ_RX_RSS) {
|
|
|
a6040a |
+ if (hw->cap & NFP_NET_CFG_CTRL_RSS) {
|
|
|
a6040a |
+ if (!nfp_net_rss_config_default(dev))
|
|
|
a6040a |
+ update |= NFP_NET_CFG_UPDATE_RSS;
|
|
|
a6040a |
+ } else {
|
|
|
a6040a |
+ PMD_INIT_LOG(INFO, "RSS not supported");
|
|
|
a6040a |
+ return -EINVAL;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ }
|
|
|
a6040a |
/* Enable device */
|
|
|
a6040a |
new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_ENABLE;
|
|
|
a6040a |
|
|
|
a6040a |
@@ -2329,22 +2353,17 @@ nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask)
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
-/* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */
|
|
|
a6040a |
static int
|
|
|
a6040a |
-nfp_net_reta_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
+nfp_net_rss_reta_write(struct rte_eth_dev *dev,
|
|
|
a6040a |
struct rte_eth_rss_reta_entry64 *reta_conf,
|
|
|
a6040a |
uint16_t reta_size)
|
|
|
a6040a |
{
|
|
|
a6040a |
uint32_t reta, mask;
|
|
|
a6040a |
int i, j;
|
|
|
a6040a |
int idx, shift;
|
|
|
a6040a |
- uint32_t update;
|
|
|
a6040a |
struct nfp_net_hw *hw =
|
|
|
a6040a |
NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
|
|
a6040a |
|
|
|
a6040a |
- if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS))
|
|
|
a6040a |
- return -EINVAL;
|
|
|
a6040a |
-
|
|
|
a6040a |
if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) {
|
|
|
a6040a |
RTE_LOG(ERR, PMD, "The size of hash lookup table configured "
|
|
|
a6040a |
"(%d) doesn't match the number hardware can supported "
|
|
|
a6040a |
@@ -2381,6 +2400,26 @@ nfp_net_reta_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
nn_cfg_writel(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift,
|
|
|
a6040a |
reta);
|
|
|
a6040a |
}
|
|
|
a6040a |
+ return 0;
|
|
|
a6040a |
+}
|
|
|
a6040a |
+
|
|
|
a6040a |
+/* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */
|
|
|
a6040a |
+static int
|
|
|
a6040a |
+nfp_net_reta_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
+ struct rte_eth_rss_reta_entry64 *reta_conf,
|
|
|
a6040a |
+ uint16_t reta_size)
|
|
|
a6040a |
+{
|
|
|
a6040a |
+ struct nfp_net_hw *hw =
|
|
|
a6040a |
+ NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
|
|
a6040a |
+ uint32_t update;
|
|
|
a6040a |
+ int ret;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS))
|
|
|
a6040a |
+ return -EINVAL;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ ret = nfp_net_rss_reta_write(dev, reta_conf, reta_size);
|
|
|
a6040a |
+ if (ret != 0)
|
|
|
a6040a |
+ return ret;
|
|
|
a6040a |
|
|
|
a6040a |
update = NFP_NET_CFG_UPDATE_RSS;
|
|
|
a6040a |
|
|
|
a6040a |
@@ -2439,33 +2478,24 @@ nfp_net_reta_query(struct rte_eth_dev *dev,
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
static int
|
|
|
a6040a |
-nfp_net_rss_hash_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
+nfp_net_rss_hash_write(struct rte_eth_dev *dev,
|
|
|
a6040a |
struct rte_eth_rss_conf *rss_conf)
|
|
|
a6040a |
{
|
|
|
a6040a |
- uint32_t update;
|
|
|
a6040a |
+ struct nfp_net_hw *hw;
|
|
|
a6040a |
+ uint64_t rss_hf;
|
|
|
a6040a |
uint32_t cfg_rss_ctrl = 0;
|
|
|
a6040a |
uint8_t key;
|
|
|
a6040a |
- uint64_t rss_hf;
|
|
|
a6040a |
int i;
|
|
|
a6040a |
- struct nfp_net_hw *hw;
|
|
|
a6040a |
|
|
|
a6040a |
hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
|
|
a6040a |
|
|
|
a6040a |
- rss_hf = rss_conf->rss_hf;
|
|
|
a6040a |
-
|
|
|
a6040a |
- /* Checking if RSS is enabled */
|
|
|
a6040a |
- if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) {
|
|
|
a6040a |
- if (rss_hf != 0) { /* Enable RSS? */
|
|
|
a6040a |
- RTE_LOG(ERR, PMD, "RSS unsupported\n");
|
|
|
a6040a |
- return -EINVAL;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- return 0; /* Nothing to do */
|
|
|
a6040a |
+ /* Writing the key byte a byte */
|
|
|
a6040a |
+ for (i = 0; i < rss_conf->rss_key_len; i++) {
|
|
|
a6040a |
+ memcpy(&key, &rss_conf->rss_key[i], 1);
|
|
|
a6040a |
+ nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
- if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) {
|
|
|
a6040a |
- RTE_LOG(ERR, PMD, "hash key too long\n");
|
|
|
a6040a |
- return -EINVAL;
|
|
|
a6040a |
- }
|
|
|
a6040a |
+ rss_hf = rss_conf->rss_hf;
|
|
|
a6040a |
|
|
|
a6040a |
if (rss_hf & ETH_RSS_IPV4)
|
|
|
a6040a |
cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4 |
|
|
|
a6040a |
@@ -2483,15 +2513,40 @@ nfp_net_rss_hash_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
/* configuring where to apply the RSS hash */
|
|
|
a6040a |
nn_cfg_writel(hw, NFP_NET_CFG_RSS_CTRL, cfg_rss_ctrl);
|
|
|
a6040a |
|
|
|
a6040a |
- /* Writing the key byte a byte */
|
|
|
a6040a |
- for (i = 0; i < rss_conf->rss_key_len; i++) {
|
|
|
a6040a |
- memcpy(&key, &rss_conf->rss_key[i], 1);
|
|
|
a6040a |
- nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key);
|
|
|
a6040a |
- }
|
|
|
a6040a |
-
|
|
|
a6040a |
/* Writing the key size */
|
|
|
a6040a |
nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY_SZ, rss_conf->rss_key_len);
|
|
|
a6040a |
|
|
|
a6040a |
+ return 0;
|
|
|
a6040a |
+}
|
|
|
a6040a |
+
|
|
|
a6040a |
+static int
|
|
|
a6040a |
+nfp_net_rss_hash_update(struct rte_eth_dev *dev,
|
|
|
a6040a |
+ struct rte_eth_rss_conf *rss_conf)
|
|
|
a6040a |
+{
|
|
|
a6040a |
+ uint32_t update;
|
|
|
a6040a |
+ uint64_t rss_hf;
|
|
|
a6040a |
+ struct nfp_net_hw *hw;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ rss_hf = rss_conf->rss_hf;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* Checking if RSS is enabled */
|
|
|
a6040a |
+ if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) {
|
|
|
a6040a |
+ if (rss_hf != 0) { /* Enable RSS? */
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "RSS unsupported\n");
|
|
|
a6040a |
+ return -EINVAL;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ return 0; /* Nothing to do */
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "hash key too long\n");
|
|
|
a6040a |
+ return -EINVAL;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nfp_net_rss_hash_write(dev, rss_conf);
|
|
|
a6040a |
+
|
|
|
a6040a |
update = NFP_NET_CFG_UPDATE_RSS;
|
|
|
a6040a |
|
|
|
a6040a |
if (nfp_net_reconfig(hw, hw->ctrl, update) < 0)
|
|
|
a6040a |
@@ -2548,6 +2603,47 @@ nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev,
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
+static int
|
|
|
a6040a |
+nfp_net_rss_config_default(struct rte_eth_dev *dev)
|
|
|
a6040a |
+{
|
|
|
a6040a |
+ struct rte_eth_conf *dev_conf;
|
|
|
a6040a |
+ struct rte_eth_rss_conf rss_conf;
|
|
|
a6040a |
+ struct rte_eth_rss_reta_entry64 nfp_reta_conf[2];
|
|
|
a6040a |
+ uint16_t rx_queues = dev->data->nb_rx_queues;
|
|
|
a6040a |
+ uint16_t queue;
|
|
|
a6040a |
+ int i, j, ret;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "setting default RSS conf for %u queues\n",
|
|
|
a6040a |
+ rx_queues);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nfp_reta_conf[0].mask = ~0x0;
|
|
|
a6040a |
+ nfp_reta_conf[1].mask = ~0x0;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ queue = 0;
|
|
|
a6040a |
+ for (i = 0; i < 0x40; i += 8) {
|
|
|
a6040a |
+ for (j = i; j < (i + 8); j++) {
|
|
|
a6040a |
+ nfp_reta_conf[0].reta[j] = queue;
|
|
|
a6040a |
+ nfp_reta_conf[1].reta[j] = queue++;
|
|
|
a6040a |
+ queue %= rx_queues;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ ret = nfp_net_rss_reta_write(dev, nfp_reta_conf, 0x80);
|
|
|
a6040a |
+ if (ret != 0)
|
|
|
a6040a |
+ return ret;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ dev_conf = &dev->data->dev_conf;
|
|
|
a6040a |
+ if (!dev_conf) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "wrong rss conf");
|
|
|
a6040a |
+ return -EINVAL;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ rss_conf = dev_conf->rx_adv_conf.rss_conf;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ ret = nfp_net_rss_hash_write(dev, &rss_conf);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ return ret;
|
|
|
a6040a |
+}
|
|
|
a6040a |
+
|
|
|
a6040a |
+
|
|
|
a6040a |
/* Initialise and register driver with DPDK Application */
|
|
|
a6040a |
static const struct eth_dev_ops nfp_net_eth_dev_ops = {
|
|
|
a6040a |
.dev_configure = nfp_net_configure,
|
|
|
a6040a |
--
|
|
|
a6040a |
2.17.0
|
|
|
a6040a |
|