diff --git a/src/drivers/net/e1000e/e1000e.h b/src/drivers/net/e1000e/e1000e.h index bc8e7b08..0e537932 100644 --- a/src/drivers/net/e1000e/e1000e.h +++ b/src/drivers/net/e1000e/e1000e.h @@ -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); diff --git a/src/drivers/net/e1000e/e1000e_defines.h b/src/drivers/net/e1000e/e1000e_defines.h index da135d91..8cfc6ed8 100644 --- a/src/drivers/net/e1000e/e1000e_defines.h +++ b/src/drivers/net/e1000e/e1000e_defines.h @@ -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 */ diff --git a/src/drivers/net/e1000e/e1000e_hw.h b/src/drivers/net/e1000e/e1000e_hw.h index 03ed35c9..336af30d 100644 --- a/src/drivers/net/e1000e/e1000e_hw.h +++ b/src/drivers/net/e1000e/e1000e_hw.h @@ -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 { diff --git a/src/drivers/net/e1000e/e1000e_ich8lan.c b/src/drivers/net/e1000e/e1000e_ich8lan.c index 7b9a49b9..d438ff1e 100644 --- a/src/drivers/net/e1000e/e1000e_ich8lan.c +++ b/src/drivers/net/e1000e/e1000e_ich8lan.c @@ -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 = { diff --git a/src/drivers/net/e1000e/e1000e_ich8lan.h b/src/drivers/net/e1000e/e1000e_ich8lan.h index af344782..8b145d92 100644 --- a/src/drivers/net/e1000e/e1000e_ich8lan.h +++ b/src/drivers/net/e1000e/e1000e_ich8lan.h @@ -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 diff --git a/src/drivers/net/e1000e/e1000e_main.c b/src/drivers/net/e1000e/e1000e_main.c index 352e3c45..69a5bc20 100644 --- a/src/drivers/net/e1000e/e1000e_main.c +++ b/src/drivers/net/e1000e/e1000e_main.c @@ -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 */ diff --git a/src/drivers/net/e1000e/e1000e_phy.c b/src/drivers/net/e1000e/e1000e_phy.c index 337be737..133109dc 100644 --- a/src/drivers/net/e1000e/e1000e_phy.c +++ b/src/drivers/net/e1000e/e1000e_phy.c @@ -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;