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

Commit 19e016d6 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
This series contains updates to e1000e, ixgbe and ixgbevf.

Majority of the changes are against e1000e (from Bruce Allan).
Bruce adds additional error handling on PHY register access, as
well as improve slow performance on 82579 when connected to a
10Mbit hub.  In addition, fixes LED blink logic for cathode
LED design.  Most notable is added EEE support which is enabled
by default and the added support for LTR on I217/I218.

The ixgbe and ixgbevf from Greg Rose changes the VM so that if a user
does not assign a MAC address, the MAC address is set to all zeros
instead of a random MAC address.  This ensures that we always know when
we have a random address and udev won't get upset about it.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ea407f0b e1941a74
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
#define E1000_STATUS_SPEED_MASK 0x000000C0
#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
@@ -788,6 +789,7 @@
	GG82563_REG(194, 18) /* Inband Control */

/* MDI Control */
#define E1000_MDIC_REG_MASK	0x001F0000
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE  0x04000000
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include <linux/ptp_clock_kernel.h>
#include <linux/ptp_classify.h>
#include <linux/mii.h>
#include <linux/mdio.h>
#include "hw.h"

struct e1000_info;
@@ -350,6 +351,8 @@ struct e1000_adapter {
	struct timecounter tc;
	struct ptp_clock *ptp_clock;
	struct ptp_clock_info ptp_clock_info;

	u16 eee_advert;
};

struct e1000_info {
+19 −44
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <linux/mdio.h>
#include <linux/pm_runtime.h>

#include "e1000.h"
@@ -2076,23 +2075,20 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	u16 cap_addr, adv_addr, lpa_addr, pcs_stat_addr, phy_data, lpi_ctrl;
	u32 status, ret_val;
	u16 cap_addr, lpa_addr, pcs_stat_addr, phy_data;
	u32 ret_val;

	if (!(adapter->flags & FLAG_IS_ICH) ||
	    !(adapter->flags2 & FLAG2_HAS_EEE))
	if (!(adapter->flags2 & FLAG2_HAS_EEE))
		return -EOPNOTSUPP;

	switch (hw->phy.type) {
	case e1000_phy_82579:
		cap_addr = I82579_EEE_CAPABILITY;
		adv_addr = I82579_EEE_ADVERTISEMENT;
		lpa_addr = I82579_EEE_LP_ABILITY;
		pcs_stat_addr = I82579_EEE_PCS_STATUS;
		break;
	case e1000_phy_i217:
		cap_addr = I217_EEE_CAPABILITY;
		adv_addr = I217_EEE_ADVERTISEMENT;
		lpa_addr = I217_EEE_LP_ABILITY;
		pcs_stat_addr = I217_EEE_PCS_STATUS;
		break;
@@ -2111,10 +2107,7 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
	edata->supported = mmd_eee_cap_to_ethtool_sup_t(phy_data);

	/* EEE Advertised */
	ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &phy_data);
	if (ret_val)
		goto release;
	edata->advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
	edata->advertised = mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);

	/* EEE Link Partner Advertised */
	ret_val = e1000_read_emi_reg_locked(hw, lpa_addr, &phy_data);
@@ -2132,25 +2125,11 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
	if (ret_val)
		return -ENODATA;

	e1e_rphy(hw, I82579_LPI_CTRL, &lpi_ctrl);
	status = er32(STATUS);

	/* Result of the EEE auto negotiation - there is no register that
	 * has the status of the EEE negotiation so do a best-guess based
	 * on whether both Tx and Rx LPI indications have been received or
	 * base it on the link speed, the EEE advertised speeds on both ends
	 * and the speeds on which EEE is enabled locally.
	 * on whether Tx or Rx LPI indications have been received.
	 */
	if (((phy_data & E1000_EEE_TX_LPI_RCVD) &&
	     (phy_data & E1000_EEE_RX_LPI_RCVD)) ||
	    ((status & E1000_STATUS_SPEED_100) &&
	     (edata->advertised & ADVERTISED_100baseT_Full) &&
	     (edata->lp_advertised & ADVERTISED_100baseT_Full) &&
	     (lpi_ctrl & I82579_LPI_CTRL_100_ENABLE)) ||
	    ((status & E1000_STATUS_SPEED_1000) &&
	     (edata->advertised & ADVERTISED_1000baseT_Full) &&
	     (edata->lp_advertised & ADVERTISED_1000baseT_Full) &&
	     (lpi_ctrl & I82579_LPI_CTRL_1000_ENABLE)))
	if (phy_data & (E1000_EEE_TX_LPI_RCVD | E1000_EEE_RX_LPI_RCVD))
		edata->eee_active = true;

	edata->eee_enabled = !hw->dev_spec.ich8lan.eee_disable;
