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
+ *
+ * Assumption: lock has already been acquired for RSS list
+ */
+static enum ice_status
+ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
+                    u32 addl_hdrs, u8 segs_cnt)
+{
+       const enum ice_block blk = ICE_BLK_RSS;
+       struct ice_flow_seg_info *segs;
+       struct ice_flow_prof *prof;
+       enum ice_status status;
+
+       segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
+       if (!segs)
+               return ICE_ERR_NO_MEMORY;
+
+       /* Construct the packet segment info from the hashed fields */
+       status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
+                                          addl_hdrs);
+       if (status)
+               goto out;
+
+       prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
+                                       vsi_handle,
+                                       ICE_FLOW_FIND_PROF_CHK_FLDS);
+       if (!prof) {
+               status = ICE_ERR_DOES_NOT_EXIST;
+               goto out;
+       }
+
+       status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
+       if (status)
+               goto out;
+
+       /* Remove RSS configuration from VSI context before deleting
+        * the flow profile.
+        */
+       ice_rem_rss_list(hw, vsi_handle, prof);
+
+       if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
+               status = ice_flow_rem_prof(hw, blk, prof->id);
+
+out:
+       kfree(segs);
+       return status;
+}
+
+/**
+ * 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
+ *
+ * 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
+ * turn build or update buffers for RSS XLT1 section.
+ */
+enum ice_status __maybe_unused
+ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
+               u32 addl_hdrs)
+{
+       enum ice_status status;
+
+       if (hashed_flds == ICE_HASH_INVALID ||
+           !ice_is_vsi_valid(hw, vsi_handle))
+               return ICE_ERR_PARAM;
+
+       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);
+       mutex_unlock(&hw->rss_locks);
+
+       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.
 
                                        vsi->vsi_num, v_ret);
                        }
                } else {
-                       v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
-                       dev_err(dev, "RSS removal not supported\n");
+                       enum ice_status status;
+
+                       status = ice_rem_rss_cfg(hw, vsi->idx, hash_flds,
+                                                addl_hdrs);
+                       /* We just ignore ICE_ERR_DOES_NOT_EXIST, because
+                        * if two configurations share the same profile remove
+                        * one of them actually removes both, since the
+                        * profile is deleted.
+                        */
+                       if (status && status != ICE_ERR_DOES_NOT_EXIST) {
+                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                               dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%s\n",
+                                       vf->vf_id, ice_stat_str(status));
+                       }
                }
        }