/**
  * ice_flow_set_rss_seg_info - setup packet segments for RSS
  * @segs: pointer to the flow field segment(s)
- * @hash_fields: fields to be hashed on for the segment(s)
- * @flow_hdr: protocol header fields within a packet segment
+ * @seg_cnt: segment count
+ * @cfg: configure parameters
  *
  * Helper function to extract fields from hash bitmap and use flow
  * header value to set flow field segment for further use in flow
  * profile entry or removal.
  */
 static int
-ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
-                         u32 flow_hdr)
+ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
+                         const struct ice_rss_hash_cfg *cfg)
 {
+       struct ice_flow_seg_info *seg;
        u64 val;
-       u8 i;
+       u16 i;
+
+       /* set inner most segment */
+       seg = &segs[seg_cnt - 1];
 
-       for_each_set_bit(i, (unsigned long *)&hash_fields,
-                        ICE_FLOW_FIELD_IDX_MAX)
-               ice_flow_set_fld(segs, (enum ice_flow_field)i,
+       for_each_set_bit(i, (const unsigned long *)&cfg->hash_flds,
+                        (u16)ICE_FLOW_FIELD_IDX_MAX)
+               ice_flow_set_fld(seg, (enum ice_flow_field)i,
                                 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
                                 ICE_FLOW_FLD_OFF_INVAL, false);
 
-       ICE_FLOW_SET_HDRS(segs, flow_hdr);
+       ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs);
 
-       if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
+       /* set outer most header */
+       if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
+               segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
+                                                   ICE_FLOW_SEG_HDR_IPV_OTHER;
+       else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
+               segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
+                                                   ICE_FLOW_SEG_HDR_IPV_OTHER;
+
+       if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
            ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
                return -EINVAL;
 
-       val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
+       val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
        if (val && !is_power_of_2(val))
                return -EIO;
 
-       val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
+       val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
        if (val && !is_power_of_2(val))
                return -EIO;
 
        return status;
 }
 
+/**
+ * ice_get_rss_hdr_type - get a RSS profile's header type
+ * @prof: RSS flow profile
+ */
+static enum ice_rss_cfg_hdr_type
+ice_get_rss_hdr_type(struct ice_flow_prof *prof)
+{
+       if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
+               return ICE_RSS_OUTER_HEADERS;
+       } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
+               const struct ice_flow_seg_info *s;
+
+               s = &prof->segs[ICE_RSS_OUTER_HEADERS];
+               if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
+                       return ICE_RSS_INNER_HEADERS;
+               if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
+                       return ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
+               if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
+                       return ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
+       }
+
+       return ICE_RSS_ANY_HEADERS;
+}
+
+static bool
+ice_rss_match_prof(struct ice_rss_cfg *r, struct ice_flow_prof *prof,
+                  enum ice_rss_cfg_hdr_type hdr_type)
+{
+       return (r->hash.hdr_type == hdr_type &&
+               r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match &&
+               r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs);
+}
+
 /**
  * ice_rem_rss_list - remove RSS configuration from list
  * @hw: pointer to the hardware structure
 static void
 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
 {
+       enum ice_rss_cfg_hdr_type hdr_type;
        struct ice_rss_cfg *r, *tmp;
 
        /* Search for RSS hash fields associated to the VSI that match the
         * hash configurations associated to the flow profile. If found
         * remove from the RSS entry list of the VSI context and delete entry.
         */
+       hdr_type = ice_get_rss_hdr_type(prof);
        list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
