diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/ethtool.c')
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ethtool.c | 46 | 
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 03215b0aee4b..06442e6bef73 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -23,6 +23,13 @@ struct e1000_stats {  	int stat_offset;  }; +static const char e1000e_priv_flags_strings[][ETH_GSTRING_LEN] = { +#define E1000E_PRIV_FLAGS_S0IX_ENABLED	BIT(0) +	"s0ix-enabled", +}; + +#define E1000E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(e1000e_priv_flags_strings) +  #define E1000_STAT(str, m) { \  		.stat_string = str, \  		.type = E1000_STATS, \ @@ -1776,6 +1783,8 @@ static int e1000e_get_sset_count(struct net_device __always_unused *netdev,  		return E1000_TEST_LEN;  	case ETH_SS_STATS:  		return E1000_STATS_LEN; +	case ETH_SS_PRIV_FLAGS: +		return E1000E_PRIV_FLAGS_STR_LEN;  	default:  		return -EOPNOTSUPP;  	} @@ -2097,6 +2106,10 @@ static void e1000_get_strings(struct net_device __always_unused *netdev,  			p += ETH_GSTRING_LEN;  		}  		break; +	case ETH_SS_PRIV_FLAGS: +		memcpy(data, e1000e_priv_flags_strings, +		       E1000E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN); +		break;  	}  } @@ -2305,6 +2318,37 @@ static int e1000e_get_ts_info(struct net_device *netdev,  	return 0;  } +static u32 e1000e_get_priv_flags(struct net_device *netdev) +{ +	struct e1000_adapter *adapter = netdev_priv(netdev); +	u32 priv_flags = 0; + +	if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) +		priv_flags |= E1000E_PRIV_FLAGS_S0IX_ENABLED; + +	return priv_flags; +} + +static int e1000e_set_priv_flags(struct net_device *netdev, u32 priv_flags) +{ +	struct e1000_adapter *adapter = netdev_priv(netdev); +	unsigned int flags2 = adapter->flags2; + +	flags2 &= ~FLAG2_ENABLE_S0IX_FLOWS; +	if (priv_flags & E1000E_PRIV_FLAGS_S0IX_ENABLED) { +		struct e1000_hw *hw = &adapter->hw; + +		if (hw->mac.type < e1000_pch_cnp) +			return -EINVAL; +		flags2 |= FLAG2_ENABLE_S0IX_FLOWS; +	} + +	if (flags2 != adapter->flags2) +		adapter->flags2 = flags2; + +	return 0; +} +  static const struct ethtool_ops e1000_ethtool_ops = {  	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,  	.get_drvinfo		= e1000_get_drvinfo, @@ -2336,6 +2380,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {  	.set_eee		= e1000e_set_eee,  	.get_link_ksettings	= e1000_get_link_ksettings,  	.set_link_ksettings	= e1000_set_link_ksettings, +	.get_priv_flags		= e1000e_get_priv_flags, +	.set_priv_flags		= e1000e_set_priv_flags,  };  void e1000e_set_ethtool_ops(struct net_device *netdev)  |