From: Md Fahad Iqbal Polash <md.fahad.iqbal.pol...@intel.com>

This patch implements ethtool hook for enabling/disabling
RSS. While disabling RSS, the LUT should be cleared. And
the LUT should be reconfigured while enabling RSS.

Signed-off-by: Md Fahad Iqbal Polash <md.fahad.iqbal.pol...@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkatarama...@intel.com>
Tested-by: Andrew Bowers <andrewx.bow...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirs...@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_lib.c  | 32 +++++++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_lib.h  |  2 ++
 drivers/net/ethernet/intel/ice/ice_main.c |  6 +++++
 3 files changed, 40 insertions(+)

diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c 
b/drivers/net/ethernet/intel/ice/ice_lib.c
index 8f7ee77cb70b..98e8b7096e47 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1222,6 +1222,38 @@ static void ice_vsi_map_rings_to_vectors(struct ice_vsi 
*vsi)
        }
 }
 
+/**
+ * ice_vsi_manage_rss_lut - disable/enable RSS
+ * @vsi: the VSI being changed
+ * @ena: boolean value indicating if this is an enable or disable request
+ *
+ * In the event of disable request for RSS, this function will zero out RSS
+ * LUT, while in the event of enable request for RSS, it will reconfigure RSS
+ * LUT.
+ */
+int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena)
+{
+       int err = 0;
+       u8 *lut;
+
+       lut = devm_kzalloc(&vsi->back->pdev->dev, vsi->rss_table_size,
+                          GFP_KERNEL);
+       if (!lut)
+               return -ENOMEM;
+
+       if (ena) {
+               if (vsi->rss_lut_user)
+                       memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
+               else
+                       ice_fill_rss_lut(lut, vsi->rss_table_size,
+                                        vsi->rss_size);
+       }
+
+       err = ice_set_rss(vsi, NULL, lut, vsi->rss_table_size);
+       devm_kfree(&vsi->back->pdev->dev, lut);
+       return err;
+}
+
 /**
  * ice_vsi_cfg_rss_lut_key - Configure RSS params for a VSI
  * @vsi: VSI to be configured
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h 
b/drivers/net/ethernet/intel/ice/ice_lib.h
index 4265464ee3d3..2617afe01c82 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -70,5 +70,7 @@ void ice_vsi_free_tx_rings(struct ice_vsi *vsi);
 
 int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc);
 
+int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena);
+
 irqreturn_t ice_msix_clean_rings(int __always_unused irq, void *data);
 #endif /* !_ICE_LIB_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c 
b/drivers/net/ethernet/intel/ice/ice_main.c
index d9f30d15ad65..bb76a0bf2fd1 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2412,6 +2412,12 @@ static int ice_set_features(struct net_device *netdev,
        struct ice_vsi *vsi = np->vsi;
        int ret = 0;
 
+       if (features & NETIF_F_RXHASH && !(netdev->features & NETIF_F_RXHASH))
+               ret = ice_vsi_manage_rss_lut(vsi, true);
+       else if (!(features & NETIF_F_RXHASH) &&
+                netdev->features & NETIF_F_RXHASH)
+               ret = ice_vsi_manage_rss_lut(vsi, false);
+
        if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
            !(netdev->features & NETIF_F_HW_VLAN_CTAG_RX))
                ret = ice_vsi_manage_vlan_stripping(vsi, true);
-- 
2.17.1

Reply via email to