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 = ð_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