@@ -2167,19 +2146,10 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
	struct ethtool_eee eee_curr;
	s32 ret_val;

	if (!(adapter->flags & FLAG_IS_ICH) ||
	    !(adapter->flags2 & FLAG2_HAS_EEE))
		return -EOPNOTSUPP;

	ret_val = e1000e_get_eee(netdev, &eee_curr);
	if (ret_val)
		return ret_val;

	if (eee_curr.advertised != edata->advertised) {
		e_err("Setting EEE advertisement is not supported\n");
		return -EINVAL;
	}

	if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
		e_err("Setting EEE tx-lpi is not supported\n");
		return -EINVAL;
@@ -2190,7 +2160,13 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
		return -EINVAL;
	}

	if (hw->dev_spec.ich8lan.eee_disable != !edata->eee_enabled) {
	if (edata->advertised & ~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
		e_err("EEE advertisement supports only 100TX and/or 1000T full-duplex\n");
		return -EINVAL;
	}

	adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);

	hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;

	/* reset the link */
@@ -2198,7 +2174,6 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
		e1000e_reinit_locked(adapter);
	else
		e1000e_reset(adapter);
	}

	return 0;
}
+181 −32
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);

static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
@@ -636,6 +637,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
	if (mac->type == e1000_pch_lpt) {
		mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
		mac->ops.rar_set = e1000_rar_set_pch_lpt;
		mac->ops.setup_physical_interface =
		    e1000_setup_copper_link_pch_lpt;
	}

	/* Enable PCS Lock-loss workaround for ICH8 */
@@ -692,7 +695,7 @@ s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data)
 *
 *  Assumes the SW/FW/HW Semaphore is already acquired.
 **/
static s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
{
	return __e1000_access_emi_reg_locked(hw, addr, &data, false);
}
@@ -709,11 +712,22 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
{
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	s32 ret_val;
	u16 lpi_ctrl;
	u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data;

	if ((hw->phy.type != e1000_phy_82579) &&
	    (hw->phy.type != e1000_phy_i217))
	switch (hw->phy.type) {
	case e1000_phy_82579:
		lpa = I82579_EEE_LP_ABILITY;
		pcs_status = I82579_EEE_PCS_STATUS;
		adv_addr = I82579_EEE_ADVERTISEMENT;
		break;
	case e1000_phy_i217:
		lpa = I217_EEE_LP_ABILITY;
		pcs_status = I217_EEE_PCS_STATUS;
		adv_addr = I217_EEE_ADVERTISEMENT;
		break;
	default:
		return 0;
	}

	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
@@ -728,34 +742,24 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)

	/* Enable EEE if not disabled by user */
	if (!dev_spec->eee_disable) {
		u16 lpa, pcs_status, data;

		/* Save off link partner's EEE ability */
		switch (hw->phy.type) {
		case e1000_phy_82579:
			lpa = I82579_EEE_LP_ABILITY;
			pcs_status = I82579_EEE_PCS_STATUS;
			break;
		case e1000_phy_i217:
			lpa = I217_EEE_LP_ABILITY;
			pcs_status = I217_EEE_PCS_STATUS;
			break;
		default:
			ret_val = -E1000_ERR_PHY;
			goto release;
		}
		ret_val = e1000_read_emi_reg_locked(hw, lpa,
						    &dev_spec->eee_lp_ability);
		if (ret_val)
			goto release;

		/* Read EEE advertisement */
		ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &adv);
		if (ret_val)
			goto release;

		/* Enable EEE only for speeds in which the link partner is
		 * EEE capable.
		 * EEE capable and for which we advertise EEE.
		 */
		if (dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
		if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
			lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE;

		if (dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
		if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
			e1e_rphy_locked(hw, MII_LPA, &data);
			if (data & LPA_100FULL)
				lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE;
@@ -767,12 +771,12 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
				dev_spec->eee_lp_ability &=
				    ~I82579_EEE_100_SUPPORTED;
		}
	}

	/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
	ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
	if (ret_val)
		goto release;
	}

	ret_val = e1e_wphy_locked(hw, I82579_LPI_CTRL, lpi_ctrl);
