From 8b3ee85efe11fd11a09e677f488f7ebed288b20f Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Sun, 7 May 2017 15:53:12 -0700 Subject: [PATCH] net/qede: fix RSS table entries for 100G adapter With the change in base APIs the logic for 100G handling needs to be adjusted to pass cid values instead for queue ids. The current API works assuming its queue id. Fixes: 69d7ba88f1a1 ("net/qede/base: use L2-handles for RSS configuration") Signed-off-by: Rasesh Mody --- drivers/net/qede/qede_eth_if.c | 27 ----------- drivers/net/qede/qede_eth_if.h | 2 - drivers/net/qede/qede_ethdev.c | 85 ++++++++++++++++++++++++++++------ drivers/net/qede/qede_ethdev.h | 1 + 4 files changed, 73 insertions(+), 42 deletions(-) diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c index 86bb1292b1..a3c0b13792 100644 --- a/drivers/net/qede/qede_eth_if.c +++ b/drivers/net/qede/qede_eth_if.c @@ -67,33 +67,6 @@ static int qed_stop_vport(struct ecore_dev *edev, uint8_t vport_id) return 0; } -bool qed_update_rss_parm_cmt(struct ecore_dev *edev, uint16_t *p_tbl) -{ - uint16_t max = 0, k; - bool rss_mode = 0; /* disable */ - int divisor; - - /* Find largest entry, since it's possible RSS needs to - * be disabled [in case only 1 queue per-hwfn] - */ - for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++) - max = (max > p_tbl[k]) ? max : p_tbl[k]; - - /* Either fix RSS values or disable RSS */ - if (edev->num_hwfns < max + 1) { - divisor = (max + edev->num_hwfns - 1) / edev->num_hwfns; - DP_VERBOSE(edev, ECORE_MSG_SPQ, - "CMT - fixing RSS values (modulo %02x)\n", - divisor); - for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++) - p_tbl[k] = p_tbl[k] % divisor; - - rss_mode = 1; - } - - return rss_mode; -} - static int qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params) { diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h index d845bac9bb..097e0257c4 100644 --- a/drivers/net/qede/qede_eth_if.h +++ b/drivers/net/qede/qede_eth_if.h @@ -129,6 +129,4 @@ const struct qed_eth_ops *qed_get_eth_ops(void); int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev, enum qed_filter_rx_mode_type type); -bool qed_update_rss_parm_cmt(struct ecore_dev *edev, uint16_t *p_tbl); - #endif /* _QEDE_ETH_IF_H */ diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 4ef57658a9..7501eb20ba 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -1576,6 +1576,61 @@ static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev, return 0; } +static bool qede_update_rss_parm_cmt(struct ecore_dev *edev, + struct ecore_rss_params *rss) +{ + int i, fn; + bool rss_mode = 1; /* enable */ + struct ecore_queue_cid *cid; + struct ecore_rss_params *t_rss; + + /* In regular scenario, we'd simply need to take input handlers. + * But in CMT, we'd have to split the handlers according to the + * engine they were configured on. We'd then have to understand + * whether RSS is really required, since 2-queues on CMT doesn't + * require RSS. + */ + + /* CMT should be round-robin */ + for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) { + cid = rss->rss_ind_table[i]; + + if (cid->p_owner == ECORE_LEADING_HWFN(edev)) + t_rss = &rss[0]; + else + t_rss = &rss[1]; + + t_rss->rss_ind_table[i / edev->num_hwfns] = cid; + } + + t_rss = &rss[1]; + t_rss->update_rss_ind_table = 1; + t_rss->rss_table_size_log = 7; + t_rss->update_rss_config = 1; + + /* Make sure RSS is actually required */ + for_each_hwfn(edev, fn) { + for (i = 1; i < ECORE_RSS_IND_TABLE_SIZE / edev->num_hwfns; + i++) { + if (rss[fn].rss_ind_table[i] != + rss[fn].rss_ind_table[0]) + break; + } + + if (i == ECORE_RSS_IND_TABLE_SIZE / edev->num_hwfns) { + DP_INFO(edev, + "CMT - 1 queue per-hwfn; Disabling RSS\n"); + rss_mode = 0; + goto out; + } + } + +out: + t_rss->rss_enable = rss_mode; + + return rss_mode; +} + int qede_rss_reta_update(struct rte_eth_dev *eth_dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) @@ -1583,11 +1638,11 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev, struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); struct ecore_sp_vport_update_params vport_update_params; - struct ecore_rss_params params; + struct ecore_rss_params *params; struct ecore_hwfn *p_hwfn; uint16_t i, idx, shift; uint8_t entry; - int rc; + int rc = 0; if (reta_size > ETH_RSS_RETA_SIZE_128) { DP_ERR(edev, "reta_size %d is not supported by hardware\n", @@ -1596,7 +1651,8 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev, } memset(&vport_update_params, 0, sizeof(vport_update_params)); - memset(¶ms, 0, sizeof(params)); + params = rte_zmalloc("qede_rss", sizeof(*params) * edev->num_hwfns, + RTE_CACHE_LINE_SIZE); for (i = 0; i < reta_size; i++) { idx = i / RTE_RETA_GROUP_SIZE; @@ -1604,24 +1660,25 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev, if (reta_conf[idx].mask & (1ULL << shift)) { entry = reta_conf[idx].reta[shift]; /* Pass rxq handles to ecore */ - params.rss_ind_table[i] = + params->rss_ind_table[i] = qdev->fp_array[entry].rxq->handle; /* Update the local copy for RETA query command */ qdev->rss_ind_table[i] = entry; } } + params->update_rss_ind_table = 1; + params->rss_table_size_log = 7; + params->update_rss_config = 1; + /* Fix up RETA for CMT mode device */ if (edev->num_hwfns > 1) - qdev->rss_enable = qed_update_rss_parm_cmt(edev, - params.rss_ind_table[0]); - params.update_rss_ind_table = 1; - params.rss_table_size_log = 7; - params.update_rss_config = 1; + qdev->rss_enable = qede_update_rss_parm_cmt(edev, + params); vport_update_params.vport_id = 0; /* Use the current value of rss_enable */ - params.rss_enable = qdev->rss_enable; - vport_update_params.rss_params = ¶ms; + params->rss_enable = qdev->rss_enable; + vport_update_params.rss_params = params; for_each_hwfn(edev, i) { p_hwfn = &edev->hwfns[i]; @@ -1630,11 +1687,13 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev, ECORE_SPQ_MODE_EBLOCK, NULL); if (rc) { DP_ERR(edev, "vport-update for RSS failed\n"); - return rc; + goto out; } } - return 0; +out: + rte_free(params); + return rc; } static int qede_rss_reta_query(struct rte_eth_dev *eth_dev, diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h index 26b63320c9..e4323a0dd6 100644 --- a/drivers/net/qede/qede_ethdev.h +++ b/drivers/net/qede/qede_ethdev.h @@ -37,6 +37,7 @@ #include "base/ecore_sp_commands.h" #include "base/ecore_l2.h" #include "base/ecore_dev_api.h" +#include "base/ecore_l2.h" #include "qede_logs.h" #include "qede_if.h" -- 2.20.1