-               if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
-                   r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
+               if (ice_rss_match_prof(r, prof, hdr_type)) {
                        clear_bit(vsi_handle, r->vsis);
                        if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
                                list_del(&r->l_entry);
 static int
 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
 {
+       enum ice_rss_cfg_hdr_type hdr_type;
        struct ice_rss_cfg *r, *rss_cfg;
 
+       hdr_type = ice_get_rss_hdr_type(prof);
        list_for_each_entry(r, &hw->rss_list_head, l_entry)
-               if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
-                   r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
+               if (ice_rss_match_prof(r, prof, hdr_type)) {
                        set_bit(vsi_handle, r->vsis);
                        return 0;
                }
        if (!rss_cfg)
                return -ENOMEM;
 
-       rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
-       rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
+       rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match;
+       rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs;
+       rss_cfg->hash.hdr_type = hdr_type;
        set_bit(vsi_handle, rss_cfg->vsis);
 
        list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
 }
 
 #define ICE_FLOW_PROF_HASH_S   0
-#define ICE_FLOW_PROF_HASH_M   (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
+#define ICE_FLOW_PROF_HASH_M   GENMASK_ULL(31, 0)
 #define ICE_FLOW_PROF_HDR_S    32
-#define ICE_FLOW_PROF_HDR_M    (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
-#define ICE_FLOW_PROF_ENCAP_S  63
-#define ICE_FLOW_PROF_ENCAP_M  (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
-
-#define ICE_RSS_OUTER_HEADERS  1
-#define ICE_RSS_INNER_HEADERS  2
+#define ICE_FLOW_PROF_HDR_M    GENMASK_ULL(61, 32)
+#define ICE_FLOW_PROF_ENCAP_S  62
+#define ICE_FLOW_PROF_ENCAP_M  GENMASK_ULL(63, 62)
 
 /* Flow profile ID format:
  * [0:31] - Packet match fields
- * [32:62] - Protocol header
- * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
+ * [32:61] - Protocol header
+ * [62:63] - Encapsulation flag:
+ *          0 if non-tunneled
+ *          1 if tunneled
+ *          2 for tunneled with outer ipv4
+ *          3 for tunneled with outer ipv6
  */
-#define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
-       ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
+#define ICE_FLOW_GEN_PROFID(hash, hdr, encap)                                \
+       ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) |                        \
               (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
-              ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
+              (((u64)(encap) << ICE_FLOW_PROF_ENCAP_S) &                    \
+               ICE_FLOW_PROF_ENCAP_M)))
 
 /**
  * ice_add_rss_cfg_sync - add an RSS configuration
  * @hw: pointer to the hardware structure
  * @vsi_handle: software VSI handle
- * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
- * @addl_hdrs: protocol header fields
- * @segs_cnt: packet segment count
+ * @cfg: configure parameters
  *
  * Assumption: lock has already been acquired for RSS list
  */
 static int
-ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
-                    u32 addl_hdrs, u8 segs_cnt)
+ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
+                    const struct ice_rss_hash_cfg *cfg)
 {
        const enum ice_block blk = ICE_BLK_RSS;
        struct ice_flow_prof *prof = NULL;
        struct ice_flow_seg_info *segs;
+       u8 segs_cnt;
        int status;
 
-       if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
-               return -EINVAL;
+       segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
+                          ICE_FLOW_SEG_SINGLE :
+                          ICE_FLOW_SEG_MAX;
 
        segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
        if (!segs)
                return -ENOMEM;
 
        /* Construct the packet segment info from the hashed fields */
-       status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
-                                          addl_hdrs);
+       status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
        if (status)
                goto exit;
 
         * segment information.
         */
        status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
-                                  ICE_FLOW_GEN_PROFID(hashed_flds,
+                                  ICE_FLOW_GEN_PROFID(cfg->hash_flds,
                                                       segs[segs_cnt - 1].hdrs,
-                                                      segs_cnt),
+                                                      cfg->hdr_type),
                                   segs, segs_cnt, &prof);
        if (status)
                goto exit;
  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
  * @hw: pointer to the hardware structure
  * @vsi_handle: software VSI handle
- * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
- * @addl_hdrs: protocol header fields
+ * @cfg: configure parameters
  *
  * This function will generate a flow profile based on fields associated with
  * the input fields to hash on, the flow type and use the VSI number to add
  * a flow entry to the profile.
  */
 int
-ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
-               u32 addl_hdrs)
+ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
+               const struct ice_rss_hash_cfg *cfg)
 {
+       struct ice_rss_hash_cfg local_cfg;
        int status;
 
-       if (hashed_flds == ICE_HASH_INVALID ||
-           !ice_is_vsi_valid(hw, vsi_handle))
+       if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
+           cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
+           cfg->hash_flds == ICE_HASH_INVALID)
                return -EINVAL;
 
        mutex_lock(&hw->rss_locks);
