[dpdk-dev] [PATCH] net/qede: fix RSS table entries for 100G adapter

Rasesh Mody rasesh.mody at cavium.com
Mon May 8 00:53:12 CEST 2017


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 <rasesh.mody at cavium.com>
---
 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 86bb129..a3c0b13 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 d845bac..097e025 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -129,6 +129,4 @@ struct qed_eth_ops {
 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 4ef5765..7501eb2 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(&params, 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 26b6332..e4323a0 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"
-- 
1.7.10.3



More information about the dev mailing list