|
@@ -2868,6 +2868,14 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
|
|
return ret;
|
|
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)
|
|
static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
|
|
{
|
|
{
|
|
struct ixgbe_adapter *adapter = netdev_priv(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;
|
|
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,
|
|
static int ixgbe_get_ts_info(struct net_device *dev,
|
|
struct ethtool_ts_info *info)
|
|
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_indir_size = ixgbe_rss_indir_size,
|
|
.get_rxfh_key_size = ixgbe_get_rxfh_key_size,
|
|
.get_rxfh_key_size = ixgbe_get_rxfh_key_size,
|
|
.get_rxfh = ixgbe_get_rxfh,
|
|
.get_rxfh = ixgbe_get_rxfh,
|
|
|
|
+ .set_rxfh = ixgbe_set_rxfh,
|
|
.get_channels = ixgbe_get_channels,
|
|
.get_channels = ixgbe_get_channels,
|
|
.set_channels = ixgbe_set_channels,
|
|
.set_channels = ixgbe_set_channels,
|
|
.get_ts_info = ixgbe_get_ts_info,
|
|
.get_ts_info = ixgbe_get_ts_info,
|