mirror of https://github.com/ipxe/ipxe.git
[e1000e] Basic 82579 support
Add support for 82579-based chips such as those found on Sandy Bridge motherboards. Based on d3738bb8203acf8552c3ec8b3447133fc0938ddd in Linux. Signed-off-by: Daniel Hokka Zakrisson <daniel@hozac.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/6/head
parent
dcccb1fb7b
commit
0e4a5ca4c7
|
@ -143,6 +143,7 @@ enum e1000_boards {
|
|||
board_ich9lan,
|
||||
board_ich10lan,
|
||||
board_pchlan,
|
||||
board_pch2lan,
|
||||
board_82583,
|
||||
};
|
||||
|
||||
|
@ -300,6 +301,7 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
|
|||
extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
||||
extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
|
||||
extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
|
||||
extern s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
|
||||
|
||||
extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
|
||||
|
|
|
@ -675,6 +675,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
|
||||
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
|
||||
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
|
||||
#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
|
||||
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000
|
||||
|
@ -1261,6 +1262,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
#define I82579_E_PHY_ID 0x01540090
|
||||
#define M88_VENDOR 0x0141
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
|
|
|
@ -85,6 +85,8 @@ struct e1000_hw;
|
|||
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
|
||||
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
|
||||
#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_REVISION_0 0
|
||||
#define E1000_REVISION_1 1
|
||||
#define E1000_REVISION_2 2
|
||||
|
@ -109,6 +111,7 @@ enum e1000_mac_type {
|
|||
e1000_ich9lan,
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
e1000_pch2lan,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
|
||||
};
|
||||
|
||||
|
@ -146,6 +149,7 @@ enum e1000_phy_type {
|
|||
e1000_phy_bm,
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
e1000_phy_82579,
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
|
|
|
@ -206,7 +206,7 @@ static s32 e1000e_init_phy_params_pchlan(struct e1000_hw *hw)
|
|||
e1000e_get_phy_id(hw);
|
||||
phy->type = e1000e_get_phy_type_from_id(phy->id);
|
||||
|
||||
if (phy->type == e1000_phy_82577) {
|
||||
if (phy->type == e1000_phy_82577 || phy->type == e1000_phy_82579) {
|
||||
phy->ops.check_polarity = e1000e_check_polarity_82577;
|
||||
#if 0
|
||||
phy->ops.force_speed_duplex =
|
||||
|
@ -449,6 +449,7 @@ static s32 e1000e_init_mac_params_ich8lan(struct e1000_hw *hw)
|
|||
mac->ops.led_off = e1000e_led_off_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000e_id_led_init_pchlan;
|
||||
/* setup LED */
|
||||
|
@ -467,6 +468,14 @@ static s32 e1000e_init_mac_params_ich8lan(struct e1000_hw *hw)
|
|||
if (mac->type == e1000_ich8lan)
|
||||
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
|
||||
|
||||
/* Disable PHY configuration by hardware, config by software */
|
||||
if (mac->type == e1000_pch2lan) {
|
||||
u32 extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
|
||||
ew32(EXTCNF_CTRL, extcnf_ctrl);
|
||||
}
|
||||
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
@ -577,6 +586,7 @@ void e1000e_init_function_pointers_ich8lan(struct e1000_hw *hw)
|
|||
hw->phy.ops.init_params = e1000e_init_phy_params_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
hw->phy.ops.init_params = e1000e_init_phy_params_pchlan;
|
||||
break;
|
||||
default:
|
||||
|
@ -765,7 +775,8 @@ static s32 e1000e_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
/* Check if SW needs to configure the PHY */
|
||||
if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
|
||||
(hw->device_id == E1000_DEV_ID_ICH8_IGP_M) ||
|
||||
(hw->mac.type == e1000_pchlan))
|
||||
(hw->mac.type == e1000_pchlan) ||
|
||||
(hw->mac.type == e1000_pch2lan))
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
else
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
|
@ -777,13 +788,15 @@ static s32 e1000e_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
/* Wait for basic configuration completes before proceeding */
|
||||
e1000e_lan_init_done_ich8lan(hw);
|
||||
|
||||
/*
|
||||
* Make sure HW does not configure LCD from PHY
|
||||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto out;
|
||||
if (hw->mac.type != e1000_pch2lan) {
|
||||
/*
|
||||
* Make sure HW does not configure LCD from PHY
|
||||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto out;
|
||||
}
|
||||
|
||||
cnf_size = er32(EXTCNF_SIZE);
|
||||
cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
|
||||
|
@ -795,7 +808,8 @@ static s32 e1000e_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
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_pchlan ||
|
||||
hw->mac.type == e1000_pch2lan)) {
|
||||
/*
|
||||
* HW configures the SMBus address and LEDs when the
|
||||
* OEM and LCD Write Enable bits are set in the NVM.
|
||||
|
@ -1006,16 +1020,18 @@ s32 e1000e_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
|
|||
u32 mac_reg;
|
||||
u16 oem_reg;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
if (hw->mac.type != e1000_pchlan && hw->mac.type != e1000_pch2lan)
|
||||
return ret_val;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto out;
|
||||
if (hw->mac.type != e1000_pch2lan) {
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mac_reg = er32(FEXTNVM);
|
||||
if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
|
||||
|
@ -2573,7 +2589,7 @@ static s32 e1000e_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
}
|
||||
}
|
||||
/* Dummy read to clear the phy wakeup bit after lcd reset */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
if (hw->mac.type == e1000_pchlan || hw->mac.type == e1000_pch2lan)
|
||||
e1e_rphy(hw, BM_WUC, ®);
|
||||
|
||||
ret_val = e1000e_sw_lcd_config_ich8lan(hw);
|
||||
|
@ -2791,6 +2807,7 @@ static s32 e1000e_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_82577)) {
|
||||
ret_val = e1e_wphy(hw,
|
||||
PHY_REG(BM_PORT_CTRL_PAGE, 27),
|
||||
|
@ -2859,6 +2876,7 @@ static s32 e1000e_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
goto out;
|
||||
break;
|
||||
case e1000_phy_82577:
|
||||
case e1000_phy_82579:
|
||||
ret_val = e1000e_copper_link_setup_82577(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
@ -3388,6 +3406,7 @@ static void e1000e_clear_hw_cntrs_ich8lan(struct e1000_hw *hw __unused)
|
|||
|
||||
/* Clear PHY statistics registers */
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82579) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
|
||||
|
@ -3434,6 +3453,8 @@ static struct pci_device_id e1000e_ich8lan_nics[] = {
|
|||
PCI_ROM(0x8086, 0x10EB, "E1000_DEV_ID_PCH_M_HV_LC", "E1000_DEV_ID_PCH_M_HV_LC", board_pchlan),
|
||||
PCI_ROM(0x8086, 0x10EF, "E1000_DEV_ID_PCH_D_HV_DM", "E1000_DEV_ID_PCH_D_HV_DM", board_pchlan),
|
||||
PCI_ROM(0x8086, 0x10F0, "E1000_DEV_ID_PCH_D_HV_DC", "E1000_DEV_ID_PCH_D_HV_DC", board_pchlan),
|
||||
PCI_ROM(0x8086, 0x1502, "E1000_DEV_ID_PCH2_LV_LM", "E1000_DEV_ID_PCH2_LV_LM", board_pch2lan),
|
||||
PCI_ROM(0x8086, 0x1503, "E1000_DEV_ID_PCH2_LV_V", "E1000_DEV_ID_PCH2_LV_V", board_pch2lan),
|
||||
};
|
||||
|
||||
struct pci_driver e1000e_ich8lan_driver __pci_driver = {
|
||||
|
|
|
@ -146,6 +146,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#define HV_SMB_ADDR_PEC_EN 0x0200
|
||||
#define HV_SMB_ADDR_VALID 0x0080
|
||||
|
||||
/* PHY Power Management Control */
|
||||
#define HV_PM_CTRL PHY_REG(770, 17)
|
||||
|
||||
/* Strapping Option Register - RO */
|
||||
#define E1000_STRAP 0x0000C
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
|
||||
|
|
|
@ -279,6 +279,22 @@ static struct e1000_info e1000_pch_info = {
|
|||
.get_variants = e1000e_get_variants_ich8lan,
|
||||
};
|
||||
|
||||
static struct e1000_info e1000_pch2_info = {
|
||||
.mac = e1000_pch2lan,
|
||||
.flags = FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_RX_CSUM_ENABLED
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_FLASH
|
||||
| FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_APME_IN_WUC,
|
||||
.pba = 26,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.init_ops = e1000e_init_function_pointers_ich8lan,
|
||||
.get_variants = e1000e_get_variants_ich8lan,
|
||||
};
|
||||
|
||||
static const struct e1000_info *e1000_info_tbl[] = {
|
||||
[board_82571] = &e1000_82571_info,
|
||||
[board_82572] = &e1000_82572_info,
|
||||
|
@ -290,6 +306,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
|||
[board_ich9lan] = &e1000_ich9_info,
|
||||
[board_ich10lan] = &e1000_ich10_info,
|
||||
[board_pchlan] = &e1000_pch_info,
|
||||
[board_pch2lan] = &e1000_pch2_info,
|
||||
};
|
||||
|
||||
/* Low-level support routines */
|
||||
|
|
|
@ -2332,6 +2332,9 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
|
|||
case I82577_E_PHY_ID:
|
||||
phy_type = e1000_phy_82577;
|
||||
break;
|
||||
case I82579_E_PHY_ID:
|
||||
phy_type = e1000_phy_82579;
|
||||
break;
|
||||
default:
|
||||
phy_type = e1000_phy_unknown;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue