]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
idpf: Fix RSS LUT configuration on down interfaces
authorSreedevi Joshi <sreedevi.joshi@intel.com>
Mon, 24 Nov 2025 18:47:49 +0000 (12:47 -0600)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 6 Jan 2026 23:42:10 +0000 (15:42 -0800)
RSS LUT provisioning and queries on a down interface currently return
silently without effect. Users should be able to configure RSS settings
even when the interface is down.

Fix by maintaining RSS configuration changes in the driver's soft copy and
deferring HW programming until the interface comes up.

Fixes: 02cbfba1add5 ("idpf: add ethtool callbacks")
Signed-off-by: Sreedevi Joshi <sreedevi.joshi@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/idpf/idpf_ethtool.c

index 7000f6283a335cd0e246d8d153fef463290e99e4..2efa3c08aba5c7fe8bc7f6a0f7d183caf9110268 100644 (file)
@@ -411,7 +411,10 @@ static u32 idpf_get_rxfh_indir_size(struct net_device *netdev)
  * @netdev: network interface device structure
  * @rxfh: pointer to param struct (indir, key, hfunc)
  *
- * Reads the indirection table directly from the hardware. Always returns 0.
+ * RSS LUT and Key information are read from driver's cached
+ * copy. When rxhash is off, rss lut will be displayed as zeros.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
 static int idpf_get_rxfh(struct net_device *netdev,
                         struct ethtool_rxfh_param *rxfh)
@@ -419,10 +422,13 @@ static int idpf_get_rxfh(struct net_device *netdev,
        struct idpf_netdev_priv *np = netdev_priv(netdev);
        struct idpf_rss_data *rss_data;
        struct idpf_adapter *adapter;
+       struct idpf_vport *vport;
+       bool rxhash_ena;
        int err = 0;
        u16 i;
 
        idpf_vport_ctrl_lock(netdev);
+       vport = idpf_netdev_to_vport(netdev);
 
        adapter = np->adapter;
 
@@ -432,9 +438,8 @@ static int idpf_get_rxfh(struct net_device *netdev,
        }
 
        rss_data = &adapter->vport_config[np->vport_idx]->user_config.rss_data;
-       if (!test_bit(IDPF_VPORT_UP, np->state))
-               goto unlock_mutex;
 
+       rxhash_ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH);
        rxfh->hfunc = ETH_RSS_HASH_TOP;
 
        if (rxfh->key)
@@ -442,7 +447,7 @@ static int idpf_get_rxfh(struct net_device *netdev,
 
        if (rxfh->indir) {
                for (i = 0; i < rss_data->rss_lut_size; i++)
-                       rxfh->indir[i] = rss_data->rss_lut[i];
+                       rxfh->indir[i] = rxhash_ena ? rss_data->rss_lut[i] : 0;
        }
 
 unlock_mutex:
@@ -482,8 +487,6 @@ static int idpf_set_rxfh(struct net_device *netdev,
        }
 
        rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
-       if (!test_bit(IDPF_VPORT_UP, np->state))
-               goto unlock_mutex;
 
        if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
            rxfh->hfunc != ETH_RSS_HASH_TOP) {
@@ -499,7 +502,8 @@ static int idpf_set_rxfh(struct net_device *netdev,
                        rss_data->rss_lut[lut] = rxfh->indir[lut];
        }
 
-       err = idpf_config_rss(vport);
+       if (test_bit(IDPF_VPORT_UP, np->state))
+               err = idpf_config_rss(vport);
 
 unlock_mutex:
        idpf_vport_ctrl_unlock(netdev);