release:
@@ -834,6 +838,94 @@ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
	return ret_val;
}

/**
 *  e1000_platform_pm_pch_lpt - Set platform power management values
 *  @hw: pointer to the HW structure
 *  @link: bool indicating link status
 *
 *  Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like"
 *  GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed
 *  when link is up (which must not exceed the maximum latency supported
 *  by the platform), otherwise specify there is no LTR requirement.
 *  Unlike true-PCIe devices which set the LTR maximum snoop/no-snoop
 *  latencies in the LTR Extended Capability Structure in the PCIe Extended
 *  Capability register set, on this device LTR is set by writing the
 *  equivalent snoop/no-snoop latencies in the LTRV register in the MAC and
 *  set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB)
 *  message to the PMC.
 **/
static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
{
	u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) |
	    link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND;
	u16 lat_enc = 0;	/* latency encoded */

	if (link) {
		u16 speed, duplex, scale = 0;
		u16 max_snoop, max_nosnoop;
		u16 max_ltr_enc;	/* max LTR latency encoded */
		s64 lat_ns;	/* latency (ns) */
		s64 value;
		u32 rxa;

		if (!hw->adapter->max_frame_size) {
			e_dbg("max_frame_size not set.\n");
			return -E1000_ERR_CONFIG;
		}

		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
		if (!speed) {
			e_dbg("Speed not set.\n");
			return -E1000_ERR_CONFIG;
		}

		/* Rx Packet Buffer Allocation size (KB) */
		rxa = er32(PBA) & E1000_PBA_RXA_MASK;

		/* Determine the maximum latency tolerated by the device.
		 *
		 * Per the PCIe spec, the tolerated latencies are encoded as
		 * a 3-bit encoded scale (only 0-5 are valid) multiplied by
		 * a 10-bit value (0-1023) to provide a range from 1 ns to
		 * 2^25*(2^10-1) ns.  The scale is encoded as 0=2^0ns,
		 * 1=2^5ns, 2=2^10ns,...5=2^25ns.
		 */
		lat_ns = ((s64)rxa * 1024 -
			  (2 * (s64)hw->adapter->max_frame_size)) * 8 * 1000;
		if (lat_ns < 0)
			lat_ns = 0;
		else
			do_div(lat_ns, speed);

		value = lat_ns;
		while (value > PCI_LTR_VALUE_MASK) {
			scale++;
			value = DIV_ROUND_UP(value, (1 << 5));
		}
		if (scale > E1000_LTRV_SCALE_MAX) {
			e_dbg("Invalid LTR latency scale %d\n", scale);
			return -E1000_ERR_CONFIG;
		}
		lat_enc = (u16)((scale << PCI_LTR_SCALE_SHIFT) | value);

		/* Determine the maximum latency tolerated by the platform */
		pci_read_config_word(hw->adapter->pdev, E1000_PCI_LTR_CAP_LPT,
				     &max_snoop);
		pci_read_config_word(hw->adapter->pdev,
				     E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop);
		max_ltr_enc = max_t(u16, max_snoop, max_nosnoop);

		if (lat_enc > max_ltr_enc)
			lat_enc = max_ltr_enc;
	}

	/* Set Snoop and No-Snoop latencies the same */
	reg |= lat_enc | (lat_enc << E1000_LTRV_NOSNOOP_SHIFT);
	ew32(LTRV, reg);

	return 0;
}