-       status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
-                                     ICE_RSS_OUTER_HEADERS);
-       if (!status)
-               status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
-                                             addl_hdrs, ICE_RSS_INNER_HEADERS);
+       local_cfg = *cfg;
+       if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
+               status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
+       } else {
+               local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
+               status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
+               if (!status) {
+                       local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
+                       status = ice_add_rss_cfg_sync(hw, vsi_handle,
+                                                     &local_cfg);
+               }
+       }
        mutex_unlock(&hw->rss_locks);
 
        return status;
  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
  * @hw: pointer to the hardware structure
  * @vsi_handle: software VSI handle
- * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
- * @addl_hdrs: Protocol header fields within a packet segment
- * @segs_cnt: packet segment count
+ * @cfg: configure parameters
  *
  * Assumption: lock has already been acquired for RSS list
  */
 static int
-ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
-                    u32 addl_hdrs, u8 segs_cnt)
+ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
+                    const struct ice_rss_hash_cfg *cfg)
 {
        const enum ice_block blk = ICE_BLK_RSS;
        struct ice_flow_seg_info *segs;
        struct ice_flow_prof *prof;
+       u8 segs_cnt;
        int status;
 
+       segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
+                          ICE_FLOW_SEG_SINGLE :
+                          ICE_FLOW_SEG_MAX;
        segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
        if (!segs)
                return -ENOMEM;
 
        /* Construct the packet segment info from the hashed fields */
-       status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
-                                          addl_hdrs);
+       status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
        if (status)
                goto out;
 
  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
  * @hw: pointer to the hardware structure
  * @vsi_handle: software VSI handle
- * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
- * @addl_hdrs: Protocol header fields within a packet segment
+ * @cfg: configure parameters
  *
  * This function will lookup the flow profile based on the input
  * hash field bitmap, iterate through the profile entry list of
  * that profile and find entry associated with input VSI to be
- * removed. Calls are made to underlying flow s which will APIs
+ * removed. Calls are made to underlying flow apis which will in
  * turn build or update buffers for RSS XLT1 section.
  */
-int __maybe_unused
-ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
-               u32 addl_hdrs)
+int
+ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
+               const struct ice_rss_hash_cfg *cfg)
 {
+       struct ice_rss_hash_cfg local_cfg;
        int status;
 
-       if (hashed_flds == ICE_HASH_INVALID ||
-           !ice_is_vsi_valid(hw, vsi_handle))
+       if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
+           cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
+           cfg->hash_flds == ICE_HASH_INVALID)
                return -EINVAL;
 
        mutex_lock(&hw->rss_locks);
-       status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
-                                     ICE_RSS_OUTER_HEADERS);
-       if (!status)
-               status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
-                                             addl_hdrs, ICE_RSS_INNER_HEADERS);
+       local_cfg = *cfg;
+       if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
+               status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
+       } else {
+               local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
+               status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
+               if (!status) {
+                       local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
+                       status = ice_rem_rss_cfg_sync(hw, vsi_handle,
+                                                     &local_cfg);
+               }
+       }
        mutex_unlock(&hw->rss_locks);
 
        return status;
  */
 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
 {
+       struct ice_rss_hash_cfg hcfg;
        int status = 0;
        u64 hash_flds;
 
                if (rss_hash == ICE_HASH_INVALID)
                        return -EIO;
 
-               status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
-                                        ICE_FLOW_SEG_HDR_NONE);
+               hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
+               hcfg.hash_flds = rss_hash;
+               hcfg.hdr_type = ICE_RSS_ANY_HEADERS;
+               status = ice_add_rss_cfg(hw, vsi_handle, &hcfg);
                if (status)
                        break;
        }
        mutex_lock(&hw->rss_locks);
        list_for_each_entry(r, &hw->rss_list_head, l_entry) {
                if (test_bit(vsi_handle, r->vsis)) {
-                       status = ice_add_rss_cfg_sync(hw, vsi_handle,
-                                                     r->hashed_flds,
-                                                     r->packet_hdr,
-                                                     ICE_RSS_OUTER_HEADERS);
-                       if (status)
-                               break;
-                       status = ice_add_rss_cfg_sync(hw, vsi_handle,
-                                                     r->hashed_flds,
-                                                     r->packet_hdr,
-                                                     ICE_RSS_INNER_HEADERS);
+                       status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash);
                        if (status)
                                break;
                }
        mutex_lock(&hw->rss_locks);
        list_for_each_entry(r, &hw->rss_list_head, l_entry)
                if (test_bit(vsi_handle, r->vsis) &&
-                   r->packet_hdr == hdrs) {
-                       rss_hash = r->hashed_flds;
+                   r->hash.addl_hdrs == hdrs) {
+                       rss_hash = r->hash.hash_flds;
                        break;
                }
        mutex_unlock(&hw->rss_locks);
 
                        vsi->vsi_num, status);
 }
 
