From: Harish Patil <harish.pa...@qlogic.com>

This patch contains few RSS related changes as follows:

o Fix inadvarent initializing of rss_params outside of the
  if block in qed_update_vport() which could cause FW exception.

o Fix disabling of RSS when hash function is 0.

o Rename qede_config_rss() to qede_check_vport_rss_enable()
  for better clarity.

o Avoid code duplication using a helper function
  qede_init_rss_caps().

Fixes: 4c98f27 ("qede: support RSS hash configuration")
Fixes: 2ea6f76 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil at qlogic.com>
---
 doc/guides/nics/qede.rst       |    2 +-
 drivers/net/qede/qede_eth_if.c |    2 +-
 drivers/net/qede/qede_ethdev.c |   61 +++++++++++++++++++++++-----------------
 drivers/net/qede/qede_ethdev.h |   10 +++++++
 drivers/net/qede/qede_rxtx.c   |   42 +++++++++------------------
 5 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index 5b921cc..5e31c11 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -51,7 +51,7 @@ Supported Features
 - VLAN offload - Filtering and stripping
 - Stateless checksum offloads (IPv4/TCP/UDP)
 - Multiple Rx/Tx queues
-- RSS (with user configurable table/key)
+- RSS (with RETA/hash table/key)
 - TSS
 - Multiple MAC address
 - Default pause flow control
diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index b74ec19..fea18d5 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -142,8 +142,8 @@ qed_update_vport(struct ecore_dev *edev, struct 
qed_update_vport_params *params)
                       ECORE_RSS_IND_TABLE_SIZE * sizeof(uint16_t));
                rte_memcpy(sp_rss_params.rss_key, params->rss_params.rss_key,
                       ECORE_RSS_KEY_SIZE * sizeof(uint32_t));
+               sp_params.rss_params = &sp_rss_params;
        }
-       sp_params.rss_params = &sp_rss_params;

        for_each_hwfn(edev, i) {
                struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 05a9b07..4cba035 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -531,7 +531,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
        struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
-       int rc;
+       int rc, i, j;

        PMD_INIT_FUNC_TRACE(edev);

@@ -1031,42 +1031,51 @@ qede_dev_supported_ptypes_get(struct rte_eth_dev 
*eth_dev)
        return NULL;
 }

-int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
-                        struct rte_eth_rss_conf *rss_conf)
+void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
+{
+       *rss_caps = 0;
+       *rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
+       *rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
+       *rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
+       *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
+       *rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
+       *rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+}
+
+static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
+                               struct rte_eth_rss_conf *rss_conf)
 {
        struct qed_update_vport_params vport_update_params;
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
-       uint8_t rss_caps;
        uint32_t *key = (uint32_t *)rss_conf->rss_key;
        uint64_t hf = rss_conf->rss_hf;
        int i;

-       if (hf == 0)
-               DP_ERR(edev, "hash function 0 will disable RSS\n");
+       memset(&vport_update_params, 0, sizeof(vport_update_params));

-       rss_caps = 0;
-       rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
-       rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
-       rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+       if (hf != 0) {
+               /* Enable RSS */
+               qede_init_rss_caps(&qdev->rss_params.rss_caps, hf);
+               memcpy(&vport_update_params.rss_params, &qdev->rss_params,
+                      sizeof(vport_update_params.rss_params));
+               if (key)
+                       memcpy(qdev->rss_params.rss_key, rss_conf->rss_key,
+                              rss_conf->rss_key_len);
+               vport_update_params.update_rss_flg = 1;
+               qdev->rss_enabled = 1;
+       } else {
+               /* Disable RSS */
+               qdev->rss_enabled = 0;
+       }

        /* If the mapping doesn't fit any supported, return */
-       if (rss_caps == 0 && hf != 0)
+       if (qdev->rss_params.rss_caps == 0 && hf != 0)
                return -EINVAL;

-       memset(&vport_update_params, 0, sizeof(vport_update_params));
-
-       if (key != NULL)
-               memcpy(qdev->rss_params.rss_key, rss_conf->rss_key,
-                      rss_conf->rss_key_len);
+       DP_INFO(edev, "%s\n", (vport_update_params.update_rss_flg) ?
+                               "Enabling RSS" : "Disabling RSS");

-       qdev->rss_params.rss_caps = rss_caps;
-       memcpy(&vport_update_params.rss_params, &qdev->rss_params,
-              sizeof(vport_update_params.rss_params));
-       vport_update_params.update_rss_flg = 1;
        vport_update_params.vport_id = 0;

        return qdev->ops->vport_update(edev, &vport_update_params);
@@ -1104,9 +1113,9 @@ int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
        return 0;
 }

