/drivers/net/ethernet/intel/e1000e/ich8lan.c
http://github.com/mirrors/linux · C · 5952 lines · 3689 code · 779 blank · 1484 comment · 789 complexity · 03598df2fc875c966397072596100a82 MD5 · raw file
Large files are truncated click here to view the full file
- // SPDX-License-Identifier: GPL-2.0
- /* Copyright(c) 1999 - 2018 Intel Corporation. */
- /* 82562G 10/100 Network Connection
- * 82562G-2 10/100 Network Connection
- * 82562GT 10/100 Network Connection
- * 82562GT-2 10/100 Network Connection
- * 82562V 10/100 Network Connection
- * 82562V-2 10/100 Network Connection
- * 82566DC-2 Gigabit Network Connection
- * 82566DC Gigabit Network Connection
- * 82566DM-2 Gigabit Network Connection
- * 82566DM Gigabit Network Connection
- * 82566MC Gigabit Network Connection
- * 82566MM Gigabit Network Connection
- * 82567LM Gigabit Network Connection
- * 82567LF Gigabit Network Connection
- * 82567V Gigabit Network Connection
- * 82567LM-2 Gigabit Network Connection
- * 82567LF-2 Gigabit Network Connection
- * 82567V-2 Gigabit Network Connection
- * 82567LF-3 Gigabit Network Connection
- * 82567LM-3 Gigabit Network Connection
- * 82567LM-4 Gigabit Network Connection
- * 82577LM Gigabit Network Connection
- * 82577LC Gigabit Network Connection
- * 82578DM Gigabit Network Connection
- * 82578DC Gigabit Network Connection
- * 82579LM Gigabit Network Connection
- * 82579V Gigabit Network Connection
- * Ethernet Connection I217-LM
- * Ethernet Connection I217-V
- * Ethernet Connection I218-V
- * Ethernet Connection I218-LM
- * Ethernet Connection (2) I218-LM
- * Ethernet Connection (2) I218-V
- * Ethernet Connection (3) I218-LM
- * Ethernet Connection (3) I218-V
- */
- #include "e1000.h"
- /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
- /* Offset 04h HSFSTS */
- union ich8_hws_flash_status {
- struct ich8_hsfsts {
- u16 flcdone:1; /* bit 0 Flash Cycle Done */
- u16 flcerr:1; /* bit 1 Flash Cycle Error */
- u16 dael:1; /* bit 2 Direct Access error Log */
- u16 berasesz:2; /* bit 4:3 Sector Erase Size */
- u16 flcinprog:1; /* bit 5 flash cycle in Progress */
- u16 reserved1:2; /* bit 13:6 Reserved */
- u16 reserved2:6; /* bit 13:6 Reserved */
- u16 fldesvalid:1; /* bit 14 Flash Descriptor Valid */
- u16 flockdn:1; /* bit 15 Flash Config Lock-Down */
- } hsf_status;
- u16 regval;
- };
- /* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
- /* Offset 06h FLCTL */
- union ich8_hws_flash_ctrl {
- struct ich8_hsflctl {
- u16 flcgo:1; /* 0 Flash Cycle Go */
- u16 flcycle:2; /* 2:1 Flash Cycle */
- u16 reserved:5; /* 7:3 Reserved */
- u16 fldbcount:2; /* 9:8 Flash Data Byte Count */
- u16 flockdn:6; /* 15:10 Reserved */
- } hsf_ctrl;
- u16 regval;
- };
- /* ICH Flash Region Access Permissions */
- union ich8_hws_flash_regacc {
- struct ich8_flracc {
- u32 grra:8; /* 0:7 GbE region Read Access */
- u32 grwa:8; /* 8:15 GbE region Write Access */
- u32 gmrag:8; /* 23:16 GbE Master Read Access Grant */
- u32 gmwag:8; /* 31:24 GbE Master Write Access Grant */
- } hsf_flregacc;
- u16 regval;
- };
- /* ICH Flash Protected Region */
- union ich8_flash_protected_range {
- struct ich8_pr {
- u32 base:13; /* 0:12 Protected Range Base */
- u32 reserved1:2; /* 13:14 Reserved */
- u32 rpe:1; /* 15 Read Protection Enable */
- u32 limit:13; /* 16:28 Protected Range Limit */
- u32 reserved2:2; /* 29:30 Reserved */
- u32 wpe:1; /* 31 Write Protection Enable */
- } range;
- u32 regval;
- };
- static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
- static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
- static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
- static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte);
- static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 *data);
- static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
- u16 *data);
- static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 *data);
- static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
- u32 *data);
- static s32 e1000_read_flash_dword_ich8lan(struct e1000_hw *hw,
- u32 offset, u32 *data);
- static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw,
- u32 offset, u32 data);
- static s32 e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw,
- u32 offset, u32 dword);
- static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
- static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
- static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
- static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
- static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
- static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
- static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
- static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
- static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
- static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
- static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
- static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
- static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
- 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 int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
- static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
- static u32 e1000_rar_get_count_pch_lpt(struct e1000_hw *hw);
- 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_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force);
- static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);
- static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state);
- static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
- {
- return readw(hw->flash_address + reg);
- }
- static inline u32 __er32flash(struct e1000_hw *hw, unsigned long reg)
- {
- return readl(hw->flash_address + reg);
- }
- static inline void __ew16flash(struct e1000_hw *hw, unsigned long reg, u16 val)
- {
- writew(val, hw->flash_address + reg);
- }
- static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
- {
- writel(val, hw->flash_address + reg);
- }
- #define er16flash(reg) __er16flash(hw, (reg))
- #define er32flash(reg) __er32flash(hw, (reg))
- #define ew16flash(reg, val) __ew16flash(hw, (reg), (val))
- #define ew32flash(reg, val) __ew32flash(hw, (reg), (val))
- /**
- * e1000_phy_is_accessible_pchlan - Check if able to access PHY registers
- * @hw: pointer to the HW structure
- *
- * Test access to the PHY registers by reading the PHY ID registers. If
- * the PHY ID is already known (e.g. resume path) compare it with known ID,
- * otherwise assume the read PHY ID is correct if it is valid.
- *
- * Assumes the sw/fw/hw semaphore is already acquired.
- **/
- static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
- {
- u16 phy_reg = 0;
- u32 phy_id = 0;
- s32 ret_val = 0;
- u16 retry_count;
- u32 mac_reg = 0;
- for (retry_count = 0; retry_count < 2; retry_count++) {
- ret_val = e1e_rphy_locked(hw, MII_PHYSID1, &phy_reg);
- if (ret_val || (phy_reg == 0xFFFF))
- continue;
- phy_id = (u32)(phy_reg << 16);
- ret_val = e1e_rphy_locked(hw, MII_PHYSID2, &phy_reg);
- if (ret_val || (phy_reg == 0xFFFF)) {
- phy_id = 0;
- continue;
- }
- phy_id |= (u32)(phy_reg & PHY_REVISION_MASK);
- break;
- }
- if (hw->phy.id) {
- if (hw->phy.id == phy_id)
- goto out;
- } else if (phy_id) {
- hw->phy.id = phy_id;
- hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK);
- goto out;
- }
- /* In case the PHY needs to be in mdio slow mode,
- * set slow mode and try to get the PHY id again.
- */
- if (hw->mac.type < e1000_pch_lpt) {
- hw->phy.ops.release(hw);
- ret_val = e1000_set_mdio_slow_mode_hv(hw);
- if (!ret_val)
- ret_val = e1000e_get_phy_id(hw);
- hw->phy.ops.acquire(hw);
- }
- if (ret_val)
- return false;
- out:
- if (hw->mac.type >= e1000_pch_lpt) {
- /* Only unforce SMBus if ME is not active */
- if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
- /* 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);
- }
- }
- return true;
- }
- /**
- * e1000_toggle_lanphypc_pch_lpt - toggle the LANPHYPC pin value
- * @hw: pointer to the HW structure
- *
- * Toggling the LANPHYPC pin value fully power-cycles the PHY and is
- * used to reset the PHY to a quiescent state when necessary.
- **/
- static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
- {
- u32 mac_reg;
- /* Set Phy Config Counter to 50msec */
- mac_reg = er32(FEXTNVM3);
- mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK;
- mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC;
- ew32(FEXTNVM3, mac_reg);
- /* Toggle LANPHYPC Value bit */
- mac_reg = er32(CTRL);
- mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE;
- mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE;
- ew32(CTRL, mac_reg);
- e1e_flush();
- usleep_range(10, 20);
- mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
- ew32(CTRL, mac_reg);
- e1e_flush();
- if (hw->mac.type < e1000_pch_lpt) {
- msleep(50);
- } else {
- u16 count = 20;
- do {
- usleep_range(5000, 6000);
- } while (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LPCD) && count--);
- msleep(30);
- }
- }
- /**
- * e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
- * @hw: pointer to the HW structure
- *
- * Workarounds/flow necessary for PHY initialization during driver load
- * and resume paths.
- **/
- static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
- {
- struct e1000_adapter *adapter = hw->adapter;
- u32 mac_reg, fwsm = er32(FWSM);
- s32 ret_val;
- /* Gate automatic PHY configuration by hardware on managed and
- * non-managed 82579 and newer adapters.
- */
- e1000_gate_hw_phy_config_ich8lan(hw, true);
- /* It is not possible to be certain of the current state of ULP
- * so forcibly disable it.
- */
- hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown;
- e1000_disable_ulp_lpt_lp(hw, true);
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val) {
- e_dbg("Failed to initialize PHY flow\n");
- goto out;
- }
- /* The MAC-PHY interconnect may be in SMBus mode. If the PHY is
- * inaccessible and resetting the PHY is not blocked, toggle the
- * LANPHYPC Value bit to force the interconnect to PCIe mode.
- */
- switch (hw->mac.type) {
- case e1000_pch_lpt:
- case e1000_pch_spt:
- case e1000_pch_cnp:
- case e1000_pch_tgp:
- case e1000_pch_adp:
- 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);
- /* Wait 50 milliseconds for MAC to finish any retries
- * that it might be trying to perform from previous
- * attempts to acknowledge any phy read requests.
- */
- msleep(50);
- /* fall-through */
- case e1000_pch2lan:
- if (e1000_phy_is_accessible_pchlan(hw))
- break;
- /* fall-through */
- case e1000_pchlan:
- if ((hw->mac.type == e1000_pchlan) &&
- (fwsm & E1000_ICH_FWSM_FW_VALID))
- break;
- if (hw->phy.ops.check_reset_block(hw)) {
- e_dbg("Required LANPHYPC toggle blocked by ME\n");
- ret_val = -E1000_ERR_PHY;
- break;
- }
- /* Toggle LANPHYPC Value bit */
- e1000_toggle_lanphypc_pch_lpt(hw);
- if (hw->mac.type >= e1000_pch_lpt) {
- if (e1000_phy_is_accessible_pchlan(hw))
- break;
- /* Toggling LANPHYPC brings the PHY out of SMBus mode
- * so ensure that the MAC is also out of SMBus mode
- */
- mac_reg = er32(CTRL_EXT);
- mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
- ew32(CTRL_EXT, mac_reg);
- if (e1000_phy_is_accessible_pchlan(hw))
- break;
- ret_val = -E1000_ERR_PHY;
- }
- break;
- default:
- break;
- }
- hw->phy.ops.release(hw);
- if (!ret_val) {
- /* Check to see if able to reset PHY. Print error if not */
- if (hw->phy.ops.check_reset_block(hw)) {
- e_err("Reset blocked by ME\n");
- goto out;
- }
- /* Reset the PHY before any access to it. Doing so, ensures
- * that the PHY is in a known good state before we read/write
- * PHY registers. The generic reset is sufficient here,
- * because we haven't determined the PHY type yet.
- */
- ret_val = e1000e_phy_hw_reset_generic(hw);
- if (ret_val)
- goto out;
- /* On a successful reset, possibly need to wait for the PHY
- * to quiesce to an accessible state before returning control
- * to the calling function. If the PHY does not quiesce, then
- * return E1000E_BLK_PHY_RESET, as this is the condition that
- * the PHY is in.
- */
- ret_val = hw->phy.ops.check_reset_block(hw);
- if (ret_val)
- e_err("ME blocked access to PHY after reset\n");
- }
- out:
- /* Ungate automatic PHY configuration on non-managed 82579 */
- if ((hw->mac.type == e1000_pch2lan) &&
- !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
- usleep_range(10000, 11000);
- e1000_gate_hw_phy_config_ich8lan(hw, false);
- }
- return ret_val;
- }
- /**
- * e1000_init_phy_params_pchlan - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific PHY parameters and function pointers.
- **/
- static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
- {
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- phy->addr = 1;
- phy->reset_delay_us = 100;
- phy->ops.set_page = e1000_set_page_igp;
- phy->ops.read_reg = e1000_read_phy_reg_hv;
- phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked;
- phy->ops.read_reg_page = e1000_read_phy_reg_page_hv;
- phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
- phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
- phy->ops.write_reg = e1000_write_phy_reg_hv;
- phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked;
- phy->ops.write_reg_page = e1000_write_phy_reg_page_hv;
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->id = e1000_phy_unknown;
- ret_val = e1000_init_phy_workarounds_pchlan(hw);
- if (ret_val)
- return ret_val;
- if (phy->id == e1000_phy_unknown)
- switch (hw->mac.type) {
- default:
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- return ret_val;
- if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
- break;
- /* fall-through */
- case e1000_pch2lan:
- case e1000_pch_lpt:
- case e1000_pch_spt:
- case e1000_pch_cnp:
- case e1000_pch_tgp:
- case e1000_pch_adp:
- /* In case the PHY needs to be in mdio slow mode,
- * set slow mode and try to get the PHY id again.
- */
- ret_val = e1000_set_mdio_slow_mode_hv(hw);
- if (ret_val)
- return ret_val;
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- return ret_val;
- break;
- }
- phy->type = e1000e_get_phy_type_from_id(phy->id);
- 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;
- phy->ops.get_cable_length = e1000_get_cable_length_82577;
- phy->ops.get_info = e1000_get_phy_info_82577;
- phy->ops.commit = e1000e_phy_sw_reset;
- break;
- case e1000_phy_82578:
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
- phy->ops.get_cable_length = e1000e_get_cable_length_m88;
- phy->ops.get_info = e1000e_get_phy_info_m88;
- break;
- default:
- ret_val = -E1000_ERR_PHY;
- break;
- }
- return ret_val;
- }
- /**
- * e1000_init_phy_params_ich8lan - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific PHY parameters and function pointers.
- **/
- static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
- {
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 i = 0;
- phy->addr = 1;
- phy->reset_delay_us = 100;
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
- /* We may need to do this twice - once for IGP and if that fails,
- * we'll set BM func pointers and try again
- */
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val) {
- phy->ops.write_reg = e1000e_write_phy_reg_bm;
- phy->ops.read_reg = e1000e_read_phy_reg_bm;
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val) {
- e_dbg("Cannot determine PHY addr. Erroring out\n");
- return ret_val;
- }
- }
- phy->id = 0;
- while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
- (i++ < 100)) {
- usleep_range(1000, 1100);
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- return ret_val;
- }
- /* Verify phy id */
- switch (phy->id) {
- case IGP03E1000_E_PHY_ID:
- phy->type = e1000_phy_igp_3;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->ops.read_reg_locked = e1000e_read_phy_reg_igp_locked;
- phy->ops.write_reg_locked = e1000e_write_phy_reg_igp_locked;
- phy->ops.get_info = e1000e_get_phy_info_igp;
- phy->ops.check_polarity = e1000_check_polarity_igp;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_igp;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- phy->type = e1000_phy_ife;
- phy->autoneg_mask = E1000_ALL_NOT_GIG;
- phy->ops.get_info = e1000_get_phy_info_ife;
- phy->ops.check_polarity = e1000_check_polarity_ife;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
- break;
- case BME1000_E_PHY_ID:
- phy->type = e1000_phy_bm;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->ops.read_reg = e1000e_read_phy_reg_bm;
- phy->ops.write_reg = e1000e_write_phy_reg_bm;
- phy->ops.commit = e1000e_phy_sw_reset;
- phy->ops.get_info = e1000e_get_phy_info_m88;
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
- break;
- default:
- return -E1000_ERR_PHY;
- }
- return 0;
- }
- /**
- * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific NVM parameters and function
- * pointers.
- **/
- static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
- {
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 gfpreg, sector_base_addr, sector_end_addr;
- u16 i;
- u32 nvm_size;
- nvm->type = e1000_nvm_flash_sw;
- if (hw->mac.type >= e1000_pch_spt) {
- /* in SPT, gfpreg doesn't exist. NVM size is taken from the
- * STRAP register. This is because in SPT the GbE Flash region
- * is no longer accessed through the flash registers. Instead,
- * the mechanism has changed, and the Flash region access
- * registers are now implemented in GbE memory space.
- */
- nvm->flash_base_addr = 0;
- nvm_size = (((er32(STRAP) >> 1) & 0x1F) + 1)
- * NVM_SIZE_MULTIPLIER;
- nvm->flash_bank_size = nvm_size / 2;
- /* Adjust to word count */
- nvm->flash_bank_size /= sizeof(u16);
- /* Set the base address for flash register access */
- hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR;
- } else {
- /* Can't read flash registers if register set isn't mapped. */
- if (!hw->flash_address) {
- e_dbg("ERROR: Flash registers not mapped\n");
- return -E1000_ERR_CONFIG;
- }
- gfpreg = er32flash(ICH_FLASH_GFPREG);
- /* sector_X_addr is a "sector"-aligned address (4096 bytes)
- * Add 1 to sector_end_addr since this sector is included in
- * the overall size.
- */
- sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
- sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
- /* flash_base_addr is byte-aligned */
- nvm->flash_base_addr = sector_base_addr
- << FLASH_SECTOR_ADDR_SHIFT;
- /* find total size of the NVM, then cut in half since the total
- * size represents two separate NVM banks.
- */
- nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
- << FLASH_SECTOR_ADDR_SHIFT);
- nvm->flash_bank_size /= 2;
- /* Adjust to word count */
- nvm->flash_bank_size /= sizeof(u16);
- }
- nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
- /* Clear shadow ram */
- for (i = 0; i < nvm->word_size; i++) {
- dev_spec->shadow_ram[i].modified = false;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
- return 0;
- }
- /**
- * e1000_init_mac_params_ich8lan - Initialize MAC function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific MAC parameters and function
- * pointers.
- **/
- static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
- {
- struct e1000_mac_info *mac = &hw->mac;
- /* Set media type function pointer */
- hw->phy.media_type = e1000_media_type_copper;
- /* Set mta register count */
- mac->mta_reg_count = 32;
- /* Set rar entry count */
- mac->rar_entry_count = E1000_ICH_RAR_ENTRIES;
- if (mac->type == e1000_ich8lan)
- mac->rar_entry_count--;
- /* FWSM register */
- mac->has_fwsm = true;
- /* ARC subsystem not supported */
- mac->arc_subsystem_valid = false;
- /* Adaptive IFS supported */
- mac->adaptive_ifs = true;
- /* LED and other operations */
- switch (mac->type) {
- case e1000_ich8lan:
- case e1000_ich9lan:
- case e1000_ich10lan:
- /* check management mode */
- mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
- /* ID LED init */
- mac->ops.id_led_init = e1000e_id_led_init_generic;
- /* blink LED */
- mac->ops.blink_led = e1000e_blink_led_generic;
- /* setup LED */
- mac->ops.setup_led = e1000e_setup_led_generic;
- /* cleanup LED */
- mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
- /* turn on/off LED */
- mac->ops.led_on = e1000_led_on_ich8lan;
- mac->ops.led_off = e1000_led_off_ich8lan;
- break;
- case e1000_pch2lan:
- mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
- mac->ops.rar_set = e1000_rar_set_pch2lan;
- /* fall-through */
- case e1000_pch_lpt:
- case e1000_pch_spt:
- case e1000_pch_cnp:
- case e1000_pch_tgp:
- case e1000_pch_adp:
- case e1000_pchlan:
- /* check management mode */
- mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
- /* ID LED init */
- mac->ops.id_led_init = e1000_id_led_init_pchlan;
- /* setup LED */
- mac->ops.setup_led = e1000_setup_led_pchlan;
- /* cleanup LED */
- mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
- /* turn on/off LED */
- mac->ops.led_on = e1000_led_on_pchlan;
- mac->ops.led_off = e1000_led_off_pchlan;
- break;
- default:
- 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;
- mac->ops.setup_physical_interface =
- e1000_setup_copper_link_pch_lpt;
- mac->ops.rar_get_count = e1000_rar_get_count_pch_lpt;
- }
- /* Enable PCS Lock-loss workaround for ICH8 */
- if (mac->type == e1000_ich8lan)
- e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
- return 0;
- }
- /**
- * __e1000_access_emi_reg_locked - Read/write EMI register
- * @hw: pointer to the HW structure
- * @addr: EMI address to program
- * @data: pointer to value to read/write from/to the EMI address
- * @read: boolean flag to indicate read or write
- *
- * This helper function assumes the SW/FW/HW Semaphore is already acquired.
- **/
- static s32 __e1000_access_emi_reg_locked(struct e1000_hw *hw, u16 address,
- u16 *data, bool read)
- {
- s32 ret_val;
- ret_val = e1e_wphy_locked(hw, I82579_EMI_ADDR, address);
- if (ret_val)
- return ret_val;
- if (read)
- ret_val = e1e_rphy_locked(hw, I82579_EMI_DATA, data);
- else
- ret_val = e1e_wphy_locked(hw, I82579_EMI_DATA, *data);
- return ret_val;
- }
- /**
- * e1000_read_emi_reg_locked - Read Extended Management Interface register
- * @hw: pointer to the HW structure
- * @addr: EMI address to program
- * @data: value to be read from the EMI address
- *
- * Assumes the SW/FW/HW Semaphore is already acquired.
- **/
- s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data)
- {
- return __e1000_access_emi_reg_locked(hw, addr, data, true);
- }
- /**
- * e1000_write_emi_reg_locked - Write Extended Management Interface register
- * @hw: pointer to the HW structure
- * @addr: EMI address to program
- * @data: value to be written to the EMI address
- *
- * Assumes the SW/FW/HW Semaphore is already acquired.
- **/
- s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
- {
- return __e1000_access_emi_reg_locked(hw, addr, &data, false);
- }
- /**
- * e1000_set_eee_pchlan - Enable/disable EEE support
- * @hw: pointer to the HW structure
- *
- * Enable/disable EEE based on setting in dev_spec structure, the duplex of
- * the link and the EEE capabilities of the link partner. The LPI Control
- * register bits will remain set only if/when link is up.
- *
- * EEE LPI must not be asserted earlier than one second after link is up.
- * On 82579, EEE LPI should not be enabled until such time otherwise there
- * can be link issues with some switches. Other devices can have EEE LPI
- * enabled immediately upon link up since they have a timer in hardware which
- * prevents LPI from being asserted too early.
- **/
- s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
- {
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- s32 ret_val;
- u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data;
- 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)
- return ret_val;
- ret_val = e1e_rphy_locked(hw, I82579_LPI_CTRL, &lpi_ctrl);
- if (ret_val)
- goto release;
- /* Clear bits that enable EEE in various speeds */
- lpi_ctrl &= ~I82579_LPI_CTRL_ENABLE_MASK;
- /* Enable EEE if not disabled by user */
- if (!dev_spec->eee_disable) {
- /* Save off link partner's EEE ability */
- 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 and for which we advertise EEE.
- */
- if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
- lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE;
- 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;
- else
- /* EEE is not supported in 100Half, so ignore
- * partner's EEE in 100 ability if full-duplex
- * is not advertised.
- */
- dev_spec->eee_lp_ability &=
- ~I82579_EEE_100_SUPPORTED;
- }
- }
- if (hw->phy.type == e1000_phy_82579) {
- ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
- &data);
- if (ret_val)
- goto release;
- data &= ~I82579_LPI_100_PLL_SHUT;
- ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
- data);
- }
- /* 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:
- hw->phy.ops.release(hw);
- return ret_val;
- }
- /**
- * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP
- * @hw: pointer to the HW structure
- * @link: link up bool flag
- *
- * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
- * preventing further DMA write requests. Workaround the issue by disabling
- * the de-assertion of the clock request when in 1Gpbs mode.
- * Also, set appropriate Tx re-transmission timeouts for 10 and 100Half link
- * speeds in order to avoid Tx hangs.
- **/
- static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
- {
- u32 fextnvm6 = er32(FEXTNVM6);
- u32 status = er32(STATUS);
- s32 ret_val = 0;
- u16 reg;
- if (link && (status & E1000_STATUS_SPEED_1000)) {
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
- ret_val =
- e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
- ®);
- if (ret_val)
- goto release;
- ret_val =
- e1000e_write_kmrn_reg_locked(hw,
- E1000_KMRNCTRLSTA_K1_CONFIG,
- reg &
- ~E1000_KMRNCTRLSTA_K1_ENABLE);
- if (ret_val)
- goto release;
- usleep_range(10, 20);
- ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK);
- ret_val =
- e1000e_write_kmrn_reg_locked(hw,
- E1000_KMRNCTRLSTA_K1_CONFIG,
- reg);
- release:
- hw->phy.ops.release(hw);
- } else {
- /* clear FEXTNVM6 bit 8 on link down or 10/100 */
- fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
- if ((hw->phy.revision > 5) || !link ||
- ((status & E1000_STATUS_SPEED_100) &&
- (status & E1000_STATUS_FD)))
- goto update_fextnvm6;
- ret_val = e1e_rphy(hw, I217_INBAND_CTRL, ®);
- if (ret_val)
- return ret_val;
- /* Clear link status transmit timeout */
- reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK;
- if (status & E1000_STATUS_SPEED_100) {
- /* Set inband Tx timeout to 5x10us for 100Half */
- reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
- /* Do not extend the K1 entry latency for 100Half */
- fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
- } else {
- /* Set inband Tx timeout to 50x10us for 10Full/Half */
- reg |= 50 <<
- I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
- /* Extend the K1 entry latency for 10 Mbps */
- fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
- }
- ret_val = e1e_wphy(hw, I217_INBAND_CTRL, reg);
- if (ret_val)
- return ret_val;
- update_fextnvm6:
- ew32(FEXTNVM6, fextnvm6);
- }
- 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 */
- u64 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.
- */
- rxa *= 512;
- value = (rxa > hw->adapter->max_frame_size) ?
- (rxa - hw->adapter->max_frame_size) * (16000 / speed) :
- 0;
- while (value > PCI_LTR_VALUE_MASK) {
- scale++;
- value = DIV_ROUND_UP(value, BIT(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_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP
- * @hw: pointer to the HW structure
- * @to_sx: boolean indicating a system power state transition to Sx
- *
- * When link is down, configure ULP mode to significantly reduce the power
- * to the PHY. If on a Manageability Engine (ME) enabled system, tell the
- * ME firmware to start the ULP configuration. If not on an ME enabled
- * system, configure the ULP mode by software.
- */
- s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
- {
- u32 mac_reg;
- s32 ret_val = 0;
- u16 phy_reg;
- u16 oem_reg = 0;
- if ((hw->mac.type < e1000_pch_lpt) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_V) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM2) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V2) ||
- (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on))
- return 0;
- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
- /* Request ME configure ULP mode in the PHY */
- mac_reg = er32(H2ME);
- mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS;
- ew32(H2ME, mac_reg);
- goto out;
- }
- if (!to_sx) {
- int i = 0;
- /* Poll up to 5 seconds for Cable Disconnected indication */
- while (!(er32(FEXT) & E1000_FEXT_PHY_CABLE_DISCONNECTED)) {
- /* Bail if link is re-acquired */
- if (er32(STATUS) & E1000_STATUS_LU)
- return -E1000_ERR_PHY;
- if (i++ == 100)
- break;
- msleep(50);
- }
- e_dbg("CABLE_DISCONNECTED %s set after %dmsec\n",
- (er32(FEXT) &
- E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not", i * 50);
- }
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
- /* Force SMBus mode in PHY */
- ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
- if (ret_val)
- goto release;
- phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
- e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
- /* Force SMBus mode in MAC */
- mac_reg = er32(CTRL_EXT);
- mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
- ew32(CTRL_EXT, mac_reg);
- /* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
- * LPLU and disable Gig speed when entering ULP
- */
- if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
- ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
- &oem_reg);
- if (ret_val)
- goto release;
- phy_reg = oem_reg;
- phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
- ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
- phy_reg);
- if (ret_val)
- goto release;
- }
- /* Set Inband ULP Exit, Reset to SMBus mode and
- * Disable SMBus Release on PERST# in PHY
- */
- ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg);
- if (ret_val)
- goto release;
- phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS |
- I218_ULP_CONFIG1_DISABLE_SMB_PERST);
- if (to_sx) {
- if (er32(WUFC) & E1000_WUFC_LNKC)
- phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
- else
- phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
- phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
- phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT;
- } else {
- phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
- phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP;
- phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
- }
- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
- /* Set Disable SMBus Release on PERST# in MAC */
- mac_reg = er32(FEXTNVM7);
- mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST;
- ew32(FEXTNVM7, mac_reg);
- /* Commit ULP changes in PHY by starting auto ULP configuration */
- phy_reg |= I218_ULP_CONFIG1_START;
- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
- if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) &&
- to_sx && (er32(STATUS) & E1000_STATUS_LU)) {
- ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
- oem_reg);
- if (ret_val)
- goto release;
- }
- release:
- hw->phy.ops.release(hw);
- out:
- if (ret_val)
- e_dbg("Error in ULP enable flow: %d\n", ret_val);
- else
- hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on;
- return ret_val;
- }
- /**
- * e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for LynxPoint-LP
- * @hw: pointer to the HW structure
- * @force: boolean indicating whether or not to force disabling ULP
- *
- * Un-configure ULP mode when link is up, the system is transitioned from
- * Sx or the driver is unloaded. If on a Manageability Engine (ME) enabled
- * system, poll for an indication from ME that ULP has been un-configured.
- * If not on an ME enabled system, un-configure the ULP mode by software.
- *
- * During nominal operation, this function is called when link is acquired
- * to disable ULP mode (force=false); otherwise, for example when unloading
- * the driver or during Sx->S0 transitions, this is called with force=true
- * to forcibly disable ULP.
- */
- static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
- {
- s32 ret_val = 0;
- u32 mac_reg;
- u16 phy_reg;
- int i = 0;
- if ((hw->mac.type < e1000_pch_lpt) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_V) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM2) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V2) ||
- (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_off))
- return 0;
- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
- if (force) {
- /* Request ME un-configure ULP mode in the PHY */
- mac_reg = er32(H2ME);
- mac_reg &= ~E1000_H2ME_ULP;
- mac_reg |= E1000_H2ME_ENFORCE_SETTINGS;
- ew32(H2ME, mac_reg);
- }
- /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */
- while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) {
- if (i++ == 30) {
- ret_val = -E1000_ERR_PHY;
- goto out;
- }
- usleep_range(10000, 11000);
- }
- e_dbg("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10);
- if (force) {
- mac_reg = er32(H2ME);
- mac_reg &= ~E1000_H2ME_ENFORCE_SETTINGS;
- ew32(H2ME, mac_reg);
- } else {
- /* Clear H2ME.ULP after ME ULP configuration */
- mac_reg = er32(H2ME);
- mac_reg &= ~E1000_H2ME_ULP;
- ew32(H2ME, mac_reg);
- }
- goto out;
- }
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
- if (force)
- /* Toggle LANPHYPC Value bit */
- e1000_toggle_lanphypc_pch_lpt(hw);
- /* Unforce SMBus mode in PHY */
- ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
- if (ret_val) {
- /* The MAC might be in PCIe mode, so temporarily force to
- * SMBus mode in order to access the PHY.
- */
- mac_reg = er32(CTRL_EXT);
- mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
- ew32(CTRL_EXT, mac_reg);
- msleep(50);
- ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL,
- &phy_reg);
- if (ret_val)
- goto release;
- }
- phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
- e1000_write_phy_reg_hv_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);
- /* When ULP mode was previously entered, K1 was disabled by the
- * hardware. Re-Enable K1 in the PHY when exiting ULP.
- */
- ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg);
- if (ret_val)
- goto release;
- phy_reg |= HV_PM_CTRL_K1_ENABLE;
- e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg);
- /* Clear ULP enabled configuration */
- ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg);
- if (ret_val)
- goto release;
- phy_reg &= ~(I218_ULP_CONFIG1_IND |
- I218_ULP_CONFIG1_STICKY_ULP |
- I218_ULP_CONFIG1_RESET_TO_SMBUS |
- I218_ULP_CONFIG1_WOL_HOST |
- I218_ULP_CONFIG1_INBAND_EXIT |
- I218_ULP_CONFIG1_EN_ULP_LANPHYPC |
- I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST |
- I218_ULP_CONFIG1_DISABLE_SMB_PERST);
- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
- /* Commit ULP changes by starting auto ULP configuration */
- phy_reg |= I218_ULP_CONFIG1_START;
- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
- /* Clear Disable SMBus Release on PERST# in MAC */
- mac_reg = er32(FEXTNVM7);
- mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST;
- ew32(FEXTNVM7, mac_reg);
- release:
- hw->phy.ops.release(hw);
- if (force) {
- e1000_phy_hw_reset(hw);
- msleep(50);
- }
- out:
- if (ret_val)
- e_dbg("Error in ULP disable flow: %d\n", ret_val);
- else
- hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_off;
- return ret_val;
- }
- /**
- * e1000_check_for_copper_link_ich8lan - Check for link (Copper)
- * @hw: pointer to the HW structure
- *
- * Checks to see of the link status of the hardware has changed. If a
- * change in link status has been detected, then we read the PHY registers
- * to get the current speed/duplex if link exists.
- **/
- static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
- {
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val, tipg_reg = 0;
- u16 emi_addr, emi_val = 0;
- bool link;
- u16 phy_reg;
- /* We only want to go out to the PHY registers to see if Auto-Neg
- * has completed and/or if our link status has changed. The
- * get_link_status flag is set upon receiving a Link Status
- * Change or Rx Sequence Error interrupt.
- */
- if (!mac->get_link_status)
- return 0;
- mac->get_link_status = false;
- /* First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- */
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- goto out;
- if (hw->mac.type == e1000_pchlan) {
- ret_val = e1000_k1_gig_workaround_hv(hw, link);
- if (ret_val)
- goto out;
- }
- /* When connected at 10Mbps half-duplex, some 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) {
- u16 speed, duplex;
- e1000e_get_speed_and_duplex_copper(hw, &speed, &duplex);
- tipg_reg = er32(TIPG);
- tipg_reg &= ~E1000_TIPG_IPGT_MASK;
- if (duplex == HALF_DUPLEX && speed == SPEED_10) {
- tipg_reg |= 0xFF;
- /* Reduce Rx latency in analog PHY */
- emi_val = 0;
- } else if (hw->mac.type >= e1000_pch_spt &&
- duplex == FULL_DUPLEX && speed != SPEED_1000) {
- tipg_reg |= 0xC;
- emi_val = 1;
- } else {
- /* Roll back the default values */
- tipg_reg |= 0x08;
- emi_val = 1;
- }
- ew32(TIPG, tipg_reg);
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
- if (hw->mac.type == e1000_pch2lan)
- emi_addr = I82579_RX_CONFIG;
- else
- emi_addr = I217_RX_CONFIG;
- ret_val = e1000_write_emi_reg_locked(hw, emi_addr, emi_val);
- if (hw->mac.type >= e1000_pch_lpt) {
- u16 phy_reg;
- e1e_rphy_locked(hw, I217_PLL_CLOCK_GATE_REG, &phy_reg);
- phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;
- if (speed == SPEED_100 || speed == SPEED_10)
- phy_reg |= 0x3E8;
- else
- phy_reg |= 0xFA;
- e1e_wphy_locked(hw, I217_PLL_CLOCK_GATE_REG, phy_reg);
- if (speed == SPEED_1000) {
- hw->phy.ops.read_reg_locked(hw, HV_PM_CTRL,
- &phy_reg);
- phy_reg |= HV_PM_CTRL_K1_CLK_REQ;
- hw->phy.ops.write_reg_locked(hw, HV_PM_CTRL,
- phy_reg);
- }
- }
- hw->phy.ops.release(hw);
- if (ret_val)
- goto out;
- if (hw->mac.type >= e1000_pch_spt) {
- u16 data;
- u16 ptr_gap;
- if (speed == SPEED_1000) {
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
- ret_val = e1e_rphy_locked(hw,
- PHY_REG(776, 20),
- &data);
- if (ret_val) {
- hw->phy.ops.release(hw);
- goto out;
- }
- ptr_gap = (data & (0x3FF << 2)) >> 2;
- if (ptr_gap < 0x18) {
- data &= ~(0x3FF << 2);
- data |= (0x18 << 2);
- ret_val =
- e1e_wphy_locked(hw,
- PHY_REG(776, 20),
- data);
- }
- hw->phy.ops.release(hw);
- if (ret_val)
- goto out;
- } else {
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
- ret_val = e1e_wphy_locked(hw,
- PHY_REG(776, 20),
- 0xC023);
- hw->phy.ops.release(hw);
- if (ret_val)
- goto out;
- }
- }
- }
- /* I217 Packet Loss issue:
- * ensure that FEXTNVM4 Beacon Duration is set correctly
- * on power up.
- * Set the Beacon Duration for I217 to 8 usec
- */
- if (hw->mac.type >= e1000_pch_lpt) {
- u32 mac_reg;
- mac_reg = er32(FEXTNVM4);
- mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
- mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
- ew32(FEXTNVM4, mac_reg);
- }
- /* 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) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM3) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) {
- ret_val = e1000_k1_workaround_lpt_lp(hw, link);
- if (ret_val)
- goto out;
- }
- 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)
- goto out;
- }
- /* Clear link partner's EEE ability */
- hw->dev_spec.ich8lan.eee_lp_ability = 0;
- if (hw->mac.type >= e1000_pch_lpt) {
- u32 fextnvm6 = er32(FEXTNVM6);
- if (hw->mac.type == e1000_pch_spt) {
- /* FEXTNVM6 K1-off workaround - for SPT only */
- u32 pcieanacfg = er32(PCIEANACFG);
- if (pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE)
- fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE;
- else
- fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
- }
- ew32(FEXTNVM6, fextnvm6);
- }
- if (!link)
- goto out;
- switch (hw->mac.type) {
- case e1000_pch2lan:
- ret_val = e1000_k1_workaround_lv(hw);
- if (ret_val)
- return ret_val;
- /* fall-thru */
- case e1000_pchlan:
- if (hw->phy.type == e1000_phy_82578) {
- ret_val = e1000_link_stall_workaround_hv(hw);
- if (ret_val)
- return ret_val;
- }
- /* Workaround for PCHx parts in half-duplex:
- * Set the number of preambles removed from the packet
- * when it is passed from the PHY to the MAC to prevent
- * the MAC from misinterpreting the packet type.
- */
- e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg);
- phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK;
- if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD)
- phy_reg |= BIT(HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT);
- e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg);
- break;
- default:
- break;
- }
- /* Check if there was DownShift, must be checked
- * immediately after link-up
- */
- e1000e_check_downshift(hw);
- /* Enable/Disable EEE after link up */
- if (hw->phy.type > e1000_phy_82579) {
- ret_val = e1000_set_eee_pchlan(hw);
- if (ret_val)
- return ret_val;
- }
- /* If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if (!mac->autoneg)
- return -E1000_ERR_CONFIG;
- /* Auto-Neg is enabled. Auto Speed Detection takes care
- * of MAC speed/duplex configuration. So we only need to
- * configure Collision Distance in the MAC.
- */
- mac->ops.config_collision_dist(hw);
- /* Configure Flow Control now that Auto-Neg has completed.
- * First, we need to restore the desired flow control
- * settings because we may have had to re-autoneg with a
- * different link partner.
- */
- ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val)
- e_dbg("Error configuring flow control\n");
- return ret_val;
- out:
- mac->get_link_status = true;
- return ret_val;
- }
- static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
- {
- struct e1000_hw *hw = &adapter->hw;
- s32 rc;
- rc = e1000_init_mac_params_ich8lan(hw);
- if (rc)
- return rc;
- rc = e1000_init_nvm_params_ich8lan(hw);
- if (rc)
- return rc;
- switch (hw->mac.type) {
- case e1000_ich8lan:
- case e1000_ich9lan:
- case e1000_ich10lan:
- rc = e1000_init_phy_params_ich8lan(hw);
- break;
- case e1000_pchlan:
- case e1000_pch2lan:
- case e1000_pch_lpt:
- case e1000_pch_spt:
- case e1000_pch_cnp:
- case e1000_pch_tgp:
- case e1000_pch_adp:
- rc = e1000_init_phy_params_pchlan(hw);
- break;
- default:
- break;
- }
- if (rc)
- return rc;
- /* Disable Jumbo Frame support on parts with Intel 10/100 PHY or
- * on parts with MACsec enabled in NVM (reflected in CTRL_EXT).
- */
- if ((adapter->hw.phy.type == e1000_phy_ife) ||
- ((adapter->hw.mac.type >= e1000_pch2lan) &&
- (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
- adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
- adapter->max_hw_frame_size = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
- hw->mac.ops.blink_led = NULL;
- }
- if ((adapter->hw.mac.type == e1000_ich8lan) &&
- (adapter->hw.phy.type != e1000_phy_ife))
- adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
- /* Enable workaround for 82579 w/ ME enabled */
- if ((adapter->hw.mac.type == e1000_pch2lan) &&
- (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
- adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA;
- return 0;
- }
- static DEFINE_MUTEX(nvm_mutex);
- /**
- * e1000_acquire_nvm_ich8lan - Acquire NVM mutex
- * @hw: pointer to the HW structure
- *
- * Acquires the mutex for performing NVM operations.
- **/
- static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw __always_unused *hw)
- {
- mutex_lock(&nvm_mutex);
- return 0;
- }
- /**
- * e1000_release_nvm_ich8lan - Release NVM mutex
- * @hw: pointer to the HW structure
- *
- * Releases the mutex used while performing NVM operations.
- **/
- static void e1000_release_nvm_ich8lan(struct e1000_hw __always_unused *hw)
- {
- mutex_unlock(&nvm_mutex);
- }
- /**
- * e1000_acquire_swflag_ich8lan - Acquire software control flag
- * @hw: pointer to the HW structure
- *
- * Acquires the software control flag for performing PHY and select
- * MAC CSR accesses.
- **/
- static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
- {
- u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
- s32 ret_val = 0;
- if (test_and_set_bit(__E1000_ACCESS_SHARED_RESOURCE,
- &hw->adapter->state)) {
- e_dbg("contention for Phy access\n");
- return -E1000_ERR_PHY;
- }
- while (timeout) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
- break;
- mdelay(1);
- timeout--;
- }
- if (!timeout) {
- e_dbg("SW has alre…