Allow the VFs to support symmetric RSS for any flow type. The symmetric
RSS will not be supported on PFs not advertising the ADV RSS Offload
flag (ADV_RSS_SUPPORT()), for example the E700 series (i40e).

Reviewed-by: Madhu Chittim <madhu.chit...@intel.com>
Signed-off-by: Ahmed Zaki <ahmed.z...@intel.com>
---
 .../net/ethernet/intel/iavf/iavf_adv_rss.c    |  8 +++--
 .../net/ethernet/intel/iavf/iavf_adv_rss.h    |  3 +-
 .../net/ethernet/intel/iavf/iavf_ethtool.c    | 33 ++++++++++++++++---
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c 
b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c
index 6edbf134b73f..a9e1da35e248 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.c
@@ -95,17 +95,21 @@ iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, 
u64 hash_flds)
  * @rss_cfg: the virtchnl message to be filled with RSS configuration setting
  * @packet_hdrs: the RSS configuration protocol header types
  * @hash_flds: the RSS configuration protocol hash fields
+ * @symm: if true, symmetric hash is required
  *
  * Returns 0 if the RSS configuration virtchnl message is filled successfully
  */
 int
 iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
-                         u32 packet_hdrs, u64 hash_flds)
+                         u32 packet_hdrs, u64 hash_flds, bool symm)
 {
        struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
        struct virtchnl_proto_hdr *hdr;
 
-       rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
+       if (symm)
+               rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
+       else
+               rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
 
        proto_hdrs->tunnel_level = 0;   /* always outer layer */
 
diff --git a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h 
b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
index 4d3be11af7aa..e31eb2afebea 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
+++ b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
@@ -80,13 +80,14 @@ struct iavf_adv_rss {
 
        u32 packet_hdrs;
        u64 hash_flds;
+       bool symm;
 
        struct virtchnl_rss_cfg cfg_msg;
 };
 
 int
 iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
-                         u32 packet_hdrs, u64 hash_flds);
+                         u32 packet_hdrs, u64 hash_flds, bool symm);
 struct iavf_adv_rss *
 iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs);
 void
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c 
b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index 90397293525f..62a3cf88189e 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -1550,6 +1550,17 @@ static u64 iavf_adv_rss_parse_hash_flds(struct 
ethtool_rxnfc *cmd)
 {
        u64 hfld = IAVF_ADV_RSS_HASH_INVALID;
 
+       /* Sanity check: if a symmetric hash is requested, then:
+        * 1 - no other fields besides IP src/dst and/or L4 src/dst
+        * 2 - If src is set, dst must also be set
+        */
+       if ((cmd->data & RXH_SYMMETRIC_XOR) &&
+           ((cmd->data & ~(RXH_SYMMETRIC_XOR | RXH_IP_SRC | RXH_IP_DST |
+             RXH_L4_B_0_1 | RXH_L4_B_2_3)) ||
+            (!!(cmd->data & RXH_IP_SRC) ^ !!(cmd->data & RXH_IP_DST)) ||
+            (!!(cmd->data & RXH_L4_B_0_1) ^ !!(cmd->data & RXH_L4_B_2_3))))
+               return hfld;
+
        if (cmd->data & RXH_IP_SRC || cmd->data & RXH_IP_DST) {
                switch (cmd->flow_type) {
                case TCP_V4_FLOW:
@@ -1618,6 +1629,7 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
        struct iavf_adv_rss *rss_old, *rss_new;
        bool rss_new_add = false;
        int count = 50, err = 0;
+       bool symm = false;
        u64 hash_flds;
        u32 hdrs;
 
@@ -1632,11 +1644,15 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
        if (hash_flds == IAVF_ADV_RSS_HASH_INVALID)
                return -EINVAL;
 
+       if (cmd->data & RXH_SYMMETRIC_XOR)
+               symm = true;
+
        rss_new = kzalloc(sizeof(*rss_new), GFP_KERNEL);
        if (!rss_new)
                return -ENOMEM;
 
-       if (iavf_fill_adv_rss_cfg_msg(&rss_new->cfg_msg, hdrs, hash_flds)) {
+       if (iavf_fill_adv_rss_cfg_msg(&rss_new->cfg_msg, hdrs, hash_flds,
+                                     symm)) {
                kfree(rss_new);
                return -EINVAL;
        }
@@ -1655,9 +1671,11 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
        if (rss_old) {
                if (rss_old->state != IAVF_ADV_RSS_ACTIVE) {
                        err = -EBUSY;
-               } else if (rss_old->hash_flds != hash_flds) {
+               } else if (rss_old->hash_flds != hash_flds ||
+                          rss_old->symm != symm) {
                        rss_old->state = IAVF_ADV_RSS_ADD_REQUEST;
                        rss_old->hash_flds = hash_flds;
+                       rss_old->symm = symm;
                        memcpy(&rss_old->cfg_msg, &rss_new->cfg_msg,
                               sizeof(rss_new->cfg_msg));
                        adapter->aq_required |= IAVF_FLAG_AQ_ADD_ADV_RSS_CFG;
@@ -1669,6 +1687,7 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
                rss_new->state = IAVF_ADV_RSS_ADD_REQUEST;
                rss_new->packet_hdrs = hdrs;
                rss_new->hash_flds = hash_flds;
+               rss_new->symm = symm;
                list_add_tail(&rss_new->list, &adapter->adv_rss_list_head);
                adapter->aq_required |= IAVF_FLAG_AQ_ADD_ADV_RSS_CFG;
        }
@@ -1698,6 +1717,7 @@ iavf_get_adv_rss_hash_opt(struct iavf_adapter *adapter,
 {
        struct iavf_adv_rss *rss;
        u64 hash_flds;
+       bool symm;
        u32 hdrs;
 
        if (!ADV_RSS_SUPPORT(adapter))
@@ -1711,10 +1731,12 @@ iavf_get_adv_rss_hash_opt(struct iavf_adapter *adapter,
 
        spin_lock_bh(&adapter->adv_rss_lock);
        rss = iavf_find_adv_rss_cfg_by_hdrs(adapter, hdrs);
-       if (rss)
+       if (rss) {
                hash_flds = rss->hash_flds;
-       else
+               symm = rss->symm;
+       } else {
                hash_flds = IAVF_ADV_RSS_HASH_INVALID;
+       }
        spin_unlock_bh(&adapter->adv_rss_lock);
 
        if (hash_flds == IAVF_ADV_RSS_HASH_INVALID)
@@ -1738,6 +1760,9 @@ iavf_get_adv_rss_hash_opt(struct iavf_adapter *adapter,
                         IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
                cmd->data |= (u64)RXH_L4_B_2_3;
 
+       if (symm)
+               cmd->data |= (u64)RXH_SYMMETRIC_XOR;
+
        return 0;
 }
 
-- 
2.34.1

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

Reply via email to