mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-21 00:42:16 +00:00
e1000e: initial support for i217
i217 is the next-generation LOM that will be available on systems with the Lynx Point Platform Controller Hub (PCH) chipset from Intel. This patch provides the initial support for the device. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
d02c70a8ee
commit
2fbe4526e5
@ -74,7 +74,9 @@
|
||||
#define E1000_WUS_BC E1000_WUFC_BC
|
||||
|
||||
/* Extended Device Control */
|
||||
#define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */
|
||||
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
|
||||
#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000004 /* Force SMBus mode*/
|
||||
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
|
||||
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
|
||||
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
|
||||
@ -573,6 +575,7 @@
|
||||
#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
|
||||
|
||||
/* Link Partner Ability Register (Base Page) */
|
||||
#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP 100TX Full Dplx Capable */
|
||||
#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
|
||||
#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
|
||||
|
||||
@ -739,6 +742,7 @@
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
#define I82579_E_PHY_ID 0x01540090
|
||||
#define I217_E_PHY_ID 0x015400A0
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
@ -850,4 +854,8 @@
|
||||
/* SerDes Control */
|
||||
#define E1000_GEN_POLL_TIMEOUT 640
|
||||
|
||||
/* FW Semaphore */
|
||||
#define E1000_FWSM_WLOCK_MAC_MASK 0x0380
|
||||
#define E1000_FWSM_WLOCK_MAC_SHIFT 7
|
||||
|
||||
#endif /* _E1000_DEFINES_H_ */
|
||||
|
@ -206,6 +206,7 @@ enum e1000_boards {
|
||||
board_ich10lan,
|
||||
board_pchlan,
|
||||
board_pch2lan,
|
||||
board_pch_lpt,
|
||||
};
|
||||
|
||||
struct e1000_ps_page {
|
||||
@ -528,6 +529,7 @@ extern const struct e1000_info e1000_ich9_info;
|
||||
extern const struct e1000_info e1000_ich10_info;
|
||||
extern const struct e1000_info e1000_pch_info;
|
||||
extern const struct e1000_info e1000_pch2_info;
|
||||
extern const struct e1000_info e1000_pch_lpt_info;
|
||||
extern const struct e1000_info e1000_es2_info;
|
||||
|
||||
extern s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
|
||||
|
@ -773,6 +773,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
||||
u32 i;
|
||||
u32 toggle;
|
||||
u32 mask;
|
||||
u32 wlock_mac = 0;
|
||||
|
||||
/*
|
||||
* The status register is Read Only, so a write should fail.
|
||||
@ -838,19 +839,31 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
mask |= (1 << 18);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < mac->rar_entry_count; i++)
|
||||
|
||||
if (mac->type == e1000_pch_lpt)
|
||||
wlock_mac = (er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK) >>
|
||||
E1000_FWSM_WLOCK_MAC_SHIFT;
|
||||
|
||||
for (i = 0; i < mac->rar_entry_count; i++) {
|
||||
/* Cannot test write-protected SHRAL[n] registers */
|
||||
if ((wlock_mac == 1) || (wlock_mac && (i > wlock_mac)))
|
||||
continue;
|
||||
|
||||
REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
|
||||
mask, 0xFFFFFFFF);
|
||||
mask, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
|
||||
*data = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -200,6 +200,10 @@ enum e1e_registers {
|
||||
#define E1000_RA (E1000_RAL(0))
|
||||
E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */
|
||||
#define E1000_RAH(_n) (E1000_RAH_BASE + ((_n) * 8))
|
||||
E1000_SHRAL_PCH_LPT_BASE = 0x05408,
|
||||
#define E1000_SHRAL_PCH_LPT(_n) (E1000_SHRAL_PCH_LPT_BASE + ((_n) * 8))
|
||||
E1000_SHRAH_PCH_LTP_BASE = 0x0540C,
|
||||
#define E1000_SHRAH_PCH_LPT(_n) (E1000_SHRAH_PCH_LTP_BASE + ((_n) * 8))
|
||||
E1000_SHRAL_BASE = 0x05438, /* Shared Receive Address Low - RW */
|
||||
#define E1000_SHRAL(_n) (E1000_SHRAL_BASE + ((_n) * 8))
|
||||
E1000_SHRAH_BASE = 0x0543C, /* Shared Receive Address High - RW */
|
||||
@ -406,6 +410,8 @@ enum e1e_registers {
|
||||
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
|
||||
#define E1000_DEV_ID_PCH2_LV_LM 0x1502
|
||||
#define E1000_DEV_ID_PCH2_LV_V 0x1503
|
||||
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
|
||||
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
|
||||
|
||||
#define E1000_REVISION_4 4
|
||||
|
||||
@ -426,6 +432,7 @@ enum e1000_mac_type {
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
e1000_pch2lan,
|
||||
e1000_pch_lpt,
|
||||
};
|
||||
|
||||
enum e1000_media_type {
|
||||
@ -463,6 +470,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
e1000_phy_82579,
|
||||
e1000_phy_i217,
|
||||
};
|
||||
|
||||
enum e1000_bus_width {
|
||||
@ -971,6 +979,7 @@ struct e1000_dev_spec_ich8lan {
|
||||
struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
|
||||
bool nvm_k1_enabled;
|
||||
bool eee_disable;
|
||||
u16 eee_lp_ability;
|
||||
};
|
||||
|
||||
struct e1000_hw {
|
||||
|
@ -116,6 +116,7 @@
|
||||
|
||||
#define E1000_ICH_RAR_ENTRIES 7
|
||||
#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
|
||||
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
|
||||
|
||||
#define PHY_PAGE_SHIFT 5
|
||||
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
|
||||
@ -131,11 +132,18 @@
|
||||
|
||||
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
|
||||
|
||||
/* SMBus Control Phy Register */
|
||||
#define CV_SMB_CTRL PHY_REG(769, 23)
|
||||
#define CV_SMB_CTRL_FORCE_SMBUS 0x0001
|
||||
|
||||
/* SMBus Address Phy Register */
|
||||
#define HV_SMB_ADDR PHY_REG(768, 26)
|
||||
#define HV_SMB_ADDR_MASK 0x007F
|
||||
#define HV_SMB_ADDR_PEC_EN 0x0200
|
||||
#define HV_SMB_ADDR_VALID 0x0080
|
||||
#define HV_SMB_ADDR_FREQ_MASK 0x1100
|
||||
#define HV_SMB_ADDR_FREQ_LOW_SHIFT 8
|
||||
#define HV_SMB_ADDR_FREQ_HIGH_SHIFT 12
|
||||
|
||||
/* PHY Power Management Control */
|
||||
#define HV_PM_CTRL PHY_REG(770, 17)
|
||||
@ -152,11 +160,26 @@
|
||||
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
|
||||
#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */
|
||||
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
|
||||
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
|
||||
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
|
||||
#define I217_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE supported */
|
||||
|
||||
/* Intel Rapid Start Technology Support */
|
||||
#define I217_PROXY_CTRL PHY_REG(BM_WUC_PAGE, 70)
|
||||
#define I217_PROXY_CTRL_AUTO_DISABLE 0x0080
|
||||
#define I217_SxCTRL PHY_REG(BM_PORT_CTRL_PAGE, 28)
|
||||
#define I217_SxCTRL_MASK 0x1000
|
||||
#define I217_CGFREG PHY_REG(772, 29)
|
||||
#define I217_CGFREG_MASK 0x0002
|
||||
#define I217_MEMPWR PHY_REG(772, 26)
|
||||
#define I217_MEMPWR_MASK 0x0010
|
||||
|
||||
/* Strapping Option Register - RO */
|
||||
#define E1000_STRAP 0x0000C
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
|
||||
#define E1000_STRAP_SMT_FREQ_MASK 0x00003000
|
||||
#define E1000_STRAP_SMT_FREQ_SHIFT 12
|
||||
|
||||
/* OEM Bits Phy Register */
|
||||
#define HV_OEM_BITS PHY_REG(768, 25)
|
||||
@ -261,6 +284,7 @@ static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
|
||||
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
|
||||
static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
|
||||
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);
|
||||
|
||||
@ -332,6 +356,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
u32 mac_reg, fwsm = er32(FWSM);
|
||||
s32 ret_val;
|
||||
u16 phy_reg;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val) {
|
||||
@ -345,16 +370,42 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
|
||||
* LANPHYPC Value bit to force the interconnect to PCIe mode.
|
||||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_pch_lpt:
|
||||
if (e1000_phy_is_accessible_pchlan(hw))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Before toggling LANPHYPC, see if PHY is accessible by
|
||||
* forcing MAC to SMBus mode first.
|
||||
*/
|
||||
mac_reg = er32(CTRL_EXT);
|
||||
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
|
||||
ew32(CTRL_EXT, mac_reg);
|
||||
|
||||
/* fall-through */
|
||||
case e1000_pch2lan:
|
||||
/*
|
||||
* Gate automatic PHY configuration by hardware on
|
||||
* non-managed 82579
|
||||
*/
|
||||
if (!(fwsm & E1000_ICH_FWSM_FW_VALID))
|
||||
if ((hw->mac.type == e1000_pch2lan) &&
|
||||
!(fwsm & E1000_ICH_FWSM_FW_VALID))
|
||||
e1000_gate_hw_phy_config_ich8lan(hw, true);
|
||||
|
||||
if (e1000_phy_is_accessible_pchlan(hw))
|
||||
if (e1000_phy_is_accessible_pchlan(hw)) {
|
||||
if (hw->mac.type == e1000_pch_lpt) {
|
||||
/* Unforce SMBus mode in PHY */
|
||||
e1e_rphy_locked(hw, CV_SMB_CTRL, &phy_reg);
|
||||
phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
|
||||
e1e_wphy_locked(hw, CV_SMB_CTRL, phy_reg);
|
||||
|
||||
/* Unforce SMBus mode in MAC */
|
||||
mac_reg = er32(CTRL_EXT);
|
||||
mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
|
||||
ew32(CTRL_EXT, mac_reg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* fall-through */
|
||||
case e1000_pchlan:
|
||||
@ -385,7 +436,15 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
|
||||
mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
|
||||
ew32(CTRL, mac_reg);
|
||||
e1e_flush();
|
||||
msleep(50);
|
||||
if (hw->mac.type < e1000_pch_lpt) {
|
||||
msleep(50);
|
||||
} else {
|
||||
u16 count = 20;
|
||||
do {
|
||||
usleep_range(5000, 10000);
|
||||
} while (!(er32(CTRL_EXT) &
|
||||
E1000_CTRL_EXT_LPCD) && count--);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -454,6 +513,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
||||
break;
|
||||
/* fall-through */
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
/*
|
||||
* In case the PHY needs to be in mdio slow mode,
|
||||
* set slow mode and try to get the PHY id again.
|
||||
@ -471,6 +531,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
||||
switch (phy->type) {
|
||||
case e1000_phy_82577:
|
||||
case e1000_phy_82579:
|
||||
case e1000_phy_i217:
|
||||
phy->ops.check_polarity = e1000_check_polarity_82577;
|
||||
phy->ops.force_speed_duplex =
|
||||
e1000_phy_force_speed_duplex_82577;
|
||||
@ -655,7 +716,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
||||
/* Adaptive IFS supported */
|
||||
mac->adaptive_ifs = true;
|
||||
|
||||
/* LED operations */
|
||||
/* LED and other operations */
|
||||
switch (mac->type) {
|
||||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
@ -678,6 +739,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
||||
mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
|
||||
mac->ops.rar_set = e1000_rar_set_pch2lan;
|
||||
/* fall-through */
|
||||
case e1000_pch_lpt:
|
||||
case e1000_pchlan:
|
||||
/* check management mode */
|
||||
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
|
||||
@ -695,12 +757,20 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mac->type == e1000_pch_lpt) {
|
||||
mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
|
||||
mac->ops.rar_set = e1000_rar_set_pch_lpt;
|
||||
}
|
||||
|
||||
/* Enable PCS Lock-loss workaround for ICH8 */
|
||||
if (mac->type == e1000_ich8lan)
|
||||
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
|
||||
|
||||
/* Gate automatic PHY configuration by hardware on managed 82579 */
|
||||
if ((mac->type == e1000_pch2lan) &&
|
||||
/*
|
||||
* Gate automatic PHY configuration by hardware on managed
|
||||
* 82579 and i217
|
||||
*/
|
||||
if ((mac->type == e1000_pch2lan || mac->type == e1000_pch_lpt) &&
|
||||
(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
|
||||
e1000_gate_hw_phy_config_ich8lan(hw, true);
|
||||
|
||||
@ -716,22 +786,50 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
|
||||
s32 ret_val = 0;
|
||||
u16 phy_reg;
|
||||
|
||||
if (hw->phy.type != e1000_phy_82579)
|
||||
if ((hw->phy.type != e1000_phy_82579) &&
|
||||
(hw->phy.type != e1000_phy_i217))
|
||||
return 0;
|
||||
|
||||
ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (hw->dev_spec.ich8lan.eee_disable)
|
||||
if (dev_spec->eee_disable)
|
||||
phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
|
||||
else
|
||||
phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;
|
||||
|
||||
return e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
|
||||
ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if ((hw->phy.type == e1000_phy_i217) && !dev_spec->eee_disable) {
|
||||
/* Save off link partner's EEE ability */
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = e1e_wphy_locked(hw, I82579_EMI_ADDR,
|
||||
I217_EEE_LP_ABILITY);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
e1e_rphy_locked(hw, I82579_EMI_DATA, &dev_spec->eee_lp_ability);
|
||||
|
||||
/*
|
||||
* EEE is not supported in 100Half, so ignore partner's EEE
|
||||
* in 100 ability if full-duplex is not advertised.
|
||||
*/
|
||||
e1e_rphy_locked(hw, PHY_LP_ABILITY, &phy_reg);
|
||||
if (!(phy_reg & NWAY_LPAR_100TX_FD_CAPS))
|
||||
dev_spec->eee_lp_ability &= ~I217_EEE_100_SUPPORTED;
|
||||
release:
|
||||
hw->phy.ops.release(hw);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -773,6 +871,9 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Clear link partner's EEE ability */
|
||||
hw->dev_spec.ich8lan.eee_lp_ability = 0;
|
||||
|
||||
if (!link)
|
||||
return 0; /* No link detected */
|
||||
|
||||
@ -868,6 +969,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
rc = e1000_init_phy_params_pchlan(hw);
|
||||
break;
|
||||
default:
|
||||
@ -1116,6 +1218,81 @@ out:
|
||||
e_dbg("Failed to write receive address at index %d\n", index);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_rar_set_pch_lpt - Set receive address registers
|
||||
* @hw: pointer to the HW structure
|
||||
* @addr: pointer to the receive address
|
||||
* @index: receive address array register
|
||||
*
|
||||
* Sets the receive address register array at index to the address passed
|
||||
* in by addr. For LPT, RAR[0] is the base address register that is to
|
||||
* contain the MAC address. SHRA[0-10] are the shared receive address
|
||||
* registers that are shared between the Host and manageability engine (ME).
|
||||
**/
|
||||
static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
|
||||
{
|
||||
u32 rar_low, rar_high;
|
||||
u32 wlock_mac;
|
||||
|
||||
/*
|
||||
* HW expects these in little endian so we reverse the byte order
|
||||
* from network order (big endian) to little endian
|
||||
*/
|
||||
rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
|
||||
((u32)addr[2] << 16) | ((u32)addr[3] << 24));
|
||||
|
||||
rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
|
||||
|
||||
/* If MAC address zero, no need to set the AV bit */
|
||||
if (rar_low || rar_high)
|
||||
rar_high |= E1000_RAH_AV;
|
||||
|
||||
if (index == 0) {
|
||||
ew32(RAL(index), rar_low);
|
||||
e1e_flush();
|
||||
ew32(RAH(index), rar_high);
|
||||
e1e_flush();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The manageability engine (ME) can lock certain SHRAR registers that
|
||||
* it is using - those registers are unavailable for use.
|
||||
*/
|
||||
if (index < hw->mac.rar_entry_count) {
|
||||
wlock_mac = er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK;
|
||||
wlock_mac >>= E1000_FWSM_WLOCK_MAC_SHIFT;
|
||||
|
||||
/* Check if all SHRAR registers are locked */
|
||||
if (wlock_mac == 1)
|
||||
goto out;
|
||||
|
||||
if ((wlock_mac == 0) || (index <= wlock_mac)) {
|
||||
s32 ret_val;
|
||||
|
||||
ret_val = e1000_acquire_swflag_ich8lan(hw);
|
||||
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ew32(SHRAL_PCH_LPT(index - 1), rar_low);
|
||||
e1e_flush();
|
||||
ew32(SHRAH_PCH_LPT(index - 1), rar_high);
|
||||
e1e_flush();
|
||||
|
||||
e1000_release_swflag_ich8lan(hw);
|
||||
|
||||
/* verify the register updates */
|
||||
if ((er32(SHRAL_PCH_LPT(index - 1)) == rar_low) &&
|
||||
(er32(SHRAH_PCH_LPT(index - 1)) == rar_high))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
e_dbg("Failed to write receive address at index %d\n", index);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
|
||||
* @hw: pointer to the HW structure
|
||||
@ -1144,6 +1321,8 @@ static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
|
||||
{
|
||||
u16 phy_data;
|
||||
u32 strap = er32(STRAP);
|
||||
u32 freq = (strap & E1000_STRAP_SMT_FREQ_MASK) >>
|
||||
E1000_STRAP_SMT_FREQ_SHIFT;
|
||||
s32 ret_val = 0;
|
||||
|
||||
strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;
|
||||
@ -1156,6 +1335,19 @@ static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
|
||||
phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
|
||||
phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
|
||||
|
||||
if (hw->phy.type == e1000_phy_i217) {
|
||||
/* Restore SMBus frequency */
|
||||
if (freq--) {
|
||||
phy_data &= ~HV_SMB_ADDR_FREQ_MASK;
|
||||
phy_data |= (freq & (1 << 0)) <<
|
||||
HV_SMB_ADDR_FREQ_LOW_SHIFT;
|
||||
phy_data |= (freq & (1 << 1)) <<
|
||||
(HV_SMB_ADDR_FREQ_HIGH_SHIFT - 1);
|
||||
} else {
|
||||
e_dbg("Unsupported SMB frequency in PHY\n");
|
||||
}
|
||||
}
|
||||
|
||||
return e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
|
||||
}
|
||||
|
||||
@ -1193,6 +1385,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
/* Fall-thru */
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
break;
|
||||
default:
|
||||
@ -1212,10 +1405,9 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (!(hw->mac.type == e1000_pch2lan)) {
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto release;
|
||||
}
|
||||
if ((hw->mac.type < e1000_pch2lan) &&
|
||||
(data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE))
|
||||
goto release;
|
||||
|
||||
cnf_size = er32(EXTCNF_SIZE);
|
||||
cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
|
||||
@ -1226,9 +1418,9 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
|
||||
cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
|
||||
|
||||
if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
|
||||
(hw->mac.type == e1000_pchlan)) ||
|
||||
(hw->mac.type == e1000_pch2lan)) {
|
||||
if (((hw->mac.type == e1000_pchlan) &&
|
||||
!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)) ||
|
||||
(hw->mac.type > e1000_pchlan)) {
|
||||
/*
|
||||
* HW configures the SMBus address and LEDs when the
|
||||
* OEM and LCD Write Enable bits are set in the NVM.
|
||||
@ -1425,14 +1617,14 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
|
||||
u32 mac_reg;
|
||||
u16 oem_reg;
|
||||
|
||||
if ((hw->mac.type != e1000_pch2lan) && (hw->mac.type != e1000_pchlan))
|
||||
if (hw->mac.type < e1000_pchlan)
|
||||
return ret_val;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (!(hw->mac.type == e1000_pch2lan)) {
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto release;
|
||||
@ -1629,7 +1821,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
|
||||
u32 mac_reg;
|
||||
u16 i;
|
||||
|
||||
if (hw->mac.type != e1000_pch2lan)
|
||||
if (hw->mac.type < e1000_pch2lan)
|
||||
return 0;
|
||||
|
||||
/* disable Rx path while enabling/disabling workaround */
|
||||
@ -1886,7 +2078,7 @@ static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
|
||||
{
|
||||
u32 extcnf_ctrl;
|
||||
|
||||
if (hw->mac.type != e1000_pch2lan)
|
||||
if (hw->mac.type < e1000_pch2lan)
|
||||
return;
|
||||
|
||||
extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
@ -3525,6 +3717,7 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
|
||||
ew32(FCTTV, hw->fc.pause_time);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82579) ||
|
||||
(hw->phy.type == e1000_phy_i217) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
ew32(FCRTV_PCH, hw->fc.refresh_time);
|
||||
|
||||
@ -3588,6 +3781,7 @@ 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;
|
||||
@ -3834,14 +4028,88 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
|
||||
* the LPLU setting in the NVM or custom setting. For PCH and newer parts,
|
||||
* the OEM bits PHY register (LED, GbE disable and LPLU configurations) also
|
||||
* needs to be written.
|
||||
* Parts that support (and are linked to a partner which support) EEE in
|
||||
* 100Mbps should disable LPLU since 100Mbps w/ EEE requires less power
|
||||
* than 10Mbps w/o EEE.
|
||||
**/
|
||||
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
|
||||
u32 phy_ctrl;
|
||||
s32 ret_val;
|
||||
|
||||
phy_ctrl = er32(PHY_CTRL);
|
||||
phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
|
||||
if (hw->phy.type == e1000_phy_i217) {
|
||||
u16 phy_reg;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (!dev_spec->eee_disable) {
|
||||
u16 eee_advert;
|
||||
|
||||
ret_val = e1e_wphy_locked(hw, I82579_EMI_ADDR,
|
||||
I217_EEE_ADVERTISEMENT);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
e1e_rphy_locked(hw, I82579_EMI_DATA, &eee_advert);
|
||||
|
||||
/*
|
||||
* Disable LPLU if both link partners support 100BaseT
|
||||
* EEE and 100Full is advertised on both ends of the
|
||||
* link.
|
||||
*/
|
||||
if ((eee_advert & I217_EEE_100_SUPPORTED) &&
|
||||
(dev_spec->eee_lp_ability &
|
||||
I217_EEE_100_SUPPORTED) &&
|
||||
(hw->phy.autoneg_advertised & ADVERTISE_100_FULL))
|
||||
phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU |
|
||||
E1000_PHY_CTRL_NOND0A_LPLU);
|
||||
}
|
||||
|
||||
/*
|
||||
* For i217 Intel Rapid Start Technology support,
|
||||
* when the system is going into Sx and no manageability engine
|
||||
* is present, the driver must configure proxy to reset only on
|
||||
* power good. LPI (Low Power Idle) state must also reset only
|
||||
* on power good, as well as the MTA (Multicast table array).
|
||||
* The SMBus release must also be disabled on LCD reset.
|
||||
*/
|
||||
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
|
||||
|
||||
/* Enable proxy to reset only on power good. */
|
||||
e1e_rphy_locked(hw, I217_PROXY_CTRL, &phy_reg);
|
||||
phy_reg |= I217_PROXY_CTRL_AUTO_DISABLE;
|
||||
e1e_wphy_locked(hw, I217_PROXY_CTRL, phy_reg);
|
||||
|
||||
/*
|
||||
* Set bit enable LPI (EEE) to reset only on
|
||||
* power good.
|
||||
*/
|
||||
e1e_rphy_locked(hw, I217_SxCTRL, &phy_reg);
|
||||
phy_reg |= I217_SxCTRL_MASK;
|
||||
e1e_wphy_locked(hw, I217_SxCTRL, phy_reg);
|
||||
|
||||
/* Disable the SMB release on LCD reset. */
|
||||
e1e_rphy_locked(hw, I217_MEMPWR, &phy_reg);
|
||||
phy_reg &= ~I217_MEMPWR;
|
||||
e1e_wphy_locked(hw, I217_MEMPWR, phy_reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable MTA to reset for Intel Rapid Start Technology
|
||||
* Support
|
||||
*/
|
||||
e1e_rphy_locked(hw, I217_CGFREG, &phy_reg);
|
||||
phy_reg |= I217_CGFREG_MASK;
|
||||
e1e_wphy_locked(hw, I217_CGFREG, phy_reg);
|
||||
|
||||
release:
|
||||
hw->phy.ops.release(hw);
|
||||
}
|
||||
out:
|
||||
ew32(PHY_CTRL, phy_ctrl);
|
||||
|
||||
if (hw->mac.type == e1000_ich8lan)
|
||||
@ -3870,6 +4138,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
* on which PHY resets are not blocked, if the PHY registers cannot be
|
||||
* accessed properly by the s/w toggle the LANPHYPC value to power cycle
|
||||
* the PHY.
|
||||
* On i217, setup Intel Rapid Start Technology.
|
||||
**/
|
||||
void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
@ -3883,6 +4152,47 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
|
||||
e_dbg("Failed to init PHY flow ret_val=%d\n", ret_val);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For i217 Intel Rapid Start Technology support when the system
|
||||
* is transitioning from Sx and no manageability engine is present
|
||||
* configure SMBus to restore on reset, disable proxy, and enable
|
||||
* the reset on MTA (Multicast table array).
|
||||
*/
|
||||
if (hw->phy.type == e1000_phy_i217) {
|
||||
u16 phy_reg;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val) {
|
||||
e_dbg("Failed to setup iRST\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
|
||||
/*
|
||||
* Restore clear on SMB if no manageability engine
|
||||
* is present
|
||||
*/
|
||||
ret_val = e1e_rphy_locked(hw, I217_MEMPWR, &phy_reg);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
phy_reg |= I217_MEMPWR_MASK;
|
||||
e1e_wphy_locked(hw, I217_MEMPWR, phy_reg);
|
||||
|
||||
/* Disable Proxy */
|
||||
e1e_wphy_locked(hw, I217_PROXY_CTRL, 0);
|
||||
}
|
||||
/* Enable reset on MTA */
|
||||
ret_val = e1e_rphy_locked(hw, I217_CGFREG, &phy_reg);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
phy_reg &= ~I217_CGFREG_MASK;
|
||||
e1e_wphy_locked(hw, I217_CGFREG, phy_reg);
|
||||
release:
|
||||
if (ret_val)
|
||||
e_dbg("Error %d in resume workarounds\n", ret_val);
|
||||
hw->phy.ops.release(hw);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4123,6 +4433,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
||||
/* Clear PHY statistics registers */
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82579) ||
|
||||
(hw->phy.type == e1000_phy_i217) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
@ -4282,3 +4593,22 @@ const struct e1000_info e1000_pch2_info = {
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &ich8_nvm_ops,
|
||||
};
|
||||
|
||||
const struct e1000_info e1000_pch_lpt_info = {
|
||||
.mac = e1000_pch_lpt,
|
||||
.flags = FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_FLASH
|
||||
| FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_APME_IN_WUC,
|
||||
.flags2 = FLAG2_HAS_PHY_STATS
|
||||
| FLAG2_HAS_EEE,
|
||||
.pba = 26,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &ich8_nvm_ops,
|
||||
};
|
||||
|
@ -79,6 +79,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
||||
[board_ich10lan] = &e1000_ich10_info,
|
||||
[board_pchlan] = &e1000_pch_info,
|
||||
[board_pch2lan] = &e1000_pch2_info,
|
||||
[board_pch_lpt] = &e1000_pch_lpt_info,
|
||||
};
|
||||
|
||||
struct e1000_reg_info {
|
||||
@ -2863,8 +2864,8 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
|
||||
u32 rctl, rfctl;
|
||||
u32 pages = 0;
|
||||
|
||||
/* Workaround Si errata on 82579 - configure jumbo frame flow */
|
||||
if (hw->mac.type == e1000_pch2lan) {
|
||||
/* Workaround Si errata on PCHx - configure jumbo frame flow */
|
||||
if (hw->mac.type >= e1000_pch2lan) {
|
||||
s32 ret_val;
|
||||
|
||||
if (adapter->netdev->mtu > ETH_DATA_LEN)
|
||||
@ -3487,6 +3488,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
||||
fc->refresh_time = 0x1000;
|
||||
break;
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
fc->high_water = 0x05C20;
|
||||
fc->low_water = 0x05048;
|
||||
fc->pause_time = 0x0650;
|
||||
@ -5264,11 +5266,11 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Jumbo frame workaround on 82579 requires CRC be stripped */
|
||||
if ((adapter->hw.mac.type == e1000_pch2lan) &&
|
||||
/* Jumbo frame workaround on 82579 and newer requires CRC be stripped */
|
||||
if ((adapter->hw.mac.type >= e1000_pch2lan) &&
|
||||
!(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
|
||||
(new_mtu > ETH_DATA_LEN)) {
|
||||
e_err("Jumbo Frames not supported on 82579 when CRC stripping is disabled.\n");
|
||||
e_err("Jumbo Frames not supported on this device when CRC stripping is disabled.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -5665,7 +5667,7 @@ static int __e1000_resume(struct pci_dev *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (hw->mac.type == e1000_pch2lan)
|
||||
if (hw->mac.type >= e1000_pch2lan)
|
||||
e1000_resume_workarounds_pchlan(&adapter->hw);
|
||||
|
||||
e1000e_power_up_phy(adapter);
|
||||
@ -6564,6 +6566,9 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
|
||||
|
@ -2335,6 +2335,9 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
|
||||
case I82579_E_PHY_ID:
|
||||
phy_type = e1000_phy_82579;
|
||||
break;
|
||||
case I217_E_PHY_ID:
|
||||
phy_type = e1000_phy_i217;
|
||||
break;
|
||||
default:
|
||||
phy_type = e1000_phy_unknown;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user