/**
 *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
 *  @hw: pointer to the HW structure
@@ -871,6 +963,34 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
			return ret_val;
	}

	/* When connected at 10Mbps half-duplex, 82579 parts are excessively
	 * aggressive resulting in many collisions. To avoid this, increase
	 * the IPG and reduce Rx latency in the PHY.
	 */
	if ((hw->mac.type == e1000_pch2lan) && link) {
		u32 reg;
		reg = er32(STATUS);
		if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
			reg = er32(TIPG);
			reg &= ~E1000_TIPG_IPGT_MASK;
			reg |= 0xFF;
			ew32(TIPG, reg);

			/* Reduce Rx latency in analog PHY */
			ret_val = hw->phy.ops.acquire(hw);
			if (ret_val)
				return ret_val;

			ret_val =
			    e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0);

			hw->phy.ops.release(hw);

			if (ret_val)
				return ret_val;
		}
	}

	/* Work-around I218 hang issue */
	if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
	    (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
@@ -879,6 +999,15 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
			return ret_val;
	}

	if (hw->mac.type == e1000_pch_lpt) {
		/* Set platform power management values for
		 * Latency Tolerance Reporting (LTR)
		 */
		ret_val = e1000_platform_pm_pch_lpt(hw, link);
		if (ret_val)
			return ret_val;
	}

	/* Clear link partner's EEE ability */
	hw->dev_spec.ich8lan.eee_lp_ability = 0;

@@ -1002,10 +1131,6 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
	    (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
		adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA;

	/* Disable EEE by default until IEEE802.3az spec is finalized */
	if (adapter->flags2 & FLAG2_HAS_EEE)
		adapter->hw.dev_spec.ich8lan.eee_disable = true;

	return 0;
}

@@ -3760,7 +3885,6 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
		break;
	case e1000_phy_82577:
	case e1000_phy_82579:
	case e1000_phy_i217:
		ret_val = e1000_copper_link_setup_82577(hw);
		if (ret_val)
			return ret_val;
@@ -3795,6 +3919,31 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
	return e1000e_setup_copper_link(hw);
}

/**
 *  e1000_setup_copper_link_pch_lpt - Configure MAC/PHY interface
 *  @hw: pointer to the HW structure
 *
 *  Calls the PHY specific link setup function and then calls the
 *  generic setup_copper_link to finish configuring the link for
 *  Lynxpoint PCH devices
 **/
static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw)
{
	u32 ctrl;
	s32 ret_val;

	ctrl = er32(CTRL);
	ctrl |= E1000_CTRL_SLU;
	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
	ew32(CTRL, ctrl);

	ret_val = e1000_copper_link_setup_82577(hw);
	if (ret_val)
		return ret_val;

	return e1000e_setup_copper_link(hw);
}

/**
 *  e1000_get_link_up_info_ich8lan - Get current link speed and duplex
 *  @hw: pointer to the HW structure
+3 −8
Original line number Diff line number Diff line
@@ -211,7 +211,8 @@
#define I82579_MSE_THRESHOLD	0x084F	/* 82579 Mean Square Error Threshold */
#define I82577_MSE_THRESHOLD	0x0887	/* 82577 Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN	0x2411	/* MSE count before dropping link */
#define I82579_EEE_PCS_STATUS		0x182D	/* IEEE MMD Register 3.1 >> 8 */
#define I82579_RX_CONFIG		0x3412	/* Receive configuration */
#define I82579_EEE_PCS_STATUS		0x182E	/* IEEE MMD Register 3.1 >> 8 */
#define I82579_EEE_CAPABILITY		0x0410	/* IEEE MMD Register 3.20 */
#define I82579_EEE_ADVERTISEMENT	0x040E	/* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY		0x040F	/* IEEE MMD Register 7.61 */
@@ -249,13 +250,6 @@
/* Proprietary Latency Tolerance Reporting PCI Capability */
#define E1000_PCI_LTR_CAP_LPT		0xA8

/* OBFF Control & Threshold Defines */
#define E1000_SVCR_OFF_EN		0x00000001
#define E1000_SVCR_OFF_MASKINT		0x00001000
#define E1000_SVCR_OFF_TIMER_MASK	0xFFFF0000
#define E1000_SVCR_OFF_TIMER_SHIFT	16
#define E1000_SVT_OFF_HWM_MASK		0x0000001F

void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
						  bool state);
@@ -267,4 +261,5 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data);
#endif /* _E1000E_ICH8LAN_H_ */
Loading