+static const struct ice_rss_hash_cfg default_rss_cfgs[] = {
+       /* configure RSS for IPv4 with input set IP src/dst */
+       {ICE_FLOW_SEG_HDR_IPV4, ICE_FLOW_HASH_IPV4, ICE_RSS_ANY_HEADERS},
+       /* configure RSS for IPv6 with input set IPv6 src/dst */
+       {ICE_FLOW_SEG_HDR_IPV6, ICE_FLOW_HASH_IPV6, ICE_RSS_ANY_HEADERS},
+       /* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */
+       {ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4,
+                               ICE_HASH_TCP_IPV4,  ICE_RSS_ANY_HEADERS},
+       /* configure RSS for udp4 with input set IP src/dst, UDP src/dst */
+       {ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4,
+                               ICE_HASH_UDP_IPV4,  ICE_RSS_ANY_HEADERS},
+       /* configure RSS for sctp4 with input set IP src/dst - only support
+        * RSS on SCTPv4 on outer headers (non-tunneled)
+        */
+       {ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4,
+               ICE_HASH_SCTP_IPV4, ICE_RSS_OUTER_HEADERS},
+       /* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */
+       {ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6,
+                               ICE_HASH_TCP_IPV6,  ICE_RSS_ANY_HEADERS},
+       /* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */
+       {ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6,
+                               ICE_HASH_UDP_IPV6,  ICE_RSS_ANY_HEADERS},
+       /* configure RSS for sctp6 with input set IPv6 src/dst - only support
+        * RSS on SCTPv6 on outer headers (non-tunneled)
+        */
+       {ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6,
+               ICE_HASH_SCTP_IPV6, ICE_RSS_OUTER_HEADERS},
+       /* configure RSS for IPSEC ESP SPI with input set MAC_IPV4_SPI */
+       {ICE_FLOW_SEG_HDR_ESP,
+               ICE_FLOW_HASH_ESP_SPI, ICE_RSS_OUTER_HEADERS},
+};
+
 /**
  * ice_vsi_set_rss_flow_fld - Sets RSS input set for different flows
  * @vsi: VSI to be configured
        struct ice_hw *hw = &pf->hw;
        struct device *dev;
        int status;
+       u32 i;
 
        dev = ice_pf_to_dev(pf);
        if (ice_is_safe_mode(pf)) {
                        vsi_num);
                return;
        }
-       /* configure RSS for IPv4 with input set IP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4,
-                                ICE_FLOW_SEG_HDR_IPV4);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for ipv4 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for IPv6 with input set IPv6 src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6,
-                                ICE_FLOW_SEG_HDR_IPV6);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for ipv6 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV4,
-                                ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for tcp4 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
+       for (i = 0; i < ARRAY_SIZE(default_rss_cfgs); i++) {
+               const struct ice_rss_hash_cfg *cfg = &default_rss_cfgs[i];
 
-       /* configure RSS for udp4 with input set IP src/dst, UDP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV4,
-                                ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for udp4 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for sctp4 with input set IP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4,
-                                ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for sctp4 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV6,
-                                ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for tcp6 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV6,
-                                ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for udp6 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       /* configure RSS for sctp6 with input set IPv6 src/dst */
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6,
-                                ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for sctp6 flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
-
-       status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_ESP_SPI,
-                                ICE_FLOW_SEG_HDR_ESP);
-       if (status)
-               dev_dbg(dev, "ice_add_rss_cfg failed for esp/spi flow, vsi = %d, error = %d\n",
-                       vsi_num, status);
+               status = ice_add_rss_cfg(hw, vsi_handle, cfg);
+               if (status)
+                       dev_dbg(dev, "ice_add_rss_cfg failed, addl_hdrs = %x, hash_flds = %llx, hdr_type = %d\n",
+                               cfg->addl_hdrs, cfg->hash_flds, cfg->hdr_type);
+       }
 }
 
 /**