ixgbe: support for ethtool set_rxfh
authorTom Barbette <tom.barbette@ulg.ac.be>
Fri, 26 Jun 2015 13:40:18 +0000 (15:40 +0200)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 2 Sep 2015 00:10:38 +0000 (17:10 -0700)
Allows to change the rxfh indirection table and/or key using
ethtool interface.

Signed-off-by: Tom Barbette <tom.barbette@ulg.ac.be>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

index 8830c0fb5ffb5057c0a5f003b12cc6f09e00fbe0..edf1fb91320967f98cdc3ba56a4ad984a48b1063 100644 (file)
@@ -973,4 +973,5 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                                  struct ixgbe_adapter *adapter,
                                  struct ixgbe_ring *tx_ring);
 u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter);
+void ixgbe_store_reta(struct ixgbe_adapter *adapter);
 #endif /* _IXGBE_H_ */
index f7aeb560a504af040603b2c3ebfa939f5d85b285..b0cc439d7b01887c6f803bdead3d397dfd3ba156 100644 (file)
@@ -2868,6 +2868,14 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
        return ret;
 }
 
+static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
+{
+       if (adapter->hw.mac.type < ixgbe_mac_X550)
+               return 16;
+       else
+               return 64;
+}
+
 static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -2907,6 +2915,44 @@ static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
        return 0;
 }
 
+static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
+                         const u8 *key, const u8 hfunc)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       int i;
+       u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
+
+       if (hfunc)
+               return -EINVAL;
+
+       /* Fill out the redirection table */
+       if (indir) {
+               int max_queues = min_t(int, adapter->num_rx_queues,
+                                      ixgbe_rss_indir_tbl_max(adapter));
+
+               /*Allow at least 2 queues w/ SR-IOV.*/
+               if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) &&
+                   (max_queues < 2))
+                       max_queues = 2;
+
+               /* Verify user input. */
+               for (i = 0; i < reta_entries; i++)
+                       if (indir[i] >= max_queues)
+                               return -EINVAL;
+
+               for (i = 0; i < reta_entries; i++)
+                       adapter->rss_indir_tbl[i] = indir[i];
+       }
+
+       /* Fill out the rss hash key */
+       if (key)
+               memcpy(adapter->rss_key, key, ixgbe_get_rxfh_key_size(netdev));
+
+       ixgbe_store_reta(adapter);
+
+       return 0;
+}
+
 static int ixgbe_get_ts_info(struct net_device *dev,
                             struct ethtool_ts_info *info)
 {
@@ -3159,6 +3205,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
        .get_rxfh_indir_size    = ixgbe_rss_indir_size,
        .get_rxfh_key_size      = ixgbe_get_rxfh_key_size,
        .get_rxfh               = ixgbe_get_rxfh,
+       .set_rxfh               = ixgbe_set_rxfh,
        .get_channels           = ixgbe_get_channels,
        .set_channels           = ixgbe_set_channels,
        .get_ts_info            = ixgbe_get_ts_info,
index 7389c9692c9563324cf8e14adb109439e43135ba..afdc7fb39b2c1615db679ab0fe0af1f7a4a8485e 100644 (file)
@@ -3313,7 +3313,7 @@ u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter)
  *
  * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
  */
-static void ixgbe_store_reta(struct ixgbe_adapter *adapter)
+void ixgbe_store_reta(struct ixgbe_adapter *adapter)
 {
        u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
        struct ixgbe_hw *hw = &adapter->hw;