Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0d8c733 authored by Shannon Nelson's avatar Shannon Nelson Committed by Jeff Kirsher
Browse files

i40e: limit WoL and link settings to partition 1



When in multi-function mode, e.g. Dell's NPAR, only partition 1
of each MAC is allowed to set WoL, speed, and flow control.

Change-ID: I87a9debc7479361c55a71f0120294ea319f23588
Signed-off-by: default avatarShannon Nelson <shannon.nelson@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 18f680c6
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -218,6 +218,16 @@ static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {

#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)

/**
 * i40e_partition_setting_complaint - generic complaint for MFP restriction
 * @pf: the PF struct
 **/
static void i40e_partition_setting_complaint(struct i40e_pf *pf)
{
	dev_info(&pf->pdev->dev,
		 "The link settings are allowed to be changed only from the first partition of a given port. Please switch to the first partition in order to change the setting.\n");
}

/**
 * i40e_get_settings - Get Link Speed and Duplex settings
 * @netdev: network interface device structure
@@ -485,6 +495,14 @@ static int i40e_set_settings(struct net_device *netdev,
	u8 autoneg;
	u32 advertise;

	/* Changing port settings is not supported if this isn't the
	 * port's controlling PF
	 */
	if (hw->partition_id != 1) {
		i40e_partition_setting_complaint(pf);
		return -EOPNOTSUPP;
	}

	if (vsi != pf->vsi[pf->lan_vsi])
		return -EOPNOTSUPP;

@@ -687,6 +705,14 @@ static int i40e_set_pauseparam(struct net_device *netdev,
	u8 aq_failures;
	int err = 0;

	/* Changing the port's flow control is not supported if this isn't the
	 * port's controlling PF
	 */
	if (hw->partition_id != 1) {
		i40e_partition_setting_complaint(pf);
		return -EOPNOTSUPP;
	}

	if (vsi != pf->vsi[pf->lan_vsi])
		return -EOPNOTSUPP;

@@ -1503,7 +1529,7 @@ static void i40e_get_wol(struct net_device *netdev,

	/* NVM bit on means WoL disabled for the port */
	i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
	if ((1 << hw->port) & wol_nvm_bits) {
	if ((1 << hw->port) & wol_nvm_bits || hw->partition_id != 1) {
		wol->supported = 0;
		wol->wolopts = 0;
	} else {
@@ -1512,13 +1538,28 @@ static void i40e_get_wol(struct net_device *netdev,
	}
}

/**
 * i40e_set_wol - set the WakeOnLAN configuration
 * @netdev: the netdev in question
 * @wol: the ethtool WoL setting data
 **/
static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_pf *pf = np->vsi->back;
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_hw *hw = &pf->hw;
	u16 wol_nvm_bits;

	/* WoL not supported if this isn't the controlling PF on the port */
	if (hw->partition_id != 1) {
		i40e_partition_setting_complaint(pf);
		return -EOPNOTSUPP;
	}

	if (vsi != pf->vsi[pf->lan_vsi])
		return -EOPNOTSUPP;

	/* NVM bit on means WoL disabled for the port */
	i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
	if (((1 << hw->port) & wol_nvm_bits))