net/ice/base: rollback AVF RSS configurations
authorLeyi Rong <leyi.rong@intel.com>
Wed, 19 Jun 2019 15:17:47 +0000 (23:17 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 28 Jun 2019 18:31:48 +0000 (20:31 +0200)
Adding support to remove RSS configurations added
prior to failing case in AVF.

Signed-off-by: Vignesh Sridhar <vignesh.sridhar@intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Signed-off-by: Leyi Rong <leyi.rong@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/ice/base/ice_flow.c

index f1bf5b5..d97fe1f 100644 (file)
@@ -1915,6 +1915,134 @@ out:
        return status;
 }
 
+/* Mapping of AVF hash bit fields to an L3-L4 hash combination.
+ * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
+ * convert its values to their appropriate flow L3, L4 values.
+ */
+#define ICE_FLOW_AVF_RSS_IPV4_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
+#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
+#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
+#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
+       (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
+        ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
+
+#define ICE_FLOW_AVF_RSS_IPV6_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
+#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
+#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
+       (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
+        BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
+#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
+       (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
+        ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
+
+#define ICE_FLOW_MAX_CFG       10
+
+/**
+ * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
+ * @hw: pointer to the hardware structure
+ * @vsi_handle: software VSI handle
+ * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
+ *
+ * This function will take the hash bitmap provided by the AVF driver via a
+ * message, convert it to ICE-compatible values, and configure RSS flow
+ * profiles.
+ */
+enum ice_status
+ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
+{
+       enum ice_status status = ICE_SUCCESS;
+       u64 hash_flds;
+
+       if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
+           !ice_is_vsi_valid(hw, vsi_handle))
+               return ICE_ERR_PARAM;
+
+       /* Make sure no unsupported bits are specified */
+       if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
+                        ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
+               return ICE_ERR_CFG;
+
+       hash_flds = avf_hash;
+
+       /* Always create an L3 RSS configuration for any L4 RSS configuration */
+       if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
+               hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
+
+       if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
+               hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
+
+       /* Create the corresponding RSS configuration for each valid hash bit */
+       while (hash_flds) {
+               u64 rss_hash = ICE_HASH_INVALID;
+
+               if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
+                       if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV4;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
+                       } else if (hash_flds &
+                                  ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV4 |
+                                       ICE_FLOW_HASH_TCP_PORT;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
+                       } else if (hash_flds &
+                                  ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV4 |
+                                       ICE_FLOW_HASH_UDP_PORT;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
+                       } else if (hash_flds &
+                                  BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
+                               rss_hash = ICE_FLOW_HASH_IPV4 |
+                                       ICE_FLOW_HASH_SCTP_PORT;
+                               hash_flds &=
+                                       ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
+                       }
+               } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
+                       if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV6;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
+                       } else if (hash_flds &
+                                  ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV6 |
+                                       ICE_FLOW_HASH_TCP_PORT;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
+                       } else if (hash_flds &
+                                  ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
+                               rss_hash = ICE_FLOW_HASH_IPV6 |
+                                       ICE_FLOW_HASH_UDP_PORT;
+                               hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
+                       } else if (hash_flds &
+                                  BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
+                               rss_hash = ICE_FLOW_HASH_IPV6 |
+                                       ICE_FLOW_HASH_SCTP_PORT;
+                               hash_flds &=
+                                       ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
+                       }
+               }
+
+               if (rss_hash == ICE_HASH_INVALID)
+                       return ICE_ERR_OUT_OF_RANGE;
+
+               status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
+                                        ICE_FLOW_SEG_HDR_NONE);
+               if (status)
+                       break;
+       }
+
+       return status;
+}
+
 /**
  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
  * @hw: pointer to the hardware structure