]> git.droids-corp.org - dpdk.git/commitdiff
net/qede: fix RSS table entries for 100G adapter
authorRasesh Mody <rasesh.mody@cavium.com>
Sun, 7 May 2017 22:53:12 +0000 (15:53 -0700)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 10 May 2017 16:07:15 +0000 (18:07 +0200)
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@cavium.com>
drivers/net/qede/qede_eth_if.c
drivers/net/qede/qede_eth_if.h
drivers/net/qede/qede_ethdev.c
drivers/net/qede/qede_ethdev.h

index 86bb1292b1840dc8eef5c72a91929f6733e1f53a..a3c0b13792ef9f4b7e3b403cbba950e01029ffb2 100644 (file)
@@ -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)
 {
index d845bac9bb9f24a15f375d0ef78b9072b7cfc548..097e0257c4732e5054809c106c041912b070a8d7 100644 (file)
@@ -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 */
index 4ef57658a9f31e48d306b05611cb9fe479863429..7501eb20bab5e1519696470bc1e6a75733a3ad2b 100644 (file)
@@ -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 = &params;
+       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,
index 26b63320c9b64016fc90815ba112dc352654ee14..e4323a0dd601888cd0e5b5907f350ae29fb93bc5 100644 (file)
@@ -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"