david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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>
This commit is contained in:
Daniel Hokka Zakrisson 2012-04-06 10:13:04 +02:00 committed by Michael Brown
parent dcccb1fb7b
commit 0e4a5ca4c7
7 changed files with 67 additions and 15 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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 {

View File

@ -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, &reg);
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 = {

View File

@ -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

View File

@ -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 */

View File

@ -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;