-int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
-                        struct rte_eth_rss_reta_entry64 *reta_conf,
-                        uint16_t reta_size)
+static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
+                               struct rte_eth_rss_reta_entry64 *reta_conf,
+                               uint16_t reta_size)
 {
        struct qed_update_vport_params vport_update_params;
        struct qede_dev *qdev = eth_dev->data->dev_private;
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 526d3be..d1daa44 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -156,6 +156,16 @@ struct qede_dev {
 static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
                                uint16_t vlan_id, int on);

+static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
+                               struct rte_eth_rss_conf *rss_conf);
+
+static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
+                               struct rte_eth_rss_reta_entry64 *reta_conf,
+                               uint16_t reta_size);
+
+/* Non-static functions */
+void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf);
+
 int qed_fill_eth_dev_info(struct ecore_dev *edev,
                                 struct qed_dev_eth_info *info);
 int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up);
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 9df0d13..681232f 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -502,9 +502,9 @@ static void qede_prandom_bytes(uint32_t *buff, size_t bytes)
                buff[i] = rand();
 }

-static int
-qede_config_rss(struct rte_eth_dev *eth_dev,
-               struct qed_update_vport_rss_params *rss_params)
+static bool
+qede_check_vport_rss_enable(struct rte_eth_dev *eth_dev,
+                           struct qed_update_vport_rss_params *rss_params)
 {
        struct rte_eth_rss_conf rss_conf;
        enum rte_eth_rx_mq_mode mode = eth_dev->data->dev_conf.rxmode.mq_mode;
@@ -515,29 +515,25 @@ qede_config_rss(struct rte_eth_dev *eth_dev,
        uint64_t hf;
        uint32_t *key;

+       PMD_INIT_FUNC_TRACE(edev);
+
        rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
        key = (uint32_t *)rss_conf.rss_key;
        hf = rss_conf.rss_hf;
-       PMD_INIT_FUNC_TRACE(edev);

        /* Check if RSS conditions are met.
         * Note: Even though its meaningless to enable RSS with one queue, it
         * could be used to produce RSS Hash, so skipping that check.
         */
-
        if (!(mode & ETH_MQ_RX_RSS)) {
                DP_INFO(edev, "RSS flag is not set\n");
-               return -EINVAL;
+               return false;
        }

-       DP_INFO(edev, "RSS flag is set\n");
-
-       if (rss_conf.rss_hf == 0)
-               DP_NOTICE(edev, false, "RSS hash function = 0, disables RSS\n");
-
-       if (rss_conf.rss_key != NULL)
-               memcpy(qdev->rss_params.rss_key, rss_conf.rss_key,
-                      rss_conf.rss_key_len);
+       if (hf == 0) {
+               DP_INFO(edev, "Request to disable RSS\n");
+               return false;
+       }

        memset(rss_params, 0, sizeof(*rss_params));

@@ -545,25 +541,18 @@ qede_config_rss(struct rte_eth_dev *eth_dev,
                rss_params->rss_ind_table[i] = qede_rxfh_indir_default(i,
                                                        QEDE_RSS_CNT(qdev));

-       /* key and protocols */
-       if (rss_conf.rss_key == NULL)
+       if (!key)
                qede_prandom_bytes(rss_params->rss_key,
                                   sizeof(rss_params->rss_key));
        else
                memcpy(rss_params->rss_key, rss_conf.rss_key,
                       rss_conf.rss_key_len);

-       rss_caps = 0;
-       rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
-       rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
-       rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
-       rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+       qede_init_rss_caps(&rss_caps, hf);

        rss_params->rss_caps = rss_caps;

-       DP_INFO(edev, "RSS check passes\n");
+       DP_INFO(edev, "RSS conditions are met\n");

        return 0;
 }
@@ -663,14 +652,11 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, 
bool clear_stats)
                vport_update_params.tx_switching_flg = 1;
        }

-       if (!qede_config_rss(eth_dev, rss_params)) {
+       if (qede_check_vport_rss_enable(eth_dev, rss_params)) {
                vport_update_params.update_rss_flg = 1;
-
                qdev->rss_enabled = 1;
-               DP_INFO(edev, "Updating RSS flag\n");
        } else {
                qdev->rss_enabled = 0;
-               DP_INFO(edev, "Not Updating RSS flag\n");
        }

        rte_memcpy(&vport_update_params.rss_params, rss_params,
-- 
1.7.10.3

Reply via email to