175eba5b6SRobert Mustacchi /****************************************************************************** 275eba5b6SRobert Mustacchi 3*42cc51e0SRobert Mustacchi Copyright (c) 2001-2015, Intel Corporation 475eba5b6SRobert Mustacchi All rights reserved. 575eba5b6SRobert Mustacchi 675eba5b6SRobert Mustacchi Redistribution and use in source and binary forms, with or without 775eba5b6SRobert Mustacchi modification, are permitted provided that the following conditions are met: 875eba5b6SRobert Mustacchi 975eba5b6SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice, 1075eba5b6SRobert Mustacchi this list of conditions and the following disclaimer. 1175eba5b6SRobert Mustacchi 1275eba5b6SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright 1375eba5b6SRobert Mustacchi notice, this list of conditions and the following disclaimer in the 1475eba5b6SRobert Mustacchi documentation and/or other materials provided with the distribution. 1575eba5b6SRobert Mustacchi 1675eba5b6SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its 1775eba5b6SRobert Mustacchi contributors may be used to endorse or promote products derived from 1875eba5b6SRobert Mustacchi this software without specific prior written permission. 1975eba5b6SRobert Mustacchi 2075eba5b6SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2175eba5b6SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2275eba5b6SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2375eba5b6SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2475eba5b6SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2575eba5b6SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2675eba5b6SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2775eba5b6SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2875eba5b6SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2975eba5b6SRobert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3075eba5b6SRobert Mustacchi POSSIBILITY OF SUCH DAMAGE. 3175eba5b6SRobert Mustacchi 3275eba5b6SRobert Mustacchi ******************************************************************************/ 3375eba5b6SRobert Mustacchi /*$FreeBSD$*/ 3475eba5b6SRobert Mustacchi 3575eba5b6SRobert Mustacchi /* 82562G 10/100 Network Connection 3675eba5b6SRobert Mustacchi * 82562G-2 10/100 Network Connection 3775eba5b6SRobert Mustacchi * 82562GT 10/100 Network Connection 3875eba5b6SRobert Mustacchi * 82562GT-2 10/100 Network Connection 3975eba5b6SRobert Mustacchi * 82562V 10/100 Network Connection 4075eba5b6SRobert Mustacchi * 82562V-2 10/100 Network Connection 4175eba5b6SRobert Mustacchi * 82566DC-2 Gigabit Network Connection 4275eba5b6SRobert Mustacchi * 82566DC Gigabit Network Connection 4375eba5b6SRobert Mustacchi * 82566DM-2 Gigabit Network Connection 4475eba5b6SRobert Mustacchi * 82566DM Gigabit Network Connection 4575eba5b6SRobert Mustacchi * 82566MC Gigabit Network Connection 4675eba5b6SRobert Mustacchi * 82566MM Gigabit Network Connection 4775eba5b6SRobert Mustacchi * 82567LM Gigabit Network Connection 4875eba5b6SRobert Mustacchi * 82567LF Gigabit Network Connection 4975eba5b6SRobert Mustacchi * 82567V Gigabit Network Connection 5075eba5b6SRobert Mustacchi * 82567LM-2 Gigabit Network Connection 5175eba5b6SRobert Mustacchi * 82567LF-2 Gigabit Network Connection 5275eba5b6SRobert Mustacchi * 82567V-2 Gigabit Network Connection 5375eba5b6SRobert Mustacchi * 82567LF-3 Gigabit Network Connection 5475eba5b6SRobert Mustacchi * 82567LM-3 Gigabit Network Connection 5575eba5b6SRobert Mustacchi * 82567LM-4 Gigabit Network Connection 5675eba5b6SRobert Mustacchi * 82577LM Gigabit Network Connection 5775eba5b6SRobert Mustacchi * 82577LC Gigabit Network Connection 5875eba5b6SRobert Mustacchi * 82578DM Gigabit Network Connection 5975eba5b6SRobert Mustacchi * 82578DC Gigabit Network Connection 6075eba5b6SRobert Mustacchi * 82579LM Gigabit Network Connection 6175eba5b6SRobert Mustacchi * 82579V Gigabit Network Connection 62c124a83eSRobert Mustacchi * Ethernet Connection I217-LM 63c124a83eSRobert Mustacchi * Ethernet Connection I217-V 64c124a83eSRobert Mustacchi * Ethernet Connection I218-V 65c124a83eSRobert Mustacchi * Ethernet Connection I218-LM 66c124a83eSRobert Mustacchi * Ethernet Connection (2) I218-LM 67c124a83eSRobert Mustacchi * Ethernet Connection (2) I218-V 68c124a83eSRobert Mustacchi * Ethernet Connection (3) I218-LM 69c124a83eSRobert Mustacchi * Ethernet Connection (3) I218-V 7075eba5b6SRobert Mustacchi */ 7175eba5b6SRobert Mustacchi 7275eba5b6SRobert Mustacchi #include "e1000_api.h" 7375eba5b6SRobert Mustacchi 7475eba5b6SRobert Mustacchi static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); 7575eba5b6SRobert Mustacchi static void e1000_release_swflag_ich8lan(struct e1000_hw *hw); 7675eba5b6SRobert Mustacchi static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw); 7775eba5b6SRobert Mustacchi static void e1000_release_nvm_ich8lan(struct e1000_hw *hw); 7875eba5b6SRobert Mustacchi static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); 7975eba5b6SRobert Mustacchi static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); 80c124a83eSRobert Mustacchi static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); 81c124a83eSRobert Mustacchi static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); 82c124a83eSRobert Mustacchi static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw); 8375eba5b6SRobert Mustacchi static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw, 8475eba5b6SRobert Mustacchi u8 *mc_addr_list, 8575eba5b6SRobert Mustacchi u32 mc_addr_count); 8675eba5b6SRobert Mustacchi static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); 8775eba5b6SRobert Mustacchi static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); 8875eba5b6SRobert Mustacchi static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); 8975eba5b6SRobert Mustacchi static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, 9075eba5b6SRobert Mustacchi bool active); 9175eba5b6SRobert Mustacchi static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, 9275eba5b6SRobert Mustacchi bool active); 9375eba5b6SRobert Mustacchi static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, 9475eba5b6SRobert Mustacchi u16 words, u16 *data); 95*42cc51e0SRobert Mustacchi static s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words, 96*42cc51e0SRobert Mustacchi u16 *data); 9775eba5b6SRobert Mustacchi static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, 9875eba5b6SRobert Mustacchi u16 words, u16 *data); 9975eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); 10075eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); 101*42cc51e0SRobert Mustacchi static s32 e1000_update_nvm_checksum_spt(struct e1000_hw *hw); 10275eba5b6SRobert Mustacchi static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, 10375eba5b6SRobert Mustacchi u16 *data); 10475eba5b6SRobert Mustacchi static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw); 10575eba5b6SRobert Mustacchi static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); 10675eba5b6SRobert Mustacchi static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); 10775eba5b6SRobert Mustacchi static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); 10875eba5b6SRobert Mustacchi static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); 10975eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); 11075eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw); 11175eba5b6SRobert Mustacchi static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, 11275eba5b6SRobert Mustacchi u16 *speed, u16 *duplex); 11375eba5b6SRobert Mustacchi static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); 11475eba5b6SRobert Mustacchi static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); 11575eba5b6SRobert Mustacchi static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); 11675eba5b6SRobert Mustacchi static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); 11775eba5b6SRobert Mustacchi static s32 e1000_setup_led_pchlan(struct e1000_hw *hw); 11875eba5b6SRobert Mustacchi static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); 11975eba5b6SRobert Mustacchi static s32 e1000_led_on_pchlan(struct e1000_hw *hw); 12075eba5b6SRobert Mustacchi static s32 e1000_led_off_pchlan(struct e1000_hw *hw); 12175eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); 12275eba5b6SRobert Mustacchi static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); 12375eba5b6SRobert Mustacchi static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); 12475eba5b6SRobert Mustacchi static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); 12575eba5b6SRobert Mustacchi static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, 12675eba5b6SRobert Mustacchi u32 offset, u8 *data); 12775eba5b6SRobert Mustacchi static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, 12875eba5b6SRobert Mustacchi u8 size, u16 *data); 129*42cc51e0SRobert Mustacchi static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset, 130*42cc51e0SRobert Mustacchi u32 *data); 131*42cc51e0SRobert Mustacchi static s32 e1000_read_flash_dword_ich8lan(struct e1000_hw *hw, 132*42cc51e0SRobert Mustacchi u32 offset, u32 *data); 133*42cc51e0SRobert Mustacchi static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, 134*42cc51e0SRobert Mustacchi u32 offset, u32 data); 135*42cc51e0SRobert Mustacchi static s32 e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw, 136*42cc51e0SRobert Mustacchi u32 offset, u32 dword); 13775eba5b6SRobert Mustacchi static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, 13875eba5b6SRobert Mustacchi u32 offset, u16 *data); 13975eba5b6SRobert Mustacchi static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, 14075eba5b6SRobert Mustacchi u32 offset, u8 byte); 14175eba5b6SRobert Mustacchi static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); 14275eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); 14375eba5b6SRobert Mustacchi static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw); 14475eba5b6SRobert Mustacchi static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); 14575eba5b6SRobert Mustacchi static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); 14675eba5b6SRobert Mustacchi static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); 14775eba5b6SRobert Mustacchi static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr); 14875eba5b6SRobert Mustacchi 14975eba5b6SRobert Mustacchi /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ 15075eba5b6SRobert Mustacchi /* Offset 04h HSFSTS */ 15175eba5b6SRobert Mustacchi union ich8_hws_flash_status { 15275eba5b6SRobert Mustacchi struct ich8_hsfsts { 15375eba5b6SRobert Mustacchi u16 flcdone:1; /* bit 0 Flash Cycle Done */ 15475eba5b6SRobert Mustacchi u16 flcerr:1; /* bit 1 Flash Cycle Error */ 15575eba5b6SRobert Mustacchi u16 dael:1; /* bit 2 Direct Access error Log */ 15675eba5b6SRobert Mustacchi u16 berasesz:2; /* bit 4:3 Sector Erase Size */ 15775eba5b6SRobert Mustacchi u16 flcinprog:1; /* bit 5 flash cycle in Progress */ 15875eba5b6SRobert Mustacchi u16 reserved1:2; /* bit 13:6 Reserved */ 15975eba5b6SRobert Mustacchi u16 reserved2:6; /* bit 13:6 Reserved */ 16075eba5b6SRobert Mustacchi u16 fldesvalid:1; /* bit 14 Flash Descriptor Valid */ 16175eba5b6SRobert Mustacchi u16 flockdn:1; /* bit 15 Flash Config Lock-Down */ 16275eba5b6SRobert Mustacchi } hsf_status; 16375eba5b6SRobert Mustacchi u16 regval; 16475eba5b6SRobert Mustacchi }; 16575eba5b6SRobert Mustacchi 16675eba5b6SRobert Mustacchi /* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */ 16775eba5b6SRobert Mustacchi /* Offset 06h FLCTL */ 16875eba5b6SRobert Mustacchi union ich8_hws_flash_ctrl { 16975eba5b6SRobert Mustacchi struct ich8_hsflctl { 17075eba5b6SRobert Mustacchi u16 flcgo:1; /* 0 Flash Cycle Go */ 17175eba5b6SRobert Mustacchi u16 flcycle:2; /* 2:1 Flash Cycle */ 17275eba5b6SRobert Mustacchi u16 reserved:5; /* 7:3 Reserved */ 17375eba5b6SRobert Mustacchi u16 fldbcount:2; /* 9:8 Flash Data Byte Count */ 17475eba5b6SRobert Mustacchi u16 flockdn:6; /* 15:10 Reserved */ 17575eba5b6SRobert Mustacchi } hsf_ctrl; 17675eba5b6SRobert Mustacchi u16 regval; 17775eba5b6SRobert Mustacchi }; 17875eba5b6SRobert Mustacchi 17975eba5b6SRobert Mustacchi /* ICH Flash Region Access Permissions */ 18075eba5b6SRobert Mustacchi union ich8_hws_flash_regacc { 18175eba5b6SRobert Mustacchi struct ich8_flracc { 18275eba5b6SRobert Mustacchi u32 grra:8; /* 0:7 GbE region Read Access */ 18375eba5b6SRobert Mustacchi u32 grwa:8; /* 8:15 GbE region Write Access */ 18475eba5b6SRobert Mustacchi u32 gmrag:8; /* 23:16 GbE Master Read Access Grant */ 18575eba5b6SRobert Mustacchi u32 gmwag:8; /* 31:24 GbE Master Write Access Grant */ 18675eba5b6SRobert Mustacchi } hsf_flregacc; 18775eba5b6SRobert Mustacchi u16 regval; 18875eba5b6SRobert Mustacchi }; 18975eba5b6SRobert Mustacchi 19075eba5b6SRobert Mustacchi /** 19175eba5b6SRobert Mustacchi * e1000_phy_is_accessible_pchlan - Check if able to access PHY registers 19275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 19375eba5b6SRobert Mustacchi * 19475eba5b6SRobert Mustacchi * Test access to the PHY registers by reading the PHY ID registers. If 19575eba5b6SRobert Mustacchi * the PHY ID is already known (e.g. resume path) compare it with known ID, 19675eba5b6SRobert Mustacchi * otherwise assume the read PHY ID is correct if it is valid. 19775eba5b6SRobert Mustacchi * 19875eba5b6SRobert Mustacchi * Assumes the sw/fw/hw semaphore is already acquired. 19975eba5b6SRobert Mustacchi **/ 20075eba5b6SRobert Mustacchi static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) 20175eba5b6SRobert Mustacchi { 20275eba5b6SRobert Mustacchi u16 phy_reg = 0; 20375eba5b6SRobert Mustacchi u32 phy_id = 0; 204c124a83eSRobert Mustacchi s32 ret_val = 0; 20575eba5b6SRobert Mustacchi u16 retry_count; 206c124a83eSRobert Mustacchi u32 mac_reg = 0; 20775eba5b6SRobert Mustacchi 20875eba5b6SRobert Mustacchi for (retry_count = 0; retry_count < 2; retry_count++) { 20975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_reg); 21075eba5b6SRobert Mustacchi if (ret_val || (phy_reg == 0xFFFF)) 21175eba5b6SRobert Mustacchi continue; 21275eba5b6SRobert Mustacchi phy_id = (u32)(phy_reg << 16); 21375eba5b6SRobert Mustacchi 21475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_reg); 21575eba5b6SRobert Mustacchi if (ret_val || (phy_reg == 0xFFFF)) { 21675eba5b6SRobert Mustacchi phy_id = 0; 21775eba5b6SRobert Mustacchi continue; 21875eba5b6SRobert Mustacchi } 21975eba5b6SRobert Mustacchi phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); 22075eba5b6SRobert Mustacchi break; 22175eba5b6SRobert Mustacchi } 22275eba5b6SRobert Mustacchi 22375eba5b6SRobert Mustacchi if (hw->phy.id) { 22475eba5b6SRobert Mustacchi if (hw->phy.id == phy_id) 225c124a83eSRobert Mustacchi goto out; 22675eba5b6SRobert Mustacchi } else if (phy_id) { 22775eba5b6SRobert Mustacchi hw->phy.id = phy_id; 22875eba5b6SRobert Mustacchi hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK); 229c124a83eSRobert Mustacchi goto out; 23075eba5b6SRobert Mustacchi } 23175eba5b6SRobert Mustacchi 23275eba5b6SRobert Mustacchi /* In case the PHY needs to be in mdio slow mode, 23375eba5b6SRobert Mustacchi * set slow mode and try to get the PHY id again. 23475eba5b6SRobert Mustacchi */ 235c124a83eSRobert Mustacchi if (hw->mac.type < e1000_pch_lpt) { 23675eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 23775eba5b6SRobert Mustacchi ret_val = e1000_set_mdio_slow_mode_hv(hw); 23875eba5b6SRobert Mustacchi if (!ret_val) 23975eba5b6SRobert Mustacchi ret_val = e1000_get_phy_id(hw); 24075eba5b6SRobert Mustacchi hw->phy.ops.acquire(hw); 241c124a83eSRobert Mustacchi } 24275eba5b6SRobert Mustacchi 243c124a83eSRobert Mustacchi if (ret_val) 244c124a83eSRobert Mustacchi return FALSE; 245c124a83eSRobert Mustacchi out: 246*42cc51e0SRobert Mustacchi if ((hw->mac.type == e1000_pch_lpt) || 247*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) { 248*42cc51e0SRobert Mustacchi /* Only unforce SMBus if ME is not active */ 249*42cc51e0SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_FWSM) & 250*42cc51e0SRobert Mustacchi E1000_ICH_FWSM_FW_VALID)) { 251c124a83eSRobert Mustacchi /* Unforce SMBus mode in PHY */ 252c124a83eSRobert Mustacchi hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg); 253c124a83eSRobert Mustacchi phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; 254c124a83eSRobert Mustacchi hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg); 255c124a83eSRobert Mustacchi 256c124a83eSRobert Mustacchi /* Unforce SMBus mode in MAC */ 257c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 258c124a83eSRobert Mustacchi mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; 259c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 260c124a83eSRobert Mustacchi } 261*42cc51e0SRobert Mustacchi } 262c124a83eSRobert Mustacchi 263c124a83eSRobert Mustacchi return TRUE; 264c124a83eSRobert Mustacchi } 265c124a83eSRobert Mustacchi 266c124a83eSRobert Mustacchi /** 267c124a83eSRobert Mustacchi * e1000_toggle_lanphypc_pch_lpt - toggle the LANPHYPC pin value 268c124a83eSRobert Mustacchi * @hw: pointer to the HW structure 269c124a83eSRobert Mustacchi * 270c124a83eSRobert Mustacchi * Toggling the LANPHYPC pin value fully power-cycles the PHY and is 271c124a83eSRobert Mustacchi * used to reset the PHY to a quiescent state when necessary. 272c124a83eSRobert Mustacchi **/ 273c124a83eSRobert Mustacchi static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw) 274c124a83eSRobert Mustacchi { 275c124a83eSRobert Mustacchi u32 mac_reg; 276c124a83eSRobert Mustacchi 277c124a83eSRobert Mustacchi DEBUGFUNC("e1000_toggle_lanphypc_pch_lpt"); 278c124a83eSRobert Mustacchi 279c124a83eSRobert Mustacchi /* Set Phy Config Counter to 50msec */ 280c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM3); 281c124a83eSRobert Mustacchi mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; 282c124a83eSRobert Mustacchi mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; 283c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM3, mac_reg); 284c124a83eSRobert Mustacchi 285c124a83eSRobert Mustacchi /* Toggle LANPHYPC Value bit */ 286c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL); 287c124a83eSRobert Mustacchi mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; 288c124a83eSRobert Mustacchi mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; 289c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); 290c124a83eSRobert Mustacchi E1000_WRITE_FLUSH(hw); 291c124a83eSRobert Mustacchi usec_delay(10); 292c124a83eSRobert Mustacchi mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; 293c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); 294c124a83eSRobert Mustacchi E1000_WRITE_FLUSH(hw); 295c124a83eSRobert Mustacchi 296c124a83eSRobert Mustacchi if (hw->mac.type < e1000_pch_lpt) { 297c124a83eSRobert Mustacchi msec_delay(50); 298c124a83eSRobert Mustacchi } else { 299c124a83eSRobert Mustacchi u16 count = 20; 300c124a83eSRobert Mustacchi 301c124a83eSRobert Mustacchi do { 302c124a83eSRobert Mustacchi msec_delay(5); 303c124a83eSRobert Mustacchi } while (!(E1000_READ_REG(hw, E1000_CTRL_EXT) & 304c124a83eSRobert Mustacchi E1000_CTRL_EXT_LPCD) && count--); 305c124a83eSRobert Mustacchi 306c124a83eSRobert Mustacchi msec_delay(30); 307c124a83eSRobert Mustacchi } 30875eba5b6SRobert Mustacchi } 30975eba5b6SRobert Mustacchi 31075eba5b6SRobert Mustacchi /** 31175eba5b6SRobert Mustacchi * e1000_init_phy_workarounds_pchlan - PHY initialization workarounds 31275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 31375eba5b6SRobert Mustacchi * 31475eba5b6SRobert Mustacchi * Workarounds/flow necessary for PHY initialization during driver load 31575eba5b6SRobert Mustacchi * and resume paths. 31675eba5b6SRobert Mustacchi **/ 31775eba5b6SRobert Mustacchi static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) 31875eba5b6SRobert Mustacchi { 31975eba5b6SRobert Mustacchi u32 mac_reg, fwsm = E1000_READ_REG(hw, E1000_FWSM); 32075eba5b6SRobert Mustacchi s32 ret_val; 32175eba5b6SRobert Mustacchi 32275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_phy_workarounds_pchlan"); 32375eba5b6SRobert Mustacchi 32475eba5b6SRobert Mustacchi /* Gate automatic PHY configuration by hardware on managed and 32575eba5b6SRobert Mustacchi * non-managed 82579 and newer adapters. 32675eba5b6SRobert Mustacchi */ 32775eba5b6SRobert Mustacchi e1000_gate_hw_phy_config_ich8lan(hw, TRUE); 32875eba5b6SRobert Mustacchi 329c124a83eSRobert Mustacchi /* It is not possible to be certain of the current state of ULP 330c124a83eSRobert Mustacchi * so forcibly disable it. 331c124a83eSRobert Mustacchi */ 332c124a83eSRobert Mustacchi hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown; 333c124a83eSRobert Mustacchi e1000_disable_ulp_lpt_lp(hw, TRUE); 334c124a83eSRobert Mustacchi 33575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 33675eba5b6SRobert Mustacchi if (ret_val) { 33775eba5b6SRobert Mustacchi DEBUGOUT("Failed to initialize PHY flow\n"); 33875eba5b6SRobert Mustacchi goto out; 33975eba5b6SRobert Mustacchi } 34075eba5b6SRobert Mustacchi 34175eba5b6SRobert Mustacchi /* The MAC-PHY interconnect may be in SMBus mode. If the PHY is 34275eba5b6SRobert Mustacchi * inaccessible and resetting the PHY is not blocked, toggle the 34375eba5b6SRobert Mustacchi * LANPHYPC Value bit to force the interconnect to PCIe mode. 34475eba5b6SRobert Mustacchi */ 34575eba5b6SRobert Mustacchi switch (hw->mac.type) { 34675eba5b6SRobert Mustacchi case e1000_pch_lpt: 347*42cc51e0SRobert Mustacchi case e1000_pch_spt: 34875eba5b6SRobert Mustacchi if (e1000_phy_is_accessible_pchlan(hw)) 34975eba5b6SRobert Mustacchi break; 35075eba5b6SRobert Mustacchi 35175eba5b6SRobert Mustacchi /* Before toggling LANPHYPC, see if PHY is accessible by 35275eba5b6SRobert Mustacchi * forcing MAC to SMBus mode first. 35375eba5b6SRobert Mustacchi */ 35475eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 35575eba5b6SRobert Mustacchi mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; 35675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 35775eba5b6SRobert Mustacchi 358c124a83eSRobert Mustacchi /* Wait 50 milliseconds for MAC to finish any retries 359c124a83eSRobert Mustacchi * that it might be trying to perform from previous 360c124a83eSRobert Mustacchi * attempts to acknowledge any phy read requests. 361c124a83eSRobert Mustacchi */ 362c124a83eSRobert Mustacchi msec_delay(50); 363c124a83eSRobert Mustacchi 36475eba5b6SRobert Mustacchi /* fall-through */ 36575eba5b6SRobert Mustacchi case e1000_pch2lan: 366c124a83eSRobert Mustacchi if (e1000_phy_is_accessible_pchlan(hw)) 36775eba5b6SRobert Mustacchi break; 36875eba5b6SRobert Mustacchi 36975eba5b6SRobert Mustacchi /* fall-through */ 37075eba5b6SRobert Mustacchi case e1000_pchlan: 37175eba5b6SRobert Mustacchi if ((hw->mac.type == e1000_pchlan) && 37275eba5b6SRobert Mustacchi (fwsm & E1000_ICH_FWSM_FW_VALID)) 37375eba5b6SRobert Mustacchi break; 37475eba5b6SRobert Mustacchi 37575eba5b6SRobert Mustacchi if (hw->phy.ops.check_reset_block(hw)) { 37675eba5b6SRobert Mustacchi DEBUGOUT("Required LANPHYPC toggle blocked by ME\n"); 377c124a83eSRobert Mustacchi ret_val = -E1000_ERR_PHY; 37875eba5b6SRobert Mustacchi break; 37975eba5b6SRobert Mustacchi } 38075eba5b6SRobert Mustacchi 381c124a83eSRobert Mustacchi /* Toggle LANPHYPC Value bit */ 382c124a83eSRobert Mustacchi e1000_toggle_lanphypc_pch_lpt(hw); 383c124a83eSRobert Mustacchi if (hw->mac.type >= e1000_pch_lpt) { 384c124a83eSRobert Mustacchi if (e1000_phy_is_accessible_pchlan(hw)) 385c124a83eSRobert Mustacchi break; 38675eba5b6SRobert Mustacchi 38775eba5b6SRobert Mustacchi /* Toggling LANPHYPC brings the PHY out of SMBus mode 388c124a83eSRobert Mustacchi * so ensure that the MAC is also out of SMBus mode 38975eba5b6SRobert Mustacchi */ 39075eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 39175eba5b6SRobert Mustacchi mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; 39275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 39375eba5b6SRobert Mustacchi 394c124a83eSRobert Mustacchi if (e1000_phy_is_accessible_pchlan(hw)) 395c124a83eSRobert Mustacchi break; 396c124a83eSRobert Mustacchi 397c124a83eSRobert Mustacchi ret_val = -E1000_ERR_PHY; 39875eba5b6SRobert Mustacchi } 39975eba5b6SRobert Mustacchi break; 40075eba5b6SRobert Mustacchi default: 40175eba5b6SRobert Mustacchi break; 40275eba5b6SRobert Mustacchi } 40375eba5b6SRobert Mustacchi 40475eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 405c124a83eSRobert Mustacchi if (!ret_val) { 406c124a83eSRobert Mustacchi 407c124a83eSRobert Mustacchi /* Check to see if able to reset PHY. Print error if not */ 408c124a83eSRobert Mustacchi if (hw->phy.ops.check_reset_block(hw)) { 409c124a83eSRobert Mustacchi ERROR_REPORT("Reset blocked by ME\n"); 410c124a83eSRobert Mustacchi goto out; 411c124a83eSRobert Mustacchi } 41275eba5b6SRobert Mustacchi 41375eba5b6SRobert Mustacchi /* Reset the PHY before any access to it. Doing so, ensures 41475eba5b6SRobert Mustacchi * that the PHY is in a known good state before we read/write 41575eba5b6SRobert Mustacchi * PHY registers. The generic reset is sufficient here, 41675eba5b6SRobert Mustacchi * because we haven't determined the PHY type yet. 41775eba5b6SRobert Mustacchi */ 41875eba5b6SRobert Mustacchi ret_val = e1000_phy_hw_reset_generic(hw); 419c124a83eSRobert Mustacchi if (ret_val) 420c124a83eSRobert Mustacchi goto out; 421c124a83eSRobert Mustacchi 422c124a83eSRobert Mustacchi /* On a successful reset, possibly need to wait for the PHY 423c124a83eSRobert Mustacchi * to quiesce to an accessible state before returning control 424c124a83eSRobert Mustacchi * to the calling function. If the PHY does not quiesce, then 425c124a83eSRobert Mustacchi * return E1000E_BLK_PHY_RESET, as this is the condition that 426c124a83eSRobert Mustacchi * the PHY is in. 427c124a83eSRobert Mustacchi */ 428c124a83eSRobert Mustacchi ret_val = hw->phy.ops.check_reset_block(hw); 429c124a83eSRobert Mustacchi if (ret_val) 430c124a83eSRobert Mustacchi ERROR_REPORT("ME blocked access to PHY after reset\n"); 431c124a83eSRobert Mustacchi } 43275eba5b6SRobert Mustacchi 43375eba5b6SRobert Mustacchi out: 43475eba5b6SRobert Mustacchi /* Ungate automatic PHY configuration on non-managed 82579 */ 43575eba5b6SRobert Mustacchi if ((hw->mac.type == e1000_pch2lan) && 43675eba5b6SRobert Mustacchi !(fwsm & E1000_ICH_FWSM_FW_VALID)) { 43775eba5b6SRobert Mustacchi msec_delay(10); 43875eba5b6SRobert Mustacchi e1000_gate_hw_phy_config_ich8lan(hw, FALSE); 43975eba5b6SRobert Mustacchi } 44075eba5b6SRobert Mustacchi 44175eba5b6SRobert Mustacchi return ret_val; 44275eba5b6SRobert Mustacchi } 44375eba5b6SRobert Mustacchi 44475eba5b6SRobert Mustacchi /** 44575eba5b6SRobert Mustacchi * e1000_init_phy_params_pchlan - Initialize PHY function pointers 44675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 44775eba5b6SRobert Mustacchi * 44875eba5b6SRobert Mustacchi * Initialize family-specific PHY parameters and function pointers. 44975eba5b6SRobert Mustacchi **/ 45075eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) 45175eba5b6SRobert Mustacchi { 45275eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 45375eba5b6SRobert Mustacchi s32 ret_val; 45475eba5b6SRobert Mustacchi 45575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_phy_params_pchlan"); 45675eba5b6SRobert Mustacchi 45775eba5b6SRobert Mustacchi phy->addr = 1; 45875eba5b6SRobert Mustacchi phy->reset_delay_us = 100; 45975eba5b6SRobert Mustacchi 46075eba5b6SRobert Mustacchi phy->ops.acquire = e1000_acquire_swflag_ich8lan; 46175eba5b6SRobert Mustacchi phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; 46275eba5b6SRobert Mustacchi phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; 46375eba5b6SRobert Mustacchi phy->ops.set_page = e1000_set_page_igp; 46475eba5b6SRobert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_hv; 46575eba5b6SRobert Mustacchi phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked; 46675eba5b6SRobert Mustacchi phy->ops.read_reg_page = e1000_read_phy_reg_page_hv; 46775eba5b6SRobert Mustacchi phy->ops.release = e1000_release_swflag_ich8lan; 46875eba5b6SRobert Mustacchi phy->ops.reset = e1000_phy_hw_reset_ich8lan; 46975eba5b6SRobert Mustacchi phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; 47075eba5b6SRobert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; 47175eba5b6SRobert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_hv; 47275eba5b6SRobert Mustacchi phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; 47375eba5b6SRobert Mustacchi phy->ops.write_reg_page = e1000_write_phy_reg_page_hv; 47475eba5b6SRobert Mustacchi phy->ops.power_up = e1000_power_up_phy_copper; 47575eba5b6SRobert Mustacchi phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; 47675eba5b6SRobert Mustacchi phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 47775eba5b6SRobert Mustacchi 47875eba5b6SRobert Mustacchi phy->id = e1000_phy_unknown; 47975eba5b6SRobert Mustacchi 48075eba5b6SRobert Mustacchi ret_val = e1000_init_phy_workarounds_pchlan(hw); 48175eba5b6SRobert Mustacchi if (ret_val) 48275eba5b6SRobert Mustacchi return ret_val; 48375eba5b6SRobert Mustacchi 48475eba5b6SRobert Mustacchi if (phy->id == e1000_phy_unknown) 48575eba5b6SRobert Mustacchi switch (hw->mac.type) { 48675eba5b6SRobert Mustacchi default: 48775eba5b6SRobert Mustacchi ret_val = e1000_get_phy_id(hw); 48875eba5b6SRobert Mustacchi if (ret_val) 48975eba5b6SRobert Mustacchi return ret_val; 49075eba5b6SRobert Mustacchi if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) 49175eba5b6SRobert Mustacchi break; 49275eba5b6SRobert Mustacchi /* fall-through */ 49375eba5b6SRobert Mustacchi case e1000_pch2lan: 49475eba5b6SRobert Mustacchi case e1000_pch_lpt: 495*42cc51e0SRobert Mustacchi case e1000_pch_spt: 49675eba5b6SRobert Mustacchi /* In case the PHY needs to be in mdio slow mode, 49775eba5b6SRobert Mustacchi * set slow mode and try to get the PHY id again. 49875eba5b6SRobert Mustacchi */ 49975eba5b6SRobert Mustacchi ret_val = e1000_set_mdio_slow_mode_hv(hw); 50075eba5b6SRobert Mustacchi if (ret_val) 50175eba5b6SRobert Mustacchi return ret_val; 50275eba5b6SRobert Mustacchi ret_val = e1000_get_phy_id(hw); 50375eba5b6SRobert Mustacchi if (ret_val) 50475eba5b6SRobert Mustacchi return ret_val; 50575eba5b6SRobert Mustacchi break; 50675eba5b6SRobert Mustacchi } 50775eba5b6SRobert Mustacchi phy->type = e1000_get_phy_type_from_id(phy->id); 50875eba5b6SRobert Mustacchi 50975eba5b6SRobert Mustacchi switch (phy->type) { 51075eba5b6SRobert Mustacchi case e1000_phy_82577: 51175eba5b6SRobert Mustacchi case e1000_phy_82579: 51275eba5b6SRobert Mustacchi case e1000_phy_i217: 51375eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_82577; 51475eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = 51575eba5b6SRobert Mustacchi e1000_phy_force_speed_duplex_82577; 51675eba5b6SRobert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_82577; 51775eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_82577; 51875eba5b6SRobert Mustacchi phy->ops.commit = e1000_phy_sw_reset_generic; 51975eba5b6SRobert Mustacchi break; 52075eba5b6SRobert Mustacchi case e1000_phy_82578: 52175eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_m88; 52275eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; 52375eba5b6SRobert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_m88; 52475eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_m88; 52575eba5b6SRobert Mustacchi break; 52675eba5b6SRobert Mustacchi default: 52775eba5b6SRobert Mustacchi ret_val = -E1000_ERR_PHY; 52875eba5b6SRobert Mustacchi break; 52975eba5b6SRobert Mustacchi } 53075eba5b6SRobert Mustacchi 53175eba5b6SRobert Mustacchi return ret_val; 53275eba5b6SRobert Mustacchi } 53375eba5b6SRobert Mustacchi 53475eba5b6SRobert Mustacchi /** 53575eba5b6SRobert Mustacchi * e1000_init_phy_params_ich8lan - Initialize PHY function pointers 53675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 53775eba5b6SRobert Mustacchi * 53875eba5b6SRobert Mustacchi * Initialize family-specific PHY parameters and function pointers. 53975eba5b6SRobert Mustacchi **/ 54075eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) 54175eba5b6SRobert Mustacchi { 54275eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 54375eba5b6SRobert Mustacchi s32 ret_val; 54475eba5b6SRobert Mustacchi u16 i = 0; 54575eba5b6SRobert Mustacchi 54675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_phy_params_ich8lan"); 54775eba5b6SRobert Mustacchi 54875eba5b6SRobert Mustacchi phy->addr = 1; 54975eba5b6SRobert Mustacchi phy->reset_delay_us = 100; 55075eba5b6SRobert Mustacchi 55175eba5b6SRobert Mustacchi phy->ops.acquire = e1000_acquire_swflag_ich8lan; 55275eba5b6SRobert Mustacchi phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; 55375eba5b6SRobert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_igp_2; 55475eba5b6SRobert Mustacchi phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; 55575eba5b6SRobert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_igp; 55675eba5b6SRobert Mustacchi phy->ops.release = e1000_release_swflag_ich8lan; 55775eba5b6SRobert Mustacchi phy->ops.reset = e1000_phy_hw_reset_ich8lan; 55875eba5b6SRobert Mustacchi phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; 55975eba5b6SRobert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; 56075eba5b6SRobert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_igp; 56175eba5b6SRobert Mustacchi phy->ops.power_up = e1000_power_up_phy_copper; 56275eba5b6SRobert Mustacchi phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; 56375eba5b6SRobert Mustacchi 56475eba5b6SRobert Mustacchi /* We may need to do this twice - once for IGP and if that fails, 56575eba5b6SRobert Mustacchi * we'll set BM func pointers and try again 56675eba5b6SRobert Mustacchi */ 56775eba5b6SRobert Mustacchi ret_val = e1000_determine_phy_address(hw); 56875eba5b6SRobert Mustacchi if (ret_val) { 56975eba5b6SRobert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_bm; 57075eba5b6SRobert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_bm; 57175eba5b6SRobert Mustacchi ret_val = e1000_determine_phy_address(hw); 57275eba5b6SRobert Mustacchi if (ret_val) { 57375eba5b6SRobert Mustacchi DEBUGOUT("Cannot determine PHY addr. Erroring out\n"); 57475eba5b6SRobert Mustacchi return ret_val; 57575eba5b6SRobert Mustacchi } 57675eba5b6SRobert Mustacchi } 57775eba5b6SRobert Mustacchi 57875eba5b6SRobert Mustacchi phy->id = 0; 57975eba5b6SRobert Mustacchi while ((e1000_phy_unknown == e1000_get_phy_type_from_id(phy->id)) && 58075eba5b6SRobert Mustacchi (i++ < 100)) { 58175eba5b6SRobert Mustacchi msec_delay(1); 58275eba5b6SRobert Mustacchi ret_val = e1000_get_phy_id(hw); 58375eba5b6SRobert Mustacchi if (ret_val) 58475eba5b6SRobert Mustacchi return ret_val; 58575eba5b6SRobert Mustacchi } 58675eba5b6SRobert Mustacchi 58775eba5b6SRobert Mustacchi /* Verify phy id */ 58875eba5b6SRobert Mustacchi switch (phy->id) { 58975eba5b6SRobert Mustacchi case IGP03E1000_E_PHY_ID: 59075eba5b6SRobert Mustacchi phy->type = e1000_phy_igp_3; 59175eba5b6SRobert Mustacchi phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 59275eba5b6SRobert Mustacchi phy->ops.read_reg_locked = e1000_read_phy_reg_igp_locked; 59375eba5b6SRobert Mustacchi phy->ops.write_reg_locked = e1000_write_phy_reg_igp_locked; 59475eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_igp; 59575eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_igp; 59675eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; 59775eba5b6SRobert Mustacchi break; 59875eba5b6SRobert Mustacchi case IFE_E_PHY_ID: 59975eba5b6SRobert Mustacchi case IFE_PLUS_E_PHY_ID: 60075eba5b6SRobert Mustacchi case IFE_C_E_PHY_ID: 60175eba5b6SRobert Mustacchi phy->type = e1000_phy_ife; 60275eba5b6SRobert Mustacchi phy->autoneg_mask = E1000_ALL_NOT_GIG; 60375eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_ife; 60475eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_ife; 60575eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife; 60675eba5b6SRobert Mustacchi break; 60775eba5b6SRobert Mustacchi case BME1000_E_PHY_ID: 60875eba5b6SRobert Mustacchi phy->type = e1000_phy_bm; 60975eba5b6SRobert Mustacchi phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 61075eba5b6SRobert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_bm; 61175eba5b6SRobert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_bm; 61275eba5b6SRobert Mustacchi phy->ops.commit = e1000_phy_sw_reset_generic; 61375eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_m88; 61475eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_m88; 61575eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; 61675eba5b6SRobert Mustacchi break; 61775eba5b6SRobert Mustacchi default: 61875eba5b6SRobert Mustacchi return -E1000_ERR_PHY; 61975eba5b6SRobert Mustacchi break; 62075eba5b6SRobert Mustacchi } 62175eba5b6SRobert Mustacchi 62275eba5b6SRobert Mustacchi return E1000_SUCCESS; 62375eba5b6SRobert Mustacchi } 62475eba5b6SRobert Mustacchi 62575eba5b6SRobert Mustacchi /** 62675eba5b6SRobert Mustacchi * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers 62775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 62875eba5b6SRobert Mustacchi * 62975eba5b6SRobert Mustacchi * Initialize family-specific NVM parameters and function 63075eba5b6SRobert Mustacchi * pointers. 63175eba5b6SRobert Mustacchi **/ 63275eba5b6SRobert Mustacchi static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) 63375eba5b6SRobert Mustacchi { 63475eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 63575eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 63675eba5b6SRobert Mustacchi u32 gfpreg, sector_base_addr, sector_end_addr; 63775eba5b6SRobert Mustacchi u16 i; 638*42cc51e0SRobert Mustacchi u32 nvm_size; 63975eba5b6SRobert Mustacchi 64075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_nvm_params_ich8lan"); 64175eba5b6SRobert Mustacchi 642c124a83eSRobert Mustacchi nvm->type = e1000_nvm_flash_sw; 643*42cc51e0SRobert Mustacchi 644*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 645*42cc51e0SRobert Mustacchi /* in SPT, gfpreg doesn't exist. NVM size is taken from the 646*42cc51e0SRobert Mustacchi * STRAP register. This is because in SPT the GbE Flash region 647*42cc51e0SRobert Mustacchi * is no longer accessed through the flash registers. Instead, 648*42cc51e0SRobert Mustacchi * the mechanism has changed, and the Flash region access 649*42cc51e0SRobert Mustacchi * registers are now implemented in GbE memory space. 650*42cc51e0SRobert Mustacchi */ 651*42cc51e0SRobert Mustacchi nvm->flash_base_addr = 0; 652*42cc51e0SRobert Mustacchi nvm_size = 653*42cc51e0SRobert Mustacchi (((E1000_READ_REG(hw, E1000_STRAP) >> 1) & 0x1F) + 1) 654*42cc51e0SRobert Mustacchi * NVM_SIZE_MULTIPLIER; 655*42cc51e0SRobert Mustacchi nvm->flash_bank_size = nvm_size / 2; 656*42cc51e0SRobert Mustacchi /* Adjust to word count */ 657*42cc51e0SRobert Mustacchi nvm->flash_bank_size /= sizeof(u16); 658*42cc51e0SRobert Mustacchi /* Set the base address for flash register access */ 659*42cc51e0SRobert Mustacchi hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR; 660*42cc51e0SRobert Mustacchi } else { 661*42cc51e0SRobert Mustacchi /* Can't read flash registers if register set isn't mapped. */ 66275eba5b6SRobert Mustacchi if (!hw->flash_address) { 66375eba5b6SRobert Mustacchi DEBUGOUT("ERROR: Flash registers not mapped\n"); 66475eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 66575eba5b6SRobert Mustacchi } 66675eba5b6SRobert Mustacchi 66775eba5b6SRobert Mustacchi gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); 66875eba5b6SRobert Mustacchi 66975eba5b6SRobert Mustacchi /* sector_X_addr is a "sector"-aligned address (4096 bytes) 67075eba5b6SRobert Mustacchi * Add 1 to sector_end_addr since this sector is included in 67175eba5b6SRobert Mustacchi * the overall size. 67275eba5b6SRobert Mustacchi */ 67375eba5b6SRobert Mustacchi sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; 67475eba5b6SRobert Mustacchi sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1; 67575eba5b6SRobert Mustacchi 67675eba5b6SRobert Mustacchi /* flash_base_addr is byte-aligned */ 677*42cc51e0SRobert Mustacchi nvm->flash_base_addr = sector_base_addr 678*42cc51e0SRobert Mustacchi << FLASH_SECTOR_ADDR_SHIFT; 67975eba5b6SRobert Mustacchi 68075eba5b6SRobert Mustacchi /* find total size of the NVM, then cut in half since the total 68175eba5b6SRobert Mustacchi * size represents two separate NVM banks. 68275eba5b6SRobert Mustacchi */ 683c124a83eSRobert Mustacchi nvm->flash_bank_size = ((sector_end_addr - sector_base_addr) 684c124a83eSRobert Mustacchi << FLASH_SECTOR_ADDR_SHIFT); 68575eba5b6SRobert Mustacchi nvm->flash_bank_size /= 2; 68675eba5b6SRobert Mustacchi /* Adjust to word count */ 68775eba5b6SRobert Mustacchi nvm->flash_bank_size /= sizeof(u16); 688*42cc51e0SRobert Mustacchi } 68975eba5b6SRobert Mustacchi 69075eba5b6SRobert Mustacchi nvm->word_size = E1000_SHADOW_RAM_WORDS; 69175eba5b6SRobert Mustacchi 69275eba5b6SRobert Mustacchi /* Clear shadow ram */ 69375eba5b6SRobert Mustacchi for (i = 0; i < nvm->word_size; i++) { 69475eba5b6SRobert Mustacchi dev_spec->shadow_ram[i].modified = FALSE; 69575eba5b6SRobert Mustacchi dev_spec->shadow_ram[i].value = 0xFFFF; 69675eba5b6SRobert Mustacchi } 69775eba5b6SRobert Mustacchi 69875eba5b6SRobert Mustacchi E1000_MUTEX_INIT(&dev_spec->nvm_mutex); 69975eba5b6SRobert Mustacchi E1000_MUTEX_INIT(&dev_spec->swflag_mutex); 70075eba5b6SRobert Mustacchi 70175eba5b6SRobert Mustacchi /* Function Pointers */ 70275eba5b6SRobert Mustacchi nvm->ops.acquire = e1000_acquire_nvm_ich8lan; 70375eba5b6SRobert Mustacchi nvm->ops.release = e1000_release_nvm_ich8lan; 704*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 705*42cc51e0SRobert Mustacchi nvm->ops.read = e1000_read_nvm_spt; 706*42cc51e0SRobert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_spt; 707*42cc51e0SRobert Mustacchi } else { 70875eba5b6SRobert Mustacchi nvm->ops.read = e1000_read_nvm_ich8lan; 70975eba5b6SRobert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_ich8lan; 710*42cc51e0SRobert Mustacchi } 71175eba5b6SRobert Mustacchi nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan; 71275eba5b6SRobert Mustacchi nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; 71375eba5b6SRobert Mustacchi nvm->ops.write = e1000_write_nvm_ich8lan; 71475eba5b6SRobert Mustacchi 71575eba5b6SRobert Mustacchi return E1000_SUCCESS; 71675eba5b6SRobert Mustacchi } 71775eba5b6SRobert Mustacchi 71875eba5b6SRobert Mustacchi /** 71975eba5b6SRobert Mustacchi * e1000_init_mac_params_ich8lan - Initialize MAC function pointers 72075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 72175eba5b6SRobert Mustacchi * 72275eba5b6SRobert Mustacchi * Initialize family-specific MAC parameters and function 72375eba5b6SRobert Mustacchi * pointers. 72475eba5b6SRobert Mustacchi **/ 72575eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) 72675eba5b6SRobert Mustacchi { 72775eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 72875eba5b6SRobert Mustacchi 72975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_mac_params_ich8lan"); 73075eba5b6SRobert Mustacchi 73175eba5b6SRobert Mustacchi /* Set media type function pointer */ 73275eba5b6SRobert Mustacchi hw->phy.media_type = e1000_media_type_copper; 73375eba5b6SRobert Mustacchi 73475eba5b6SRobert Mustacchi /* Set mta register count */ 73575eba5b6SRobert Mustacchi mac->mta_reg_count = 32; 73675eba5b6SRobert Mustacchi /* Set rar entry count */ 73775eba5b6SRobert Mustacchi mac->rar_entry_count = E1000_ICH_RAR_ENTRIES; 73875eba5b6SRobert Mustacchi if (mac->type == e1000_ich8lan) 73975eba5b6SRobert Mustacchi mac->rar_entry_count--; 74075eba5b6SRobert Mustacchi /* Set if part includes ASF firmware */ 74175eba5b6SRobert Mustacchi mac->asf_firmware_present = TRUE; 74275eba5b6SRobert Mustacchi /* FWSM register */ 74375eba5b6SRobert Mustacchi mac->has_fwsm = TRUE; 74475eba5b6SRobert Mustacchi /* ARC subsystem not supported */ 74575eba5b6SRobert Mustacchi mac->arc_subsystem_valid = FALSE; 74675eba5b6SRobert Mustacchi /* Adaptive IFS supported */ 74775eba5b6SRobert Mustacchi mac->adaptive_ifs = TRUE; 74875eba5b6SRobert Mustacchi 74975eba5b6SRobert Mustacchi /* Function pointers */ 75075eba5b6SRobert Mustacchi 75175eba5b6SRobert Mustacchi /* bus type/speed/width */ 75275eba5b6SRobert Mustacchi mac->ops.get_bus_info = e1000_get_bus_info_ich8lan; 75375eba5b6SRobert Mustacchi /* function id */ 75475eba5b6SRobert Mustacchi mac->ops.set_lan_id = e1000_set_lan_id_single_port; 75575eba5b6SRobert Mustacchi /* reset */ 75675eba5b6SRobert Mustacchi mac->ops.reset_hw = e1000_reset_hw_ich8lan; 75775eba5b6SRobert Mustacchi /* hw initialization */ 75875eba5b6SRobert Mustacchi mac->ops.init_hw = e1000_init_hw_ich8lan; 75975eba5b6SRobert Mustacchi /* link setup */ 76075eba5b6SRobert Mustacchi mac->ops.setup_link = e1000_setup_link_ich8lan; 76175eba5b6SRobert Mustacchi /* physical interface setup */ 76275eba5b6SRobert Mustacchi mac->ops.setup_physical_interface = e1000_setup_copper_link_ich8lan; 76375eba5b6SRobert Mustacchi /* check for link */ 76475eba5b6SRobert Mustacchi mac->ops.check_for_link = e1000_check_for_copper_link_ich8lan; 76575eba5b6SRobert Mustacchi /* link info */ 76675eba5b6SRobert Mustacchi mac->ops.get_link_up_info = e1000_get_link_up_info_ich8lan; 76775eba5b6SRobert Mustacchi /* multicast address update */ 76875eba5b6SRobert Mustacchi mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; 76975eba5b6SRobert Mustacchi /* clear hardware counters */ 77075eba5b6SRobert Mustacchi mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan; 77175eba5b6SRobert Mustacchi 77275eba5b6SRobert Mustacchi /* LED and other operations */ 77375eba5b6SRobert Mustacchi switch (mac->type) { 77475eba5b6SRobert Mustacchi case e1000_ich8lan: 77575eba5b6SRobert Mustacchi case e1000_ich9lan: 77675eba5b6SRobert Mustacchi case e1000_ich10lan: 77775eba5b6SRobert Mustacchi /* check management mode */ 77875eba5b6SRobert Mustacchi mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan; 77975eba5b6SRobert Mustacchi /* ID LED init */ 78075eba5b6SRobert Mustacchi mac->ops.id_led_init = e1000_id_led_init_generic; 78175eba5b6SRobert Mustacchi /* blink LED */ 78275eba5b6SRobert Mustacchi mac->ops.blink_led = e1000_blink_led_generic; 78375eba5b6SRobert Mustacchi /* setup LED */ 78475eba5b6SRobert Mustacchi mac->ops.setup_led = e1000_setup_led_generic; 78575eba5b6SRobert Mustacchi /* cleanup LED */ 78675eba5b6SRobert Mustacchi mac->ops.cleanup_led = e1000_cleanup_led_ich8lan; 78775eba5b6SRobert Mustacchi /* turn on/off LED */ 78875eba5b6SRobert Mustacchi mac->ops.led_on = e1000_led_on_ich8lan; 78975eba5b6SRobert Mustacchi mac->ops.led_off = e1000_led_off_ich8lan; 79075eba5b6SRobert Mustacchi break; 79175eba5b6SRobert Mustacchi case e1000_pch2lan: 79275eba5b6SRobert Mustacchi mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES; 79375eba5b6SRobert Mustacchi mac->ops.rar_set = e1000_rar_set_pch2lan; 79475eba5b6SRobert Mustacchi /* fall-through */ 79575eba5b6SRobert Mustacchi case e1000_pch_lpt: 796*42cc51e0SRobert Mustacchi case e1000_pch_spt: 79775eba5b6SRobert Mustacchi /* multicast address update for pch2 */ 79875eba5b6SRobert Mustacchi mac->ops.update_mc_addr_list = 79975eba5b6SRobert Mustacchi e1000_update_mc_addr_list_pch2lan; 800*42cc51e0SRobert Mustacchi /* fall-through */ 80175eba5b6SRobert Mustacchi case e1000_pchlan: 80275eba5b6SRobert Mustacchi /* check management mode */ 80375eba5b6SRobert Mustacchi mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan; 80475eba5b6SRobert Mustacchi /* ID LED init */ 80575eba5b6SRobert Mustacchi mac->ops.id_led_init = e1000_id_led_init_pchlan; 80675eba5b6SRobert Mustacchi /* setup LED */ 80775eba5b6SRobert Mustacchi mac->ops.setup_led = e1000_setup_led_pchlan; 80875eba5b6SRobert Mustacchi /* cleanup LED */ 80975eba5b6SRobert Mustacchi mac->ops.cleanup_led = e1000_cleanup_led_pchlan; 81075eba5b6SRobert Mustacchi /* turn on/off LED */ 81175eba5b6SRobert Mustacchi mac->ops.led_on = e1000_led_on_pchlan; 81275eba5b6SRobert Mustacchi mac->ops.led_off = e1000_led_off_pchlan; 81375eba5b6SRobert Mustacchi break; 81475eba5b6SRobert Mustacchi default: 81575eba5b6SRobert Mustacchi break; 81675eba5b6SRobert Mustacchi } 81775eba5b6SRobert Mustacchi 818*42cc51e0SRobert Mustacchi if ((mac->type == e1000_pch_lpt) || 819*42cc51e0SRobert Mustacchi (mac->type == e1000_pch_spt)) { 82075eba5b6SRobert Mustacchi mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES; 82175eba5b6SRobert Mustacchi mac->ops.rar_set = e1000_rar_set_pch_lpt; 82275eba5b6SRobert Mustacchi mac->ops.setup_physical_interface = e1000_setup_copper_link_pch_lpt; 82375eba5b6SRobert Mustacchi mac->ops.set_obff_timer = e1000_set_obff_timer_pch_lpt; 82475eba5b6SRobert Mustacchi } 82575eba5b6SRobert Mustacchi 82675eba5b6SRobert Mustacchi /* Enable PCS Lock-loss workaround for ICH8 */ 82775eba5b6SRobert Mustacchi if (mac->type == e1000_ich8lan) 82875eba5b6SRobert Mustacchi e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, TRUE); 82975eba5b6SRobert Mustacchi 83075eba5b6SRobert Mustacchi return E1000_SUCCESS; 83175eba5b6SRobert Mustacchi } 83275eba5b6SRobert Mustacchi 83375eba5b6SRobert Mustacchi /** 83475eba5b6SRobert Mustacchi * __e1000_access_emi_reg_locked - Read/write EMI register 83575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 83675eba5b6SRobert Mustacchi * @addr: EMI address to program 83775eba5b6SRobert Mustacchi * @data: pointer to value to read/write from/to the EMI address 83875eba5b6SRobert Mustacchi * @read: boolean flag to indicate read or write 83975eba5b6SRobert Mustacchi * 84075eba5b6SRobert Mustacchi * This helper function assumes the SW/FW/HW Semaphore is already acquired. 84175eba5b6SRobert Mustacchi **/ 84275eba5b6SRobert Mustacchi static s32 __e1000_access_emi_reg_locked(struct e1000_hw *hw, u16 address, 84375eba5b6SRobert Mustacchi u16 *data, bool read) 84475eba5b6SRobert Mustacchi { 84575eba5b6SRobert Mustacchi s32 ret_val; 84675eba5b6SRobert Mustacchi 84775eba5b6SRobert Mustacchi DEBUGFUNC("__e1000_access_emi_reg_locked"); 84875eba5b6SRobert Mustacchi 84975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, address); 85075eba5b6SRobert Mustacchi if (ret_val) 85175eba5b6SRobert Mustacchi return ret_val; 85275eba5b6SRobert Mustacchi 85375eba5b6SRobert Mustacchi if (read) 85475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, I82579_EMI_DATA, 85575eba5b6SRobert Mustacchi data); 85675eba5b6SRobert Mustacchi else 85775eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 85875eba5b6SRobert Mustacchi *data); 85975eba5b6SRobert Mustacchi 86075eba5b6SRobert Mustacchi return ret_val; 86175eba5b6SRobert Mustacchi } 86275eba5b6SRobert Mustacchi 86375eba5b6SRobert Mustacchi /** 86475eba5b6SRobert Mustacchi * e1000_read_emi_reg_locked - Read Extended Management Interface register 86575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 86675eba5b6SRobert Mustacchi * @addr: EMI address to program 86775eba5b6SRobert Mustacchi * @data: value to be read from the EMI address 86875eba5b6SRobert Mustacchi * 86975eba5b6SRobert Mustacchi * Assumes the SW/FW/HW Semaphore is already acquired. 87075eba5b6SRobert Mustacchi **/ 87175eba5b6SRobert Mustacchi s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data) 87275eba5b6SRobert Mustacchi { 87375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_emi_reg_locked"); 87475eba5b6SRobert Mustacchi 87575eba5b6SRobert Mustacchi return __e1000_access_emi_reg_locked(hw, addr, data, TRUE); 87675eba5b6SRobert Mustacchi } 87775eba5b6SRobert Mustacchi 87875eba5b6SRobert Mustacchi /** 87975eba5b6SRobert Mustacchi * e1000_write_emi_reg_locked - Write Extended Management Interface register 88075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 88175eba5b6SRobert Mustacchi * @addr: EMI address to program 88275eba5b6SRobert Mustacchi * @data: value to be written to the EMI address 88375eba5b6SRobert Mustacchi * 88475eba5b6SRobert Mustacchi * Assumes the SW/FW/HW Semaphore is already acquired. 88575eba5b6SRobert Mustacchi **/ 886c124a83eSRobert Mustacchi s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data) 88775eba5b6SRobert Mustacchi { 88875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_emi_reg_locked"); 88975eba5b6SRobert Mustacchi 89075eba5b6SRobert Mustacchi return __e1000_access_emi_reg_locked(hw, addr, &data, FALSE); 89175eba5b6SRobert Mustacchi } 89275eba5b6SRobert Mustacchi 89375eba5b6SRobert Mustacchi /** 89475eba5b6SRobert Mustacchi * e1000_set_eee_pchlan - Enable/disable EEE support 89575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 89675eba5b6SRobert Mustacchi * 89775eba5b6SRobert Mustacchi * Enable/disable EEE based on setting in dev_spec structure, the duplex of 89875eba5b6SRobert Mustacchi * the link and the EEE capabilities of the link partner. The LPI Control 89975eba5b6SRobert Mustacchi * register bits will remain set only if/when link is up. 900c124a83eSRobert Mustacchi * 901c124a83eSRobert Mustacchi * EEE LPI must not be asserted earlier than one second after link is up. 902c124a83eSRobert Mustacchi * On 82579, EEE LPI should not be enabled until such time otherwise there 903c124a83eSRobert Mustacchi * can be link issues with some switches. Other devices can have EEE LPI 904c124a83eSRobert Mustacchi * enabled immediately upon link up since they have a timer in hardware which 905c124a83eSRobert Mustacchi * prevents LPI from being asserted too early. 90675eba5b6SRobert Mustacchi **/ 907c124a83eSRobert Mustacchi s32 e1000_set_eee_pchlan(struct e1000_hw *hw) 90875eba5b6SRobert Mustacchi { 90975eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 91075eba5b6SRobert Mustacchi s32 ret_val; 911c124a83eSRobert Mustacchi u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data; 91275eba5b6SRobert Mustacchi 91375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_eee_pchlan"); 91475eba5b6SRobert Mustacchi 915c124a83eSRobert Mustacchi switch (hw->phy.type) { 916c124a83eSRobert Mustacchi case e1000_phy_82579: 917c124a83eSRobert Mustacchi lpa = I82579_EEE_LP_ABILITY; 918c124a83eSRobert Mustacchi pcs_status = I82579_EEE_PCS_STATUS; 919c124a83eSRobert Mustacchi adv_addr = I82579_EEE_ADVERTISEMENT; 920c124a83eSRobert Mustacchi break; 921c124a83eSRobert Mustacchi case e1000_phy_i217: 922c124a83eSRobert Mustacchi lpa = I217_EEE_LP_ABILITY; 923c124a83eSRobert Mustacchi pcs_status = I217_EEE_PCS_STATUS; 924c124a83eSRobert Mustacchi adv_addr = I217_EEE_ADVERTISEMENT; 925c124a83eSRobert Mustacchi break; 926c124a83eSRobert Mustacchi default: 92775eba5b6SRobert Mustacchi return E1000_SUCCESS; 928c124a83eSRobert Mustacchi } 92975eba5b6SRobert Mustacchi 93075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 93175eba5b6SRobert Mustacchi if (ret_val) 93275eba5b6SRobert Mustacchi return ret_val; 93375eba5b6SRobert Mustacchi 93475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, I82579_LPI_CTRL, &lpi_ctrl); 93575eba5b6SRobert Mustacchi if (ret_val) 93675eba5b6SRobert Mustacchi goto release; 93775eba5b6SRobert Mustacchi 93875eba5b6SRobert Mustacchi /* Clear bits that enable EEE in various speeds */ 93975eba5b6SRobert Mustacchi lpi_ctrl &= ~I82579_LPI_CTRL_ENABLE_MASK; 94075eba5b6SRobert Mustacchi 94175eba5b6SRobert Mustacchi /* Enable EEE if not disabled by user */ 94275eba5b6SRobert Mustacchi if (!dev_spec->eee_disable) { 94375eba5b6SRobert Mustacchi /* Save off link partner's EEE ability */ 94475eba5b6SRobert Mustacchi ret_val = e1000_read_emi_reg_locked(hw, lpa, 94575eba5b6SRobert Mustacchi &dev_spec->eee_lp_ability); 94675eba5b6SRobert Mustacchi if (ret_val) 94775eba5b6SRobert Mustacchi goto release; 94875eba5b6SRobert Mustacchi 949c124a83eSRobert Mustacchi /* Read EEE advertisement */ 950c124a83eSRobert Mustacchi ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &adv); 951c124a83eSRobert Mustacchi if (ret_val) 952c124a83eSRobert Mustacchi goto release; 953c124a83eSRobert Mustacchi 95475eba5b6SRobert Mustacchi /* Enable EEE only for speeds in which the link partner is 955c124a83eSRobert Mustacchi * EEE capable and for which we advertise EEE. 95675eba5b6SRobert Mustacchi */ 957c124a83eSRobert Mustacchi if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED) 95875eba5b6SRobert Mustacchi lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE; 95975eba5b6SRobert Mustacchi 960c124a83eSRobert Mustacchi if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) { 96175eba5b6SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, PHY_LP_ABILITY, &data); 96275eba5b6SRobert Mustacchi if (data & NWAY_LPAR_100TX_FD_CAPS) 96375eba5b6SRobert Mustacchi lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE; 96475eba5b6SRobert Mustacchi else 96575eba5b6SRobert Mustacchi /* EEE is not supported in 100Half, so ignore 96675eba5b6SRobert Mustacchi * partner's EEE in 100 ability if full-duplex 96775eba5b6SRobert Mustacchi * is not advertised. 96875eba5b6SRobert Mustacchi */ 96975eba5b6SRobert Mustacchi dev_spec->eee_lp_ability &= 97075eba5b6SRobert Mustacchi ~I82579_EEE_100_SUPPORTED; 97175eba5b6SRobert Mustacchi } 972c124a83eSRobert Mustacchi } 973c124a83eSRobert Mustacchi 974c124a83eSRobert Mustacchi if (hw->phy.type == e1000_phy_82579) { 975c124a83eSRobert Mustacchi ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, 976c124a83eSRobert Mustacchi &data); 977c124a83eSRobert Mustacchi if (ret_val) 978c124a83eSRobert Mustacchi goto release; 979c124a83eSRobert Mustacchi 980c124a83eSRobert Mustacchi data &= ~I82579_LPI_100_PLL_SHUT; 981c124a83eSRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, 982c124a83eSRobert Mustacchi data); 983c124a83eSRobert Mustacchi } 98475eba5b6SRobert Mustacchi 98575eba5b6SRobert Mustacchi /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ 98675eba5b6SRobert Mustacchi ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); 98775eba5b6SRobert Mustacchi if (ret_val) 98875eba5b6SRobert Mustacchi goto release; 98975eba5b6SRobert Mustacchi 99075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, I82579_LPI_CTRL, lpi_ctrl); 99175eba5b6SRobert Mustacchi release: 99275eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 99375eba5b6SRobert Mustacchi 99475eba5b6SRobert Mustacchi return ret_val; 99575eba5b6SRobert Mustacchi } 99675eba5b6SRobert Mustacchi 99775eba5b6SRobert Mustacchi /** 99875eba5b6SRobert Mustacchi * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP 99975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 100075eba5b6SRobert Mustacchi * @link: link up bool flag 100175eba5b6SRobert Mustacchi * 100275eba5b6SRobert Mustacchi * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications 100375eba5b6SRobert Mustacchi * preventing further DMA write requests. Workaround the issue by disabling 100475eba5b6SRobert Mustacchi * the de-assertion of the clock request when in 1Gpbs mode. 1005c124a83eSRobert Mustacchi * Also, set appropriate Tx re-transmission timeouts for 10 and 100Half link 1006c124a83eSRobert Mustacchi * speeds in order to avoid Tx hangs. 100775eba5b6SRobert Mustacchi **/ 100875eba5b6SRobert Mustacchi static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) 100975eba5b6SRobert Mustacchi { 101075eba5b6SRobert Mustacchi u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6); 1011c124a83eSRobert Mustacchi u32 status = E1000_READ_REG(hw, E1000_STATUS); 101275eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 1013c124a83eSRobert Mustacchi u16 reg; 101475eba5b6SRobert Mustacchi 1015c124a83eSRobert Mustacchi if (link && (status & E1000_STATUS_SPEED_1000)) { 101675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 101775eba5b6SRobert Mustacchi if (ret_val) 101875eba5b6SRobert Mustacchi return ret_val; 101975eba5b6SRobert Mustacchi 102075eba5b6SRobert Mustacchi ret_val = 102175eba5b6SRobert Mustacchi e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, 1022c124a83eSRobert Mustacchi ®); 102375eba5b6SRobert Mustacchi if (ret_val) 102475eba5b6SRobert Mustacchi goto release; 102575eba5b6SRobert Mustacchi 102675eba5b6SRobert Mustacchi ret_val = 102775eba5b6SRobert Mustacchi e1000_write_kmrn_reg_locked(hw, 102875eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_K1_CONFIG, 1029c124a83eSRobert Mustacchi reg & 103075eba5b6SRobert Mustacchi ~E1000_KMRNCTRLSTA_K1_ENABLE); 103175eba5b6SRobert Mustacchi if (ret_val) 103275eba5b6SRobert Mustacchi goto release; 103375eba5b6SRobert Mustacchi 103475eba5b6SRobert Mustacchi usec_delay(10); 103575eba5b6SRobert Mustacchi 103675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM6, 103775eba5b6SRobert Mustacchi fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK); 103875eba5b6SRobert Mustacchi 103975eba5b6SRobert Mustacchi ret_val = 104075eba5b6SRobert Mustacchi e1000_write_kmrn_reg_locked(hw, 104175eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_K1_CONFIG, 1042c124a83eSRobert Mustacchi reg); 104375eba5b6SRobert Mustacchi release: 104475eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 104575eba5b6SRobert Mustacchi } else { 104675eba5b6SRobert Mustacchi /* clear FEXTNVM6 bit 8 on link down or 10/100 */ 1047c124a83eSRobert Mustacchi fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK; 1048c124a83eSRobert Mustacchi 1049*42cc51e0SRobert Mustacchi if ((hw->phy.revision > 5) || !link || 1050*42cc51e0SRobert Mustacchi ((status & E1000_STATUS_SPEED_100) && 1051c124a83eSRobert Mustacchi (status & E1000_STATUS_FD))) 1052c124a83eSRobert Mustacchi goto update_fextnvm6; 1053c124a83eSRobert Mustacchi 1054c124a83eSRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, I217_INBAND_CTRL, ®); 1055c124a83eSRobert Mustacchi if (ret_val) 1056c124a83eSRobert Mustacchi return ret_val; 1057c124a83eSRobert Mustacchi 1058c124a83eSRobert Mustacchi /* Clear link status transmit timeout */ 1059c124a83eSRobert Mustacchi reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK; 1060c124a83eSRobert Mustacchi 1061c124a83eSRobert Mustacchi if (status & E1000_STATUS_SPEED_100) { 1062c124a83eSRobert Mustacchi /* Set inband Tx timeout to 5x10us for 100Half */ 1063c124a83eSRobert Mustacchi reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT; 1064c124a83eSRobert Mustacchi 1065c124a83eSRobert Mustacchi /* Do not extend the K1 entry latency for 100Half */ 1066c124a83eSRobert Mustacchi fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION; 1067c124a83eSRobert Mustacchi } else { 1068c124a83eSRobert Mustacchi /* Set inband Tx timeout to 50x10us for 10Full/Half */ 1069c124a83eSRobert Mustacchi reg |= 50 << 1070c124a83eSRobert Mustacchi I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT; 1071c124a83eSRobert Mustacchi 1072c124a83eSRobert Mustacchi /* Extend the K1 entry latency for 10 Mbps */ 1073c124a83eSRobert Mustacchi fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION; 1074c124a83eSRobert Mustacchi } 1075c124a83eSRobert Mustacchi 1076c124a83eSRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, I217_INBAND_CTRL, reg); 1077c124a83eSRobert Mustacchi if (ret_val) 1078c124a83eSRobert Mustacchi return ret_val; 1079c124a83eSRobert Mustacchi 1080c124a83eSRobert Mustacchi update_fextnvm6: 1081c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6); 108275eba5b6SRobert Mustacchi } 108375eba5b6SRobert Mustacchi 108475eba5b6SRobert Mustacchi return ret_val; 108575eba5b6SRobert Mustacchi } 108675eba5b6SRobert Mustacchi 108775eba5b6SRobert Mustacchi static u64 e1000_ltr2ns(u16 ltr) 108875eba5b6SRobert Mustacchi { 108975eba5b6SRobert Mustacchi u32 value, scale; 109075eba5b6SRobert Mustacchi 109175eba5b6SRobert Mustacchi /* Determine the latency in nsec based on the LTR value & scale */ 109275eba5b6SRobert Mustacchi value = ltr & E1000_LTRV_VALUE_MASK; 109375eba5b6SRobert Mustacchi scale = (ltr & E1000_LTRV_SCALE_MASK) >> E1000_LTRV_SCALE_SHIFT; 109475eba5b6SRobert Mustacchi 109575eba5b6SRobert Mustacchi return value * (1 << (scale * E1000_LTRV_SCALE_FACTOR)); 109675eba5b6SRobert Mustacchi } 109775eba5b6SRobert Mustacchi 109875eba5b6SRobert Mustacchi /** 109975eba5b6SRobert Mustacchi * e1000_platform_pm_pch_lpt - Set platform power management values 110075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 110175eba5b6SRobert Mustacchi * @link: bool indicating link status 110275eba5b6SRobert Mustacchi * 110375eba5b6SRobert Mustacchi * Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like" 110475eba5b6SRobert Mustacchi * GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed 110575eba5b6SRobert Mustacchi * when link is up (which must not exceed the maximum latency supported 110675eba5b6SRobert Mustacchi * by the platform), otherwise specify there is no LTR requirement. 110775eba5b6SRobert Mustacchi * Unlike TRUE-PCIe devices which set the LTR maximum snoop/no-snoop 110875eba5b6SRobert Mustacchi * latencies in the LTR Extended Capability Structure in the PCIe Extended 110975eba5b6SRobert Mustacchi * Capability register set, on this device LTR is set by writing the 111075eba5b6SRobert Mustacchi * equivalent snoop/no-snoop latencies in the LTRV register in the MAC and 111175eba5b6SRobert Mustacchi * set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB) 111275eba5b6SRobert Mustacchi * message to the PMC. 111375eba5b6SRobert Mustacchi * 111475eba5b6SRobert Mustacchi * Use the LTR value to calculate the Optimized Buffer Flush/Fill (OBFF) 111575eba5b6SRobert Mustacchi * high-water mark. 111675eba5b6SRobert Mustacchi **/ 111775eba5b6SRobert Mustacchi static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) 111875eba5b6SRobert Mustacchi { 111975eba5b6SRobert Mustacchi u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) | 112075eba5b6SRobert Mustacchi link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND; 112175eba5b6SRobert Mustacchi u16 lat_enc = 0; /* latency encoded */ 112275eba5b6SRobert Mustacchi s32 obff_hwm = 0; 112375eba5b6SRobert Mustacchi 112475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_platform_pm_pch_lpt"); 112575eba5b6SRobert Mustacchi 112675eba5b6SRobert Mustacchi if (link) { 112775eba5b6SRobert Mustacchi u16 speed, duplex, scale = 0; 112875eba5b6SRobert Mustacchi u16 max_snoop, max_nosnoop; 112975eba5b6SRobert Mustacchi u16 max_ltr_enc; /* max LTR latency encoded */ 1130*42cc51e0SRobert Mustacchi s64 lat_ns; 113175eba5b6SRobert Mustacchi s64 value; 113275eba5b6SRobert Mustacchi u32 rxa; 113375eba5b6SRobert Mustacchi 113475eba5b6SRobert Mustacchi if (!hw->mac.max_frame_size) { 113575eba5b6SRobert Mustacchi DEBUGOUT("max_frame_size not set.\n"); 113675eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 113775eba5b6SRobert Mustacchi } 113875eba5b6SRobert Mustacchi 113975eba5b6SRobert Mustacchi hw->mac.ops.get_link_up_info(hw, &speed, &duplex); 114075eba5b6SRobert Mustacchi if (!speed) { 114175eba5b6SRobert Mustacchi DEBUGOUT("Speed not set.\n"); 114275eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 114375eba5b6SRobert Mustacchi } 114475eba5b6SRobert Mustacchi 114575eba5b6SRobert Mustacchi /* Rx Packet Buffer Allocation size (KB) */ 114675eba5b6SRobert Mustacchi rxa = E1000_READ_REG(hw, E1000_PBA) & E1000_PBA_RXA_MASK; 114775eba5b6SRobert Mustacchi 114875eba5b6SRobert Mustacchi /* Determine the maximum latency tolerated by the device. 114975eba5b6SRobert Mustacchi * 115075eba5b6SRobert Mustacchi * Per the PCIe spec, the tolerated latencies are encoded as 115175eba5b6SRobert Mustacchi * a 3-bit encoded scale (only 0-5 are valid) multiplied by 115275eba5b6SRobert Mustacchi * a 10-bit value (0-1023) to provide a range from 1 ns to 115375eba5b6SRobert Mustacchi * 2^25*(2^10-1) ns. The scale is encoded as 0=2^0ns, 115475eba5b6SRobert Mustacchi * 1=2^5ns, 2=2^10ns,...5=2^25ns. 115575eba5b6SRobert Mustacchi */ 115675eba5b6SRobert Mustacchi lat_ns = ((s64)rxa * 1024 - 115775eba5b6SRobert Mustacchi (2 * (s64)hw->mac.max_frame_size)) * 8 * 1000; 115875eba5b6SRobert Mustacchi if (lat_ns < 0) 115975eba5b6SRobert Mustacchi lat_ns = 0; 116075eba5b6SRobert Mustacchi else 116175eba5b6SRobert Mustacchi lat_ns /= speed; 116275eba5b6SRobert Mustacchi value = lat_ns; 1163*42cc51e0SRobert Mustacchi 116475eba5b6SRobert Mustacchi while (value > E1000_LTRV_VALUE_MASK) { 116575eba5b6SRobert Mustacchi scale++; 116675eba5b6SRobert Mustacchi value = E1000_DIVIDE_ROUND_UP(value, (1 << 5)); 116775eba5b6SRobert Mustacchi } 116875eba5b6SRobert Mustacchi if (scale > E1000_LTRV_SCALE_MAX) { 116975eba5b6SRobert Mustacchi DEBUGOUT1("Invalid LTR latency scale %d\n", scale); 117075eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 117175eba5b6SRobert Mustacchi } 117275eba5b6SRobert Mustacchi lat_enc = (u16)((scale << E1000_LTRV_SCALE_SHIFT) | value); 117375eba5b6SRobert Mustacchi 117475eba5b6SRobert Mustacchi /* Determine the maximum latency tolerated by the platform */ 117575eba5b6SRobert Mustacchi e1000_read_pci_cfg(hw, E1000_PCI_LTR_CAP_LPT, &max_snoop); 117675eba5b6SRobert Mustacchi e1000_read_pci_cfg(hw, E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop); 117775eba5b6SRobert Mustacchi max_ltr_enc = E1000_MAX(max_snoop, max_nosnoop); 117875eba5b6SRobert Mustacchi 117975eba5b6SRobert Mustacchi if (lat_enc > max_ltr_enc) { 118075eba5b6SRobert Mustacchi lat_enc = max_ltr_enc; 118175eba5b6SRobert Mustacchi lat_ns = e1000_ltr2ns(max_ltr_enc); 118275eba5b6SRobert Mustacchi } 118375eba5b6SRobert Mustacchi 118475eba5b6SRobert Mustacchi if (lat_ns) { 118575eba5b6SRobert Mustacchi lat_ns *= speed * 1000; 118675eba5b6SRobert Mustacchi lat_ns /= 8; 118775eba5b6SRobert Mustacchi lat_ns /= 1000000000; 118875eba5b6SRobert Mustacchi obff_hwm = (s32)(rxa - lat_ns); 118975eba5b6SRobert Mustacchi } 119075eba5b6SRobert Mustacchi if ((obff_hwm < 0) || (obff_hwm > E1000_SVT_OFF_HWM_MASK)) { 119175eba5b6SRobert Mustacchi DEBUGOUT1("Invalid high water mark %d\n", obff_hwm); 119275eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 119375eba5b6SRobert Mustacchi } 119475eba5b6SRobert Mustacchi } 119575eba5b6SRobert Mustacchi 119675eba5b6SRobert Mustacchi /* Set Snoop and No-Snoop latencies the same */ 119775eba5b6SRobert Mustacchi reg |= lat_enc | (lat_enc << E1000_LTRV_NOSNOOP_SHIFT); 119875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_LTRV, reg); 119975eba5b6SRobert Mustacchi 120075eba5b6SRobert Mustacchi /* Set OBFF high water mark */ 120175eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_SVT) & ~E1000_SVT_OFF_HWM_MASK; 120275eba5b6SRobert Mustacchi reg |= obff_hwm; 120375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SVT, reg); 120475eba5b6SRobert Mustacchi 120575eba5b6SRobert Mustacchi /* Enable OBFF */ 120675eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_SVCR); 120775eba5b6SRobert Mustacchi reg |= E1000_SVCR_OFF_EN; 120875eba5b6SRobert Mustacchi /* Always unblock interrupts to the CPU even when the system is 120975eba5b6SRobert Mustacchi * in OBFF mode. This ensures that small round-robin traffic 121075eba5b6SRobert Mustacchi * (like ping) does not get dropped or experience long latency. 121175eba5b6SRobert Mustacchi */ 121275eba5b6SRobert Mustacchi reg |= E1000_SVCR_OFF_MASKINT; 121375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SVCR, reg); 121475eba5b6SRobert Mustacchi 121575eba5b6SRobert Mustacchi return E1000_SUCCESS; 121675eba5b6SRobert Mustacchi } 121775eba5b6SRobert Mustacchi 121875eba5b6SRobert Mustacchi /** 121975eba5b6SRobert Mustacchi * e1000_set_obff_timer_pch_lpt - Update Optimized Buffer Flush/Fill timer 122075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 122175eba5b6SRobert Mustacchi * @itr: interrupt throttling rate 122275eba5b6SRobert Mustacchi * 122375eba5b6SRobert Mustacchi * Configure OBFF with the updated interrupt rate. 122475eba5b6SRobert Mustacchi **/ 122575eba5b6SRobert Mustacchi static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr) 122675eba5b6SRobert Mustacchi { 122775eba5b6SRobert Mustacchi u32 svcr; 122875eba5b6SRobert Mustacchi s32 timer; 122975eba5b6SRobert Mustacchi 123075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_obff_timer_pch_lpt"); 123175eba5b6SRobert Mustacchi 123275eba5b6SRobert Mustacchi /* Convert ITR value into microseconds for OBFF timer */ 123375eba5b6SRobert Mustacchi timer = itr & E1000_ITR_MASK; 123475eba5b6SRobert Mustacchi timer = (timer * E1000_ITR_MULT) / 1000; 123575eba5b6SRobert Mustacchi 123675eba5b6SRobert Mustacchi if ((timer < 0) || (timer > E1000_ITR_MASK)) { 123775eba5b6SRobert Mustacchi DEBUGOUT1("Invalid OBFF timer %d\n", timer); 123875eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 123975eba5b6SRobert Mustacchi } 124075eba5b6SRobert Mustacchi 124175eba5b6SRobert Mustacchi svcr = E1000_READ_REG(hw, E1000_SVCR); 124275eba5b6SRobert Mustacchi svcr &= ~E1000_SVCR_OFF_TIMER_MASK; 124375eba5b6SRobert Mustacchi svcr |= timer << E1000_SVCR_OFF_TIMER_SHIFT; 124475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SVCR, svcr); 124575eba5b6SRobert Mustacchi 124675eba5b6SRobert Mustacchi return E1000_SUCCESS; 124775eba5b6SRobert Mustacchi } 124875eba5b6SRobert Mustacchi 124975eba5b6SRobert Mustacchi /** 1250c124a83eSRobert Mustacchi * e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP 1251c124a83eSRobert Mustacchi * @hw: pointer to the HW structure 1252c124a83eSRobert Mustacchi * @to_sx: boolean indicating a system power state transition to Sx 1253c124a83eSRobert Mustacchi * 1254c124a83eSRobert Mustacchi * When link is down, configure ULP mode to significantly reduce the power 1255c124a83eSRobert Mustacchi * to the PHY. If on a Manageability Engine (ME) enabled system, tell the 1256c124a83eSRobert Mustacchi * ME firmware to start the ULP configuration. If not on an ME enabled 1257c124a83eSRobert Mustacchi * system, configure the ULP mode by software. 1258c124a83eSRobert Mustacchi */ 1259c124a83eSRobert Mustacchi s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) 1260c124a83eSRobert Mustacchi { 1261c124a83eSRobert Mustacchi u32 mac_reg; 1262c124a83eSRobert Mustacchi s32 ret_val = E1000_SUCCESS; 1263c124a83eSRobert Mustacchi u16 phy_reg; 1264*42cc51e0SRobert Mustacchi u16 oem_reg = 0; 1265c124a83eSRobert Mustacchi 1266c124a83eSRobert Mustacchi if ((hw->mac.type < e1000_pch_lpt) || 1267c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) || 1268c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) || 1269c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) || 1270c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_V2) || 1271c124a83eSRobert Mustacchi (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on)) 1272c124a83eSRobert Mustacchi return 0; 1273c124a83eSRobert Mustacchi 1274c124a83eSRobert Mustacchi if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { 1275c124a83eSRobert Mustacchi /* Request ME configure ULP mode in the PHY */ 1276c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_H2ME); 1277c124a83eSRobert Mustacchi mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS; 1278c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); 1279c124a83eSRobert Mustacchi 1280c124a83eSRobert Mustacchi goto out; 1281c124a83eSRobert Mustacchi } 1282c124a83eSRobert Mustacchi 1283c124a83eSRobert Mustacchi if (!to_sx) { 1284c124a83eSRobert Mustacchi int i = 0; 1285c124a83eSRobert Mustacchi 1286c124a83eSRobert Mustacchi /* Poll up to 5 seconds for Cable Disconnected indication */ 1287c124a83eSRobert Mustacchi while (!(E1000_READ_REG(hw, E1000_FEXT) & 1288c124a83eSRobert Mustacchi E1000_FEXT_PHY_CABLE_DISCONNECTED)) { 1289c124a83eSRobert Mustacchi /* Bail if link is re-acquired */ 1290c124a83eSRobert Mustacchi if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU) 1291c124a83eSRobert Mustacchi return -E1000_ERR_PHY; 1292c124a83eSRobert Mustacchi 1293c124a83eSRobert Mustacchi if (i++ == 100) 1294c124a83eSRobert Mustacchi break; 1295c124a83eSRobert Mustacchi 1296c124a83eSRobert Mustacchi msec_delay(50); 1297c124a83eSRobert Mustacchi } 1298c124a83eSRobert Mustacchi DEBUGOUT2("CABLE_DISCONNECTED %s set after %dmsec\n", 1299c124a83eSRobert Mustacchi (E1000_READ_REG(hw, E1000_FEXT) & 1300c124a83eSRobert Mustacchi E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not", 1301c124a83eSRobert Mustacchi i * 50); 1302c124a83eSRobert Mustacchi } 1303c124a83eSRobert Mustacchi 1304c124a83eSRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 1305c124a83eSRobert Mustacchi if (ret_val) 1306c124a83eSRobert Mustacchi goto out; 1307c124a83eSRobert Mustacchi 1308c124a83eSRobert Mustacchi /* Force SMBus mode in PHY */ 1309c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); 1310c124a83eSRobert Mustacchi if (ret_val) 1311c124a83eSRobert Mustacchi goto release; 1312c124a83eSRobert Mustacchi phy_reg |= CV_SMB_CTRL_FORCE_SMBUS; 1313c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); 1314c124a83eSRobert Mustacchi 1315c124a83eSRobert Mustacchi /* Force SMBus mode in MAC */ 1316c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 1317c124a83eSRobert Mustacchi mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; 1318c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 1319c124a83eSRobert Mustacchi 1320*42cc51e0SRobert Mustacchi /* Si workaround for ULP entry flow on i127/rev6 h/w. Enable 1321*42cc51e0SRobert Mustacchi * LPLU and disable Gig speed when entering ULP 1322*42cc51e0SRobert Mustacchi */ 1323*42cc51e0SRobert Mustacchi if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) { 1324*42cc51e0SRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS, 1325*42cc51e0SRobert Mustacchi &oem_reg); 1326*42cc51e0SRobert Mustacchi if (ret_val) 1327*42cc51e0SRobert Mustacchi goto release; 1328*42cc51e0SRobert Mustacchi 1329*42cc51e0SRobert Mustacchi phy_reg = oem_reg; 1330*42cc51e0SRobert Mustacchi phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS; 1331*42cc51e0SRobert Mustacchi 1332*42cc51e0SRobert Mustacchi ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS, 1333*42cc51e0SRobert Mustacchi phy_reg); 1334*42cc51e0SRobert Mustacchi 1335*42cc51e0SRobert Mustacchi if (ret_val) 1336*42cc51e0SRobert Mustacchi goto release; 1337*42cc51e0SRobert Mustacchi } 1338*42cc51e0SRobert Mustacchi 1339c124a83eSRobert Mustacchi /* Set Inband ULP Exit, Reset to SMBus mode and 1340c124a83eSRobert Mustacchi * Disable SMBus Release on PERST# in PHY 1341c124a83eSRobert Mustacchi */ 1342c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); 1343c124a83eSRobert Mustacchi if (ret_val) 1344c124a83eSRobert Mustacchi goto release; 1345c124a83eSRobert Mustacchi phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS | 1346c124a83eSRobert Mustacchi I218_ULP_CONFIG1_DISABLE_SMB_PERST); 1347c124a83eSRobert Mustacchi if (to_sx) { 1348c124a83eSRobert Mustacchi if (E1000_READ_REG(hw, E1000_WUFC) & E1000_WUFC_LNKC) 1349c124a83eSRobert Mustacchi phy_reg |= I218_ULP_CONFIG1_WOL_HOST; 1350*42cc51e0SRobert Mustacchi else 1351*42cc51e0SRobert Mustacchi phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST; 1352c124a83eSRobert Mustacchi 1353c124a83eSRobert Mustacchi phy_reg |= I218_ULP_CONFIG1_STICKY_ULP; 1354*42cc51e0SRobert Mustacchi phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT; 1355c124a83eSRobert Mustacchi } else { 1356c124a83eSRobert Mustacchi phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT; 1357*42cc51e0SRobert Mustacchi phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP; 1358*42cc51e0SRobert Mustacchi phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST; 1359c124a83eSRobert Mustacchi } 1360c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1361c124a83eSRobert Mustacchi 1362c124a83eSRobert Mustacchi /* Set Disable SMBus Release on PERST# in MAC */ 1363c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); 1364c124a83eSRobert Mustacchi mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST; 1365c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); 1366c124a83eSRobert Mustacchi 1367c124a83eSRobert Mustacchi /* Commit ULP changes in PHY by starting auto ULP configuration */ 1368c124a83eSRobert Mustacchi phy_reg |= I218_ULP_CONFIG1_START; 1369c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1370*42cc51e0SRobert Mustacchi 1371*42cc51e0SRobert Mustacchi if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) && 1372*42cc51e0SRobert Mustacchi to_sx && (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { 1373*42cc51e0SRobert Mustacchi ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS, 1374*42cc51e0SRobert Mustacchi oem_reg); 1375*42cc51e0SRobert Mustacchi if (ret_val) 1376*42cc51e0SRobert Mustacchi goto release; 1377*42cc51e0SRobert Mustacchi } 1378*42cc51e0SRobert Mustacchi 1379c124a83eSRobert Mustacchi release: 1380c124a83eSRobert Mustacchi hw->phy.ops.release(hw); 1381c124a83eSRobert Mustacchi out: 1382*42cc51e0SRobert Mustacchi if (ret_val) 1383c124a83eSRobert Mustacchi DEBUGOUT1("Error in ULP enable flow: %d\n", ret_val); 1384*42cc51e0SRobert Mustacchi else 1385c124a83eSRobert Mustacchi hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on; 1386c124a83eSRobert Mustacchi 1387c124a83eSRobert Mustacchi return ret_val; 1388c124a83eSRobert Mustacchi } 1389c124a83eSRobert Mustacchi 1390c124a83eSRobert Mustacchi /** 1391c124a83eSRobert Mustacchi * e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for LynxPoint-LP 1392c124a83eSRobert Mustacchi * @hw: pointer to the HW structure 1393c124a83eSRobert Mustacchi * @force: boolean indicating whether or not to force disabling ULP 1394c124a83eSRobert Mustacchi * 1395c124a83eSRobert Mustacchi * Un-configure ULP mode when link is up, the system is transitioned from 1396c124a83eSRobert Mustacchi * Sx or the driver is unloaded. If on a Manageability Engine (ME) enabled 1397c124a83eSRobert Mustacchi * system, poll for an indication from ME that ULP has been un-configured. 1398c124a83eSRobert Mustacchi * If not on an ME enabled system, un-configure the ULP mode by software. 1399c124a83eSRobert Mustacchi * 1400c124a83eSRobert Mustacchi * During nominal operation, this function is called when link is acquired 1401c124a83eSRobert Mustacchi * to disable ULP mode (force=FALSE); otherwise, for example when unloading 1402c124a83eSRobert Mustacchi * the driver or during Sx->S0 transitions, this is called with force=TRUE 1403c124a83eSRobert Mustacchi * to forcibly disable ULP. 1404c124a83eSRobert Mustacchi */ 1405c124a83eSRobert Mustacchi s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) 1406c124a83eSRobert Mustacchi { 1407c124a83eSRobert Mustacchi s32 ret_val = E1000_SUCCESS; 1408c124a83eSRobert Mustacchi u32 mac_reg; 1409c124a83eSRobert Mustacchi u16 phy_reg; 1410c124a83eSRobert Mustacchi int i = 0; 1411c124a83eSRobert Mustacchi 1412c124a83eSRobert Mustacchi if ((hw->mac.type < e1000_pch_lpt) || 1413c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) || 1414c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) || 1415c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) || 1416c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_V2) || 1417c124a83eSRobert Mustacchi (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_off)) 1418c124a83eSRobert Mustacchi return 0; 1419c124a83eSRobert Mustacchi 1420c124a83eSRobert Mustacchi if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { 1421c124a83eSRobert Mustacchi if (force) { 1422c124a83eSRobert Mustacchi /* Request ME un-configure ULP mode in the PHY */ 1423c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_H2ME); 1424c124a83eSRobert Mustacchi mac_reg &= ~E1000_H2ME_ULP; 1425c124a83eSRobert Mustacchi mac_reg |= E1000_H2ME_ENFORCE_SETTINGS; 1426c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); 1427c124a83eSRobert Mustacchi } 1428c124a83eSRobert Mustacchi 1429*42cc51e0SRobert Mustacchi /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */ 1430c124a83eSRobert Mustacchi while (E1000_READ_REG(hw, E1000_FWSM) & 1431c124a83eSRobert Mustacchi E1000_FWSM_ULP_CFG_DONE) { 1432*42cc51e0SRobert Mustacchi if (i++ == 30) { 1433c124a83eSRobert Mustacchi ret_val = -E1000_ERR_PHY; 1434c124a83eSRobert Mustacchi goto out; 1435c124a83eSRobert Mustacchi } 1436c124a83eSRobert Mustacchi 1437c124a83eSRobert Mustacchi msec_delay(10); 1438c124a83eSRobert Mustacchi } 1439c124a83eSRobert Mustacchi DEBUGOUT1("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10); 1440c124a83eSRobert Mustacchi 1441c124a83eSRobert Mustacchi if (force) { 1442c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_H2ME); 1443c124a83eSRobert Mustacchi mac_reg &= ~E1000_H2ME_ENFORCE_SETTINGS; 1444c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); 1445c124a83eSRobert Mustacchi } else { 1446c124a83eSRobert Mustacchi /* Clear H2ME.ULP after ME ULP configuration */ 1447c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_H2ME); 1448c124a83eSRobert Mustacchi mac_reg &= ~E1000_H2ME_ULP; 1449c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); 1450c124a83eSRobert Mustacchi } 1451c124a83eSRobert Mustacchi 1452c124a83eSRobert Mustacchi goto out; 1453c124a83eSRobert Mustacchi } 1454c124a83eSRobert Mustacchi 1455c124a83eSRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 1456c124a83eSRobert Mustacchi if (ret_val) 1457c124a83eSRobert Mustacchi goto out; 1458c124a83eSRobert Mustacchi 1459c124a83eSRobert Mustacchi if (force) 1460c124a83eSRobert Mustacchi /* Toggle LANPHYPC Value bit */ 1461c124a83eSRobert Mustacchi e1000_toggle_lanphypc_pch_lpt(hw); 1462c124a83eSRobert Mustacchi 1463c124a83eSRobert Mustacchi /* Unforce SMBus mode in PHY */ 1464c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); 1465c124a83eSRobert Mustacchi if (ret_val) { 1466c124a83eSRobert Mustacchi /* The MAC might be in PCIe mode, so temporarily force to 1467c124a83eSRobert Mustacchi * SMBus mode in order to access the PHY. 1468c124a83eSRobert Mustacchi */ 1469c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 1470c124a83eSRobert Mustacchi mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; 1471c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 1472c124a83eSRobert Mustacchi 1473c124a83eSRobert Mustacchi msec_delay(50); 1474c124a83eSRobert Mustacchi 1475c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, 1476c124a83eSRobert Mustacchi &phy_reg); 1477c124a83eSRobert Mustacchi if (ret_val) 1478c124a83eSRobert Mustacchi goto release; 1479c124a83eSRobert Mustacchi } 1480c124a83eSRobert Mustacchi phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; 1481c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); 1482c124a83eSRobert Mustacchi 1483c124a83eSRobert Mustacchi /* Unforce SMBus mode in MAC */ 1484c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 1485c124a83eSRobert Mustacchi mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; 1486c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); 1487c124a83eSRobert Mustacchi 1488c124a83eSRobert Mustacchi /* When ULP mode was previously entered, K1 was disabled by the 1489c124a83eSRobert Mustacchi * hardware. Re-Enable K1 in the PHY when exiting ULP. 1490c124a83eSRobert Mustacchi */ 1491c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg); 1492c124a83eSRobert Mustacchi if (ret_val) 1493c124a83eSRobert Mustacchi goto release; 1494c124a83eSRobert Mustacchi phy_reg |= HV_PM_CTRL_K1_ENABLE; 1495c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg); 1496c124a83eSRobert Mustacchi 1497c124a83eSRobert Mustacchi /* Clear ULP enabled configuration */ 1498c124a83eSRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); 1499c124a83eSRobert Mustacchi if (ret_val) 1500c124a83eSRobert Mustacchi goto release; 1501c124a83eSRobert Mustacchi phy_reg &= ~(I218_ULP_CONFIG1_IND | 1502c124a83eSRobert Mustacchi I218_ULP_CONFIG1_STICKY_ULP | 1503c124a83eSRobert Mustacchi I218_ULP_CONFIG1_RESET_TO_SMBUS | 1504c124a83eSRobert Mustacchi I218_ULP_CONFIG1_WOL_HOST | 1505c124a83eSRobert Mustacchi I218_ULP_CONFIG1_INBAND_EXIT | 1506*42cc51e0SRobert Mustacchi I218_ULP_CONFIG1_EN_ULP_LANPHYPC | 1507*42cc51e0SRobert Mustacchi I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST | 1508c124a83eSRobert Mustacchi I218_ULP_CONFIG1_DISABLE_SMB_PERST); 1509c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1510c124a83eSRobert Mustacchi 1511c124a83eSRobert Mustacchi /* Commit ULP changes by starting auto ULP configuration */ 1512c124a83eSRobert Mustacchi phy_reg |= I218_ULP_CONFIG1_START; 1513c124a83eSRobert Mustacchi e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1514c124a83eSRobert Mustacchi 1515c124a83eSRobert Mustacchi /* Clear Disable SMBus Release on PERST# in MAC */ 1516c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); 1517c124a83eSRobert Mustacchi mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; 1518c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); 1519c124a83eSRobert Mustacchi 1520c124a83eSRobert Mustacchi release: 1521c124a83eSRobert Mustacchi hw->phy.ops.release(hw); 1522c124a83eSRobert Mustacchi if (force) { 1523c124a83eSRobert Mustacchi hw->phy.ops.reset(hw); 1524c124a83eSRobert Mustacchi msec_delay(50); 1525c124a83eSRobert Mustacchi } 1526c124a83eSRobert Mustacchi out: 1527*42cc51e0SRobert Mustacchi if (ret_val) 1528c124a83eSRobert Mustacchi DEBUGOUT1("Error in ULP disable flow: %d\n", ret_val); 1529*42cc51e0SRobert Mustacchi else 1530c124a83eSRobert Mustacchi hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_off; 1531c124a83eSRobert Mustacchi 1532c124a83eSRobert Mustacchi return ret_val; 1533c124a83eSRobert Mustacchi } 1534c124a83eSRobert Mustacchi 1535c124a83eSRobert Mustacchi /** 153675eba5b6SRobert Mustacchi * e1000_check_for_copper_link_ich8lan - Check for link (Copper) 153775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 153875eba5b6SRobert Mustacchi * 153975eba5b6SRobert Mustacchi * Checks to see of the link status of the hardware has changed. If a 154075eba5b6SRobert Mustacchi * change in link status has been detected, then we read the PHY registers 154175eba5b6SRobert Mustacchi * to get the current speed/duplex if link exists. 154275eba5b6SRobert Mustacchi **/ 154375eba5b6SRobert Mustacchi static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) 154475eba5b6SRobert Mustacchi { 154575eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 1546*42cc51e0SRobert Mustacchi s32 ret_val, tipg_reg = 0; 1547*42cc51e0SRobert Mustacchi u16 emi_addr, emi_val = 0; 154875eba5b6SRobert Mustacchi bool link; 154975eba5b6SRobert Mustacchi u16 phy_reg; 155075eba5b6SRobert Mustacchi 155175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_copper_link_ich8lan"); 155275eba5b6SRobert Mustacchi 155375eba5b6SRobert Mustacchi /* We only want to go out to the PHY registers to see if Auto-Neg 155475eba5b6SRobert Mustacchi * has completed and/or if our link status has changed. The 155575eba5b6SRobert Mustacchi * get_link_status flag is set upon receiving a Link Status 155675eba5b6SRobert Mustacchi * Change or Rx Sequence Error interrupt. 155775eba5b6SRobert Mustacchi */ 155875eba5b6SRobert Mustacchi if (!mac->get_link_status) 155975eba5b6SRobert Mustacchi return E1000_SUCCESS; 156075eba5b6SRobert Mustacchi 156175eba5b6SRobert Mustacchi /* First we want to see if the MII Status Register reports 156275eba5b6SRobert Mustacchi * link. If so, then we want to get the current speed/duplex 156375eba5b6SRobert Mustacchi * of the PHY. 156475eba5b6SRobert Mustacchi */ 156575eba5b6SRobert Mustacchi ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); 156675eba5b6SRobert Mustacchi if (ret_val) 156775eba5b6SRobert Mustacchi return ret_val; 156875eba5b6SRobert Mustacchi 156975eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pchlan) { 157075eba5b6SRobert Mustacchi ret_val = e1000_k1_gig_workaround_hv(hw, link); 157175eba5b6SRobert Mustacchi if (ret_val) 157275eba5b6SRobert Mustacchi return ret_val; 157375eba5b6SRobert Mustacchi } 157475eba5b6SRobert Mustacchi 1575c124a83eSRobert Mustacchi /* When connected at 10Mbps half-duplex, some parts are excessively 157675eba5b6SRobert Mustacchi * aggressive resulting in many collisions. To avoid this, increase 157775eba5b6SRobert Mustacchi * the IPG and reduce Rx latency in the PHY. 157875eba5b6SRobert Mustacchi */ 1579c124a83eSRobert Mustacchi if (((hw->mac.type == e1000_pch2lan) || 1580*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_lpt) || 1581*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) && link) { 1582*42cc51e0SRobert Mustacchi u16 speed, duplex; 1583c124a83eSRobert Mustacchi 1584*42cc51e0SRobert Mustacchi e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex); 1585*42cc51e0SRobert Mustacchi tipg_reg = E1000_READ_REG(hw, E1000_TIPG); 1586*42cc51e0SRobert Mustacchi tipg_reg &= ~E1000_TIPG_IPGT_MASK; 158775eba5b6SRobert Mustacchi 1588*42cc51e0SRobert Mustacchi if (duplex == HALF_DUPLEX && speed == SPEED_10) { 1589*42cc51e0SRobert Mustacchi tipg_reg |= 0xFF; 159075eba5b6SRobert Mustacchi /* Reduce Rx latency in analog PHY */ 1591*42cc51e0SRobert Mustacchi emi_val = 0; 1592*42cc51e0SRobert Mustacchi } else if (hw->mac.type == e1000_pch_spt && 1593*42cc51e0SRobert Mustacchi duplex == FULL_DUPLEX && speed != SPEED_1000) { 1594*42cc51e0SRobert Mustacchi tipg_reg |= 0xC; 1595*42cc51e0SRobert Mustacchi emi_val = 1; 1596*42cc51e0SRobert Mustacchi } else { 1597*42cc51e0SRobert Mustacchi /* Roll back the default values */ 1598*42cc51e0SRobert Mustacchi tipg_reg |= 0x08; 1599*42cc51e0SRobert Mustacchi emi_val = 1; 1600*42cc51e0SRobert Mustacchi } 1601*42cc51e0SRobert Mustacchi 1602*42cc51e0SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TIPG, tipg_reg); 1603*42cc51e0SRobert Mustacchi 160475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 160575eba5b6SRobert Mustacchi if (ret_val) 160675eba5b6SRobert Mustacchi return ret_val; 160775eba5b6SRobert Mustacchi 1608c124a83eSRobert Mustacchi if (hw->mac.type == e1000_pch2lan) 1609c124a83eSRobert Mustacchi emi_addr = I82579_RX_CONFIG; 1610c124a83eSRobert Mustacchi else 1611c124a83eSRobert Mustacchi emi_addr = I217_RX_CONFIG; 1612*42cc51e0SRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, emi_addr, emi_val); 161375eba5b6SRobert Mustacchi 1614*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_lpt || 1615*42cc51e0SRobert Mustacchi hw->mac.type == e1000_pch_spt) { 1616*42cc51e0SRobert Mustacchi u16 phy_reg; 1617*42cc51e0SRobert Mustacchi 1618*42cc51e0SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG, 1619*42cc51e0SRobert Mustacchi &phy_reg); 1620*42cc51e0SRobert Mustacchi phy_reg &= ~I217_PLL_CLOCK_GATE_MASK; 1621*42cc51e0SRobert Mustacchi if (speed == SPEED_100 || speed == SPEED_10) 1622*42cc51e0SRobert Mustacchi phy_reg |= 0x3E8; 1623*42cc51e0SRobert Mustacchi else 1624*42cc51e0SRobert Mustacchi phy_reg |= 0xFA; 1625*42cc51e0SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, 1626*42cc51e0SRobert Mustacchi I217_PLL_CLOCK_GATE_REG, 1627*42cc51e0SRobert Mustacchi phy_reg); 1628*42cc51e0SRobert Mustacchi } 162975eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 163075eba5b6SRobert Mustacchi 163175eba5b6SRobert Mustacchi if (ret_val) 163275eba5b6SRobert Mustacchi return ret_val; 1633*42cc51e0SRobert Mustacchi 1634*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 1635*42cc51e0SRobert Mustacchi u16 data; 1636*42cc51e0SRobert Mustacchi u16 ptr_gap; 1637*42cc51e0SRobert Mustacchi 1638*42cc51e0SRobert Mustacchi if (speed == SPEED_1000) { 1639*42cc51e0SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 1640*42cc51e0SRobert Mustacchi if (ret_val) 1641*42cc51e0SRobert Mustacchi return ret_val; 1642*42cc51e0SRobert Mustacchi 1643*42cc51e0SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, 1644*42cc51e0SRobert Mustacchi PHY_REG(776, 20), 1645*42cc51e0SRobert Mustacchi &data); 1646*42cc51e0SRobert Mustacchi if (ret_val) { 1647*42cc51e0SRobert Mustacchi hw->phy.ops.release(hw); 1648*42cc51e0SRobert Mustacchi return ret_val; 164975eba5b6SRobert Mustacchi } 1650*42cc51e0SRobert Mustacchi 1651*42cc51e0SRobert Mustacchi ptr_gap = (data & (0x3FF << 2)) >> 2; 1652*42cc51e0SRobert Mustacchi if (ptr_gap < 0x18) { 1653*42cc51e0SRobert Mustacchi data &= ~(0x3FF << 2); 1654*42cc51e0SRobert Mustacchi data |= (0x18 << 2); 1655*42cc51e0SRobert Mustacchi ret_val = 1656*42cc51e0SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, 1657*42cc51e0SRobert Mustacchi PHY_REG(776, 20), data); 1658*42cc51e0SRobert Mustacchi } 1659*42cc51e0SRobert Mustacchi hw->phy.ops.release(hw); 1660*42cc51e0SRobert Mustacchi if (ret_val) 1661*42cc51e0SRobert Mustacchi return ret_val; 1662*42cc51e0SRobert Mustacchi } else { 1663*42cc51e0SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 1664*42cc51e0SRobert Mustacchi if (ret_val) 1665*42cc51e0SRobert Mustacchi return ret_val; 1666*42cc51e0SRobert Mustacchi 1667*42cc51e0SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, 1668*42cc51e0SRobert Mustacchi PHY_REG(776, 20), 1669*42cc51e0SRobert Mustacchi 0xC023); 1670*42cc51e0SRobert Mustacchi hw->phy.ops.release(hw); 1671*42cc51e0SRobert Mustacchi if (ret_val) 1672*42cc51e0SRobert Mustacchi return ret_val; 1673*42cc51e0SRobert Mustacchi 1674*42cc51e0SRobert Mustacchi } 1675*42cc51e0SRobert Mustacchi } 1676*42cc51e0SRobert Mustacchi } 1677*42cc51e0SRobert Mustacchi 1678*42cc51e0SRobert Mustacchi /* I217 Packet Loss issue: 1679*42cc51e0SRobert Mustacchi * ensure that FEXTNVM4 Beacon Duration is set correctly 1680*42cc51e0SRobert Mustacchi * on power up. 1681*42cc51e0SRobert Mustacchi * Set the Beacon Duration for I217 to 8 usec 1682*42cc51e0SRobert Mustacchi */ 1683*42cc51e0SRobert Mustacchi if ((hw->mac.type == e1000_pch_lpt) || 1684*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) { 1685*42cc51e0SRobert Mustacchi u32 mac_reg; 1686*42cc51e0SRobert Mustacchi 1687*42cc51e0SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4); 1688*42cc51e0SRobert Mustacchi mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; 1689*42cc51e0SRobert Mustacchi mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; 1690*42cc51e0SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg); 169175eba5b6SRobert Mustacchi } 169275eba5b6SRobert Mustacchi 169375eba5b6SRobert Mustacchi /* Work-around I218 hang issue */ 169475eba5b6SRobert Mustacchi if ((hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || 1695c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) || 1696c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_LM3) || 1697c124a83eSRobert Mustacchi (hw->device_id == E1000_DEV_ID_PCH_I218_V3)) { 169875eba5b6SRobert Mustacchi ret_val = e1000_k1_workaround_lpt_lp(hw, link); 169975eba5b6SRobert Mustacchi if (ret_val) 170075eba5b6SRobert Mustacchi return ret_val; 170175eba5b6SRobert Mustacchi } 1702*42cc51e0SRobert Mustacchi if ((hw->mac.type == e1000_pch_lpt) || 1703*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) { 1704c124a83eSRobert Mustacchi /* Set platform power management values for 1705c124a83eSRobert Mustacchi * Latency Tolerance Reporting (LTR) 1706c124a83eSRobert Mustacchi * Optimized Buffer Flush/Fill (OBFF) 170775eba5b6SRobert Mustacchi */ 170875eba5b6SRobert Mustacchi ret_val = e1000_platform_pm_pch_lpt(hw, link); 170975eba5b6SRobert Mustacchi if (ret_val) 171075eba5b6SRobert Mustacchi return ret_val; 171175eba5b6SRobert Mustacchi } 171275eba5b6SRobert Mustacchi 171375eba5b6SRobert Mustacchi /* Clear link partner's EEE ability */ 171475eba5b6SRobert Mustacchi hw->dev_spec.ich8lan.eee_lp_ability = 0; 171575eba5b6SRobert Mustacchi 1716*42cc51e0SRobert Mustacchi /* FEXTNVM6 K1-off workaround */ 1717*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 1718*42cc51e0SRobert Mustacchi u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG); 1719*42cc51e0SRobert Mustacchi u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6); 1720*42cc51e0SRobert Mustacchi 1721*42cc51e0SRobert Mustacchi if (pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE) 1722*42cc51e0SRobert Mustacchi fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE; 1723*42cc51e0SRobert Mustacchi else 1724*42cc51e0SRobert Mustacchi fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; 1725*42cc51e0SRobert Mustacchi 1726*42cc51e0SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6); 1727*42cc51e0SRobert Mustacchi } 1728*42cc51e0SRobert Mustacchi 172975eba5b6SRobert Mustacchi if (!link) 173075eba5b6SRobert Mustacchi return E1000_SUCCESS; /* No link detected */ 173175eba5b6SRobert Mustacchi 173275eba5b6SRobert Mustacchi mac->get_link_status = FALSE; 173375eba5b6SRobert Mustacchi 173475eba5b6SRobert Mustacchi switch (hw->mac.type) { 173575eba5b6SRobert Mustacchi case e1000_pch2lan: 173675eba5b6SRobert Mustacchi ret_val = e1000_k1_workaround_lv(hw); 173775eba5b6SRobert Mustacchi if (ret_val) 173875eba5b6SRobert Mustacchi return ret_val; 173975eba5b6SRobert Mustacchi /* fall-thru */ 174075eba5b6SRobert Mustacchi case e1000_pchlan: 174175eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82578) { 174275eba5b6SRobert Mustacchi ret_val = e1000_link_stall_workaround_hv(hw); 174375eba5b6SRobert Mustacchi if (ret_val) 174475eba5b6SRobert Mustacchi return ret_val; 174575eba5b6SRobert Mustacchi } 174675eba5b6SRobert Mustacchi 174775eba5b6SRobert Mustacchi /* Workaround for PCHx parts in half-duplex: 174875eba5b6SRobert Mustacchi * Set the number of preambles removed from the packet 174975eba5b6SRobert Mustacchi * when it is passed from the PHY to the MAC to prevent 175075eba5b6SRobert Mustacchi * the MAC from misinterpreting the packet type. 175175eba5b6SRobert Mustacchi */ 175275eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg); 175375eba5b6SRobert Mustacchi phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK; 175475eba5b6SRobert Mustacchi 175575eba5b6SRobert Mustacchi if ((E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_FD) != 175675eba5b6SRobert Mustacchi E1000_STATUS_FD) 175775eba5b6SRobert Mustacchi phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT); 175875eba5b6SRobert Mustacchi 175975eba5b6SRobert Mustacchi hw->phy.ops.write_reg(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg); 176075eba5b6SRobert Mustacchi break; 176175eba5b6SRobert Mustacchi default: 176275eba5b6SRobert Mustacchi break; 176375eba5b6SRobert Mustacchi } 176475eba5b6SRobert Mustacchi 176575eba5b6SRobert Mustacchi /* Check if there was DownShift, must be checked 176675eba5b6SRobert Mustacchi * immediately after link-up 176775eba5b6SRobert Mustacchi */ 176875eba5b6SRobert Mustacchi e1000_check_downshift_generic(hw); 176975eba5b6SRobert Mustacchi 177075eba5b6SRobert Mustacchi /* Enable/Disable EEE after link up */ 1771c124a83eSRobert Mustacchi if (hw->phy.type > e1000_phy_82579) { 177275eba5b6SRobert Mustacchi ret_val = e1000_set_eee_pchlan(hw); 177375eba5b6SRobert Mustacchi if (ret_val) 177475eba5b6SRobert Mustacchi return ret_val; 1775c124a83eSRobert Mustacchi } 177675eba5b6SRobert Mustacchi 177775eba5b6SRobert Mustacchi /* If we are forcing speed/duplex, then we simply return since 177875eba5b6SRobert Mustacchi * we have already determined whether we have link or not. 177975eba5b6SRobert Mustacchi */ 178075eba5b6SRobert Mustacchi if (!mac->autoneg) 178175eba5b6SRobert Mustacchi return -E1000_ERR_CONFIG; 178275eba5b6SRobert Mustacchi 178375eba5b6SRobert Mustacchi /* Auto-Neg is enabled. Auto Speed Detection takes care 178475eba5b6SRobert Mustacchi * of MAC speed/duplex configuration. So we only need to 178575eba5b6SRobert Mustacchi * configure Collision Distance in the MAC. 178675eba5b6SRobert Mustacchi */ 178775eba5b6SRobert Mustacchi mac->ops.config_collision_dist(hw); 178875eba5b6SRobert Mustacchi 178975eba5b6SRobert Mustacchi /* Configure Flow Control now that Auto-Neg has completed. 179075eba5b6SRobert Mustacchi * First, we need to restore the desired flow control 179175eba5b6SRobert Mustacchi * settings because we may have had to re-autoneg with a 179275eba5b6SRobert Mustacchi * different link partner. 179375eba5b6SRobert Mustacchi */ 179475eba5b6SRobert Mustacchi ret_val = e1000_config_fc_after_link_up_generic(hw); 179575eba5b6SRobert Mustacchi if (ret_val) 179675eba5b6SRobert Mustacchi DEBUGOUT("Error configuring flow control\n"); 179775eba5b6SRobert Mustacchi 179875eba5b6SRobert Mustacchi return ret_val; 179975eba5b6SRobert Mustacchi } 180075eba5b6SRobert Mustacchi 180175eba5b6SRobert Mustacchi /** 180275eba5b6SRobert Mustacchi * e1000_init_function_pointers_ich8lan - Initialize ICH8 function pointers 180375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 180475eba5b6SRobert Mustacchi * 180575eba5b6SRobert Mustacchi * Initialize family-specific function pointers for PHY, MAC, and NVM. 180675eba5b6SRobert Mustacchi **/ 180775eba5b6SRobert Mustacchi void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) 180875eba5b6SRobert Mustacchi { 180975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_function_pointers_ich8lan"); 181075eba5b6SRobert Mustacchi 181175eba5b6SRobert Mustacchi hw->mac.ops.init_params = e1000_init_mac_params_ich8lan; 181275eba5b6SRobert Mustacchi hw->nvm.ops.init_params = e1000_init_nvm_params_ich8lan; 181375eba5b6SRobert Mustacchi switch (hw->mac.type) { 181475eba5b6SRobert Mustacchi case e1000_ich8lan: 181575eba5b6SRobert Mustacchi case e1000_ich9lan: 181675eba5b6SRobert Mustacchi case e1000_ich10lan: 181775eba5b6SRobert Mustacchi hw->phy.ops.init_params = e1000_init_phy_params_ich8lan; 181875eba5b6SRobert Mustacchi break; 181975eba5b6SRobert Mustacchi case e1000_pchlan: 182075eba5b6SRobert Mustacchi case e1000_pch2lan: 182175eba5b6SRobert Mustacchi case e1000_pch_lpt: 1822*42cc51e0SRobert Mustacchi case e1000_pch_spt: 182375eba5b6SRobert Mustacchi hw->phy.ops.init_params = e1000_init_phy_params_pchlan; 182475eba5b6SRobert Mustacchi break; 182575eba5b6SRobert Mustacchi default: 182675eba5b6SRobert Mustacchi break; 182775eba5b6SRobert Mustacchi } 182875eba5b6SRobert Mustacchi } 182975eba5b6SRobert Mustacchi 183075eba5b6SRobert Mustacchi /** 183175eba5b6SRobert Mustacchi * e1000_acquire_nvm_ich8lan - Acquire NVM mutex 183275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 183375eba5b6SRobert Mustacchi * 183475eba5b6SRobert Mustacchi * Acquires the mutex for performing NVM operations. 183575eba5b6SRobert Mustacchi **/ 183675eba5b6SRobert Mustacchi static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw) 183775eba5b6SRobert Mustacchi { 183875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_nvm_ich8lan"); 183975eba5b6SRobert Mustacchi 184075eba5b6SRobert Mustacchi E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.nvm_mutex); 184175eba5b6SRobert Mustacchi 184275eba5b6SRobert Mustacchi return E1000_SUCCESS; 184375eba5b6SRobert Mustacchi } 184475eba5b6SRobert Mustacchi 184575eba5b6SRobert Mustacchi /** 184675eba5b6SRobert Mustacchi * e1000_release_nvm_ich8lan - Release NVM mutex 184775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 184875eba5b6SRobert Mustacchi * 184975eba5b6SRobert Mustacchi * Releases the mutex used while performing NVM operations. 185075eba5b6SRobert Mustacchi **/ 185175eba5b6SRobert Mustacchi static void e1000_release_nvm_ich8lan(struct e1000_hw *hw) 185275eba5b6SRobert Mustacchi { 185375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_nvm_ich8lan"); 185475eba5b6SRobert Mustacchi 185575eba5b6SRobert Mustacchi E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.nvm_mutex); 185675eba5b6SRobert Mustacchi 185775eba5b6SRobert Mustacchi return; 185875eba5b6SRobert Mustacchi } 185975eba5b6SRobert Mustacchi 186075eba5b6SRobert Mustacchi /** 186175eba5b6SRobert Mustacchi * e1000_acquire_swflag_ich8lan - Acquire software control flag 186275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 186375eba5b6SRobert Mustacchi * 186475eba5b6SRobert Mustacchi * Acquires the software control flag for performing PHY and select 186575eba5b6SRobert Mustacchi * MAC CSR accesses. 186675eba5b6SRobert Mustacchi **/ 186775eba5b6SRobert Mustacchi static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) 186875eba5b6SRobert Mustacchi { 186975eba5b6SRobert Mustacchi u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT; 187075eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 187175eba5b6SRobert Mustacchi 187275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_swflag_ich8lan"); 187375eba5b6SRobert Mustacchi 187475eba5b6SRobert Mustacchi E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.swflag_mutex); 187575eba5b6SRobert Mustacchi 187675eba5b6SRobert Mustacchi while (timeout) { 187775eba5b6SRobert Mustacchi extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 187875eba5b6SRobert Mustacchi if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) 187975eba5b6SRobert Mustacchi break; 188075eba5b6SRobert Mustacchi 188175eba5b6SRobert Mustacchi msec_delay_irq(1); 188275eba5b6SRobert Mustacchi timeout--; 188375eba5b6SRobert Mustacchi } 188475eba5b6SRobert Mustacchi 188575eba5b6SRobert Mustacchi if (!timeout) { 188675eba5b6SRobert Mustacchi DEBUGOUT("SW has already locked the resource.\n"); 188775eba5b6SRobert Mustacchi ret_val = -E1000_ERR_CONFIG; 188875eba5b6SRobert Mustacchi goto out; 188975eba5b6SRobert Mustacchi } 189075eba5b6SRobert Mustacchi 189175eba5b6SRobert Mustacchi timeout = SW_FLAG_TIMEOUT; 189275eba5b6SRobert Mustacchi 189375eba5b6SRobert Mustacchi extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; 189475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); 189575eba5b6SRobert Mustacchi 189675eba5b6SRobert Mustacchi while (timeout) { 189775eba5b6SRobert Mustacchi extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 189875eba5b6SRobert Mustacchi if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) 189975eba5b6SRobert Mustacchi break; 190075eba5b6SRobert Mustacchi 190175eba5b6SRobert Mustacchi msec_delay_irq(1); 190275eba5b6SRobert Mustacchi timeout--; 190375eba5b6SRobert Mustacchi } 190475eba5b6SRobert Mustacchi 190575eba5b6SRobert Mustacchi if (!timeout) { 190675eba5b6SRobert Mustacchi DEBUGOUT2("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", 190775eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_FWSM), extcnf_ctrl); 190875eba5b6SRobert Mustacchi extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; 190975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); 191075eba5b6SRobert Mustacchi ret_val = -E1000_ERR_CONFIG; 191175eba5b6SRobert Mustacchi goto out; 191275eba5b6SRobert Mustacchi } 191375eba5b6SRobert Mustacchi 191475eba5b6SRobert Mustacchi out: 191575eba5b6SRobert Mustacchi if (ret_val) 191675eba5b6SRobert Mustacchi E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); 191775eba5b6SRobert Mustacchi 191875eba5b6SRobert Mustacchi return ret_val; 191975eba5b6SRobert Mustacchi } 192075eba5b6SRobert Mustacchi 192175eba5b6SRobert Mustacchi /** 192275eba5b6SRobert Mustacchi * e1000_release_swflag_ich8lan - Release software control flag 192375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 192475eba5b6SRobert Mustacchi * 192575eba5b6SRobert Mustacchi * Releases the software control flag for performing PHY and select 192675eba5b6SRobert Mustacchi * MAC CSR accesses. 192775eba5b6SRobert Mustacchi **/ 192875eba5b6SRobert Mustacchi static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) 192975eba5b6SRobert Mustacchi { 193075eba5b6SRobert Mustacchi u32 extcnf_ctrl; 193175eba5b6SRobert Mustacchi 193275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_swflag_ich8lan"); 193375eba5b6SRobert Mustacchi 193475eba5b6SRobert Mustacchi extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 193575eba5b6SRobert Mustacchi 193675eba5b6SRobert Mustacchi if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) { 193775eba5b6SRobert Mustacchi extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; 193875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); 193975eba5b6SRobert Mustacchi } else { 194075eba5b6SRobert Mustacchi DEBUGOUT("Semaphore unexpectedly released by sw/fw/hw\n"); 194175eba5b6SRobert Mustacchi } 194275eba5b6SRobert Mustacchi 194375eba5b6SRobert Mustacchi E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); 194475eba5b6SRobert Mustacchi 194575eba5b6SRobert Mustacchi return; 194675eba5b6SRobert Mustacchi } 194775eba5b6SRobert Mustacchi 194875eba5b6SRobert Mustacchi /** 194975eba5b6SRobert Mustacchi * e1000_check_mng_mode_ich8lan - Checks management mode 195075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 195175eba5b6SRobert Mustacchi * 195275eba5b6SRobert Mustacchi * This checks if the adapter has any manageability enabled. 195375eba5b6SRobert Mustacchi * This is a function pointer entry point only called by read/write 195475eba5b6SRobert Mustacchi * routines for the PHY and NVM parts. 195575eba5b6SRobert Mustacchi **/ 195675eba5b6SRobert Mustacchi static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) 195775eba5b6SRobert Mustacchi { 195875eba5b6SRobert Mustacchi u32 fwsm; 195975eba5b6SRobert Mustacchi 196075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_mng_mode_ich8lan"); 196175eba5b6SRobert Mustacchi 196275eba5b6SRobert Mustacchi fwsm = E1000_READ_REG(hw, E1000_FWSM); 196375eba5b6SRobert Mustacchi 196475eba5b6SRobert Mustacchi return (fwsm & E1000_ICH_FWSM_FW_VALID) && 196575eba5b6SRobert Mustacchi ((fwsm & E1000_FWSM_MODE_MASK) == 196675eba5b6SRobert Mustacchi (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); 196775eba5b6SRobert Mustacchi } 196875eba5b6SRobert Mustacchi 196975eba5b6SRobert Mustacchi /** 197075eba5b6SRobert Mustacchi * e1000_check_mng_mode_pchlan - Checks management mode 197175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 197275eba5b6SRobert Mustacchi * 197375eba5b6SRobert Mustacchi * This checks if the adapter has iAMT enabled. 197475eba5b6SRobert Mustacchi * This is a function pointer entry point only called by read/write 197575eba5b6SRobert Mustacchi * routines for the PHY and NVM parts. 197675eba5b6SRobert Mustacchi **/ 197775eba5b6SRobert Mustacchi static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw) 197875eba5b6SRobert Mustacchi { 197975eba5b6SRobert Mustacchi u32 fwsm; 198075eba5b6SRobert Mustacchi 198175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_mng_mode_pchlan"); 198275eba5b6SRobert Mustacchi 198375eba5b6SRobert Mustacchi fwsm = E1000_READ_REG(hw, E1000_FWSM); 198475eba5b6SRobert Mustacchi 198575eba5b6SRobert Mustacchi return (fwsm & E1000_ICH_FWSM_FW_VALID) && 198675eba5b6SRobert Mustacchi (fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); 198775eba5b6SRobert Mustacchi } 198875eba5b6SRobert Mustacchi 198975eba5b6SRobert Mustacchi /** 199075eba5b6SRobert Mustacchi * e1000_rar_set_pch2lan - Set receive address register 199175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 199275eba5b6SRobert Mustacchi * @addr: pointer to the receive address 199375eba5b6SRobert Mustacchi * @index: receive address array register 199475eba5b6SRobert Mustacchi * 199575eba5b6SRobert Mustacchi * Sets the receive address array register at index to the address passed 199675eba5b6SRobert Mustacchi * in by addr. For 82579, RAR[0] is the base address register that is to 199775eba5b6SRobert Mustacchi * contain the MAC address but RAR[1-6] are reserved for manageability (ME). 199875eba5b6SRobert Mustacchi * Use SHRA[0-3] in place of those reserved for ME. 199975eba5b6SRobert Mustacchi **/ 2000c124a83eSRobert Mustacchi static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) 200175eba5b6SRobert Mustacchi { 200275eba5b6SRobert Mustacchi u32 rar_low, rar_high; 200375eba5b6SRobert Mustacchi 200475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_rar_set_pch2lan"); 200575eba5b6SRobert Mustacchi 200675eba5b6SRobert Mustacchi /* HW expects these in little endian so we reverse the byte order 200775eba5b6SRobert Mustacchi * from network order (big endian) to little endian 200875eba5b6SRobert Mustacchi */ 200975eba5b6SRobert Mustacchi rar_low = ((u32) addr[0] | 201075eba5b6SRobert Mustacchi ((u32) addr[1] << 8) | 201175eba5b6SRobert Mustacchi ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); 201275eba5b6SRobert Mustacchi 201375eba5b6SRobert Mustacchi rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); 201475eba5b6SRobert Mustacchi 201575eba5b6SRobert Mustacchi /* If MAC address zero, no need to set the AV bit */ 201675eba5b6SRobert Mustacchi if (rar_low || rar_high) 201775eba5b6SRobert Mustacchi rar_high |= E1000_RAH_AV; 201875eba5b6SRobert Mustacchi 201975eba5b6SRobert Mustacchi if (index == 0) { 202075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RAL(index), rar_low); 202175eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 202275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); 202375eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 2024c124a83eSRobert Mustacchi return E1000_SUCCESS; 202575eba5b6SRobert Mustacchi } 202675eba5b6SRobert Mustacchi 2027c124a83eSRobert Mustacchi /* RAR[1-6] are owned by manageability. Skip those and program the 2028c124a83eSRobert Mustacchi * next address into the SHRA register array. 2029c124a83eSRobert Mustacchi */ 2030c124a83eSRobert Mustacchi if (index < (u32) (hw->mac.rar_entry_count)) { 203175eba5b6SRobert Mustacchi s32 ret_val; 203275eba5b6SRobert Mustacchi 203375eba5b6SRobert Mustacchi ret_val = e1000_acquire_swflag_ich8lan(hw); 203475eba5b6SRobert Mustacchi if (ret_val) 203575eba5b6SRobert Mustacchi goto out; 203675eba5b6SRobert Mustacchi 203775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SHRAL(index - 1), rar_low); 203875eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 203975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SHRAH(index - 1), rar_high); 204075eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 204175eba5b6SRobert Mustacchi 204275eba5b6SRobert Mustacchi e1000_release_swflag_ich8lan(hw); 204375eba5b6SRobert Mustacchi 204475eba5b6SRobert Mustacchi /* verify the register updates */ 204575eba5b6SRobert Mustacchi if ((E1000_READ_REG(hw, E1000_SHRAL(index - 1)) == rar_low) && 204675eba5b6SRobert Mustacchi (E1000_READ_REG(hw, E1000_SHRAH(index - 1)) == rar_high)) 2047c124a83eSRobert Mustacchi return E1000_SUCCESS; 204875eba5b6SRobert Mustacchi 204975eba5b6SRobert Mustacchi DEBUGOUT2("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n", 205075eba5b6SRobert Mustacchi (index - 1), E1000_READ_REG(hw, E1000_FWSM)); 205175eba5b6SRobert Mustacchi } 205275eba5b6SRobert Mustacchi 205375eba5b6SRobert Mustacchi out: 205475eba5b6SRobert Mustacchi DEBUGOUT1("Failed to write receive address at index %d\n", index); 2055c124a83eSRobert Mustacchi return -E1000_ERR_CONFIG; 205675eba5b6SRobert Mustacchi } 205775eba5b6SRobert Mustacchi 205875eba5b6SRobert Mustacchi /** 205975eba5b6SRobert Mustacchi * e1000_rar_set_pch_lpt - Set receive address registers 206075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 206175eba5b6SRobert Mustacchi * @addr: pointer to the receive address 206275eba5b6SRobert Mustacchi * @index: receive address array register 206375eba5b6SRobert Mustacchi * 206475eba5b6SRobert Mustacchi * Sets the receive address register array at index to the address passed 206575eba5b6SRobert Mustacchi * in by addr. For LPT, RAR[0] is the base address register that is to 206675eba5b6SRobert Mustacchi * contain the MAC address. SHRA[0-10] are the shared receive address 206775eba5b6SRobert Mustacchi * registers that are shared between the Host and manageability engine (ME). 206875eba5b6SRobert Mustacchi **/ 2069c124a83eSRobert Mustacchi static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) 207075eba5b6SRobert Mustacchi { 207175eba5b6SRobert Mustacchi u32 rar_low, rar_high; 207275eba5b6SRobert Mustacchi u32 wlock_mac; 207375eba5b6SRobert Mustacchi 207475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_rar_set_pch_lpt"); 207575eba5b6SRobert Mustacchi 207675eba5b6SRobert Mustacchi /* HW expects these in little endian so we reverse the byte order 207775eba5b6SRobert Mustacchi * from network order (big endian) to little endian 207875eba5b6SRobert Mustacchi */ 207975eba5b6SRobert Mustacchi rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) | 208075eba5b6SRobert Mustacchi ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); 208175eba5b6SRobert Mustacchi 208275eba5b6SRobert Mustacchi rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); 208375eba5b6SRobert Mustacchi 208475eba5b6SRobert Mustacchi /* If MAC address zero, no need to set the AV bit */ 208575eba5b6SRobert Mustacchi if (rar_low || rar_high) 208675eba5b6SRobert Mustacchi rar_high |= E1000_RAH_AV; 208775eba5b6SRobert Mustacchi 208875eba5b6SRobert Mustacchi if (index == 0) { 208975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RAL(index), rar_low); 209075eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 209175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); 209275eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 2093c124a83eSRobert Mustacchi return E1000_SUCCESS; 209475eba5b6SRobert Mustacchi } 209575eba5b6SRobert Mustacchi 209675eba5b6SRobert Mustacchi /* The manageability engine (ME) can lock certain SHRAR registers that 209775eba5b6SRobert Mustacchi * it is using - those registers are unavailable for use. 209875eba5b6SRobert Mustacchi */ 209975eba5b6SRobert Mustacchi if (index < hw->mac.rar_entry_count) { 210075eba5b6SRobert Mustacchi wlock_mac = E1000_READ_REG(hw, E1000_FWSM) & 210175eba5b6SRobert Mustacchi E1000_FWSM_WLOCK_MAC_MASK; 210275eba5b6SRobert Mustacchi wlock_mac >>= E1000_FWSM_WLOCK_MAC_SHIFT; 210375eba5b6SRobert Mustacchi 210475eba5b6SRobert Mustacchi /* Check if all SHRAR registers are locked */ 210575eba5b6SRobert Mustacchi if (wlock_mac == 1) 210675eba5b6SRobert Mustacchi goto out; 210775eba5b6SRobert Mustacchi 210875eba5b6SRobert Mustacchi if ((wlock_mac == 0) || (index <= wlock_mac)) { 210975eba5b6SRobert Mustacchi s32 ret_val; 211075eba5b6SRobert Mustacchi 211175eba5b6SRobert Mustacchi ret_val = e1000_acquire_swflag_ich8lan(hw); 211275eba5b6SRobert Mustacchi 211375eba5b6SRobert Mustacchi if (ret_val) 211475eba5b6SRobert Mustacchi goto out; 211575eba5b6SRobert Mustacchi 211675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SHRAL_PCH_LPT(index - 1), 211775eba5b6SRobert Mustacchi rar_low); 211875eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 211975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SHRAH_PCH_LPT(index - 1), 212075eba5b6SRobert Mustacchi rar_high); 212175eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 212275eba5b6SRobert Mustacchi 212375eba5b6SRobert Mustacchi e1000_release_swflag_ich8lan(hw); 212475eba5b6SRobert Mustacchi 212575eba5b6SRobert Mustacchi /* verify the register updates */ 212675eba5b6SRobert Mustacchi if ((E1000_READ_REG(hw, E1000_SHRAL_PCH_LPT(index - 1)) == rar_low) && 212775eba5b6SRobert Mustacchi (E1000_READ_REG(hw, E1000_SHRAH_PCH_LPT(index - 1)) == rar_high)) 2128c124a83eSRobert Mustacchi return E1000_SUCCESS; 212975eba5b6SRobert Mustacchi } 213075eba5b6SRobert Mustacchi } 213175eba5b6SRobert Mustacchi 213275eba5b6SRobert Mustacchi out: 213375eba5b6SRobert Mustacchi DEBUGOUT1("Failed to write receive address at index %d\n", index); 2134c124a83eSRobert Mustacchi return -E1000_ERR_CONFIG; 213575eba5b6SRobert Mustacchi } 213675eba5b6SRobert Mustacchi 213775eba5b6SRobert Mustacchi /** 213875eba5b6SRobert Mustacchi * e1000_update_mc_addr_list_pch2lan - Update Multicast addresses 213975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 214075eba5b6SRobert Mustacchi * @mc_addr_list: array of multicast addresses to program 214175eba5b6SRobert Mustacchi * @mc_addr_count: number of multicast addresses to program 214275eba5b6SRobert Mustacchi * 214375eba5b6SRobert Mustacchi * Updates entire Multicast Table Array of the PCH2 MAC and PHY. 214475eba5b6SRobert Mustacchi * The caller must have a packed mc_addr_list of multicast addresses. 214575eba5b6SRobert Mustacchi **/ 214675eba5b6SRobert Mustacchi static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw, 214775eba5b6SRobert Mustacchi u8 *mc_addr_list, 214875eba5b6SRobert Mustacchi u32 mc_addr_count) 214975eba5b6SRobert Mustacchi { 215075eba5b6SRobert Mustacchi u16 phy_reg = 0; 215175eba5b6SRobert Mustacchi int i; 215275eba5b6SRobert Mustacchi s32 ret_val; 215375eba5b6SRobert Mustacchi 215475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_update_mc_addr_list_pch2lan"); 215575eba5b6SRobert Mustacchi 215675eba5b6SRobert Mustacchi e1000_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count); 215775eba5b6SRobert Mustacchi 215875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 215975eba5b6SRobert Mustacchi if (ret_val) 216075eba5b6SRobert Mustacchi return; 216175eba5b6SRobert Mustacchi 216275eba5b6SRobert Mustacchi ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); 216375eba5b6SRobert Mustacchi if (ret_val) 216475eba5b6SRobert Mustacchi goto release; 216575eba5b6SRobert Mustacchi 216675eba5b6SRobert Mustacchi for (i = 0; i < hw->mac.mta_reg_count; i++) { 216775eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, BM_MTA(i), 216875eba5b6SRobert Mustacchi (u16)(hw->mac.mta_shadow[i] & 216975eba5b6SRobert Mustacchi 0xFFFF)); 217075eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, (BM_MTA(i) + 1), 217175eba5b6SRobert Mustacchi (u16)((hw->mac.mta_shadow[i] >> 16) & 217275eba5b6SRobert Mustacchi 0xFFFF)); 217375eba5b6SRobert Mustacchi } 217475eba5b6SRobert Mustacchi 217575eba5b6SRobert Mustacchi e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); 217675eba5b6SRobert Mustacchi 217775eba5b6SRobert Mustacchi release: 217875eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 217975eba5b6SRobert Mustacchi } 218075eba5b6SRobert Mustacchi 218175eba5b6SRobert Mustacchi /** 218275eba5b6SRobert Mustacchi * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked 218375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 218475eba5b6SRobert Mustacchi * 218575eba5b6SRobert Mustacchi * Checks if firmware is blocking the reset of the PHY. 218675eba5b6SRobert Mustacchi * This is a function pointer entry point only called by 218775eba5b6SRobert Mustacchi * reset routines. 218875eba5b6SRobert Mustacchi **/ 218975eba5b6SRobert Mustacchi static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) 219075eba5b6SRobert Mustacchi { 219175eba5b6SRobert Mustacchi u32 fwsm; 2192c124a83eSRobert Mustacchi bool blocked = FALSE; 2193c124a83eSRobert Mustacchi int i = 0; 219475eba5b6SRobert Mustacchi 219575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_reset_block_ich8lan"); 219675eba5b6SRobert Mustacchi 2197c124a83eSRobert Mustacchi do { 219875eba5b6SRobert Mustacchi fwsm = E1000_READ_REG(hw, E1000_FWSM); 2199c124a83eSRobert Mustacchi if (!(fwsm & E1000_ICH_FWSM_RSPCIPHY)) { 2200c124a83eSRobert Mustacchi blocked = TRUE; 2201c124a83eSRobert Mustacchi msec_delay(10); 2202c124a83eSRobert Mustacchi continue; 2203c124a83eSRobert Mustacchi } 2204c124a83eSRobert Mustacchi blocked = FALSE; 2205*42cc51e0SRobert Mustacchi } while (blocked && (i++ < 30)); 2206c124a83eSRobert Mustacchi return blocked ? E1000_BLK_PHY_RESET : E1000_SUCCESS; 220775eba5b6SRobert Mustacchi } 220875eba5b6SRobert Mustacchi 220975eba5b6SRobert Mustacchi /** 221075eba5b6SRobert Mustacchi * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states 221175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 221275eba5b6SRobert Mustacchi * 221375eba5b6SRobert Mustacchi * Assumes semaphore already acquired. 221475eba5b6SRobert Mustacchi * 221575eba5b6SRobert Mustacchi **/ 221675eba5b6SRobert Mustacchi static s32 e1000_write_smbus_addr(struct e1000_hw *hw) 221775eba5b6SRobert Mustacchi { 221875eba5b6SRobert Mustacchi u16 phy_data; 221975eba5b6SRobert Mustacchi u32 strap = E1000_READ_REG(hw, E1000_STRAP); 222075eba5b6SRobert Mustacchi u32 freq = (strap & E1000_STRAP_SMT_FREQ_MASK) >> 222175eba5b6SRobert Mustacchi E1000_STRAP_SMT_FREQ_SHIFT; 222275eba5b6SRobert Mustacchi s32 ret_val; 222375eba5b6SRobert Mustacchi 222475eba5b6SRobert Mustacchi strap &= E1000_STRAP_SMBUS_ADDRESS_MASK; 222575eba5b6SRobert Mustacchi 222675eba5b6SRobert Mustacchi ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data); 222775eba5b6SRobert Mustacchi if (ret_val) 222875eba5b6SRobert Mustacchi return ret_val; 222975eba5b6SRobert Mustacchi 223075eba5b6SRobert Mustacchi phy_data &= ~HV_SMB_ADDR_MASK; 223175eba5b6SRobert Mustacchi phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT); 223275eba5b6SRobert Mustacchi phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; 223375eba5b6SRobert Mustacchi 223475eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_i217) { 223575eba5b6SRobert Mustacchi /* Restore SMBus frequency */ 223675eba5b6SRobert Mustacchi if (freq--) { 223775eba5b6SRobert Mustacchi phy_data &= ~HV_SMB_ADDR_FREQ_MASK; 223875eba5b6SRobert Mustacchi phy_data |= (freq & (1 << 0)) << 223975eba5b6SRobert Mustacchi HV_SMB_ADDR_FREQ_LOW_SHIFT; 224075eba5b6SRobert Mustacchi phy_data |= (freq & (1 << 1)) << 224175eba5b6SRobert Mustacchi (HV_SMB_ADDR_FREQ_HIGH_SHIFT - 1); 224275eba5b6SRobert Mustacchi } else { 224375eba5b6SRobert Mustacchi DEBUGOUT("Unsupported SMB frequency in PHY\n"); 224475eba5b6SRobert Mustacchi } 224575eba5b6SRobert Mustacchi } 224675eba5b6SRobert Mustacchi 224775eba5b6SRobert Mustacchi return e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); 224875eba5b6SRobert Mustacchi } 224975eba5b6SRobert Mustacchi 225075eba5b6SRobert Mustacchi /** 225175eba5b6SRobert Mustacchi * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration 225275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 225375eba5b6SRobert Mustacchi * 225475eba5b6SRobert Mustacchi * SW should configure the LCD from the NVM extended configuration region 225575eba5b6SRobert Mustacchi * as a workaround for certain parts. 225675eba5b6SRobert Mustacchi **/ 225775eba5b6SRobert Mustacchi static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) 225875eba5b6SRobert Mustacchi { 225975eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 226075eba5b6SRobert Mustacchi u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; 226175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 226275eba5b6SRobert Mustacchi u16 word_addr, reg_data, reg_addr, phy_page = 0; 226375eba5b6SRobert Mustacchi 226475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_sw_lcd_config_ich8lan"); 226575eba5b6SRobert Mustacchi 226675eba5b6SRobert Mustacchi /* Initialize the PHY from the NVM on ICH platforms. This 226775eba5b6SRobert Mustacchi * is needed due to an issue where the NVM configuration is 226875eba5b6SRobert Mustacchi * not properly autoloaded after power transitions. 226975eba5b6SRobert Mustacchi * Therefore, after each PHY reset, we will load the 227075eba5b6SRobert Mustacchi * configuration data out of the NVM manually. 227175eba5b6SRobert Mustacchi */ 227275eba5b6SRobert Mustacchi switch (hw->mac.type) { 227375eba5b6SRobert Mustacchi case e1000_ich8lan: 227475eba5b6SRobert Mustacchi if (phy->type != e1000_phy_igp_3) 227575eba5b6SRobert Mustacchi return ret_val; 227675eba5b6SRobert Mustacchi 227775eba5b6SRobert Mustacchi if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_AMT) || 227875eba5b6SRobert Mustacchi (hw->device_id == E1000_DEV_ID_ICH8_IGP_C)) { 227975eba5b6SRobert Mustacchi sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; 228075eba5b6SRobert Mustacchi break; 228175eba5b6SRobert Mustacchi } 228275eba5b6SRobert Mustacchi /* Fall-thru */ 228375eba5b6SRobert Mustacchi case e1000_pchlan: 228475eba5b6SRobert Mustacchi case e1000_pch2lan: 228575eba5b6SRobert Mustacchi case e1000_pch_lpt: 2286*42cc51e0SRobert Mustacchi case e1000_pch_spt: 228775eba5b6SRobert Mustacchi sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; 228875eba5b6SRobert Mustacchi break; 228975eba5b6SRobert Mustacchi default: 229075eba5b6SRobert Mustacchi return ret_val; 229175eba5b6SRobert Mustacchi } 229275eba5b6SRobert Mustacchi 229375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 229475eba5b6SRobert Mustacchi if (ret_val) 229575eba5b6SRobert Mustacchi return ret_val; 229675eba5b6SRobert Mustacchi 229775eba5b6SRobert Mustacchi data = E1000_READ_REG(hw, E1000_FEXTNVM); 229875eba5b6SRobert Mustacchi if (!(data & sw_cfg_mask)) 229975eba5b6SRobert Mustacchi goto release; 230075eba5b6SRobert Mustacchi 230175eba5b6SRobert Mustacchi /* Make sure HW does not configure LCD from PHY 230275eba5b6SRobert Mustacchi * extended configuration before SW configuration 230375eba5b6SRobert Mustacchi */ 230475eba5b6SRobert Mustacchi data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 230575eba5b6SRobert Mustacchi if ((hw->mac.type < e1000_pch2lan) && 230675eba5b6SRobert Mustacchi (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)) 230775eba5b6SRobert Mustacchi goto release; 230875eba5b6SRobert Mustacchi 230975eba5b6SRobert Mustacchi cnf_size = E1000_READ_REG(hw, E1000_EXTCNF_SIZE); 231075eba5b6SRobert Mustacchi cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; 231175eba5b6SRobert Mustacchi cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; 231275eba5b6SRobert Mustacchi if (!cnf_size) 231375eba5b6SRobert Mustacchi goto release; 231475eba5b6SRobert Mustacchi 231575eba5b6SRobert Mustacchi cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; 231675eba5b6SRobert Mustacchi cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; 231775eba5b6SRobert Mustacchi 231875eba5b6SRobert Mustacchi if (((hw->mac.type == e1000_pchlan) && 231975eba5b6SRobert Mustacchi !(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)) || 232075eba5b6SRobert Mustacchi (hw->mac.type > e1000_pchlan)) { 232175eba5b6SRobert Mustacchi /* HW configures the SMBus address and LEDs when the 232275eba5b6SRobert Mustacchi * OEM and LCD Write Enable bits are set in the NVM. 232375eba5b6SRobert Mustacchi * When both NVM bits are cleared, SW will configure 232475eba5b6SRobert Mustacchi * them instead. 232575eba5b6SRobert Mustacchi */ 232675eba5b6SRobert Mustacchi ret_val = e1000_write_smbus_addr(hw); 232775eba5b6SRobert Mustacchi if (ret_val) 232875eba5b6SRobert Mustacchi goto release; 232975eba5b6SRobert Mustacchi 233075eba5b6SRobert Mustacchi data = E1000_READ_REG(hw, E1000_LEDCTL); 233175eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG, 233275eba5b6SRobert Mustacchi (u16)data); 233375eba5b6SRobert Mustacchi if (ret_val) 233475eba5b6SRobert Mustacchi goto release; 233575eba5b6SRobert Mustacchi } 233675eba5b6SRobert Mustacchi 233775eba5b6SRobert Mustacchi /* Configure LCD from extended configuration region. */ 233875eba5b6SRobert Mustacchi 233975eba5b6SRobert Mustacchi /* cnf_base_addr is in DWORD */ 234075eba5b6SRobert Mustacchi word_addr = (u16)(cnf_base_addr << 1); 234175eba5b6SRobert Mustacchi 234275eba5b6SRobert Mustacchi for (i = 0; i < cnf_size; i++) { 234375eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2), 1, 234475eba5b6SRobert Mustacchi ®_data); 234575eba5b6SRobert Mustacchi if (ret_val) 234675eba5b6SRobert Mustacchi goto release; 234775eba5b6SRobert Mustacchi 234875eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2 + 1), 234975eba5b6SRobert Mustacchi 1, ®_addr); 235075eba5b6SRobert Mustacchi if (ret_val) 235175eba5b6SRobert Mustacchi goto release; 235275eba5b6SRobert Mustacchi 235375eba5b6SRobert Mustacchi /* Save off the PHY page for future writes. */ 235475eba5b6SRobert Mustacchi if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { 235575eba5b6SRobert Mustacchi phy_page = reg_data; 235675eba5b6SRobert Mustacchi continue; 235775eba5b6SRobert Mustacchi } 235875eba5b6SRobert Mustacchi 235975eba5b6SRobert Mustacchi reg_addr &= PHY_REG_MASK; 236075eba5b6SRobert Mustacchi reg_addr |= phy_page; 236175eba5b6SRobert Mustacchi 236275eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr, 236375eba5b6SRobert Mustacchi reg_data); 236475eba5b6SRobert Mustacchi if (ret_val) 236575eba5b6SRobert Mustacchi goto release; 236675eba5b6SRobert Mustacchi } 236775eba5b6SRobert Mustacchi 236875eba5b6SRobert Mustacchi release: 236975eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 237075eba5b6SRobert Mustacchi return ret_val; 237175eba5b6SRobert Mustacchi } 237275eba5b6SRobert Mustacchi 237375eba5b6SRobert Mustacchi /** 237475eba5b6SRobert Mustacchi * e1000_k1_gig_workaround_hv - K1 Si workaround 237575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 237675eba5b6SRobert Mustacchi * @link: link up bool flag 237775eba5b6SRobert Mustacchi * 237875eba5b6SRobert Mustacchi * If K1 is enabled for 1Gbps, the MAC might stall when transitioning 237975eba5b6SRobert Mustacchi * from a lower speed. This workaround disables K1 whenever link is at 1Gig 238075eba5b6SRobert Mustacchi * If link is down, the function will restore the default K1 setting located 238175eba5b6SRobert Mustacchi * in the NVM. 238275eba5b6SRobert Mustacchi **/ 238375eba5b6SRobert Mustacchi static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) 238475eba5b6SRobert Mustacchi { 238575eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 238675eba5b6SRobert Mustacchi u16 status_reg = 0; 238775eba5b6SRobert Mustacchi bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; 238875eba5b6SRobert Mustacchi 238975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_k1_gig_workaround_hv"); 239075eba5b6SRobert Mustacchi 239175eba5b6SRobert Mustacchi if (hw->mac.type != e1000_pchlan) 239275eba5b6SRobert Mustacchi return E1000_SUCCESS; 239375eba5b6SRobert Mustacchi 239475eba5b6SRobert Mustacchi /* Wrap the whole flow with the sw flag */ 239575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 239675eba5b6SRobert Mustacchi if (ret_val) 239775eba5b6SRobert Mustacchi return ret_val; 239875eba5b6SRobert Mustacchi 239975eba5b6SRobert Mustacchi /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ 240075eba5b6SRobert Mustacchi if (link) { 240175eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82578) { 240275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, BM_CS_STATUS, 240375eba5b6SRobert Mustacchi &status_reg); 240475eba5b6SRobert Mustacchi if (ret_val) 240575eba5b6SRobert Mustacchi goto release; 240675eba5b6SRobert Mustacchi 2407c124a83eSRobert Mustacchi status_reg &= (BM_CS_STATUS_LINK_UP | 240875eba5b6SRobert Mustacchi BM_CS_STATUS_RESOLVED | 2409c124a83eSRobert Mustacchi BM_CS_STATUS_SPEED_MASK); 241075eba5b6SRobert Mustacchi 241175eba5b6SRobert Mustacchi if (status_reg == (BM_CS_STATUS_LINK_UP | 241275eba5b6SRobert Mustacchi BM_CS_STATUS_RESOLVED | 241375eba5b6SRobert Mustacchi BM_CS_STATUS_SPEED_1000)) 241475eba5b6SRobert Mustacchi k1_enable = FALSE; 241575eba5b6SRobert Mustacchi } 241675eba5b6SRobert Mustacchi 241775eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82577) { 241875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, HV_M_STATUS, 241975eba5b6SRobert Mustacchi &status_reg); 242075eba5b6SRobert Mustacchi if (ret_val) 242175eba5b6SRobert Mustacchi goto release; 242275eba5b6SRobert Mustacchi 2423c124a83eSRobert Mustacchi status_reg &= (HV_M_STATUS_LINK_UP | 242475eba5b6SRobert Mustacchi HV_M_STATUS_AUTONEG_COMPLETE | 2425c124a83eSRobert Mustacchi HV_M_STATUS_SPEED_MASK); 242675eba5b6SRobert Mustacchi 242775eba5b6SRobert Mustacchi if (status_reg == (HV_M_STATUS_LINK_UP | 242875eba5b6SRobert Mustacchi HV_M_STATUS_AUTONEG_COMPLETE | 242975eba5b6SRobert Mustacchi HV_M_STATUS_SPEED_1000)) 243075eba5b6SRobert Mustacchi k1_enable = FALSE; 243175eba5b6SRobert Mustacchi } 243275eba5b6SRobert Mustacchi 243375eba5b6SRobert Mustacchi /* Link stall fix for link up */ 243475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), 243575eba5b6SRobert Mustacchi 0x0100); 243675eba5b6SRobert Mustacchi if (ret_val) 243775eba5b6SRobert Mustacchi goto release; 243875eba5b6SRobert Mustacchi 243975eba5b6SRobert Mustacchi } else { 244075eba5b6SRobert Mustacchi /* Link stall fix for link down */ 244175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), 244275eba5b6SRobert Mustacchi 0x4100); 244375eba5b6SRobert Mustacchi if (ret_val) 244475eba5b6SRobert Mustacchi goto release; 244575eba5b6SRobert Mustacchi } 244675eba5b6SRobert Mustacchi 244775eba5b6SRobert Mustacchi ret_val = e1000_configure_k1_ich8lan(hw, k1_enable); 244875eba5b6SRobert Mustacchi 244975eba5b6SRobert Mustacchi release: 245075eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 245175eba5b6SRobert Mustacchi 245275eba5b6SRobert Mustacchi return ret_val; 245375eba5b6SRobert Mustacchi } 245475eba5b6SRobert Mustacchi 245575eba5b6SRobert Mustacchi /** 245675eba5b6SRobert Mustacchi * e1000_configure_k1_ich8lan - Configure K1 power state 245775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 245875eba5b6SRobert Mustacchi * @enable: K1 state to configure 245975eba5b6SRobert Mustacchi * 246075eba5b6SRobert Mustacchi * Configure the K1 power state based on the provided parameter. 246175eba5b6SRobert Mustacchi * Assumes semaphore already acquired. 246275eba5b6SRobert Mustacchi * 246375eba5b6SRobert Mustacchi * Success returns 0, Failure returns -E1000_ERR_PHY (-2) 246475eba5b6SRobert Mustacchi **/ 246575eba5b6SRobert Mustacchi s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) 246675eba5b6SRobert Mustacchi { 246775eba5b6SRobert Mustacchi s32 ret_val; 246875eba5b6SRobert Mustacchi u32 ctrl_reg = 0; 246975eba5b6SRobert Mustacchi u32 ctrl_ext = 0; 247075eba5b6SRobert Mustacchi u32 reg = 0; 247175eba5b6SRobert Mustacchi u16 kmrn_reg = 0; 247275eba5b6SRobert Mustacchi 247375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_configure_k1_ich8lan"); 247475eba5b6SRobert Mustacchi 247575eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, 247675eba5b6SRobert Mustacchi &kmrn_reg); 247775eba5b6SRobert Mustacchi if (ret_val) 247875eba5b6SRobert Mustacchi return ret_val; 247975eba5b6SRobert Mustacchi 248075eba5b6SRobert Mustacchi if (k1_enable) 248175eba5b6SRobert Mustacchi kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; 248275eba5b6SRobert Mustacchi else 248375eba5b6SRobert Mustacchi kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; 248475eba5b6SRobert Mustacchi 248575eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, 248675eba5b6SRobert Mustacchi kmrn_reg); 248775eba5b6SRobert Mustacchi if (ret_val) 248875eba5b6SRobert Mustacchi return ret_val; 248975eba5b6SRobert Mustacchi 249075eba5b6SRobert Mustacchi usec_delay(20); 249175eba5b6SRobert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 249275eba5b6SRobert Mustacchi ctrl_reg = E1000_READ_REG(hw, E1000_CTRL); 249375eba5b6SRobert Mustacchi 249475eba5b6SRobert Mustacchi reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); 249575eba5b6SRobert Mustacchi reg |= E1000_CTRL_FRCSPD; 249675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, reg); 249775eba5b6SRobert Mustacchi 249875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); 249975eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 250075eba5b6SRobert Mustacchi usec_delay(20); 250175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg); 250275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 250375eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 250475eba5b6SRobert Mustacchi usec_delay(20); 250575eba5b6SRobert Mustacchi 250675eba5b6SRobert Mustacchi return E1000_SUCCESS; 250775eba5b6SRobert Mustacchi } 250875eba5b6SRobert Mustacchi 250975eba5b6SRobert Mustacchi /** 251075eba5b6SRobert Mustacchi * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration 251175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 251275eba5b6SRobert Mustacchi * @d0_state: boolean if entering d0 or d3 device state 251375eba5b6SRobert Mustacchi * 251475eba5b6SRobert Mustacchi * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are 251575eba5b6SRobert Mustacchi * collectively called OEM bits. The OEM Write Enable bit and SW Config bit 251675eba5b6SRobert Mustacchi * in NVM determines whether HW should configure LPLU and Gbe Disable. 251775eba5b6SRobert Mustacchi **/ 251875eba5b6SRobert Mustacchi static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) 251975eba5b6SRobert Mustacchi { 252075eba5b6SRobert Mustacchi s32 ret_val = 0; 252175eba5b6SRobert Mustacchi u32 mac_reg; 252275eba5b6SRobert Mustacchi u16 oem_reg; 252375eba5b6SRobert Mustacchi 252475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_oem_bits_config_ich8lan"); 252575eba5b6SRobert Mustacchi 252675eba5b6SRobert Mustacchi if (hw->mac.type < e1000_pchlan) 252775eba5b6SRobert Mustacchi return ret_val; 252875eba5b6SRobert Mustacchi 252975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 253075eba5b6SRobert Mustacchi if (ret_val) 253175eba5b6SRobert Mustacchi return ret_val; 253275eba5b6SRobert Mustacchi 253375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pchlan) { 253475eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 253575eba5b6SRobert Mustacchi if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) 253675eba5b6SRobert Mustacchi goto release; 253775eba5b6SRobert Mustacchi } 253875eba5b6SRobert Mustacchi 253975eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM); 254075eba5b6SRobert Mustacchi if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) 254175eba5b6SRobert Mustacchi goto release; 254275eba5b6SRobert Mustacchi 254375eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_PHY_CTRL); 254475eba5b6SRobert Mustacchi 254575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg); 254675eba5b6SRobert Mustacchi if (ret_val) 254775eba5b6SRobert Mustacchi goto release; 254875eba5b6SRobert Mustacchi 254975eba5b6SRobert Mustacchi oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); 255075eba5b6SRobert Mustacchi 255175eba5b6SRobert Mustacchi if (d0_state) { 255275eba5b6SRobert Mustacchi if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) 255375eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_GBE_DIS; 255475eba5b6SRobert Mustacchi 255575eba5b6SRobert Mustacchi if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) 255675eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_LPLU; 255775eba5b6SRobert Mustacchi } else { 255875eba5b6SRobert Mustacchi if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE | 255975eba5b6SRobert Mustacchi E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) 256075eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_GBE_DIS; 256175eba5b6SRobert Mustacchi 256275eba5b6SRobert Mustacchi if (mac_reg & (E1000_PHY_CTRL_D0A_LPLU | 256375eba5b6SRobert Mustacchi E1000_PHY_CTRL_NOND0A_LPLU)) 256475eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_LPLU; 256575eba5b6SRobert Mustacchi } 256675eba5b6SRobert Mustacchi 256775eba5b6SRobert Mustacchi /* Set Restart auto-neg to activate the bits */ 256875eba5b6SRobert Mustacchi if ((d0_state || (hw->mac.type != e1000_pchlan)) && 256975eba5b6SRobert Mustacchi !hw->phy.ops.check_reset_block(hw)) 257075eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_RESTART_AN; 257175eba5b6SRobert Mustacchi 257275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); 257375eba5b6SRobert Mustacchi 257475eba5b6SRobert Mustacchi release: 257575eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 257675eba5b6SRobert Mustacchi 257775eba5b6SRobert Mustacchi return ret_val; 257875eba5b6SRobert Mustacchi } 257975eba5b6SRobert Mustacchi 258075eba5b6SRobert Mustacchi 258175eba5b6SRobert Mustacchi /** 258275eba5b6SRobert Mustacchi * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode 258375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 258475eba5b6SRobert Mustacchi **/ 258575eba5b6SRobert Mustacchi static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) 258675eba5b6SRobert Mustacchi { 258775eba5b6SRobert Mustacchi s32 ret_val; 258875eba5b6SRobert Mustacchi u16 data; 258975eba5b6SRobert Mustacchi 259075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_mdio_slow_mode_hv"); 259175eba5b6SRobert Mustacchi 259275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, HV_KMRN_MODE_CTRL, &data); 259375eba5b6SRobert Mustacchi if (ret_val) 259475eba5b6SRobert Mustacchi return ret_val; 259575eba5b6SRobert Mustacchi 259675eba5b6SRobert Mustacchi data |= HV_KMRN_MDIO_SLOW; 259775eba5b6SRobert Mustacchi 259875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, HV_KMRN_MODE_CTRL, data); 259975eba5b6SRobert Mustacchi 260075eba5b6SRobert Mustacchi return ret_val; 260175eba5b6SRobert Mustacchi } 260275eba5b6SRobert Mustacchi 260375eba5b6SRobert Mustacchi /** 260475eba5b6SRobert Mustacchi * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be 260575eba5b6SRobert Mustacchi * done after every PHY reset. 260675eba5b6SRobert Mustacchi **/ 260775eba5b6SRobert Mustacchi static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) 260875eba5b6SRobert Mustacchi { 260975eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 261075eba5b6SRobert Mustacchi u16 phy_data; 261175eba5b6SRobert Mustacchi 261275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_hv_phy_workarounds_ich8lan"); 261375eba5b6SRobert Mustacchi 261475eba5b6SRobert Mustacchi if (hw->mac.type != e1000_pchlan) 261575eba5b6SRobert Mustacchi return E1000_SUCCESS; 261675eba5b6SRobert Mustacchi 261775eba5b6SRobert Mustacchi /* Set MDIO slow mode before any other MDIO access */ 261875eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82577) { 261975eba5b6SRobert Mustacchi ret_val = e1000_set_mdio_slow_mode_hv(hw); 262075eba5b6SRobert Mustacchi if (ret_val) 262175eba5b6SRobert Mustacchi return ret_val; 262275eba5b6SRobert Mustacchi } 262375eba5b6SRobert Mustacchi 262475eba5b6SRobert Mustacchi if (((hw->phy.type == e1000_phy_82577) && 262575eba5b6SRobert Mustacchi ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || 262675eba5b6SRobert Mustacchi ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { 262775eba5b6SRobert Mustacchi /* Disable generation of early preamble */ 262875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 25), 0x4431); 262975eba5b6SRobert Mustacchi if (ret_val) 263075eba5b6SRobert Mustacchi return ret_val; 263175eba5b6SRobert Mustacchi 263275eba5b6SRobert Mustacchi /* Preamble tuning for SSC */ 263375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, HV_KMRN_FIFO_CTRLSTA, 263475eba5b6SRobert Mustacchi 0xA204); 263575eba5b6SRobert Mustacchi if (ret_val) 263675eba5b6SRobert Mustacchi return ret_val; 263775eba5b6SRobert Mustacchi } 263875eba5b6SRobert Mustacchi 263975eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82578) { 264075eba5b6SRobert Mustacchi /* Return registers to default by doing a soft reset then 264175eba5b6SRobert Mustacchi * writing 0x3140 to the control register. 264275eba5b6SRobert Mustacchi */ 264375eba5b6SRobert Mustacchi if (hw->phy.revision < 2) { 264475eba5b6SRobert Mustacchi e1000_phy_sw_reset_generic(hw); 264575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, 264675eba5b6SRobert Mustacchi 0x3140); 264775eba5b6SRobert Mustacchi } 264875eba5b6SRobert Mustacchi } 264975eba5b6SRobert Mustacchi 265075eba5b6SRobert Mustacchi /* Select page 0 */ 265175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 265275eba5b6SRobert Mustacchi if (ret_val) 265375eba5b6SRobert Mustacchi return ret_val; 265475eba5b6SRobert Mustacchi 265575eba5b6SRobert Mustacchi hw->phy.addr = 1; 265675eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); 265775eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 265875eba5b6SRobert Mustacchi if (ret_val) 265975eba5b6SRobert Mustacchi return ret_val; 266075eba5b6SRobert Mustacchi 266175eba5b6SRobert Mustacchi /* Configure the K1 Si workaround during phy reset assuming there is 266275eba5b6SRobert Mustacchi * link so that it disables K1 if link is in 1Gbps. 266375eba5b6SRobert Mustacchi */ 266475eba5b6SRobert Mustacchi ret_val = e1000_k1_gig_workaround_hv(hw, TRUE); 266575eba5b6SRobert Mustacchi if (ret_val) 266675eba5b6SRobert Mustacchi return ret_val; 266775eba5b6SRobert Mustacchi 266875eba5b6SRobert Mustacchi /* Workaround for link disconnects on a busy hub in half duplex */ 266975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 267075eba5b6SRobert Mustacchi if (ret_val) 267175eba5b6SRobert Mustacchi return ret_val; 267275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data); 267375eba5b6SRobert Mustacchi if (ret_val) 267475eba5b6SRobert Mustacchi goto release; 267575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG, 267675eba5b6SRobert Mustacchi phy_data & 0x00FF); 267775eba5b6SRobert Mustacchi if (ret_val) 267875eba5b6SRobert Mustacchi goto release; 267975eba5b6SRobert Mustacchi 268075eba5b6SRobert Mustacchi /* set MSE higher to enable link to stay up when noise is high */ 268175eba5b6SRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, I82577_MSE_THRESHOLD, 0x0034); 268275eba5b6SRobert Mustacchi release: 268375eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 268475eba5b6SRobert Mustacchi 268575eba5b6SRobert Mustacchi return ret_val; 268675eba5b6SRobert Mustacchi } 268775eba5b6SRobert Mustacchi 268875eba5b6SRobert Mustacchi /** 268975eba5b6SRobert Mustacchi * e1000_copy_rx_addrs_to_phy_ich8lan - Copy Rx addresses from MAC to PHY 269075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 269175eba5b6SRobert Mustacchi **/ 269275eba5b6SRobert Mustacchi void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) 269375eba5b6SRobert Mustacchi { 269475eba5b6SRobert Mustacchi u32 mac_reg; 269575eba5b6SRobert Mustacchi u16 i, phy_reg = 0; 269675eba5b6SRobert Mustacchi s32 ret_val; 269775eba5b6SRobert Mustacchi 269875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_copy_rx_addrs_to_phy_ich8lan"); 269975eba5b6SRobert Mustacchi 270075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 270175eba5b6SRobert Mustacchi if (ret_val) 270275eba5b6SRobert Mustacchi return; 270375eba5b6SRobert Mustacchi ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); 270475eba5b6SRobert Mustacchi if (ret_val) 270575eba5b6SRobert Mustacchi goto release; 270675eba5b6SRobert Mustacchi 2707c124a83eSRobert Mustacchi /* Copy both RAL/H (rar_entry_count) and SHRAL/H to PHY */ 2708c124a83eSRobert Mustacchi for (i = 0; i < (hw->mac.rar_entry_count); i++) { 270975eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_RAL(i)); 271075eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, BM_RAR_L(i), 271175eba5b6SRobert Mustacchi (u16)(mac_reg & 0xFFFF)); 271275eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, BM_RAR_M(i), 271375eba5b6SRobert Mustacchi (u16)((mac_reg >> 16) & 0xFFFF)); 271475eba5b6SRobert Mustacchi 271575eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_RAH(i)); 271675eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, BM_RAR_H(i), 271775eba5b6SRobert Mustacchi (u16)(mac_reg & 0xFFFF)); 271875eba5b6SRobert Mustacchi hw->phy.ops.write_reg_page(hw, BM_RAR_CTRL(i), 271975eba5b6SRobert Mustacchi (u16)((mac_reg & E1000_RAH_AV) 272075eba5b6SRobert Mustacchi >> 16)); 272175eba5b6SRobert Mustacchi } 272275eba5b6SRobert Mustacchi 272375eba5b6SRobert Mustacchi e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); 272475eba5b6SRobert Mustacchi 272575eba5b6SRobert Mustacchi release: 272675eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 272775eba5b6SRobert Mustacchi } 272875eba5b6SRobert Mustacchi 272975eba5b6SRobert Mustacchi static u32 e1000_calc_rx_da_crc(u8 mac[]) 273075eba5b6SRobert Mustacchi { 273175eba5b6SRobert Mustacchi u32 poly = 0xEDB88320; /* Polynomial for 802.3 CRC calculation */ 273275eba5b6SRobert Mustacchi u32 i, j, mask, crc; 273375eba5b6SRobert Mustacchi 273475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_calc_rx_da_crc"); 273575eba5b6SRobert Mustacchi 273675eba5b6SRobert Mustacchi crc = 0xffffffff; 273775eba5b6SRobert Mustacchi for (i = 0; i < 6; i++) { 273875eba5b6SRobert Mustacchi crc = crc ^ mac[i]; 273975eba5b6SRobert Mustacchi for (j = 8; j > 0; j--) { 274075eba5b6SRobert Mustacchi mask = (crc & 1) * (-1); 274175eba5b6SRobert Mustacchi crc = (crc >> 1) ^ (poly & mask); 274275eba5b6SRobert Mustacchi } 274375eba5b6SRobert Mustacchi } 274475eba5b6SRobert Mustacchi return ~crc; 274575eba5b6SRobert Mustacchi } 274675eba5b6SRobert Mustacchi 274775eba5b6SRobert Mustacchi /** 274875eba5b6SRobert Mustacchi * e1000_lv_jumbo_workaround_ich8lan - required for jumbo frame operation 274975eba5b6SRobert Mustacchi * with 82579 PHY 275075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 275175eba5b6SRobert Mustacchi * @enable: flag to enable/disable workaround when enabling/disabling jumbos 275275eba5b6SRobert Mustacchi **/ 275375eba5b6SRobert Mustacchi s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) 275475eba5b6SRobert Mustacchi { 275575eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 275675eba5b6SRobert Mustacchi u16 phy_reg, data; 275775eba5b6SRobert Mustacchi u32 mac_reg; 275875eba5b6SRobert Mustacchi u16 i; 275975eba5b6SRobert Mustacchi 276075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_lv_jumbo_workaround_ich8lan"); 276175eba5b6SRobert Mustacchi 276275eba5b6SRobert Mustacchi if (hw->mac.type < e1000_pch2lan) 276375eba5b6SRobert Mustacchi return E1000_SUCCESS; 276475eba5b6SRobert Mustacchi 276575eba5b6SRobert Mustacchi /* disable Rx path while enabling/disabling workaround */ 276675eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(769, 20), &phy_reg); 276775eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 20), 276875eba5b6SRobert Mustacchi phy_reg | (1 << 14)); 276975eba5b6SRobert Mustacchi if (ret_val) 277075eba5b6SRobert Mustacchi return ret_val; 277175eba5b6SRobert Mustacchi 277275eba5b6SRobert Mustacchi if (enable) { 2773c124a83eSRobert Mustacchi /* Write Rx addresses (rar_entry_count for RAL/H, and 277475eba5b6SRobert Mustacchi * SHRAL/H) and initial CRC values to the MAC 277575eba5b6SRobert Mustacchi */ 2776c124a83eSRobert Mustacchi for (i = 0; i < hw->mac.rar_entry_count; i++) { 277775eba5b6SRobert Mustacchi u8 mac_addr[ETH_ADDR_LEN] = {0}; 277875eba5b6SRobert Mustacchi u32 addr_high, addr_low; 277975eba5b6SRobert Mustacchi 278075eba5b6SRobert Mustacchi addr_high = E1000_READ_REG(hw, E1000_RAH(i)); 278175eba5b6SRobert Mustacchi if (!(addr_high & E1000_RAH_AV)) 278275eba5b6SRobert Mustacchi continue; 278375eba5b6SRobert Mustacchi addr_low = E1000_READ_REG(hw, E1000_RAL(i)); 278475eba5b6SRobert Mustacchi mac_addr[0] = (addr_low & 0xFF); 278575eba5b6SRobert Mustacchi mac_addr[1] = ((addr_low >> 8) & 0xFF); 278675eba5b6SRobert Mustacchi mac_addr[2] = ((addr_low >> 16) & 0xFF); 278775eba5b6SRobert Mustacchi mac_addr[3] = ((addr_low >> 24) & 0xFF); 278875eba5b6SRobert Mustacchi mac_addr[4] = (addr_high & 0xFF); 278975eba5b6SRobert Mustacchi mac_addr[5] = ((addr_high >> 8) & 0xFF); 279075eba5b6SRobert Mustacchi 279175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PCH_RAICC(i), 279275eba5b6SRobert Mustacchi e1000_calc_rx_da_crc(mac_addr)); 279375eba5b6SRobert Mustacchi } 279475eba5b6SRobert Mustacchi 279575eba5b6SRobert Mustacchi /* Write Rx addresses to the PHY */ 279675eba5b6SRobert Mustacchi e1000_copy_rx_addrs_to_phy_ich8lan(hw); 279775eba5b6SRobert Mustacchi 279875eba5b6SRobert Mustacchi /* Enable jumbo frame workaround in the MAC */ 279975eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FFLT_DBG); 280075eba5b6SRobert Mustacchi mac_reg &= ~(1 << 14); 280175eba5b6SRobert Mustacchi mac_reg |= (7 << 15); 280275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FFLT_DBG, mac_reg); 280375eba5b6SRobert Mustacchi 280475eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_RCTL); 280575eba5b6SRobert Mustacchi mac_reg |= E1000_RCTL_SECRC; 280675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, mac_reg); 280775eba5b6SRobert Mustacchi 280875eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, 280975eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_CTRL_OFFSET, 281075eba5b6SRobert Mustacchi &data); 281175eba5b6SRobert Mustacchi if (ret_val) 281275eba5b6SRobert Mustacchi return ret_val; 281375eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 281475eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_CTRL_OFFSET, 281575eba5b6SRobert Mustacchi data | (1 << 0)); 281675eba5b6SRobert Mustacchi if (ret_val) 281775eba5b6SRobert Mustacchi return ret_val; 281875eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, 281975eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_HD_CTRL, 282075eba5b6SRobert Mustacchi &data); 282175eba5b6SRobert Mustacchi if (ret_val) 282275eba5b6SRobert Mustacchi return ret_val; 282375eba5b6SRobert Mustacchi data &= ~(0xF << 8); 282475eba5b6SRobert Mustacchi data |= (0xB << 8); 282575eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 282675eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_HD_CTRL, 282775eba5b6SRobert Mustacchi data); 282875eba5b6SRobert Mustacchi if (ret_val) 282975eba5b6SRobert Mustacchi return ret_val; 283075eba5b6SRobert Mustacchi 283175eba5b6SRobert Mustacchi /* Enable jumbo frame workaround in the PHY */ 283275eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(769, 23), &data); 283375eba5b6SRobert Mustacchi data &= ~(0x7F << 5); 283475eba5b6SRobert Mustacchi data |= (0x37 << 5); 283575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 23), data); 283675eba5b6SRobert Mustacchi if (ret_val) 283775eba5b6SRobert Mustacchi return ret_val; 283875eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(769, 16), &data); 283975eba5b6SRobert Mustacchi data &= ~(1 << 13); 284075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 16), data); 284175eba5b6SRobert Mustacchi if (ret_val) 284275eba5b6SRobert Mustacchi return ret_val; 284375eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(776, 20), &data); 284475eba5b6SRobert Mustacchi data &= ~(0x3FF << 2); 2845c124a83eSRobert Mustacchi data |= (E1000_TX_PTR_GAP << 2); 284675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 20), data); 284775eba5b6SRobert Mustacchi if (ret_val) 284875eba5b6SRobert Mustacchi return ret_val; 284975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 23), 0xF100); 285075eba5b6SRobert Mustacchi if (ret_val) 285175eba5b6SRobert Mustacchi return ret_val; 285275eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, HV_PM_CTRL, &data); 285375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data | 285475eba5b6SRobert Mustacchi (1 << 10)); 285575eba5b6SRobert Mustacchi if (ret_val) 285675eba5b6SRobert Mustacchi return ret_val; 285775eba5b6SRobert Mustacchi } else { 285875eba5b6SRobert Mustacchi /* Write MAC register values back to h/w defaults */ 285975eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FFLT_DBG); 286075eba5b6SRobert Mustacchi mac_reg &= ~(0xF << 14); 286175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FFLT_DBG, mac_reg); 286275eba5b6SRobert Mustacchi 286375eba5b6SRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_RCTL); 286475eba5b6SRobert Mustacchi mac_reg &= ~E1000_RCTL_SECRC; 286575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, mac_reg); 286675eba5b6SRobert Mustacchi 286775eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, 286875eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_CTRL_OFFSET, 286975eba5b6SRobert Mustacchi &data); 287075eba5b6SRobert Mustacchi if (ret_val) 287175eba5b6SRobert Mustacchi return ret_val; 287275eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 287375eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_CTRL_OFFSET, 287475eba5b6SRobert Mustacchi data & ~(1 << 0)); 287575eba5b6SRobert Mustacchi if (ret_val) 287675eba5b6SRobert Mustacchi return ret_val; 287775eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, 287875eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_HD_CTRL, 287975eba5b6SRobert Mustacchi &data); 288075eba5b6SRobert Mustacchi if (ret_val) 288175eba5b6SRobert Mustacchi return ret_val; 288275eba5b6SRobert Mustacchi data &= ~(0xF << 8); 288375eba5b6SRobert Mustacchi data |= (0xB << 8); 288475eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 288575eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_HD_CTRL, 288675eba5b6SRobert Mustacchi data); 288775eba5b6SRobert Mustacchi if (ret_val) 288875eba5b6SRobert Mustacchi return ret_val; 288975eba5b6SRobert Mustacchi 289075eba5b6SRobert Mustacchi /* Write PHY register values back to h/w defaults */ 289175eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(769, 23), &data); 289275eba5b6SRobert Mustacchi data &= ~(0x7F << 5); 289375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 23), data); 289475eba5b6SRobert Mustacchi if (ret_val) 289575eba5b6SRobert Mustacchi return ret_val; 289675eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(769, 16), &data); 289775eba5b6SRobert Mustacchi data |= (1 << 13); 289875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 16), data); 289975eba5b6SRobert Mustacchi if (ret_val) 290075eba5b6SRobert Mustacchi return ret_val; 290175eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, PHY_REG(776, 20), &data); 290275eba5b6SRobert Mustacchi data &= ~(0x3FF << 2); 290375eba5b6SRobert Mustacchi data |= (0x8 << 2); 290475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 20), data); 290575eba5b6SRobert Mustacchi if (ret_val) 290675eba5b6SRobert Mustacchi return ret_val; 290775eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 23), 0x7E00); 290875eba5b6SRobert Mustacchi if (ret_val) 290975eba5b6SRobert Mustacchi return ret_val; 291075eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, HV_PM_CTRL, &data); 291175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data & 291275eba5b6SRobert Mustacchi ~(1 << 10)); 291375eba5b6SRobert Mustacchi if (ret_val) 291475eba5b6SRobert Mustacchi return ret_val; 291575eba5b6SRobert Mustacchi } 291675eba5b6SRobert Mustacchi 291775eba5b6SRobert Mustacchi /* re-enable Rx path after enabling/disabling workaround */ 291875eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, PHY_REG(769, 20), phy_reg & 291975eba5b6SRobert Mustacchi ~(1 << 14)); 292075eba5b6SRobert Mustacchi } 292175eba5b6SRobert Mustacchi 292275eba5b6SRobert Mustacchi /** 292375eba5b6SRobert Mustacchi * e1000_lv_phy_workarounds_ich8lan - A series of Phy workarounds to be 292475eba5b6SRobert Mustacchi * done after every PHY reset. 292575eba5b6SRobert Mustacchi **/ 292675eba5b6SRobert Mustacchi static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) 292775eba5b6SRobert Mustacchi { 292875eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 292975eba5b6SRobert Mustacchi 293075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_lv_phy_workarounds_ich8lan"); 293175eba5b6SRobert Mustacchi 293275eba5b6SRobert Mustacchi if (hw->mac.type != e1000_pch2lan) 293375eba5b6SRobert Mustacchi return E1000_SUCCESS; 293475eba5b6SRobert Mustacchi 293575eba5b6SRobert Mustacchi /* Set MDIO slow mode before any other MDIO access */ 293675eba5b6SRobert Mustacchi ret_val = e1000_set_mdio_slow_mode_hv(hw); 293775eba5b6SRobert Mustacchi if (ret_val) 293875eba5b6SRobert Mustacchi return ret_val; 293975eba5b6SRobert Mustacchi 294075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 294175eba5b6SRobert Mustacchi if (ret_val) 294275eba5b6SRobert Mustacchi return ret_val; 294375eba5b6SRobert Mustacchi /* set MSE higher to enable link to stay up when noise is high */ 294475eba5b6SRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, I82579_MSE_THRESHOLD, 0x0034); 294575eba5b6SRobert Mustacchi if (ret_val) 294675eba5b6SRobert Mustacchi goto release; 294775eba5b6SRobert Mustacchi /* drop link after 5 times MSE threshold was reached */ 294875eba5b6SRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, I82579_MSE_LINK_DOWN, 0x0005); 294975eba5b6SRobert Mustacchi release: 295075eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 295175eba5b6SRobert Mustacchi 295275eba5b6SRobert Mustacchi return ret_val; 295375eba5b6SRobert Mustacchi } 295475eba5b6SRobert Mustacchi 295575eba5b6SRobert Mustacchi /** 295675eba5b6SRobert Mustacchi * e1000_k1_gig_workaround_lv - K1 Si workaround 295775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 295875eba5b6SRobert Mustacchi * 2959c124a83eSRobert Mustacchi * Workaround to set the K1 beacon duration for 82579 parts in 10Mbps 2960c124a83eSRobert Mustacchi * Disable K1 for 1000 and 100 speeds 296175eba5b6SRobert Mustacchi **/ 296275eba5b6SRobert Mustacchi static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) 296375eba5b6SRobert Mustacchi { 296475eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 296575eba5b6SRobert Mustacchi u16 status_reg = 0; 296675eba5b6SRobert Mustacchi 296775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_k1_workaround_lv"); 296875eba5b6SRobert Mustacchi 296975eba5b6SRobert Mustacchi if (hw->mac.type != e1000_pch2lan) 297075eba5b6SRobert Mustacchi return E1000_SUCCESS; 297175eba5b6SRobert Mustacchi 2972c124a83eSRobert Mustacchi /* Set K1 beacon duration based on 10Mbs speed */ 297375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, HV_M_STATUS, &status_reg); 297475eba5b6SRobert Mustacchi if (ret_val) 297575eba5b6SRobert Mustacchi return ret_val; 297675eba5b6SRobert Mustacchi 297775eba5b6SRobert Mustacchi if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) 297875eba5b6SRobert Mustacchi == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { 2979c124a83eSRobert Mustacchi if (status_reg & 2980c124a83eSRobert Mustacchi (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) { 298175eba5b6SRobert Mustacchi u16 pm_phy_reg; 298275eba5b6SRobert Mustacchi 2983c124a83eSRobert Mustacchi /* LV 1G/100 Packet drop issue wa */ 298475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, HV_PM_CTRL, 298575eba5b6SRobert Mustacchi &pm_phy_reg); 298675eba5b6SRobert Mustacchi if (ret_val) 298775eba5b6SRobert Mustacchi return ret_val; 2988c124a83eSRobert Mustacchi pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE; 298975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, 299075eba5b6SRobert Mustacchi pm_phy_reg); 299175eba5b6SRobert Mustacchi if (ret_val) 299275eba5b6SRobert Mustacchi return ret_val; 299375eba5b6SRobert Mustacchi } else { 2994c124a83eSRobert Mustacchi u32 mac_reg; 2995c124a83eSRobert Mustacchi mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4); 2996c124a83eSRobert Mustacchi mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; 299775eba5b6SRobert Mustacchi mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; 299875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg); 2999c124a83eSRobert Mustacchi } 300075eba5b6SRobert Mustacchi } 300175eba5b6SRobert Mustacchi 300275eba5b6SRobert Mustacchi return ret_val; 300375eba5b6SRobert Mustacchi } 300475eba5b6SRobert Mustacchi 300575eba5b6SRobert Mustacchi /** 300675eba5b6SRobert Mustacchi * e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware 300775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 300875eba5b6SRobert Mustacchi * @gate: boolean set to TRUE to gate, FALSE to ungate 300975eba5b6SRobert Mustacchi * 301075eba5b6SRobert Mustacchi * Gate/ungate the automatic PHY configuration via hardware; perform 301175eba5b6SRobert Mustacchi * the configuration via software instead. 301275eba5b6SRobert Mustacchi **/ 301375eba5b6SRobert Mustacchi static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) 301475eba5b6SRobert Mustacchi { 301575eba5b6SRobert Mustacchi u32 extcnf_ctrl; 301675eba5b6SRobert Mustacchi 301775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_gate_hw_phy_config_ich8lan"); 301875eba5b6SRobert Mustacchi 301975eba5b6SRobert Mustacchi if (hw->mac.type < e1000_pch2lan) 302075eba5b6SRobert Mustacchi return; 302175eba5b6SRobert Mustacchi 302275eba5b6SRobert Mustacchi extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); 302375eba5b6SRobert Mustacchi 302475eba5b6SRobert Mustacchi if (gate) 302575eba5b6SRobert Mustacchi extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; 302675eba5b6SRobert Mustacchi else 302775eba5b6SRobert Mustacchi extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; 302875eba5b6SRobert Mustacchi 302975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); 303075eba5b6SRobert Mustacchi } 303175eba5b6SRobert Mustacchi 303275eba5b6SRobert Mustacchi /** 303375eba5b6SRobert Mustacchi * e1000_lan_init_done_ich8lan - Check for PHY config completion 303475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 303575eba5b6SRobert Mustacchi * 303675eba5b6SRobert Mustacchi * Check the appropriate indication the MAC has finished configuring the 303775eba5b6SRobert Mustacchi * PHY after a software reset. 303875eba5b6SRobert Mustacchi **/ 303975eba5b6SRobert Mustacchi static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) 304075eba5b6SRobert Mustacchi { 304175eba5b6SRobert Mustacchi u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT; 304275eba5b6SRobert Mustacchi 304375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_lan_init_done_ich8lan"); 304475eba5b6SRobert Mustacchi 304575eba5b6SRobert Mustacchi /* Wait for basic configuration completes before proceeding */ 304675eba5b6SRobert Mustacchi do { 304775eba5b6SRobert Mustacchi data = E1000_READ_REG(hw, E1000_STATUS); 304875eba5b6SRobert Mustacchi data &= E1000_STATUS_LAN_INIT_DONE; 304975eba5b6SRobert Mustacchi usec_delay(100); 305075eba5b6SRobert Mustacchi } while ((!data) && --loop); 305175eba5b6SRobert Mustacchi 305275eba5b6SRobert Mustacchi /* If basic configuration is incomplete before the above loop 305375eba5b6SRobert Mustacchi * count reaches 0, loading the configuration from NVM will 305475eba5b6SRobert Mustacchi * leave the PHY in a bad state possibly resulting in no link. 305575eba5b6SRobert Mustacchi */ 305675eba5b6SRobert Mustacchi if (loop == 0) 305775eba5b6SRobert Mustacchi DEBUGOUT("LAN_INIT_DONE not set, increase timeout\n"); 305875eba5b6SRobert Mustacchi 305975eba5b6SRobert Mustacchi /* Clear the Init Done bit for the next init event */ 306075eba5b6SRobert Mustacchi data = E1000_READ_REG(hw, E1000_STATUS); 306175eba5b6SRobert Mustacchi data &= ~E1000_STATUS_LAN_INIT_DONE; 306275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_STATUS, data); 306375eba5b6SRobert Mustacchi } 306475eba5b6SRobert Mustacchi 306575eba5b6SRobert Mustacchi /** 306675eba5b6SRobert Mustacchi * e1000_post_phy_reset_ich8lan - Perform steps required after a PHY reset 306775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 306875eba5b6SRobert Mustacchi **/ 306975eba5b6SRobert Mustacchi static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) 307075eba5b6SRobert Mustacchi { 307175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 307275eba5b6SRobert Mustacchi u16 reg; 307375eba5b6SRobert Mustacchi 307475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_post_phy_reset_ich8lan"); 307575eba5b6SRobert Mustacchi 307675eba5b6SRobert Mustacchi if (hw->phy.ops.check_reset_block(hw)) 307775eba5b6SRobert Mustacchi return E1000_SUCCESS; 307875eba5b6SRobert Mustacchi 307975eba5b6SRobert Mustacchi /* Allow time for h/w to get to quiescent state after reset */ 308075eba5b6SRobert Mustacchi msec_delay(10); 308175eba5b6SRobert Mustacchi 308275eba5b6SRobert Mustacchi /* Perform any necessary post-reset workarounds */ 308375eba5b6SRobert Mustacchi switch (hw->mac.type) { 308475eba5b6SRobert Mustacchi case e1000_pchlan: 308575eba5b6SRobert Mustacchi ret_val = e1000_hv_phy_workarounds_ich8lan(hw); 308675eba5b6SRobert Mustacchi if (ret_val) 308775eba5b6SRobert Mustacchi return ret_val; 308875eba5b6SRobert Mustacchi break; 308975eba5b6SRobert Mustacchi case e1000_pch2lan: 309075eba5b6SRobert Mustacchi ret_val = e1000_lv_phy_workarounds_ich8lan(hw); 309175eba5b6SRobert Mustacchi if (ret_val) 309275eba5b6SRobert Mustacchi return ret_val; 309375eba5b6SRobert Mustacchi break; 309475eba5b6SRobert Mustacchi default: 309575eba5b6SRobert Mustacchi break; 309675eba5b6SRobert Mustacchi } 309775eba5b6SRobert Mustacchi 309875eba5b6SRobert Mustacchi /* Clear the host wakeup bit after lcd reset */ 309975eba5b6SRobert Mustacchi if (hw->mac.type >= e1000_pchlan) { 310075eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, BM_PORT_GEN_CFG, ®); 310175eba5b6SRobert Mustacchi reg &= ~BM_WUC_HOST_WU_BIT; 310275eba5b6SRobert Mustacchi hw->phy.ops.write_reg(hw, BM_PORT_GEN_CFG, reg); 310375eba5b6SRobert Mustacchi } 310475eba5b6SRobert Mustacchi 310575eba5b6SRobert Mustacchi /* Configure the LCD with the extended configuration region in NVM */ 310675eba5b6SRobert Mustacchi ret_val = e1000_sw_lcd_config_ich8lan(hw); 310775eba5b6SRobert Mustacchi if (ret_val) 310875eba5b6SRobert Mustacchi return ret_val; 310975eba5b6SRobert Mustacchi 311075eba5b6SRobert Mustacchi /* Configure the LCD with the OEM bits in NVM */ 311175eba5b6SRobert Mustacchi ret_val = e1000_oem_bits_config_ich8lan(hw, TRUE); 311275eba5b6SRobert Mustacchi 311375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pch2lan) { 311475eba5b6SRobert Mustacchi /* Ungate automatic PHY configuration on non-managed 82579 */ 311575eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_FWSM) & 311675eba5b6SRobert Mustacchi E1000_ICH_FWSM_FW_VALID)) { 311775eba5b6SRobert Mustacchi msec_delay(10); 311875eba5b6SRobert Mustacchi e1000_gate_hw_phy_config_ich8lan(hw, FALSE); 311975eba5b6SRobert Mustacchi } 312075eba5b6SRobert Mustacchi 312175eba5b6SRobert Mustacchi /* Set EEE LPI Update Timer to 200usec */ 312275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 312375eba5b6SRobert Mustacchi if (ret_val) 312475eba5b6SRobert Mustacchi return ret_val; 312575eba5b6SRobert Mustacchi ret_val = e1000_write_emi_reg_locked(hw, 312675eba5b6SRobert Mustacchi I82579_LPI_UPDATE_TIMER, 312775eba5b6SRobert Mustacchi 0x1387); 312875eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 312975eba5b6SRobert Mustacchi } 313075eba5b6SRobert Mustacchi 313175eba5b6SRobert Mustacchi return ret_val; 313275eba5b6SRobert Mustacchi } 313375eba5b6SRobert Mustacchi 313475eba5b6SRobert Mustacchi /** 313575eba5b6SRobert Mustacchi * e1000_phy_hw_reset_ich8lan - Performs a PHY reset 313675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 313775eba5b6SRobert Mustacchi * 313875eba5b6SRobert Mustacchi * Resets the PHY 313975eba5b6SRobert Mustacchi * This is a function pointer entry point called by drivers 314075eba5b6SRobert Mustacchi * or other shared routines. 314175eba5b6SRobert Mustacchi **/ 314275eba5b6SRobert Mustacchi static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) 314375eba5b6SRobert Mustacchi { 314475eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 314575eba5b6SRobert Mustacchi 314675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_phy_hw_reset_ich8lan"); 314775eba5b6SRobert Mustacchi 314875eba5b6SRobert Mustacchi /* Gate automatic PHY configuration by hardware on non-managed 82579 */ 314975eba5b6SRobert Mustacchi if ((hw->mac.type == e1000_pch2lan) && 315075eba5b6SRobert Mustacchi !(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID)) 315175eba5b6SRobert Mustacchi e1000_gate_hw_phy_config_ich8lan(hw, TRUE); 315275eba5b6SRobert Mustacchi 315375eba5b6SRobert Mustacchi ret_val = e1000_phy_hw_reset_generic(hw); 315475eba5b6SRobert Mustacchi if (ret_val) 315575eba5b6SRobert Mustacchi return ret_val; 315675eba5b6SRobert Mustacchi 315775eba5b6SRobert Mustacchi return e1000_post_phy_reset_ich8lan(hw); 315875eba5b6SRobert Mustacchi } 315975eba5b6SRobert Mustacchi 316075eba5b6SRobert Mustacchi /** 316175eba5b6SRobert Mustacchi * e1000_set_lplu_state_pchlan - Set Low Power Link Up state 316275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 316375eba5b6SRobert Mustacchi * @active: TRUE to enable LPLU, FALSE to disable 316475eba5b6SRobert Mustacchi * 316575eba5b6SRobert Mustacchi * Sets the LPLU state according to the active flag. For PCH, if OEM write 316675eba5b6SRobert Mustacchi * bit are disabled in the NVM, writing the LPLU bits in the MAC will not set 316775eba5b6SRobert Mustacchi * the phy speed. This function will manually set the LPLU bit and restart 316875eba5b6SRobert Mustacchi * auto-neg as hw would do. D3 and D0 LPLU will call the same function 316975eba5b6SRobert Mustacchi * since it configures the same bit. 317075eba5b6SRobert Mustacchi **/ 317175eba5b6SRobert Mustacchi static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) 317275eba5b6SRobert Mustacchi { 317375eba5b6SRobert Mustacchi s32 ret_val; 317475eba5b6SRobert Mustacchi u16 oem_reg; 317575eba5b6SRobert Mustacchi 317675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_lplu_state_pchlan"); 317775eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, HV_OEM_BITS, &oem_reg); 317875eba5b6SRobert Mustacchi if (ret_val) 317975eba5b6SRobert Mustacchi return ret_val; 318075eba5b6SRobert Mustacchi 318175eba5b6SRobert Mustacchi if (active) 318275eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_LPLU; 318375eba5b6SRobert Mustacchi else 318475eba5b6SRobert Mustacchi oem_reg &= ~HV_OEM_BITS_LPLU; 318575eba5b6SRobert Mustacchi 318675eba5b6SRobert Mustacchi if (!hw->phy.ops.check_reset_block(hw)) 318775eba5b6SRobert Mustacchi oem_reg |= HV_OEM_BITS_RESTART_AN; 318875eba5b6SRobert Mustacchi 318975eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, HV_OEM_BITS, oem_reg); 319075eba5b6SRobert Mustacchi } 319175eba5b6SRobert Mustacchi 319275eba5b6SRobert Mustacchi /** 319375eba5b6SRobert Mustacchi * e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state 319475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 319575eba5b6SRobert Mustacchi * @active: TRUE to enable LPLU, FALSE to disable 319675eba5b6SRobert Mustacchi * 319775eba5b6SRobert Mustacchi * Sets the LPLU D0 state according to the active flag. When 319875eba5b6SRobert Mustacchi * activating LPLU this function also disables smart speed 319975eba5b6SRobert Mustacchi * and vice versa. LPLU will not be activated unless the 320075eba5b6SRobert Mustacchi * device autonegotiation advertisement meets standards of 320175eba5b6SRobert Mustacchi * either 10 or 10/100 or 10/100/1000 at all duplexes. 320275eba5b6SRobert Mustacchi * This is a function pointer entry point only called by 320375eba5b6SRobert Mustacchi * PHY setup routines. 320475eba5b6SRobert Mustacchi **/ 320575eba5b6SRobert Mustacchi static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) 320675eba5b6SRobert Mustacchi { 320775eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 320875eba5b6SRobert Mustacchi u32 phy_ctrl; 320975eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 321075eba5b6SRobert Mustacchi u16 data; 321175eba5b6SRobert Mustacchi 321275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_d0_lplu_state_ich8lan"); 321375eba5b6SRobert Mustacchi 321475eba5b6SRobert Mustacchi if (phy->type == e1000_phy_ife) 321575eba5b6SRobert Mustacchi return E1000_SUCCESS; 321675eba5b6SRobert Mustacchi 321775eba5b6SRobert Mustacchi phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); 321875eba5b6SRobert Mustacchi 321975eba5b6SRobert Mustacchi if (active) { 322075eba5b6SRobert Mustacchi phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; 322175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 322275eba5b6SRobert Mustacchi 322375eba5b6SRobert Mustacchi if (phy->type != e1000_phy_igp_3) 322475eba5b6SRobert Mustacchi return E1000_SUCCESS; 322575eba5b6SRobert Mustacchi 322675eba5b6SRobert Mustacchi /* Call gig speed drop workaround on LPLU before accessing 322775eba5b6SRobert Mustacchi * any PHY registers 322875eba5b6SRobert Mustacchi */ 322975eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 323075eba5b6SRobert Mustacchi e1000_gig_downshift_workaround_ich8lan(hw); 323175eba5b6SRobert Mustacchi 323275eba5b6SRobert Mustacchi /* When LPLU is enabled, we should disable SmartSpeed */ 323375eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 323475eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 323575eba5b6SRobert Mustacchi &data); 323675eba5b6SRobert Mustacchi if (ret_val) 323775eba5b6SRobert Mustacchi return ret_val; 323875eba5b6SRobert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED; 323975eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 324075eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 324175eba5b6SRobert Mustacchi data); 324275eba5b6SRobert Mustacchi if (ret_val) 324375eba5b6SRobert Mustacchi return ret_val; 324475eba5b6SRobert Mustacchi } else { 324575eba5b6SRobert Mustacchi phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; 324675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 324775eba5b6SRobert Mustacchi 324875eba5b6SRobert Mustacchi if (phy->type != e1000_phy_igp_3) 324975eba5b6SRobert Mustacchi return E1000_SUCCESS; 325075eba5b6SRobert Mustacchi 325175eba5b6SRobert Mustacchi /* LPLU and SmartSpeed are mutually exclusive. LPLU is used 325275eba5b6SRobert Mustacchi * during Dx states where the power conservation is most 325375eba5b6SRobert Mustacchi * important. During driver activity we should enable 325475eba5b6SRobert Mustacchi * SmartSpeed, so performance is maintained. 325575eba5b6SRobert Mustacchi */ 325675eba5b6SRobert Mustacchi if (phy->smart_speed == e1000_smart_speed_on) { 325775eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 325875eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 325975eba5b6SRobert Mustacchi &data); 326075eba5b6SRobert Mustacchi if (ret_val) 326175eba5b6SRobert Mustacchi return ret_val; 326275eba5b6SRobert Mustacchi 326375eba5b6SRobert Mustacchi data |= IGP01E1000_PSCFR_SMART_SPEED; 326475eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 326575eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 326675eba5b6SRobert Mustacchi data); 326775eba5b6SRobert Mustacchi if (ret_val) 326875eba5b6SRobert Mustacchi return ret_val; 326975eba5b6SRobert Mustacchi } else if (phy->smart_speed == e1000_smart_speed_off) { 327075eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 327175eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 327275eba5b6SRobert Mustacchi &data); 327375eba5b6SRobert Mustacchi if (ret_val) 327475eba5b6SRobert Mustacchi return ret_val; 327575eba5b6SRobert Mustacchi 327675eba5b6SRobert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED; 327775eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 327875eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 327975eba5b6SRobert Mustacchi data); 328075eba5b6SRobert Mustacchi if (ret_val) 328175eba5b6SRobert Mustacchi return ret_val; 328275eba5b6SRobert Mustacchi } 328375eba5b6SRobert Mustacchi } 328475eba5b6SRobert Mustacchi 328575eba5b6SRobert Mustacchi return E1000_SUCCESS; 328675eba5b6SRobert Mustacchi } 328775eba5b6SRobert Mustacchi 328875eba5b6SRobert Mustacchi /** 328975eba5b6SRobert Mustacchi * e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state 329075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 329175eba5b6SRobert Mustacchi * @active: TRUE to enable LPLU, FALSE to disable 329275eba5b6SRobert Mustacchi * 329375eba5b6SRobert Mustacchi * Sets the LPLU D3 state according to the active flag. When 329475eba5b6SRobert Mustacchi * activating LPLU this function also disables smart speed 329575eba5b6SRobert Mustacchi * and vice versa. LPLU will not be activated unless the 329675eba5b6SRobert Mustacchi * device autonegotiation advertisement meets standards of 329775eba5b6SRobert Mustacchi * either 10 or 10/100 or 10/100/1000 at all duplexes. 329875eba5b6SRobert Mustacchi * This is a function pointer entry point only called by 329975eba5b6SRobert Mustacchi * PHY setup routines. 330075eba5b6SRobert Mustacchi **/ 330175eba5b6SRobert Mustacchi static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) 330275eba5b6SRobert Mustacchi { 330375eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 330475eba5b6SRobert Mustacchi u32 phy_ctrl; 330575eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 330675eba5b6SRobert Mustacchi u16 data; 330775eba5b6SRobert Mustacchi 330875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_d3_lplu_state_ich8lan"); 330975eba5b6SRobert Mustacchi 331075eba5b6SRobert Mustacchi phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); 331175eba5b6SRobert Mustacchi 331275eba5b6SRobert Mustacchi if (!active) { 331375eba5b6SRobert Mustacchi phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; 331475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 331575eba5b6SRobert Mustacchi 331675eba5b6SRobert Mustacchi if (phy->type != e1000_phy_igp_3) 331775eba5b6SRobert Mustacchi return E1000_SUCCESS; 331875eba5b6SRobert Mustacchi 331975eba5b6SRobert Mustacchi /* LPLU and SmartSpeed are mutually exclusive. LPLU is used 332075eba5b6SRobert Mustacchi * during Dx states where the power conservation is most 332175eba5b6SRobert Mustacchi * important. During driver activity we should enable 332275eba5b6SRobert Mustacchi * SmartSpeed, so performance is maintained. 332375eba5b6SRobert Mustacchi */ 332475eba5b6SRobert Mustacchi if (phy->smart_speed == e1000_smart_speed_on) { 332575eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 332675eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 332775eba5b6SRobert Mustacchi &data); 332875eba5b6SRobert Mustacchi if (ret_val) 332975eba5b6SRobert Mustacchi return ret_val; 333075eba5b6SRobert Mustacchi 333175eba5b6SRobert Mustacchi data |= IGP01E1000_PSCFR_SMART_SPEED; 333275eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 333375eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 333475eba5b6SRobert Mustacchi data); 333575eba5b6SRobert Mustacchi if (ret_val) 333675eba5b6SRobert Mustacchi return ret_val; 333775eba5b6SRobert Mustacchi } else if (phy->smart_speed == e1000_smart_speed_off) { 333875eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 333975eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 334075eba5b6SRobert Mustacchi &data); 334175eba5b6SRobert Mustacchi if (ret_val) 334275eba5b6SRobert Mustacchi return ret_val; 334375eba5b6SRobert Mustacchi 334475eba5b6SRobert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED; 334575eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 334675eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 334775eba5b6SRobert Mustacchi data); 334875eba5b6SRobert Mustacchi if (ret_val) 334975eba5b6SRobert Mustacchi return ret_val; 335075eba5b6SRobert Mustacchi } 335175eba5b6SRobert Mustacchi } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || 335275eba5b6SRobert Mustacchi (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || 335375eba5b6SRobert Mustacchi (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { 335475eba5b6SRobert Mustacchi phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; 335575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 335675eba5b6SRobert Mustacchi 335775eba5b6SRobert Mustacchi if (phy->type != e1000_phy_igp_3) 335875eba5b6SRobert Mustacchi return E1000_SUCCESS; 335975eba5b6SRobert Mustacchi 336075eba5b6SRobert Mustacchi /* Call gig speed drop workaround on LPLU before accessing 336175eba5b6SRobert Mustacchi * any PHY registers 336275eba5b6SRobert Mustacchi */ 336375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 336475eba5b6SRobert Mustacchi e1000_gig_downshift_workaround_ich8lan(hw); 336575eba5b6SRobert Mustacchi 336675eba5b6SRobert Mustacchi /* When LPLU is enabled, we should disable SmartSpeed */ 336775eba5b6SRobert Mustacchi ret_val = phy->ops.read_reg(hw, 336875eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 336975eba5b6SRobert Mustacchi &data); 337075eba5b6SRobert Mustacchi if (ret_val) 337175eba5b6SRobert Mustacchi return ret_val; 337275eba5b6SRobert Mustacchi 337375eba5b6SRobert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED; 337475eba5b6SRobert Mustacchi ret_val = phy->ops.write_reg(hw, 337575eba5b6SRobert Mustacchi IGP01E1000_PHY_PORT_CONFIG, 337675eba5b6SRobert Mustacchi data); 337775eba5b6SRobert Mustacchi } 337875eba5b6SRobert Mustacchi 337975eba5b6SRobert Mustacchi return ret_val; 338075eba5b6SRobert Mustacchi } 338175eba5b6SRobert Mustacchi 338275eba5b6SRobert Mustacchi /** 338375eba5b6SRobert Mustacchi * e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1 338475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 338575eba5b6SRobert Mustacchi * @bank: pointer to the variable that returns the active bank 338675eba5b6SRobert Mustacchi * 338775eba5b6SRobert Mustacchi * Reads signature byte from the NVM using the flash access registers. 338875eba5b6SRobert Mustacchi * Word 0x13 bits 15:14 = 10b indicate a valid signature for that bank. 338975eba5b6SRobert Mustacchi **/ 339075eba5b6SRobert Mustacchi static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) 339175eba5b6SRobert Mustacchi { 339275eba5b6SRobert Mustacchi u32 eecd; 339375eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 339475eba5b6SRobert Mustacchi u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); 339575eba5b6SRobert Mustacchi u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; 3396*42cc51e0SRobert Mustacchi u32 nvm_dword = 0; 339775eba5b6SRobert Mustacchi u8 sig_byte = 0; 339875eba5b6SRobert Mustacchi s32 ret_val; 339975eba5b6SRobert Mustacchi 340075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_valid_nvm_bank_detect_ich8lan"); 340175eba5b6SRobert Mustacchi 340275eba5b6SRobert Mustacchi switch (hw->mac.type) { 3403*42cc51e0SRobert Mustacchi case e1000_pch_spt: 3404*42cc51e0SRobert Mustacchi bank1_offset = nvm->flash_bank_size; 3405*42cc51e0SRobert Mustacchi act_offset = E1000_ICH_NVM_SIG_WORD; 3406*42cc51e0SRobert Mustacchi 3407*42cc51e0SRobert Mustacchi /* set bank to 0 in case flash read fails */ 3408*42cc51e0SRobert Mustacchi *bank = 0; 3409*42cc51e0SRobert Mustacchi 3410*42cc51e0SRobert Mustacchi /* Check bank 0 */ 3411*42cc51e0SRobert Mustacchi ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, 3412*42cc51e0SRobert Mustacchi &nvm_dword); 3413*42cc51e0SRobert Mustacchi if (ret_val) 3414*42cc51e0SRobert Mustacchi return ret_val; 3415*42cc51e0SRobert Mustacchi sig_byte = (u8)((nvm_dword & 0xFF00) >> 8); 3416*42cc51e0SRobert Mustacchi if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == 3417*42cc51e0SRobert Mustacchi E1000_ICH_NVM_SIG_VALUE) { 3418*42cc51e0SRobert Mustacchi *bank = 0; 3419*42cc51e0SRobert Mustacchi return E1000_SUCCESS; 3420*42cc51e0SRobert Mustacchi } 3421*42cc51e0SRobert Mustacchi 3422*42cc51e0SRobert Mustacchi /* Check bank 1 */ 3423*42cc51e0SRobert Mustacchi ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset + 3424*42cc51e0SRobert Mustacchi bank1_offset, 3425*42cc51e0SRobert Mustacchi &nvm_dword); 3426*42cc51e0SRobert Mustacchi if (ret_val) 3427*42cc51e0SRobert Mustacchi return ret_val; 3428*42cc51e0SRobert Mustacchi sig_byte = (u8)((nvm_dword & 0xFF00) >> 8); 3429*42cc51e0SRobert Mustacchi if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == 3430*42cc51e0SRobert Mustacchi E1000_ICH_NVM_SIG_VALUE) { 3431*42cc51e0SRobert Mustacchi *bank = 1; 3432*42cc51e0SRobert Mustacchi return E1000_SUCCESS; 3433*42cc51e0SRobert Mustacchi } 3434*42cc51e0SRobert Mustacchi 3435*42cc51e0SRobert Mustacchi DEBUGOUT("ERROR: No valid NVM bank present\n"); 3436*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 343775eba5b6SRobert Mustacchi case e1000_ich8lan: 343875eba5b6SRobert Mustacchi case e1000_ich9lan: 343975eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 344075eba5b6SRobert Mustacchi if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) == 344175eba5b6SRobert Mustacchi E1000_EECD_SEC1VAL_VALID_MASK) { 344275eba5b6SRobert Mustacchi if (eecd & E1000_EECD_SEC1VAL) 344375eba5b6SRobert Mustacchi *bank = 1; 344475eba5b6SRobert Mustacchi else 344575eba5b6SRobert Mustacchi *bank = 0; 344675eba5b6SRobert Mustacchi 344775eba5b6SRobert Mustacchi return E1000_SUCCESS; 344875eba5b6SRobert Mustacchi } 344975eba5b6SRobert Mustacchi DEBUGOUT("Unable to determine valid NVM bank via EEC - reading flash signature\n"); 345075eba5b6SRobert Mustacchi /* fall-thru */ 345175eba5b6SRobert Mustacchi default: 345275eba5b6SRobert Mustacchi /* set bank to 0 in case flash read fails */ 345375eba5b6SRobert Mustacchi *bank = 0; 345475eba5b6SRobert Mustacchi 345575eba5b6SRobert Mustacchi /* Check bank 0 */ 345675eba5b6SRobert Mustacchi ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset, 345775eba5b6SRobert Mustacchi &sig_byte); 345875eba5b6SRobert Mustacchi if (ret_val) 345975eba5b6SRobert Mustacchi return ret_val; 346075eba5b6SRobert Mustacchi if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == 346175eba5b6SRobert Mustacchi E1000_ICH_NVM_SIG_VALUE) { 346275eba5b6SRobert Mustacchi *bank = 0; 346375eba5b6SRobert Mustacchi return E1000_SUCCESS; 346475eba5b6SRobert Mustacchi } 346575eba5b6SRobert Mustacchi 346675eba5b6SRobert Mustacchi /* Check bank 1 */ 346775eba5b6SRobert Mustacchi ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset + 346875eba5b6SRobert Mustacchi bank1_offset, 346975eba5b6SRobert Mustacchi &sig_byte); 347075eba5b6SRobert Mustacchi if (ret_val) 347175eba5b6SRobert Mustacchi return ret_val; 347275eba5b6SRobert Mustacchi if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == 347375eba5b6SRobert Mustacchi E1000_ICH_NVM_SIG_VALUE) { 347475eba5b6SRobert Mustacchi *bank = 1; 347575eba5b6SRobert Mustacchi return E1000_SUCCESS; 347675eba5b6SRobert Mustacchi } 347775eba5b6SRobert Mustacchi 347875eba5b6SRobert Mustacchi DEBUGOUT("ERROR: No valid NVM bank present\n"); 347975eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 348075eba5b6SRobert Mustacchi } 348175eba5b6SRobert Mustacchi } 348275eba5b6SRobert Mustacchi 348375eba5b6SRobert Mustacchi /** 3484*42cc51e0SRobert Mustacchi * e1000_read_nvm_spt - NVM access for SPT 3485*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 3486*42cc51e0SRobert Mustacchi * @offset: The offset (in bytes) of the word(s) to read. 3487*42cc51e0SRobert Mustacchi * @words: Size of data to read in words. 3488*42cc51e0SRobert Mustacchi * @data: pointer to the word(s) to read at offset. 3489*42cc51e0SRobert Mustacchi * 3490*42cc51e0SRobert Mustacchi * Reads a word(s) from the NVM 3491*42cc51e0SRobert Mustacchi **/ 3492*42cc51e0SRobert Mustacchi static s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words, 3493*42cc51e0SRobert Mustacchi u16 *data) 3494*42cc51e0SRobert Mustacchi { 3495*42cc51e0SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 3496*42cc51e0SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 3497*42cc51e0SRobert Mustacchi u32 act_offset; 3498*42cc51e0SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 3499*42cc51e0SRobert Mustacchi u32 bank = 0; 3500*42cc51e0SRobert Mustacchi u32 dword = 0; 3501*42cc51e0SRobert Mustacchi u16 offset_to_read; 3502*42cc51e0SRobert Mustacchi u16 i; 3503*42cc51e0SRobert Mustacchi 3504*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_read_nvm_spt"); 3505*42cc51e0SRobert Mustacchi 3506*42cc51e0SRobert Mustacchi if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || 3507*42cc51e0SRobert Mustacchi (words == 0)) { 3508*42cc51e0SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 3509*42cc51e0SRobert Mustacchi ret_val = -E1000_ERR_NVM; 3510*42cc51e0SRobert Mustacchi goto out; 3511*42cc51e0SRobert Mustacchi } 3512*42cc51e0SRobert Mustacchi 3513*42cc51e0SRobert Mustacchi nvm->ops.acquire(hw); 3514*42cc51e0SRobert Mustacchi 3515*42cc51e0SRobert Mustacchi ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 3516*42cc51e0SRobert Mustacchi if (ret_val != E1000_SUCCESS) { 3517*42cc51e0SRobert Mustacchi DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); 3518*42cc51e0SRobert Mustacchi bank = 0; 3519*42cc51e0SRobert Mustacchi } 3520*42cc51e0SRobert Mustacchi 3521*42cc51e0SRobert Mustacchi act_offset = (bank) ? nvm->flash_bank_size : 0; 3522*42cc51e0SRobert Mustacchi act_offset += offset; 3523*42cc51e0SRobert Mustacchi 3524*42cc51e0SRobert Mustacchi ret_val = E1000_SUCCESS; 3525*42cc51e0SRobert Mustacchi 3526*42cc51e0SRobert Mustacchi for (i = 0; i < words; i += 2) { 3527*42cc51e0SRobert Mustacchi if (words - i == 1) { 3528*42cc51e0SRobert Mustacchi if (dev_spec->shadow_ram[offset+i].modified) { 3529*42cc51e0SRobert Mustacchi data[i] = dev_spec->shadow_ram[offset+i].value; 3530*42cc51e0SRobert Mustacchi } else { 3531*42cc51e0SRobert Mustacchi offset_to_read = act_offset + i - 3532*42cc51e0SRobert Mustacchi ((act_offset + i) % 2); 3533*42cc51e0SRobert Mustacchi ret_val = 3534*42cc51e0SRobert Mustacchi e1000_read_flash_dword_ich8lan(hw, 3535*42cc51e0SRobert Mustacchi offset_to_read, 3536*42cc51e0SRobert Mustacchi &dword); 3537*42cc51e0SRobert Mustacchi if (ret_val) 3538*42cc51e0SRobert Mustacchi break; 3539*42cc51e0SRobert Mustacchi if ((act_offset + i) % 2 == 0) 3540*42cc51e0SRobert Mustacchi data[i] = (u16)(dword & 0xFFFF); 3541*42cc51e0SRobert Mustacchi else 3542*42cc51e0SRobert Mustacchi data[i] = (u16)((dword >> 16) & 0xFFFF); 3543*42cc51e0SRobert Mustacchi } 3544*42cc51e0SRobert Mustacchi } else { 3545*42cc51e0SRobert Mustacchi offset_to_read = act_offset + i; 3546*42cc51e0SRobert Mustacchi if (!(dev_spec->shadow_ram[offset+i].modified) || 3547*42cc51e0SRobert Mustacchi !(dev_spec->shadow_ram[offset+i+1].modified)) { 3548*42cc51e0SRobert Mustacchi ret_val = 3549*42cc51e0SRobert Mustacchi e1000_read_flash_dword_ich8lan(hw, 3550*42cc51e0SRobert Mustacchi offset_to_read, 3551*42cc51e0SRobert Mustacchi &dword); 3552*42cc51e0SRobert Mustacchi if (ret_val) 3553*42cc51e0SRobert Mustacchi break; 3554*42cc51e0SRobert Mustacchi } 3555*42cc51e0SRobert Mustacchi if (dev_spec->shadow_ram[offset+i].modified) 3556*42cc51e0SRobert Mustacchi data[i] = dev_spec->shadow_ram[offset+i].value; 3557*42cc51e0SRobert Mustacchi else 3558*42cc51e0SRobert Mustacchi data[i] = (u16) (dword & 0xFFFF); 3559*42cc51e0SRobert Mustacchi if (dev_spec->shadow_ram[offset+i].modified) 3560*42cc51e0SRobert Mustacchi data[i+1] = 3561*42cc51e0SRobert Mustacchi dev_spec->shadow_ram[offset+i+1].value; 3562*42cc51e0SRobert Mustacchi else 3563*42cc51e0SRobert Mustacchi data[i+1] = (u16) (dword >> 16 & 0xFFFF); 3564*42cc51e0SRobert Mustacchi } 3565*42cc51e0SRobert Mustacchi } 3566*42cc51e0SRobert Mustacchi 3567*42cc51e0SRobert Mustacchi nvm->ops.release(hw); 3568*42cc51e0SRobert Mustacchi 3569*42cc51e0SRobert Mustacchi out: 3570*42cc51e0SRobert Mustacchi if (ret_val) 3571*42cc51e0SRobert Mustacchi DEBUGOUT1("NVM read error: %d\n", ret_val); 3572*42cc51e0SRobert Mustacchi 3573*42cc51e0SRobert Mustacchi return ret_val; 3574*42cc51e0SRobert Mustacchi } 3575*42cc51e0SRobert Mustacchi 3576*42cc51e0SRobert Mustacchi /** 357775eba5b6SRobert Mustacchi * e1000_read_nvm_ich8lan - Read word(s) from the NVM 357875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 357975eba5b6SRobert Mustacchi * @offset: The offset (in bytes) of the word(s) to read. 358075eba5b6SRobert Mustacchi * @words: Size of data to read in words 358175eba5b6SRobert Mustacchi * @data: Pointer to the word(s) to read at offset. 358275eba5b6SRobert Mustacchi * 358375eba5b6SRobert Mustacchi * Reads a word(s) from the NVM using the flash access registers. 358475eba5b6SRobert Mustacchi **/ 358575eba5b6SRobert Mustacchi static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, 358675eba5b6SRobert Mustacchi u16 *data) 358775eba5b6SRobert Mustacchi { 358875eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 358975eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 359075eba5b6SRobert Mustacchi u32 act_offset; 359175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 359275eba5b6SRobert Mustacchi u32 bank = 0; 359375eba5b6SRobert Mustacchi u16 i, word; 359475eba5b6SRobert Mustacchi 359575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_nvm_ich8lan"); 359675eba5b6SRobert Mustacchi 359775eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || 359875eba5b6SRobert Mustacchi (words == 0)) { 359975eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 360075eba5b6SRobert Mustacchi ret_val = -E1000_ERR_NVM; 360175eba5b6SRobert Mustacchi goto out; 360275eba5b6SRobert Mustacchi } 360375eba5b6SRobert Mustacchi 360475eba5b6SRobert Mustacchi nvm->ops.acquire(hw); 360575eba5b6SRobert Mustacchi 360675eba5b6SRobert Mustacchi ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 360775eba5b6SRobert Mustacchi if (ret_val != E1000_SUCCESS) { 360875eba5b6SRobert Mustacchi DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); 360975eba5b6SRobert Mustacchi bank = 0; 361075eba5b6SRobert Mustacchi } 361175eba5b6SRobert Mustacchi 361275eba5b6SRobert Mustacchi act_offset = (bank) ? nvm->flash_bank_size : 0; 361375eba5b6SRobert Mustacchi act_offset += offset; 361475eba5b6SRobert Mustacchi 361575eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 361675eba5b6SRobert Mustacchi for (i = 0; i < words; i++) { 361775eba5b6SRobert Mustacchi if (dev_spec->shadow_ram[offset+i].modified) { 361875eba5b6SRobert Mustacchi data[i] = dev_spec->shadow_ram[offset+i].value; 361975eba5b6SRobert Mustacchi } else { 362075eba5b6SRobert Mustacchi ret_val = e1000_read_flash_word_ich8lan(hw, 362175eba5b6SRobert Mustacchi act_offset + i, 362275eba5b6SRobert Mustacchi &word); 362375eba5b6SRobert Mustacchi if (ret_val) 362475eba5b6SRobert Mustacchi break; 362575eba5b6SRobert Mustacchi data[i] = word; 362675eba5b6SRobert Mustacchi } 362775eba5b6SRobert Mustacchi } 362875eba5b6SRobert Mustacchi 362975eba5b6SRobert Mustacchi nvm->ops.release(hw); 363075eba5b6SRobert Mustacchi 363175eba5b6SRobert Mustacchi out: 363275eba5b6SRobert Mustacchi if (ret_val) 363375eba5b6SRobert Mustacchi DEBUGOUT1("NVM read error: %d\n", ret_val); 363475eba5b6SRobert Mustacchi 363575eba5b6SRobert Mustacchi return ret_val; 363675eba5b6SRobert Mustacchi } 363775eba5b6SRobert Mustacchi 363875eba5b6SRobert Mustacchi /** 363975eba5b6SRobert Mustacchi * e1000_flash_cycle_init_ich8lan - Initialize flash 364075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 364175eba5b6SRobert Mustacchi * 364275eba5b6SRobert Mustacchi * This function does initial flash setup so that a new read/write/erase cycle 364375eba5b6SRobert Mustacchi * can be started. 364475eba5b6SRobert Mustacchi **/ 364575eba5b6SRobert Mustacchi static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) 364675eba5b6SRobert Mustacchi { 364775eba5b6SRobert Mustacchi union ich8_hws_flash_status hsfsts; 364875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_NVM; 364975eba5b6SRobert Mustacchi 365075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_flash_cycle_init_ich8lan"); 365175eba5b6SRobert Mustacchi 365275eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); 365375eba5b6SRobert Mustacchi 365475eba5b6SRobert Mustacchi /* Check if the flash descriptor is valid */ 365575eba5b6SRobert Mustacchi if (!hsfsts.hsf_status.fldesvalid) { 365675eba5b6SRobert Mustacchi DEBUGOUT("Flash descriptor invalid. SW Sequencing must be used.\n"); 365775eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 365875eba5b6SRobert Mustacchi } 365975eba5b6SRobert Mustacchi 366075eba5b6SRobert Mustacchi /* Clear FCERR and DAEL in hw status by writing 1 */ 366175eba5b6SRobert Mustacchi hsfsts.hsf_status.flcerr = 1; 366275eba5b6SRobert Mustacchi hsfsts.hsf_status.dael = 1; 3663*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3664*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 3665*42cc51e0SRobert Mustacchi hsfsts.regval & 0xFFFF); 3666*42cc51e0SRobert Mustacchi else 366775eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); 366875eba5b6SRobert Mustacchi 366975eba5b6SRobert Mustacchi /* Either we should have a hardware SPI cycle in progress 367075eba5b6SRobert Mustacchi * bit to check against, in order to start a new cycle or 367175eba5b6SRobert Mustacchi * FDONE bit should be changed in the hardware so that it 367275eba5b6SRobert Mustacchi * is 1 after hardware reset, which can then be used as an 367375eba5b6SRobert Mustacchi * indication whether a cycle is in progress or has been 367475eba5b6SRobert Mustacchi * completed. 367575eba5b6SRobert Mustacchi */ 367675eba5b6SRobert Mustacchi 367775eba5b6SRobert Mustacchi if (!hsfsts.hsf_status.flcinprog) { 367875eba5b6SRobert Mustacchi /* There is no cycle running at present, 367975eba5b6SRobert Mustacchi * so we can start a cycle. 368075eba5b6SRobert Mustacchi * Begin by setting Flash Cycle Done. 368175eba5b6SRobert Mustacchi */ 368275eba5b6SRobert Mustacchi hsfsts.hsf_status.flcdone = 1; 3683*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3684*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 3685*42cc51e0SRobert Mustacchi hsfsts.regval & 0xFFFF); 3686*42cc51e0SRobert Mustacchi else 3687*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, 3688*42cc51e0SRobert Mustacchi hsfsts.regval); 368975eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 369075eba5b6SRobert Mustacchi } else { 369175eba5b6SRobert Mustacchi s32 i; 369275eba5b6SRobert Mustacchi 369375eba5b6SRobert Mustacchi /* Otherwise poll for sometime so the current 369475eba5b6SRobert Mustacchi * cycle has a chance to end before giving up. 369575eba5b6SRobert Mustacchi */ 369675eba5b6SRobert Mustacchi for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { 369775eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, 369875eba5b6SRobert Mustacchi ICH_FLASH_HSFSTS); 369975eba5b6SRobert Mustacchi if (!hsfsts.hsf_status.flcinprog) { 370075eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 370175eba5b6SRobert Mustacchi break; 370275eba5b6SRobert Mustacchi } 370375eba5b6SRobert Mustacchi usec_delay(1); 370475eba5b6SRobert Mustacchi } 370575eba5b6SRobert Mustacchi if (ret_val == E1000_SUCCESS) { 370675eba5b6SRobert Mustacchi /* Successful in waiting for previous cycle to timeout, 370775eba5b6SRobert Mustacchi * now set the Flash Cycle Done. 370875eba5b6SRobert Mustacchi */ 370975eba5b6SRobert Mustacchi hsfsts.hsf_status.flcdone = 1; 3710*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3711*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 3712*42cc51e0SRobert Mustacchi hsfsts.regval & 0xFFFF); 3713*42cc51e0SRobert Mustacchi else 371475eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, 371575eba5b6SRobert Mustacchi hsfsts.regval); 371675eba5b6SRobert Mustacchi } else { 371775eba5b6SRobert Mustacchi DEBUGOUT("Flash controller busy, cannot get access\n"); 371875eba5b6SRobert Mustacchi } 371975eba5b6SRobert Mustacchi } 372075eba5b6SRobert Mustacchi 372175eba5b6SRobert Mustacchi return ret_val; 372275eba5b6SRobert Mustacchi } 372375eba5b6SRobert Mustacchi 372475eba5b6SRobert Mustacchi /** 372575eba5b6SRobert Mustacchi * e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase) 372675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 372775eba5b6SRobert Mustacchi * @timeout: maximum time to wait for completion 372875eba5b6SRobert Mustacchi * 372975eba5b6SRobert Mustacchi * This function starts a flash cycle and waits for its completion. 373075eba5b6SRobert Mustacchi **/ 373175eba5b6SRobert Mustacchi static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) 373275eba5b6SRobert Mustacchi { 373375eba5b6SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 373475eba5b6SRobert Mustacchi union ich8_hws_flash_status hsfsts; 373575eba5b6SRobert Mustacchi u32 i = 0; 373675eba5b6SRobert Mustacchi 373775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_flash_cycle_ich8lan"); 373875eba5b6SRobert Mustacchi 373975eba5b6SRobert Mustacchi /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ 3740*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3741*42cc51e0SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16; 3742*42cc51e0SRobert Mustacchi else 374375eba5b6SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); 374475eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.flcgo = 1; 3745c124a83eSRobert Mustacchi 3746*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3747*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 3748*42cc51e0SRobert Mustacchi hsflctl.regval << 16); 3749*42cc51e0SRobert Mustacchi else 375075eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); 375175eba5b6SRobert Mustacchi 375275eba5b6SRobert Mustacchi /* wait till FDONE bit is set to 1 */ 375375eba5b6SRobert Mustacchi do { 375475eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); 375575eba5b6SRobert Mustacchi if (hsfsts.hsf_status.flcdone) 375675eba5b6SRobert Mustacchi break; 375775eba5b6SRobert Mustacchi usec_delay(1); 375875eba5b6SRobert Mustacchi } while (i++ < timeout); 375975eba5b6SRobert Mustacchi 376075eba5b6SRobert Mustacchi if (hsfsts.hsf_status.flcdone && !hsfsts.hsf_status.flcerr) 376175eba5b6SRobert Mustacchi return E1000_SUCCESS; 376275eba5b6SRobert Mustacchi 376375eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 376475eba5b6SRobert Mustacchi } 376575eba5b6SRobert Mustacchi 376675eba5b6SRobert Mustacchi /** 3767*42cc51e0SRobert Mustacchi * e1000_read_flash_dword_ich8lan - Read dword from flash 3768*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 3769*42cc51e0SRobert Mustacchi * @offset: offset to data location 3770*42cc51e0SRobert Mustacchi * @data: pointer to the location for storing the data 3771*42cc51e0SRobert Mustacchi * 3772*42cc51e0SRobert Mustacchi * Reads the flash dword at offset into data. Offset is converted 3773*42cc51e0SRobert Mustacchi * to bytes before read. 3774*42cc51e0SRobert Mustacchi **/ 3775*42cc51e0SRobert Mustacchi static s32 e1000_read_flash_dword_ich8lan(struct e1000_hw *hw, u32 offset, 3776*42cc51e0SRobert Mustacchi u32 *data) 3777*42cc51e0SRobert Mustacchi { 3778*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_read_flash_dword_ich8lan"); 3779*42cc51e0SRobert Mustacchi 3780*42cc51e0SRobert Mustacchi if (!data) 3781*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 3782*42cc51e0SRobert Mustacchi 3783*42cc51e0SRobert Mustacchi /* Must convert word offset into bytes. */ 3784*42cc51e0SRobert Mustacchi offset <<= 1; 3785*42cc51e0SRobert Mustacchi 3786*42cc51e0SRobert Mustacchi return e1000_read_flash_data32_ich8lan(hw, offset, data); 3787*42cc51e0SRobert Mustacchi } 3788*42cc51e0SRobert Mustacchi 3789*42cc51e0SRobert Mustacchi /** 379075eba5b6SRobert Mustacchi * e1000_read_flash_word_ich8lan - Read word from flash 379175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 379275eba5b6SRobert Mustacchi * @offset: offset to data location 379375eba5b6SRobert Mustacchi * @data: pointer to the location for storing the data 379475eba5b6SRobert Mustacchi * 379575eba5b6SRobert Mustacchi * Reads the flash word at offset into data. Offset is converted 379675eba5b6SRobert Mustacchi * to bytes before read. 379775eba5b6SRobert Mustacchi **/ 379875eba5b6SRobert Mustacchi static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, 379975eba5b6SRobert Mustacchi u16 *data) 380075eba5b6SRobert Mustacchi { 380175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_flash_word_ich8lan"); 380275eba5b6SRobert Mustacchi 380375eba5b6SRobert Mustacchi if (!data) 380475eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 380575eba5b6SRobert Mustacchi 380675eba5b6SRobert Mustacchi /* Must convert offset into bytes. */ 380775eba5b6SRobert Mustacchi offset <<= 1; 380875eba5b6SRobert Mustacchi 380975eba5b6SRobert Mustacchi return e1000_read_flash_data_ich8lan(hw, offset, 2, data); 381075eba5b6SRobert Mustacchi } 381175eba5b6SRobert Mustacchi 381275eba5b6SRobert Mustacchi /** 381375eba5b6SRobert Mustacchi * e1000_read_flash_byte_ich8lan - Read byte from flash 381475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 381575eba5b6SRobert Mustacchi * @offset: The offset of the byte to read. 381675eba5b6SRobert Mustacchi * @data: Pointer to a byte to store the value read. 381775eba5b6SRobert Mustacchi * 381875eba5b6SRobert Mustacchi * Reads a single byte from the NVM using the flash access registers. 381975eba5b6SRobert Mustacchi **/ 382075eba5b6SRobert Mustacchi static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, 382175eba5b6SRobert Mustacchi u8 *data) 382275eba5b6SRobert Mustacchi { 382375eba5b6SRobert Mustacchi s32 ret_val; 382475eba5b6SRobert Mustacchi u16 word = 0; 382575eba5b6SRobert Mustacchi 3826*42cc51e0SRobert Mustacchi /* In SPT, only 32 bits access is supported, 3827*42cc51e0SRobert Mustacchi * so this function should not be called. 3828*42cc51e0SRobert Mustacchi */ 3829*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 3830*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 3831*42cc51e0SRobert Mustacchi else 383275eba5b6SRobert Mustacchi ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word); 3833c124a83eSRobert Mustacchi 383475eba5b6SRobert Mustacchi if (ret_val) 383575eba5b6SRobert Mustacchi return ret_val; 383675eba5b6SRobert Mustacchi 383775eba5b6SRobert Mustacchi *data = (u8)word; 383875eba5b6SRobert Mustacchi 383975eba5b6SRobert Mustacchi return E1000_SUCCESS; 384075eba5b6SRobert Mustacchi } 384175eba5b6SRobert Mustacchi 384275eba5b6SRobert Mustacchi /** 384375eba5b6SRobert Mustacchi * e1000_read_flash_data_ich8lan - Read byte or word from NVM 384475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 384575eba5b6SRobert Mustacchi * @offset: The offset (in bytes) of the byte or word to read. 384675eba5b6SRobert Mustacchi * @size: Size of data to read, 1=byte 2=word 384775eba5b6SRobert Mustacchi * @data: Pointer to the word to store the value read. 384875eba5b6SRobert Mustacchi * 384975eba5b6SRobert Mustacchi * Reads a byte or word from the NVM using the flash access registers. 385075eba5b6SRobert Mustacchi **/ 385175eba5b6SRobert Mustacchi static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, 385275eba5b6SRobert Mustacchi u8 size, u16 *data) 385375eba5b6SRobert Mustacchi { 385475eba5b6SRobert Mustacchi union ich8_hws_flash_status hsfsts; 385575eba5b6SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 385675eba5b6SRobert Mustacchi u32 flash_linear_addr; 385775eba5b6SRobert Mustacchi u32 flash_data = 0; 385875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_NVM; 385975eba5b6SRobert Mustacchi u8 count = 0; 386075eba5b6SRobert Mustacchi 386175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_flash_data_ich8lan"); 386275eba5b6SRobert Mustacchi 386375eba5b6SRobert Mustacchi if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) 386475eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 3865c124a83eSRobert Mustacchi flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + 3866c124a83eSRobert Mustacchi hw->nvm.flash_base_addr); 386775eba5b6SRobert Mustacchi 386875eba5b6SRobert Mustacchi do { 386975eba5b6SRobert Mustacchi usec_delay(1); 387075eba5b6SRobert Mustacchi /* Steps */ 387175eba5b6SRobert Mustacchi ret_val = e1000_flash_cycle_init_ich8lan(hw); 387275eba5b6SRobert Mustacchi if (ret_val != E1000_SUCCESS) 387375eba5b6SRobert Mustacchi break; 387475eba5b6SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); 3875c124a83eSRobert Mustacchi 387675eba5b6SRobert Mustacchi /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ 387775eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.fldbcount = size - 1; 387875eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; 387975eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); 388075eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); 388175eba5b6SRobert Mustacchi 388275eba5b6SRobert Mustacchi ret_val = e1000_flash_cycle_ich8lan(hw, 388375eba5b6SRobert Mustacchi ICH_FLASH_READ_COMMAND_TIMEOUT); 388475eba5b6SRobert Mustacchi 388575eba5b6SRobert Mustacchi /* Check if FCERR is set to 1, if set to 1, clear it 388675eba5b6SRobert Mustacchi * and try the whole sequence a few more times, else 388775eba5b6SRobert Mustacchi * read in (shift in) the Flash Data0, the order is 388875eba5b6SRobert Mustacchi * least significant byte first msb to lsb 388975eba5b6SRobert Mustacchi */ 389075eba5b6SRobert Mustacchi if (ret_val == E1000_SUCCESS) { 389175eba5b6SRobert Mustacchi flash_data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0); 389275eba5b6SRobert Mustacchi if (size == 1) 389375eba5b6SRobert Mustacchi *data = (u8)(flash_data & 0x000000FF); 389475eba5b6SRobert Mustacchi else if (size == 2) 389575eba5b6SRobert Mustacchi *data = (u16)(flash_data & 0x0000FFFF); 389675eba5b6SRobert Mustacchi break; 389775eba5b6SRobert Mustacchi } else { 389875eba5b6SRobert Mustacchi /* If we've gotten here, then things are probably 389975eba5b6SRobert Mustacchi * completely hosed, but if the error condition is 390075eba5b6SRobert Mustacchi * detected, it won't hurt to give it another try... 390175eba5b6SRobert Mustacchi * ICH_FLASH_CYCLE_REPEAT_COUNT times. 390275eba5b6SRobert Mustacchi */ 390375eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, 390475eba5b6SRobert Mustacchi ICH_FLASH_HSFSTS); 390575eba5b6SRobert Mustacchi if (hsfsts.hsf_status.flcerr) { 390675eba5b6SRobert Mustacchi /* Repeat for some time before giving up. */ 390775eba5b6SRobert Mustacchi continue; 390875eba5b6SRobert Mustacchi } else if (!hsfsts.hsf_status.flcdone) { 390975eba5b6SRobert Mustacchi DEBUGOUT("Timeout error - flash cycle did not complete.\n"); 391075eba5b6SRobert Mustacchi break; 391175eba5b6SRobert Mustacchi } 391275eba5b6SRobert Mustacchi } 391375eba5b6SRobert Mustacchi } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); 391475eba5b6SRobert Mustacchi 391575eba5b6SRobert Mustacchi return ret_val; 391675eba5b6SRobert Mustacchi } 391775eba5b6SRobert Mustacchi 3918*42cc51e0SRobert Mustacchi /** 3919*42cc51e0SRobert Mustacchi * e1000_read_flash_data32_ich8lan - Read dword from NVM 3920*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 3921*42cc51e0SRobert Mustacchi * @offset: The offset (in bytes) of the dword to read. 3922*42cc51e0SRobert Mustacchi * @data: Pointer to the dword to store the value read. 3923*42cc51e0SRobert Mustacchi * 3924*42cc51e0SRobert Mustacchi * Reads a byte or word from the NVM using the flash access registers. 3925*42cc51e0SRobert Mustacchi **/ 3926*42cc51e0SRobert Mustacchi static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset, 3927*42cc51e0SRobert Mustacchi u32 *data) 3928*42cc51e0SRobert Mustacchi { 3929*42cc51e0SRobert Mustacchi union ich8_hws_flash_status hsfsts; 3930*42cc51e0SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 3931*42cc51e0SRobert Mustacchi u32 flash_linear_addr; 3932*42cc51e0SRobert Mustacchi s32 ret_val = -E1000_ERR_NVM; 3933*42cc51e0SRobert Mustacchi u8 count = 0; 3934*42cc51e0SRobert Mustacchi 3935*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_read_flash_data_ich8lan"); 3936*42cc51e0SRobert Mustacchi 3937*42cc51e0SRobert Mustacchi if (offset > ICH_FLASH_LINEAR_ADDR_MASK || 3938*42cc51e0SRobert Mustacchi hw->mac.type != e1000_pch_spt) 3939*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 3940*42cc51e0SRobert Mustacchi flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + 3941*42cc51e0SRobert Mustacchi hw->nvm.flash_base_addr); 3942*42cc51e0SRobert Mustacchi 3943*42cc51e0SRobert Mustacchi do { 3944*42cc51e0SRobert Mustacchi usec_delay(1); 3945*42cc51e0SRobert Mustacchi /* Steps */ 3946*42cc51e0SRobert Mustacchi ret_val = e1000_flash_cycle_init_ich8lan(hw); 3947*42cc51e0SRobert Mustacchi if (ret_val != E1000_SUCCESS) 3948*42cc51e0SRobert Mustacchi break; 3949*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, not flash. 3950*42cc51e0SRobert Mustacchi * Therefore, only 32 bit access is supported 3951*42cc51e0SRobert Mustacchi */ 3952*42cc51e0SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16; 3953*42cc51e0SRobert Mustacchi 3954*42cc51e0SRobert Mustacchi /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ 3955*42cc51e0SRobert Mustacchi hsflctl.hsf_ctrl.fldbcount = sizeof(u32) - 1; 3956*42cc51e0SRobert Mustacchi hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; 3957*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, not flash. 3958*42cc51e0SRobert Mustacchi * Therefore, only 32 bit access is supported 3959*42cc51e0SRobert Mustacchi */ 3960*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 3961*42cc51e0SRobert Mustacchi (u32)hsflctl.regval << 16); 3962*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); 3963*42cc51e0SRobert Mustacchi 3964*42cc51e0SRobert Mustacchi ret_val = e1000_flash_cycle_ich8lan(hw, 3965*42cc51e0SRobert Mustacchi ICH_FLASH_READ_COMMAND_TIMEOUT); 3966*42cc51e0SRobert Mustacchi 3967*42cc51e0SRobert Mustacchi /* Check if FCERR is set to 1, if set to 1, clear it 3968*42cc51e0SRobert Mustacchi * and try the whole sequence a few more times, else 3969*42cc51e0SRobert Mustacchi * read in (shift in) the Flash Data0, the order is 3970*42cc51e0SRobert Mustacchi * least significant byte first msb to lsb 3971*42cc51e0SRobert Mustacchi */ 3972*42cc51e0SRobert Mustacchi if (ret_val == E1000_SUCCESS) { 3973*42cc51e0SRobert Mustacchi *data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0); 3974*42cc51e0SRobert Mustacchi break; 3975*42cc51e0SRobert Mustacchi } else { 3976*42cc51e0SRobert Mustacchi /* If we've gotten here, then things are probably 3977*42cc51e0SRobert Mustacchi * completely hosed, but if the error condition is 3978*42cc51e0SRobert Mustacchi * detected, it won't hurt to give it another try... 3979*42cc51e0SRobert Mustacchi * ICH_FLASH_CYCLE_REPEAT_COUNT times. 3980*42cc51e0SRobert Mustacchi */ 3981*42cc51e0SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, 3982*42cc51e0SRobert Mustacchi ICH_FLASH_HSFSTS); 3983*42cc51e0SRobert Mustacchi if (hsfsts.hsf_status.flcerr) { 3984*42cc51e0SRobert Mustacchi /* Repeat for some time before giving up. */ 3985*42cc51e0SRobert Mustacchi continue; 3986*42cc51e0SRobert Mustacchi } else if (!hsfsts.hsf_status.flcdone) { 3987*42cc51e0SRobert Mustacchi DEBUGOUT("Timeout error - flash cycle did not complete.\n"); 3988*42cc51e0SRobert Mustacchi break; 3989*42cc51e0SRobert Mustacchi } 3990*42cc51e0SRobert Mustacchi } 3991*42cc51e0SRobert Mustacchi } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); 3992*42cc51e0SRobert Mustacchi 3993*42cc51e0SRobert Mustacchi return ret_val; 3994*42cc51e0SRobert Mustacchi } 3995c124a83eSRobert Mustacchi 399675eba5b6SRobert Mustacchi /** 399775eba5b6SRobert Mustacchi * e1000_write_nvm_ich8lan - Write word(s) to the NVM 399875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 399975eba5b6SRobert Mustacchi * @offset: The offset (in bytes) of the word(s) to write. 400075eba5b6SRobert Mustacchi * @words: Size of data to write in words 400175eba5b6SRobert Mustacchi * @data: Pointer to the word(s) to write at offset. 400275eba5b6SRobert Mustacchi * 400375eba5b6SRobert Mustacchi * Writes a byte or word to the NVM using the flash access registers. 400475eba5b6SRobert Mustacchi **/ 400575eba5b6SRobert Mustacchi static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, 400675eba5b6SRobert Mustacchi u16 *data) 400775eba5b6SRobert Mustacchi { 400875eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 400975eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 401075eba5b6SRobert Mustacchi u16 i; 401175eba5b6SRobert Mustacchi 401275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_nvm_ich8lan"); 401375eba5b6SRobert Mustacchi 401475eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || 401575eba5b6SRobert Mustacchi (words == 0)) { 401675eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 401775eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 401875eba5b6SRobert Mustacchi } 401975eba5b6SRobert Mustacchi 402075eba5b6SRobert Mustacchi nvm->ops.acquire(hw); 402175eba5b6SRobert Mustacchi 402275eba5b6SRobert Mustacchi for (i = 0; i < words; i++) { 402375eba5b6SRobert Mustacchi dev_spec->shadow_ram[offset+i].modified = TRUE; 402475eba5b6SRobert Mustacchi dev_spec->shadow_ram[offset+i].value = data[i]; 402575eba5b6SRobert Mustacchi } 402675eba5b6SRobert Mustacchi 402775eba5b6SRobert Mustacchi nvm->ops.release(hw); 402875eba5b6SRobert Mustacchi 402975eba5b6SRobert Mustacchi return E1000_SUCCESS; 403075eba5b6SRobert Mustacchi } 403175eba5b6SRobert Mustacchi 403275eba5b6SRobert Mustacchi /** 4033*42cc51e0SRobert Mustacchi * e1000_update_nvm_checksum_spt - Update the checksum for NVM 4034*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 4035*42cc51e0SRobert Mustacchi * 4036*42cc51e0SRobert Mustacchi * The NVM checksum is updated by calling the generic update_nvm_checksum, 4037*42cc51e0SRobert Mustacchi * which writes the checksum to the shadow ram. The changes in the shadow 4038*42cc51e0SRobert Mustacchi * ram are then committed to the EEPROM by processing each bank at a time 4039*42cc51e0SRobert Mustacchi * checking for the modified bit and writing only the pending changes. 4040*42cc51e0SRobert Mustacchi * After a successful commit, the shadow ram is cleared and is ready for 4041*42cc51e0SRobert Mustacchi * future writes. 4042*42cc51e0SRobert Mustacchi **/ 4043*42cc51e0SRobert Mustacchi static s32 e1000_update_nvm_checksum_spt(struct e1000_hw *hw) 4044*42cc51e0SRobert Mustacchi { 4045*42cc51e0SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 4046*42cc51e0SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 4047*42cc51e0SRobert Mustacchi u32 i, act_offset, new_bank_offset, old_bank_offset, bank; 4048*42cc51e0SRobert Mustacchi s32 ret_val; 4049*42cc51e0SRobert Mustacchi u32 dword = 0; 4050*42cc51e0SRobert Mustacchi 4051*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum_spt"); 4052*42cc51e0SRobert Mustacchi 4053*42cc51e0SRobert Mustacchi ret_val = e1000_update_nvm_checksum_generic(hw); 4054*42cc51e0SRobert Mustacchi if (ret_val) 4055*42cc51e0SRobert Mustacchi goto out; 4056*42cc51e0SRobert Mustacchi 4057*42cc51e0SRobert Mustacchi if (nvm->type != e1000_nvm_flash_sw) 4058*42cc51e0SRobert Mustacchi goto out; 4059*42cc51e0SRobert Mustacchi 4060*42cc51e0SRobert Mustacchi nvm->ops.acquire(hw); 4061*42cc51e0SRobert Mustacchi 4062*42cc51e0SRobert Mustacchi /* We're writing to the opposite bank so if we're on bank 1, 4063*42cc51e0SRobert Mustacchi * write to bank 0 etc. We also need to erase the segment that 4064*42cc51e0SRobert Mustacchi * is going to be written 4065*42cc51e0SRobert Mustacchi */ 4066*42cc51e0SRobert Mustacchi ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 4067*42cc51e0SRobert Mustacchi if (ret_val != E1000_SUCCESS) { 4068*42cc51e0SRobert Mustacchi DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); 4069*42cc51e0SRobert Mustacchi bank = 0; 4070*42cc51e0SRobert Mustacchi } 4071*42cc51e0SRobert Mustacchi 4072*42cc51e0SRobert Mustacchi if (bank == 0) { 4073*42cc51e0SRobert Mustacchi new_bank_offset = nvm->flash_bank_size; 4074*42cc51e0SRobert Mustacchi old_bank_offset = 0; 4075*42cc51e0SRobert Mustacchi ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); 4076*42cc51e0SRobert Mustacchi if (ret_val) 4077*42cc51e0SRobert Mustacchi goto release; 4078*42cc51e0SRobert Mustacchi } else { 4079*42cc51e0SRobert Mustacchi old_bank_offset = nvm->flash_bank_size; 4080*42cc51e0SRobert Mustacchi new_bank_offset = 0; 4081*42cc51e0SRobert Mustacchi ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); 4082*42cc51e0SRobert Mustacchi if (ret_val) 4083*42cc51e0SRobert Mustacchi goto release; 4084*42cc51e0SRobert Mustacchi } 4085*42cc51e0SRobert Mustacchi for (i = 0; i < E1000_SHADOW_RAM_WORDS; i += 2) { 4086*42cc51e0SRobert Mustacchi /* Determine whether to write the value stored 4087*42cc51e0SRobert Mustacchi * in the other NVM bank or a modified value stored 4088*42cc51e0SRobert Mustacchi * in the shadow RAM 4089*42cc51e0SRobert Mustacchi */ 4090*42cc51e0SRobert Mustacchi ret_val = e1000_read_flash_dword_ich8lan(hw, 4091*42cc51e0SRobert Mustacchi i + old_bank_offset, 4092*42cc51e0SRobert Mustacchi &dword); 4093*42cc51e0SRobert Mustacchi 4094*42cc51e0SRobert Mustacchi if (dev_spec->shadow_ram[i].modified) { 4095*42cc51e0SRobert Mustacchi dword &= 0xffff0000; 4096*42cc51e0SRobert Mustacchi dword |= (dev_spec->shadow_ram[i].value & 0xffff); 4097*42cc51e0SRobert Mustacchi } 4098*42cc51e0SRobert Mustacchi if (dev_spec->shadow_ram[i + 1].modified) { 4099*42cc51e0SRobert Mustacchi dword &= 0x0000ffff; 4100*42cc51e0SRobert Mustacchi dword |= ((dev_spec->shadow_ram[i + 1].value & 0xffff) 4101*42cc51e0SRobert Mustacchi << 16); 4102*42cc51e0SRobert Mustacchi } 4103*42cc51e0SRobert Mustacchi if (ret_val) 4104*42cc51e0SRobert Mustacchi break; 4105*42cc51e0SRobert Mustacchi 4106*42cc51e0SRobert Mustacchi /* If the word is 0x13, then make sure the signature bits 4107*42cc51e0SRobert Mustacchi * (15:14) are 11b until the commit has completed. 4108*42cc51e0SRobert Mustacchi * This will allow us to write 10b which indicates the 4109*42cc51e0SRobert Mustacchi * signature is valid. We want to do this after the write 4110*42cc51e0SRobert Mustacchi * has completed so that we don't mark the segment valid 4111*42cc51e0SRobert Mustacchi * while the write is still in progress 4112*42cc51e0SRobert Mustacchi */ 4113*42cc51e0SRobert Mustacchi if (i == E1000_ICH_NVM_SIG_WORD - 1) 4114*42cc51e0SRobert Mustacchi dword |= E1000_ICH_NVM_SIG_MASK << 16; 4115*42cc51e0SRobert Mustacchi 4116*42cc51e0SRobert Mustacchi /* Convert offset to bytes. */ 4117*42cc51e0SRobert Mustacchi act_offset = (i + new_bank_offset) << 1; 4118*42cc51e0SRobert Mustacchi 4119*42cc51e0SRobert Mustacchi usec_delay(100); 4120*42cc51e0SRobert Mustacchi 4121*42cc51e0SRobert Mustacchi /* Write the data to the new bank. Offset in words*/ 4122*42cc51e0SRobert Mustacchi act_offset = i + new_bank_offset; 4123*42cc51e0SRobert Mustacchi ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset, 4124*42cc51e0SRobert Mustacchi dword); 4125*42cc51e0SRobert Mustacchi if (ret_val) 4126*42cc51e0SRobert Mustacchi break; 4127*42cc51e0SRobert Mustacchi } 4128*42cc51e0SRobert Mustacchi 4129*42cc51e0SRobert Mustacchi /* Don't bother writing the segment valid bits if sector 4130*42cc51e0SRobert Mustacchi * programming failed. 4131*42cc51e0SRobert Mustacchi */ 4132*42cc51e0SRobert Mustacchi if (ret_val) { 4133*42cc51e0SRobert Mustacchi DEBUGOUT("Flash commit failed.\n"); 4134*42cc51e0SRobert Mustacchi goto release; 4135*42cc51e0SRobert Mustacchi } 4136*42cc51e0SRobert Mustacchi 4137*42cc51e0SRobert Mustacchi /* Finally validate the new segment by setting bit 15:14 4138*42cc51e0SRobert Mustacchi * to 10b in word 0x13 , this can be done without an 4139*42cc51e0SRobert Mustacchi * erase as well since these bits are 11 to start with 4140*42cc51e0SRobert Mustacchi * and we need to change bit 14 to 0b 4141*42cc51e0SRobert Mustacchi */ 4142*42cc51e0SRobert Mustacchi act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; 4143*42cc51e0SRobert Mustacchi 4144*42cc51e0SRobert Mustacchi /*offset in words but we read dword*/ 4145*42cc51e0SRobert Mustacchi --act_offset; 4146*42cc51e0SRobert Mustacchi ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, &dword); 4147*42cc51e0SRobert Mustacchi 4148*42cc51e0SRobert Mustacchi if (ret_val) 4149*42cc51e0SRobert Mustacchi goto release; 4150*42cc51e0SRobert Mustacchi 4151*42cc51e0SRobert Mustacchi dword &= 0xBFFFFFFF; 4152*42cc51e0SRobert Mustacchi ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset, dword); 4153*42cc51e0SRobert Mustacchi 4154*42cc51e0SRobert Mustacchi if (ret_val) 4155*42cc51e0SRobert Mustacchi goto release; 4156*42cc51e0SRobert Mustacchi 4157*42cc51e0SRobert Mustacchi /* And invalidate the previously valid segment by setting 4158*42cc51e0SRobert Mustacchi * its signature word (0x13) high_byte to 0b. This can be 4159*42cc51e0SRobert Mustacchi * done without an erase because flash erase sets all bits 4160*42cc51e0SRobert Mustacchi * to 1's. We can write 1's to 0's without an erase 4161*42cc51e0SRobert Mustacchi */ 4162*42cc51e0SRobert Mustacchi act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; 4163*42cc51e0SRobert Mustacchi 4164*42cc51e0SRobert Mustacchi /* offset in words but we read dword*/ 4165*42cc51e0SRobert Mustacchi act_offset = old_bank_offset + E1000_ICH_NVM_SIG_WORD - 1; 4166*42cc51e0SRobert Mustacchi ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, &dword); 4167*42cc51e0SRobert Mustacchi 4168*42cc51e0SRobert Mustacchi if (ret_val) 4169*42cc51e0SRobert Mustacchi goto release; 4170*42cc51e0SRobert Mustacchi 4171*42cc51e0SRobert Mustacchi dword &= 0x00FFFFFF; 4172*42cc51e0SRobert Mustacchi ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset, dword); 4173*42cc51e0SRobert Mustacchi 4174*42cc51e0SRobert Mustacchi if (ret_val) 4175*42cc51e0SRobert Mustacchi goto release; 4176*42cc51e0SRobert Mustacchi 4177*42cc51e0SRobert Mustacchi /* Great! Everything worked, we can now clear the cached entries. */ 4178*42cc51e0SRobert Mustacchi for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { 4179*42cc51e0SRobert Mustacchi dev_spec->shadow_ram[i].modified = FALSE; 4180*42cc51e0SRobert Mustacchi dev_spec->shadow_ram[i].value = 0xFFFF; 4181*42cc51e0SRobert Mustacchi } 4182*42cc51e0SRobert Mustacchi 4183*42cc51e0SRobert Mustacchi release: 4184*42cc51e0SRobert Mustacchi nvm->ops.release(hw); 4185*42cc51e0SRobert Mustacchi 4186*42cc51e0SRobert Mustacchi /* Reload the EEPROM, or else modifications will not appear 4187*42cc51e0SRobert Mustacchi * until after the next adapter reset. 4188*42cc51e0SRobert Mustacchi */ 4189*42cc51e0SRobert Mustacchi if (!ret_val) { 4190*42cc51e0SRobert Mustacchi nvm->ops.reload(hw); 4191*42cc51e0SRobert Mustacchi msec_delay(10); 4192*42cc51e0SRobert Mustacchi } 4193*42cc51e0SRobert Mustacchi 4194*42cc51e0SRobert Mustacchi out: 4195*42cc51e0SRobert Mustacchi if (ret_val) 4196*42cc51e0SRobert Mustacchi DEBUGOUT1("NVM update error: %d\n", ret_val); 4197*42cc51e0SRobert Mustacchi 4198*42cc51e0SRobert Mustacchi return ret_val; 4199*42cc51e0SRobert Mustacchi } 4200*42cc51e0SRobert Mustacchi 4201*42cc51e0SRobert Mustacchi /** 420275eba5b6SRobert Mustacchi * e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM 420375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 420475eba5b6SRobert Mustacchi * 420575eba5b6SRobert Mustacchi * The NVM checksum is updated by calling the generic update_nvm_checksum, 420675eba5b6SRobert Mustacchi * which writes the checksum to the shadow ram. The changes in the shadow 420775eba5b6SRobert Mustacchi * ram are then committed to the EEPROM by processing each bank at a time 420875eba5b6SRobert Mustacchi * checking for the modified bit and writing only the pending changes. 420975eba5b6SRobert Mustacchi * After a successful commit, the shadow ram is cleared and is ready for 421075eba5b6SRobert Mustacchi * future writes. 421175eba5b6SRobert Mustacchi **/ 421275eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) 421375eba5b6SRobert Mustacchi { 421475eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 421575eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 421675eba5b6SRobert Mustacchi u32 i, act_offset, new_bank_offset, old_bank_offset, bank; 421775eba5b6SRobert Mustacchi s32 ret_val; 4218c124a83eSRobert Mustacchi u16 data = 0; 421975eba5b6SRobert Mustacchi 422075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum_ich8lan"); 422175eba5b6SRobert Mustacchi 422275eba5b6SRobert Mustacchi ret_val = e1000_update_nvm_checksum_generic(hw); 422375eba5b6SRobert Mustacchi if (ret_val) 422475eba5b6SRobert Mustacchi goto out; 422575eba5b6SRobert Mustacchi 422675eba5b6SRobert Mustacchi if (nvm->type != e1000_nvm_flash_sw) 422775eba5b6SRobert Mustacchi goto out; 422875eba5b6SRobert Mustacchi 422975eba5b6SRobert Mustacchi nvm->ops.acquire(hw); 423075eba5b6SRobert Mustacchi 423175eba5b6SRobert Mustacchi /* We're writing to the opposite bank so if we're on bank 1, 423275eba5b6SRobert Mustacchi * write to bank 0 etc. We also need to erase the segment that 423375eba5b6SRobert Mustacchi * is going to be written 423475eba5b6SRobert Mustacchi */ 423575eba5b6SRobert Mustacchi ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 423675eba5b6SRobert Mustacchi if (ret_val != E1000_SUCCESS) { 423775eba5b6SRobert Mustacchi DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); 423875eba5b6SRobert Mustacchi bank = 0; 423975eba5b6SRobert Mustacchi } 424075eba5b6SRobert Mustacchi 424175eba5b6SRobert Mustacchi if (bank == 0) { 424275eba5b6SRobert Mustacchi new_bank_offset = nvm->flash_bank_size; 424375eba5b6SRobert Mustacchi old_bank_offset = 0; 424475eba5b6SRobert Mustacchi ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); 424575eba5b6SRobert Mustacchi if (ret_val) 424675eba5b6SRobert Mustacchi goto release; 424775eba5b6SRobert Mustacchi } else { 424875eba5b6SRobert Mustacchi old_bank_offset = nvm->flash_bank_size; 424975eba5b6SRobert Mustacchi new_bank_offset = 0; 425075eba5b6SRobert Mustacchi ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); 425175eba5b6SRobert Mustacchi if (ret_val) 425275eba5b6SRobert Mustacchi goto release; 425375eba5b6SRobert Mustacchi } 425475eba5b6SRobert Mustacchi for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { 425575eba5b6SRobert Mustacchi if (dev_spec->shadow_ram[i].modified) { 425675eba5b6SRobert Mustacchi data = dev_spec->shadow_ram[i].value; 425775eba5b6SRobert Mustacchi } else { 425875eba5b6SRobert Mustacchi ret_val = e1000_read_flash_word_ich8lan(hw, i + 425975eba5b6SRobert Mustacchi old_bank_offset, 426075eba5b6SRobert Mustacchi &data); 426175eba5b6SRobert Mustacchi if (ret_val) 426275eba5b6SRobert Mustacchi break; 426375eba5b6SRobert Mustacchi } 426475eba5b6SRobert Mustacchi /* If the word is 0x13, then make sure the signature bits 426575eba5b6SRobert Mustacchi * (15:14) are 11b until the commit has completed. 426675eba5b6SRobert Mustacchi * This will allow us to write 10b which indicates the 426775eba5b6SRobert Mustacchi * signature is valid. We want to do this after the write 426875eba5b6SRobert Mustacchi * has completed so that we don't mark the segment valid 426975eba5b6SRobert Mustacchi * while the write is still in progress 427075eba5b6SRobert Mustacchi */ 427175eba5b6SRobert Mustacchi if (i == E1000_ICH_NVM_SIG_WORD) 427275eba5b6SRobert Mustacchi data |= E1000_ICH_NVM_SIG_MASK; 427375eba5b6SRobert Mustacchi 427475eba5b6SRobert Mustacchi /* Convert offset to bytes. */ 427575eba5b6SRobert Mustacchi act_offset = (i + new_bank_offset) << 1; 427675eba5b6SRobert Mustacchi 427775eba5b6SRobert Mustacchi usec_delay(100); 4278c124a83eSRobert Mustacchi 427975eba5b6SRobert Mustacchi /* Write the bytes to the new bank. */ 428075eba5b6SRobert Mustacchi ret_val = e1000_retry_write_flash_byte_ich8lan(hw, 428175eba5b6SRobert Mustacchi act_offset, 428275eba5b6SRobert Mustacchi (u8)data); 428375eba5b6SRobert Mustacchi if (ret_val) 428475eba5b6SRobert Mustacchi break; 428575eba5b6SRobert Mustacchi 428675eba5b6SRobert Mustacchi usec_delay(100); 428775eba5b6SRobert Mustacchi ret_val = e1000_retry_write_flash_byte_ich8lan(hw, 428875eba5b6SRobert Mustacchi act_offset + 1, 428975eba5b6SRobert Mustacchi (u8)(data >> 8)); 429075eba5b6SRobert Mustacchi if (ret_val) 429175eba5b6SRobert Mustacchi break; 429275eba5b6SRobert Mustacchi } 429375eba5b6SRobert Mustacchi 429475eba5b6SRobert Mustacchi /* Don't bother writing the segment valid bits if sector 429575eba5b6SRobert Mustacchi * programming failed. 429675eba5b6SRobert Mustacchi */ 429775eba5b6SRobert Mustacchi if (ret_val) { 429875eba5b6SRobert Mustacchi DEBUGOUT("Flash commit failed.\n"); 429975eba5b6SRobert Mustacchi goto release; 430075eba5b6SRobert Mustacchi } 430175eba5b6SRobert Mustacchi 430275eba5b6SRobert Mustacchi /* Finally validate the new segment by setting bit 15:14 430375eba5b6SRobert Mustacchi * to 10b in word 0x13 , this can be done without an 430475eba5b6SRobert Mustacchi * erase as well since these bits are 11 to start with 430575eba5b6SRobert Mustacchi * and we need to change bit 14 to 0b 430675eba5b6SRobert Mustacchi */ 430775eba5b6SRobert Mustacchi act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; 430875eba5b6SRobert Mustacchi ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); 430975eba5b6SRobert Mustacchi if (ret_val) 431075eba5b6SRobert Mustacchi goto release; 431175eba5b6SRobert Mustacchi 431275eba5b6SRobert Mustacchi data &= 0xBFFF; 4313c124a83eSRobert Mustacchi ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset * 2 + 1, 431475eba5b6SRobert Mustacchi (u8)(data >> 8)); 431575eba5b6SRobert Mustacchi if (ret_val) 431675eba5b6SRobert Mustacchi goto release; 431775eba5b6SRobert Mustacchi 431875eba5b6SRobert Mustacchi /* And invalidate the previously valid segment by setting 431975eba5b6SRobert Mustacchi * its signature word (0x13) high_byte to 0b. This can be 432075eba5b6SRobert Mustacchi * done without an erase because flash erase sets all bits 432175eba5b6SRobert Mustacchi * to 1's. We can write 1's to 0's without an erase 432275eba5b6SRobert Mustacchi */ 432375eba5b6SRobert Mustacchi act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; 4324c124a83eSRobert Mustacchi 432575eba5b6SRobert Mustacchi ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); 4326c124a83eSRobert Mustacchi 432775eba5b6SRobert Mustacchi if (ret_val) 432875eba5b6SRobert Mustacchi goto release; 432975eba5b6SRobert Mustacchi 433075eba5b6SRobert Mustacchi /* Great! Everything worked, we can now clear the cached entries. */ 433175eba5b6SRobert Mustacchi for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { 433275eba5b6SRobert Mustacchi dev_spec->shadow_ram[i].modified = FALSE; 433375eba5b6SRobert Mustacchi dev_spec->shadow_ram[i].value = 0xFFFF; 433475eba5b6SRobert Mustacchi } 433575eba5b6SRobert Mustacchi 433675eba5b6SRobert Mustacchi release: 433775eba5b6SRobert Mustacchi nvm->ops.release(hw); 433875eba5b6SRobert Mustacchi 433975eba5b6SRobert Mustacchi /* Reload the EEPROM, or else modifications will not appear 434075eba5b6SRobert Mustacchi * until after the next adapter reset. 434175eba5b6SRobert Mustacchi */ 434275eba5b6SRobert Mustacchi if (!ret_val) { 434375eba5b6SRobert Mustacchi nvm->ops.reload(hw); 434475eba5b6SRobert Mustacchi msec_delay(10); 434575eba5b6SRobert Mustacchi } 434675eba5b6SRobert Mustacchi 434775eba5b6SRobert Mustacchi out: 434875eba5b6SRobert Mustacchi if (ret_val) 434975eba5b6SRobert Mustacchi DEBUGOUT1("NVM update error: %d\n", ret_val); 435075eba5b6SRobert Mustacchi 435175eba5b6SRobert Mustacchi return ret_val; 435275eba5b6SRobert Mustacchi } 435375eba5b6SRobert Mustacchi 435475eba5b6SRobert Mustacchi /** 435575eba5b6SRobert Mustacchi * e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum 435675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 435775eba5b6SRobert Mustacchi * 435875eba5b6SRobert Mustacchi * Check to see if checksum needs to be fixed by reading bit 6 in word 0x19. 435975eba5b6SRobert Mustacchi * If the bit is 0, that the EEPROM had been modified, but the checksum was not 436075eba5b6SRobert Mustacchi * calculated, in which case we need to calculate the checksum and set bit 6. 436175eba5b6SRobert Mustacchi **/ 436275eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) 436375eba5b6SRobert Mustacchi { 436475eba5b6SRobert Mustacchi s32 ret_val; 436575eba5b6SRobert Mustacchi u16 data; 436675eba5b6SRobert Mustacchi u16 word; 436775eba5b6SRobert Mustacchi u16 valid_csum_mask; 436875eba5b6SRobert Mustacchi 436975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_validate_nvm_checksum_ich8lan"); 437075eba5b6SRobert Mustacchi 437175eba5b6SRobert Mustacchi /* Read NVM and check Invalid Image CSUM bit. If this bit is 0, 437275eba5b6SRobert Mustacchi * the checksum needs to be fixed. This bit is an indication that 437375eba5b6SRobert Mustacchi * the NVM was prepared by OEM software and did not calculate 437475eba5b6SRobert Mustacchi * the checksum...a likely scenario. 437575eba5b6SRobert Mustacchi */ 437675eba5b6SRobert Mustacchi switch (hw->mac.type) { 437775eba5b6SRobert Mustacchi case e1000_pch_lpt: 4378*42cc51e0SRobert Mustacchi case e1000_pch_spt: 437975eba5b6SRobert Mustacchi word = NVM_COMPAT; 438075eba5b6SRobert Mustacchi valid_csum_mask = NVM_COMPAT_VALID_CSUM; 438175eba5b6SRobert Mustacchi break; 438275eba5b6SRobert Mustacchi default: 438375eba5b6SRobert Mustacchi word = NVM_FUTURE_INIT_WORD1; 438475eba5b6SRobert Mustacchi valid_csum_mask = NVM_FUTURE_INIT_WORD1_VALID_CSUM; 438575eba5b6SRobert Mustacchi break; 438675eba5b6SRobert Mustacchi } 438775eba5b6SRobert Mustacchi 438875eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, word, 1, &data); 438975eba5b6SRobert Mustacchi if (ret_val) 439075eba5b6SRobert Mustacchi return ret_val; 439175eba5b6SRobert Mustacchi 439275eba5b6SRobert Mustacchi if (!(data & valid_csum_mask)) { 439375eba5b6SRobert Mustacchi data |= valid_csum_mask; 439475eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.write(hw, word, 1, &data); 439575eba5b6SRobert Mustacchi if (ret_val) 439675eba5b6SRobert Mustacchi return ret_val; 439775eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.update(hw); 439875eba5b6SRobert Mustacchi if (ret_val) 439975eba5b6SRobert Mustacchi return ret_val; 440075eba5b6SRobert Mustacchi } 440175eba5b6SRobert Mustacchi 440275eba5b6SRobert Mustacchi return e1000_validate_nvm_checksum_generic(hw); 440375eba5b6SRobert Mustacchi } 440475eba5b6SRobert Mustacchi 440575eba5b6SRobert Mustacchi /** 440675eba5b6SRobert Mustacchi * e1000_write_flash_data_ich8lan - Writes bytes to the NVM 440775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 440875eba5b6SRobert Mustacchi * @offset: The offset (in bytes) of the byte/word to read. 440975eba5b6SRobert Mustacchi * @size: Size of data to read, 1=byte 2=word 441075eba5b6SRobert Mustacchi * @data: The byte(s) to write to the NVM. 441175eba5b6SRobert Mustacchi * 441275eba5b6SRobert Mustacchi * Writes one/two bytes to the NVM using the flash access registers. 441375eba5b6SRobert Mustacchi **/ 441475eba5b6SRobert Mustacchi static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, 441575eba5b6SRobert Mustacchi u8 size, u16 data) 441675eba5b6SRobert Mustacchi { 441775eba5b6SRobert Mustacchi union ich8_hws_flash_status hsfsts; 441875eba5b6SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 441975eba5b6SRobert Mustacchi u32 flash_linear_addr; 442075eba5b6SRobert Mustacchi u32 flash_data = 0; 442175eba5b6SRobert Mustacchi s32 ret_val; 442275eba5b6SRobert Mustacchi u8 count = 0; 442375eba5b6SRobert Mustacchi 442475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_ich8_data"); 442575eba5b6SRobert Mustacchi 4426*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 4427*42cc51e0SRobert Mustacchi if (size != 4 || offset > ICH_FLASH_LINEAR_ADDR_MASK) 4428*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 4429*42cc51e0SRobert Mustacchi } else { 4430c124a83eSRobert Mustacchi if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) 443175eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 4432*42cc51e0SRobert Mustacchi } 443375eba5b6SRobert Mustacchi 4434c124a83eSRobert Mustacchi flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + 4435c124a83eSRobert Mustacchi hw->nvm.flash_base_addr); 443675eba5b6SRobert Mustacchi 443775eba5b6SRobert Mustacchi do { 443875eba5b6SRobert Mustacchi usec_delay(1); 443975eba5b6SRobert Mustacchi /* Steps */ 444075eba5b6SRobert Mustacchi ret_val = e1000_flash_cycle_init_ich8lan(hw); 444175eba5b6SRobert Mustacchi if (ret_val != E1000_SUCCESS) 444275eba5b6SRobert Mustacchi break; 4443*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, not 4444*42cc51e0SRobert Mustacchi * flash. Therefore, only 32 bit access is supported 4445*42cc51e0SRobert Mustacchi */ 4446*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4447*42cc51e0SRobert Mustacchi hsflctl.regval = 4448*42cc51e0SRobert Mustacchi E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16; 4449*42cc51e0SRobert Mustacchi else 4450*42cc51e0SRobert Mustacchi hsflctl.regval = 4451*42cc51e0SRobert Mustacchi E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); 4452c124a83eSRobert Mustacchi 445375eba5b6SRobert Mustacchi /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ 445475eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.fldbcount = size - 1; 445575eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; 4456*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, 4457*42cc51e0SRobert Mustacchi * not flash. Therefore, only 32 bit access is 4458*42cc51e0SRobert Mustacchi * supported 4459*42cc51e0SRobert Mustacchi */ 4460*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4461*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 4462*42cc51e0SRobert Mustacchi hsflctl.regval << 16); 4463*42cc51e0SRobert Mustacchi else 4464*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, 4465*42cc51e0SRobert Mustacchi hsflctl.regval); 446675eba5b6SRobert Mustacchi 446775eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); 446875eba5b6SRobert Mustacchi 446975eba5b6SRobert Mustacchi if (size == 1) 447075eba5b6SRobert Mustacchi flash_data = (u32)data & 0x00FF; 447175eba5b6SRobert Mustacchi else 447275eba5b6SRobert Mustacchi flash_data = (u32)data; 447375eba5b6SRobert Mustacchi 447475eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FDATA0, flash_data); 447575eba5b6SRobert Mustacchi 447675eba5b6SRobert Mustacchi /* check if FCERR is set to 1 , if set to 1, clear it 447775eba5b6SRobert Mustacchi * and try the whole sequence a few more times else done 447875eba5b6SRobert Mustacchi */ 4479c124a83eSRobert Mustacchi ret_val = 4480c124a83eSRobert Mustacchi e1000_flash_cycle_ich8lan(hw, 448175eba5b6SRobert Mustacchi ICH_FLASH_WRITE_COMMAND_TIMEOUT); 448275eba5b6SRobert Mustacchi if (ret_val == E1000_SUCCESS) 448375eba5b6SRobert Mustacchi break; 448475eba5b6SRobert Mustacchi 448575eba5b6SRobert Mustacchi /* If we're here, then things are most likely 448675eba5b6SRobert Mustacchi * completely hosed, but if the error condition 448775eba5b6SRobert Mustacchi * is detected, it won't hurt to give it another 448875eba5b6SRobert Mustacchi * try...ICH_FLASH_CYCLE_REPEAT_COUNT times. 448975eba5b6SRobert Mustacchi */ 449075eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); 449175eba5b6SRobert Mustacchi if (hsfsts.hsf_status.flcerr) 449275eba5b6SRobert Mustacchi /* Repeat for some time before giving up. */ 449375eba5b6SRobert Mustacchi continue; 449475eba5b6SRobert Mustacchi if (!hsfsts.hsf_status.flcdone) { 449575eba5b6SRobert Mustacchi DEBUGOUT("Timeout error - flash cycle did not complete.\n"); 449675eba5b6SRobert Mustacchi break; 449775eba5b6SRobert Mustacchi } 449875eba5b6SRobert Mustacchi } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); 449975eba5b6SRobert Mustacchi 450075eba5b6SRobert Mustacchi return ret_val; 450175eba5b6SRobert Mustacchi } 450275eba5b6SRobert Mustacchi 4503*42cc51e0SRobert Mustacchi /** 4504*42cc51e0SRobert Mustacchi * e1000_write_flash_data32_ich8lan - Writes 4 bytes to the NVM 4505*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 4506*42cc51e0SRobert Mustacchi * @offset: The offset (in bytes) of the dwords to read. 4507*42cc51e0SRobert Mustacchi * @data: The 4 bytes to write to the NVM. 4508*42cc51e0SRobert Mustacchi * 4509*42cc51e0SRobert Mustacchi * Writes one/two/four bytes to the NVM using the flash access registers. 4510*42cc51e0SRobert Mustacchi **/ 4511*42cc51e0SRobert Mustacchi static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset, 4512*42cc51e0SRobert Mustacchi u32 data) 4513*42cc51e0SRobert Mustacchi { 4514*42cc51e0SRobert Mustacchi union ich8_hws_flash_status hsfsts; 4515*42cc51e0SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 4516*42cc51e0SRobert Mustacchi u32 flash_linear_addr; 4517*42cc51e0SRobert Mustacchi s32 ret_val; 4518*42cc51e0SRobert Mustacchi u8 count = 0; 4519*42cc51e0SRobert Mustacchi 4520*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_write_flash_data32_ich8lan"); 4521*42cc51e0SRobert Mustacchi 4522*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) { 4523*42cc51e0SRobert Mustacchi if (offset > ICH_FLASH_LINEAR_ADDR_MASK) 4524*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 4525*42cc51e0SRobert Mustacchi } 4526*42cc51e0SRobert Mustacchi flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + 4527*42cc51e0SRobert Mustacchi hw->nvm.flash_base_addr); 4528*42cc51e0SRobert Mustacchi do { 4529*42cc51e0SRobert Mustacchi usec_delay(1); 4530*42cc51e0SRobert Mustacchi /* Steps */ 4531*42cc51e0SRobert Mustacchi ret_val = e1000_flash_cycle_init_ich8lan(hw); 4532*42cc51e0SRobert Mustacchi if (ret_val != E1000_SUCCESS) 4533*42cc51e0SRobert Mustacchi break; 4534*42cc51e0SRobert Mustacchi 4535*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, not 4536*42cc51e0SRobert Mustacchi * flash. Therefore, only 32 bit access is supported 4537*42cc51e0SRobert Mustacchi */ 4538*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4539*42cc51e0SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG(hw, 4540*42cc51e0SRobert Mustacchi ICH_FLASH_HSFSTS) 4541*42cc51e0SRobert Mustacchi >> 16; 4542*42cc51e0SRobert Mustacchi else 4543*42cc51e0SRobert Mustacchi hsflctl.regval = E1000_READ_FLASH_REG16(hw, 4544*42cc51e0SRobert Mustacchi ICH_FLASH_HSFCTL); 4545*42cc51e0SRobert Mustacchi 4546*42cc51e0SRobert Mustacchi hsflctl.hsf_ctrl.fldbcount = sizeof(u32) - 1; 4547*42cc51e0SRobert Mustacchi hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; 4548*42cc51e0SRobert Mustacchi 4549*42cc51e0SRobert Mustacchi /* In SPT, This register is in Lan memory space, 4550*42cc51e0SRobert Mustacchi * not flash. Therefore, only 32 bit access is 4551*42cc51e0SRobert Mustacchi * supported 4552*42cc51e0SRobert Mustacchi */ 4553*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4554*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 4555*42cc51e0SRobert Mustacchi hsflctl.regval << 16); 4556*42cc51e0SRobert Mustacchi else 4557*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, 4558*42cc51e0SRobert Mustacchi hsflctl.regval); 4559*42cc51e0SRobert Mustacchi 4560*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); 4561*42cc51e0SRobert Mustacchi 4562*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FDATA0, data); 4563*42cc51e0SRobert Mustacchi 4564*42cc51e0SRobert Mustacchi /* check if FCERR is set to 1 , if set to 1, clear it 4565*42cc51e0SRobert Mustacchi * and try the whole sequence a few more times else done 4566*42cc51e0SRobert Mustacchi */ 4567*42cc51e0SRobert Mustacchi ret_val = e1000_flash_cycle_ich8lan(hw, 4568*42cc51e0SRobert Mustacchi ICH_FLASH_WRITE_COMMAND_TIMEOUT); 4569*42cc51e0SRobert Mustacchi 4570*42cc51e0SRobert Mustacchi if (ret_val == E1000_SUCCESS) 4571*42cc51e0SRobert Mustacchi break; 4572*42cc51e0SRobert Mustacchi 4573*42cc51e0SRobert Mustacchi /* If we're here, then things are most likely 4574*42cc51e0SRobert Mustacchi * completely hosed, but if the error condition 4575*42cc51e0SRobert Mustacchi * is detected, it won't hurt to give it another 4576*42cc51e0SRobert Mustacchi * try...ICH_FLASH_CYCLE_REPEAT_COUNT times. 4577*42cc51e0SRobert Mustacchi */ 4578*42cc51e0SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); 4579*42cc51e0SRobert Mustacchi 4580*42cc51e0SRobert Mustacchi if (hsfsts.hsf_status.flcerr) 4581*42cc51e0SRobert Mustacchi /* Repeat for some time before giving up. */ 4582*42cc51e0SRobert Mustacchi continue; 4583*42cc51e0SRobert Mustacchi if (!hsfsts.hsf_status.flcdone) { 4584*42cc51e0SRobert Mustacchi DEBUGOUT("Timeout error - flash cycle did not complete.\n"); 4585*42cc51e0SRobert Mustacchi break; 4586*42cc51e0SRobert Mustacchi } 4587*42cc51e0SRobert Mustacchi } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); 4588*42cc51e0SRobert Mustacchi 4589*42cc51e0SRobert Mustacchi return ret_val; 4590*42cc51e0SRobert Mustacchi } 4591c124a83eSRobert Mustacchi 459275eba5b6SRobert Mustacchi /** 459375eba5b6SRobert Mustacchi * e1000_write_flash_byte_ich8lan - Write a single byte to NVM 459475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 459575eba5b6SRobert Mustacchi * @offset: The index of the byte to read. 459675eba5b6SRobert Mustacchi * @data: The byte to write to the NVM. 459775eba5b6SRobert Mustacchi * 459875eba5b6SRobert Mustacchi * Writes a single byte to the NVM using the flash access registers. 459975eba5b6SRobert Mustacchi **/ 460075eba5b6SRobert Mustacchi static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, 460175eba5b6SRobert Mustacchi u8 data) 460275eba5b6SRobert Mustacchi { 460375eba5b6SRobert Mustacchi u16 word = (u16)data; 460475eba5b6SRobert Mustacchi 460575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_flash_byte_ich8lan"); 460675eba5b6SRobert Mustacchi 460775eba5b6SRobert Mustacchi return e1000_write_flash_data_ich8lan(hw, offset, 1, word); 460875eba5b6SRobert Mustacchi } 460975eba5b6SRobert Mustacchi 4610*42cc51e0SRobert Mustacchi /** 4611*42cc51e0SRobert Mustacchi * e1000_retry_write_flash_dword_ich8lan - Writes a dword to NVM 4612*42cc51e0SRobert Mustacchi * @hw: pointer to the HW structure 4613*42cc51e0SRobert Mustacchi * @offset: The offset of the word to write. 4614*42cc51e0SRobert Mustacchi * @dword: The dword to write to the NVM. 4615*42cc51e0SRobert Mustacchi * 4616*42cc51e0SRobert Mustacchi * Writes a single dword to the NVM using the flash access registers. 4617*42cc51e0SRobert Mustacchi * Goes through a retry algorithm before giving up. 4618*42cc51e0SRobert Mustacchi **/ 4619*42cc51e0SRobert Mustacchi static s32 e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw, 4620*42cc51e0SRobert Mustacchi u32 offset, u32 dword) 4621*42cc51e0SRobert Mustacchi { 4622*42cc51e0SRobert Mustacchi s32 ret_val; 4623*42cc51e0SRobert Mustacchi u16 program_retries; 4624c124a83eSRobert Mustacchi 4625*42cc51e0SRobert Mustacchi DEBUGFUNC("e1000_retry_write_flash_dword_ich8lan"); 4626*42cc51e0SRobert Mustacchi 4627*42cc51e0SRobert Mustacchi /* Must convert word offset into bytes. */ 4628*42cc51e0SRobert Mustacchi offset <<= 1; 4629*42cc51e0SRobert Mustacchi 4630*42cc51e0SRobert Mustacchi ret_val = e1000_write_flash_data32_ich8lan(hw, offset, dword); 4631*42cc51e0SRobert Mustacchi 4632*42cc51e0SRobert Mustacchi if (!ret_val) 4633*42cc51e0SRobert Mustacchi return ret_val; 4634*42cc51e0SRobert Mustacchi for (program_retries = 0; program_retries < 100; program_retries++) { 4635*42cc51e0SRobert Mustacchi DEBUGOUT2("Retrying Byte %8.8X at offset %u\n", dword, offset); 4636*42cc51e0SRobert Mustacchi usec_delay(100); 4637*42cc51e0SRobert Mustacchi ret_val = e1000_write_flash_data32_ich8lan(hw, offset, dword); 4638*42cc51e0SRobert Mustacchi if (ret_val == E1000_SUCCESS) 4639*42cc51e0SRobert Mustacchi break; 4640*42cc51e0SRobert Mustacchi } 4641*42cc51e0SRobert Mustacchi if (program_retries == 100) 4642*42cc51e0SRobert Mustacchi return -E1000_ERR_NVM; 4643*42cc51e0SRobert Mustacchi 4644*42cc51e0SRobert Mustacchi return E1000_SUCCESS; 4645*42cc51e0SRobert Mustacchi } 4646c124a83eSRobert Mustacchi 464775eba5b6SRobert Mustacchi /** 464875eba5b6SRobert Mustacchi * e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM 464975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 465075eba5b6SRobert Mustacchi * @offset: The offset of the byte to write. 465175eba5b6SRobert Mustacchi * @byte: The byte to write to the NVM. 465275eba5b6SRobert Mustacchi * 465375eba5b6SRobert Mustacchi * Writes a single byte to the NVM using the flash access registers. 465475eba5b6SRobert Mustacchi * Goes through a retry algorithm before giving up. 465575eba5b6SRobert Mustacchi **/ 465675eba5b6SRobert Mustacchi static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, 465775eba5b6SRobert Mustacchi u32 offset, u8 byte) 465875eba5b6SRobert Mustacchi { 465975eba5b6SRobert Mustacchi s32 ret_val; 466075eba5b6SRobert Mustacchi u16 program_retries; 466175eba5b6SRobert Mustacchi 466275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_retry_write_flash_byte_ich8lan"); 466375eba5b6SRobert Mustacchi 466475eba5b6SRobert Mustacchi ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); 466575eba5b6SRobert Mustacchi if (!ret_val) 466675eba5b6SRobert Mustacchi return ret_val; 466775eba5b6SRobert Mustacchi 466875eba5b6SRobert Mustacchi for (program_retries = 0; program_retries < 100; program_retries++) { 466975eba5b6SRobert Mustacchi DEBUGOUT2("Retrying Byte %2.2X at offset %u\n", byte, offset); 467075eba5b6SRobert Mustacchi usec_delay(100); 467175eba5b6SRobert Mustacchi ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); 467275eba5b6SRobert Mustacchi if (ret_val == E1000_SUCCESS) 467375eba5b6SRobert Mustacchi break; 467475eba5b6SRobert Mustacchi } 467575eba5b6SRobert Mustacchi if (program_retries == 100) 467675eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 467775eba5b6SRobert Mustacchi 467875eba5b6SRobert Mustacchi return E1000_SUCCESS; 467975eba5b6SRobert Mustacchi } 468075eba5b6SRobert Mustacchi 468175eba5b6SRobert Mustacchi /** 468275eba5b6SRobert Mustacchi * e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM 468375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 468475eba5b6SRobert Mustacchi * @bank: 0 for first bank, 1 for second bank, etc. 468575eba5b6SRobert Mustacchi * 468675eba5b6SRobert Mustacchi * Erases the bank specified. Each bank is a 4k block. Banks are 0 based. 468775eba5b6SRobert Mustacchi * bank N is 4096 * N + flash_reg_addr. 468875eba5b6SRobert Mustacchi **/ 468975eba5b6SRobert Mustacchi static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) 469075eba5b6SRobert Mustacchi { 469175eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 469275eba5b6SRobert Mustacchi union ich8_hws_flash_status hsfsts; 469375eba5b6SRobert Mustacchi union ich8_hws_flash_ctrl hsflctl; 469475eba5b6SRobert Mustacchi u32 flash_linear_addr; 469575eba5b6SRobert Mustacchi /* bank size is in 16bit words - adjust to bytes */ 469675eba5b6SRobert Mustacchi u32 flash_bank_size = nvm->flash_bank_size * 2; 469775eba5b6SRobert Mustacchi s32 ret_val; 469875eba5b6SRobert Mustacchi s32 count = 0; 469975eba5b6SRobert Mustacchi s32 j, iteration, sector_size; 470075eba5b6SRobert Mustacchi 470175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_erase_flash_bank_ich8lan"); 470275eba5b6SRobert Mustacchi 470375eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); 470475eba5b6SRobert Mustacchi 470575eba5b6SRobert Mustacchi /* Determine HW Sector size: Read BERASE bits of hw flash status 470675eba5b6SRobert Mustacchi * register 470775eba5b6SRobert Mustacchi * 00: The Hw sector is 256 bytes, hence we need to erase 16 470875eba5b6SRobert Mustacchi * consecutive sectors. The start index for the nth Hw sector 470975eba5b6SRobert Mustacchi * can be calculated as = bank * 4096 + n * 256 471075eba5b6SRobert Mustacchi * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector. 471175eba5b6SRobert Mustacchi * The start index for the nth Hw sector can be calculated 471275eba5b6SRobert Mustacchi * as = bank * 4096 471375eba5b6SRobert Mustacchi * 10: The Hw sector is 8K bytes, nth sector = bank * 8192 471475eba5b6SRobert Mustacchi * (ich9 only, otherwise error condition) 471575eba5b6SRobert Mustacchi * 11: The Hw sector is 64K bytes, nth sector = bank * 65536 471675eba5b6SRobert Mustacchi */ 471775eba5b6SRobert Mustacchi switch (hsfsts.hsf_status.berasesz) { 471875eba5b6SRobert Mustacchi case 0: 471975eba5b6SRobert Mustacchi /* Hw sector size 256 */ 472075eba5b6SRobert Mustacchi sector_size = ICH_FLASH_SEG_SIZE_256; 472175eba5b6SRobert Mustacchi iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256; 472275eba5b6SRobert Mustacchi break; 472375eba5b6SRobert Mustacchi case 1: 472475eba5b6SRobert Mustacchi sector_size = ICH_FLASH_SEG_SIZE_4K; 472575eba5b6SRobert Mustacchi iteration = 1; 472675eba5b6SRobert Mustacchi break; 472775eba5b6SRobert Mustacchi case 2: 472875eba5b6SRobert Mustacchi sector_size = ICH_FLASH_SEG_SIZE_8K; 472975eba5b6SRobert Mustacchi iteration = 1; 473075eba5b6SRobert Mustacchi break; 473175eba5b6SRobert Mustacchi case 3: 473275eba5b6SRobert Mustacchi sector_size = ICH_FLASH_SEG_SIZE_64K; 473375eba5b6SRobert Mustacchi iteration = 1; 473475eba5b6SRobert Mustacchi break; 473575eba5b6SRobert Mustacchi default: 473675eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 473775eba5b6SRobert Mustacchi } 473875eba5b6SRobert Mustacchi 473975eba5b6SRobert Mustacchi /* Start with the base address, then add the sector offset. */ 474075eba5b6SRobert Mustacchi flash_linear_addr = hw->nvm.flash_base_addr; 474175eba5b6SRobert Mustacchi flash_linear_addr += (bank) ? flash_bank_size : 0; 474275eba5b6SRobert Mustacchi 474375eba5b6SRobert Mustacchi for (j = 0; j < iteration; j++) { 474475eba5b6SRobert Mustacchi do { 4745c124a83eSRobert Mustacchi u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT; 4746c124a83eSRobert Mustacchi 474775eba5b6SRobert Mustacchi /* Steps */ 474875eba5b6SRobert Mustacchi ret_val = e1000_flash_cycle_init_ich8lan(hw); 474975eba5b6SRobert Mustacchi if (ret_val) 475075eba5b6SRobert Mustacchi return ret_val; 475175eba5b6SRobert Mustacchi 475275eba5b6SRobert Mustacchi /* Write a value 11 (block Erase) in Flash 475375eba5b6SRobert Mustacchi * Cycle field in hw flash control 475475eba5b6SRobert Mustacchi */ 4755*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4756c124a83eSRobert Mustacchi hsflctl.regval = 4757*42cc51e0SRobert Mustacchi E1000_READ_FLASH_REG(hw, 4758*42cc51e0SRobert Mustacchi ICH_FLASH_HSFSTS)>>16; 4759*42cc51e0SRobert Mustacchi else 4760*42cc51e0SRobert Mustacchi hsflctl.regval = 4761*42cc51e0SRobert Mustacchi E1000_READ_FLASH_REG16(hw, 4762*42cc51e0SRobert Mustacchi ICH_FLASH_HSFCTL); 4763c124a83eSRobert Mustacchi 476475eba5b6SRobert Mustacchi hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; 4765*42cc51e0SRobert Mustacchi if (hw->mac.type == e1000_pch_spt) 4766*42cc51e0SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS, 4767*42cc51e0SRobert Mustacchi hsflctl.regval << 16); 4768*42cc51e0SRobert Mustacchi else 476975eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, 477075eba5b6SRobert Mustacchi hsflctl.regval); 477175eba5b6SRobert Mustacchi 477275eba5b6SRobert Mustacchi /* Write the last 24 bits of an index within the 477375eba5b6SRobert Mustacchi * block into Flash Linear address field in Flash 477475eba5b6SRobert Mustacchi * Address. 477575eba5b6SRobert Mustacchi */ 477675eba5b6SRobert Mustacchi flash_linear_addr += (j * sector_size); 477775eba5b6SRobert Mustacchi E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, 477875eba5b6SRobert Mustacchi flash_linear_addr); 477975eba5b6SRobert Mustacchi 4780c124a83eSRobert Mustacchi ret_val = e1000_flash_cycle_ich8lan(hw, timeout); 478175eba5b6SRobert Mustacchi if (ret_val == E1000_SUCCESS) 478275eba5b6SRobert Mustacchi break; 478375eba5b6SRobert Mustacchi 478475eba5b6SRobert Mustacchi /* Check if FCERR is set to 1. If 1, 478575eba5b6SRobert Mustacchi * clear it and try the whole sequence 478675eba5b6SRobert Mustacchi * a few more times else Done 478775eba5b6SRobert Mustacchi */ 478875eba5b6SRobert Mustacchi hsfsts.regval = E1000_READ_FLASH_REG16(hw, 478975eba5b6SRobert Mustacchi ICH_FLASH_HSFSTS); 479075eba5b6SRobert Mustacchi if (hsfsts.hsf_status.flcerr) 479175eba5b6SRobert Mustacchi /* repeat for some time before giving up */ 479275eba5b6SRobert Mustacchi continue; 479375eba5b6SRobert Mustacchi else if (!hsfsts.hsf_status.flcdone) 479475eba5b6SRobert Mustacchi return ret_val; 479575eba5b6SRobert Mustacchi } while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT); 479675eba5b6SRobert Mustacchi } 479775eba5b6SRobert Mustacchi 479875eba5b6SRobert Mustacchi return E1000_SUCCESS; 479975eba5b6SRobert Mustacchi } 480075eba5b6SRobert Mustacchi 480175eba5b6SRobert Mustacchi /** 480275eba5b6SRobert Mustacchi * e1000_valid_led_default_ich8lan - Set the default LED settings 480375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 480475eba5b6SRobert Mustacchi * @data: Pointer to the LED settings 480575eba5b6SRobert Mustacchi * 480675eba5b6SRobert Mustacchi * Reads the LED default settings from the NVM to data. If the NVM LED 480775eba5b6SRobert Mustacchi * settings is all 0's or F's, set the LED default to a valid LED default 480875eba5b6SRobert Mustacchi * setting. 480975eba5b6SRobert Mustacchi **/ 481075eba5b6SRobert Mustacchi static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) 481175eba5b6SRobert Mustacchi { 481275eba5b6SRobert Mustacchi s32 ret_val; 481375eba5b6SRobert Mustacchi 481475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_valid_led_default_ich8lan"); 481575eba5b6SRobert Mustacchi 481675eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); 481775eba5b6SRobert Mustacchi if (ret_val) { 481875eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 481975eba5b6SRobert Mustacchi return ret_val; 482075eba5b6SRobert Mustacchi } 482175eba5b6SRobert Mustacchi 482275eba5b6SRobert Mustacchi if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) 482375eba5b6SRobert Mustacchi *data = ID_LED_DEFAULT_ICH8LAN; 482475eba5b6SRobert Mustacchi 482575eba5b6SRobert Mustacchi return E1000_SUCCESS; 482675eba5b6SRobert Mustacchi } 482775eba5b6SRobert Mustacchi 482875eba5b6SRobert Mustacchi /** 482975eba5b6SRobert Mustacchi * e1000_id_led_init_pchlan - store LED configurations 483075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 483175eba5b6SRobert Mustacchi * 483275eba5b6SRobert Mustacchi * PCH does not control LEDs via the LEDCTL register, rather it uses 483375eba5b6SRobert Mustacchi * the PHY LED configuration register. 483475eba5b6SRobert Mustacchi * 483575eba5b6SRobert Mustacchi * PCH also does not have an "always on" or "always off" mode which 483675eba5b6SRobert Mustacchi * complicates the ID feature. Instead of using the "on" mode to indicate 483775eba5b6SRobert Mustacchi * in ledctl_mode2 the LEDs to use for ID (see e1000_id_led_init_generic()), 483875eba5b6SRobert Mustacchi * use "link_up" mode. The LEDs will still ID on request if there is no 483975eba5b6SRobert Mustacchi * link based on logic in e1000_led_[on|off]_pchlan(). 484075eba5b6SRobert Mustacchi **/ 484175eba5b6SRobert Mustacchi static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) 484275eba5b6SRobert Mustacchi { 484375eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 484475eba5b6SRobert Mustacchi s32 ret_val; 484575eba5b6SRobert Mustacchi const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP; 484675eba5b6SRobert Mustacchi const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT; 484775eba5b6SRobert Mustacchi u16 data, i, temp, shift; 484875eba5b6SRobert Mustacchi 484975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_id_led_init_pchlan"); 485075eba5b6SRobert Mustacchi 485175eba5b6SRobert Mustacchi /* Get default ID LED modes */ 485275eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.valid_led_default(hw, &data); 485375eba5b6SRobert Mustacchi if (ret_val) 485475eba5b6SRobert Mustacchi return ret_val; 485575eba5b6SRobert Mustacchi 485675eba5b6SRobert Mustacchi mac->ledctl_default = E1000_READ_REG(hw, E1000_LEDCTL); 485775eba5b6SRobert Mustacchi mac->ledctl_mode1 = mac->ledctl_default; 485875eba5b6SRobert Mustacchi mac->ledctl_mode2 = mac->ledctl_default; 485975eba5b6SRobert Mustacchi 486075eba5b6SRobert Mustacchi for (i = 0; i < 4; i++) { 486175eba5b6SRobert Mustacchi temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK; 486275eba5b6SRobert Mustacchi shift = (i * 5); 486375eba5b6SRobert Mustacchi switch (temp) { 486475eba5b6SRobert Mustacchi case ID_LED_ON1_DEF2: 486575eba5b6SRobert Mustacchi case ID_LED_ON1_ON2: 486675eba5b6SRobert Mustacchi case ID_LED_ON1_OFF2: 486775eba5b6SRobert Mustacchi mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift); 486875eba5b6SRobert Mustacchi mac->ledctl_mode1 |= (ledctl_on << shift); 486975eba5b6SRobert Mustacchi break; 487075eba5b6SRobert Mustacchi case ID_LED_OFF1_DEF2: 487175eba5b6SRobert Mustacchi case ID_LED_OFF1_ON2: 487275eba5b6SRobert Mustacchi case ID_LED_OFF1_OFF2: 487375eba5b6SRobert Mustacchi mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift); 487475eba5b6SRobert Mustacchi mac->ledctl_mode1 |= (ledctl_off << shift); 487575eba5b6SRobert Mustacchi break; 487675eba5b6SRobert Mustacchi default: 487775eba5b6SRobert Mustacchi /* Do nothing */ 487875eba5b6SRobert Mustacchi break; 487975eba5b6SRobert Mustacchi } 488075eba5b6SRobert Mustacchi switch (temp) { 488175eba5b6SRobert Mustacchi case ID_LED_DEF1_ON2: 488275eba5b6SRobert Mustacchi case ID_LED_ON1_ON2: 488375eba5b6SRobert Mustacchi case ID_LED_OFF1_ON2: 488475eba5b6SRobert Mustacchi mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift); 488575eba5b6SRobert Mustacchi mac->ledctl_mode2 |= (ledctl_on << shift); 488675eba5b6SRobert Mustacchi break; 488775eba5b6SRobert Mustacchi case ID_LED_DEF1_OFF2: 488875eba5b6SRobert Mustacchi case ID_LED_ON1_OFF2: 488975eba5b6SRobert Mustacchi case ID_LED_OFF1_OFF2: 489075eba5b6SRobert Mustacchi mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift); 489175eba5b6SRobert Mustacchi mac->ledctl_mode2 |= (ledctl_off << shift); 489275eba5b6SRobert Mustacchi break; 489375eba5b6SRobert Mustacchi default: 489475eba5b6SRobert Mustacchi /* Do nothing */ 489575eba5b6SRobert Mustacchi break; 489675eba5b6SRobert Mustacchi } 489775eba5b6SRobert Mustacchi } 489875eba5b6SRobert Mustacchi 489975eba5b6SRobert Mustacchi return E1000_SUCCESS; 490075eba5b6SRobert Mustacchi } 490175eba5b6SRobert Mustacchi 490275eba5b6SRobert Mustacchi /** 490375eba5b6SRobert Mustacchi * e1000_get_bus_info_ich8lan - Get/Set the bus type and width 490475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 490575eba5b6SRobert Mustacchi * 490675eba5b6SRobert Mustacchi * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability 490775eba5b6SRobert Mustacchi * register, so the the bus width is hard coded. 490875eba5b6SRobert Mustacchi **/ 490975eba5b6SRobert Mustacchi static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) 491075eba5b6SRobert Mustacchi { 491175eba5b6SRobert Mustacchi struct e1000_bus_info *bus = &hw->bus; 491275eba5b6SRobert Mustacchi s32 ret_val; 491375eba5b6SRobert Mustacchi 491475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_bus_info_ich8lan"); 491575eba5b6SRobert Mustacchi 491675eba5b6SRobert Mustacchi ret_val = e1000_get_bus_info_pcie_generic(hw); 491775eba5b6SRobert Mustacchi 491875eba5b6SRobert Mustacchi /* ICH devices are "PCI Express"-ish. They have 491975eba5b6SRobert Mustacchi * a configuration space, but do not contain 492075eba5b6SRobert Mustacchi * PCI Express Capability registers, so bus width 492175eba5b6SRobert Mustacchi * must be hardcoded. 492275eba5b6SRobert Mustacchi */ 492375eba5b6SRobert Mustacchi if (bus->width == e1000_bus_width_unknown) 492475eba5b6SRobert Mustacchi bus->width = e1000_bus_width_pcie_x1; 492575eba5b6SRobert Mustacchi 492675eba5b6SRobert Mustacchi return ret_val; 492775eba5b6SRobert Mustacchi } 492875eba5b6SRobert Mustacchi 492975eba5b6SRobert Mustacchi /** 493075eba5b6SRobert Mustacchi * e1000_reset_hw_ich8lan - Reset the hardware 493175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 493275eba5b6SRobert Mustacchi * 493375eba5b6SRobert Mustacchi * Does a full reset of the hardware which includes a reset of the PHY and 493475eba5b6SRobert Mustacchi * MAC. 493575eba5b6SRobert Mustacchi **/ 493675eba5b6SRobert Mustacchi static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) 493775eba5b6SRobert Mustacchi { 493875eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 493975eba5b6SRobert Mustacchi u16 kum_cfg; 494075eba5b6SRobert Mustacchi u32 ctrl, reg; 494175eba5b6SRobert Mustacchi s32 ret_val; 494275eba5b6SRobert Mustacchi 494375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_reset_hw_ich8lan"); 494475eba5b6SRobert Mustacchi 494575eba5b6SRobert Mustacchi /* Prevent the PCI-E bus from sticking if there is no TLP connection 494675eba5b6SRobert Mustacchi * on the last TLP read/write transaction when MAC is reset. 494775eba5b6SRobert Mustacchi */ 494875eba5b6SRobert Mustacchi ret_val = e1000_disable_pcie_master_generic(hw); 494975eba5b6SRobert Mustacchi if (ret_val) 495075eba5b6SRobert Mustacchi DEBUGOUT("PCI-E Master disable polling has failed.\n"); 495175eba5b6SRobert Mustacchi 495275eba5b6SRobert Mustacchi DEBUGOUT("Masking off all interrupts\n"); 495375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 495475eba5b6SRobert Mustacchi 495575eba5b6SRobert Mustacchi /* Disable the Transmit and Receive units. Then delay to allow 495675eba5b6SRobert Mustacchi * any pending transactions to complete before we hit the MAC 495775eba5b6SRobert Mustacchi * with the global reset. 495875eba5b6SRobert Mustacchi */ 495975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, 0); 496075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); 496175eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 496275eba5b6SRobert Mustacchi 496375eba5b6SRobert Mustacchi msec_delay(10); 496475eba5b6SRobert Mustacchi 496575eba5b6SRobert Mustacchi /* Workaround for ICH8 bit corruption issue in FIFO memory */ 496675eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) { 496775eba5b6SRobert Mustacchi /* Set Tx and Rx buffer allocation to 8k apiece. */ 496875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PBA, E1000_PBA_8K); 496975eba5b6SRobert Mustacchi /* Set Packet Buffer Size to 16k. */ 497075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PBS, E1000_PBS_16K); 497175eba5b6SRobert Mustacchi } 497275eba5b6SRobert Mustacchi 497375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pchlan) { 497475eba5b6SRobert Mustacchi /* Save the NVM K1 bit setting*/ 497575eba5b6SRobert Mustacchi ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &kum_cfg); 497675eba5b6SRobert Mustacchi if (ret_val) 497775eba5b6SRobert Mustacchi return ret_val; 497875eba5b6SRobert Mustacchi 497975eba5b6SRobert Mustacchi if (kum_cfg & E1000_NVM_K1_ENABLE) 498075eba5b6SRobert Mustacchi dev_spec->nvm_k1_enabled = TRUE; 498175eba5b6SRobert Mustacchi else 498275eba5b6SRobert Mustacchi dev_spec->nvm_k1_enabled = FALSE; 498375eba5b6SRobert Mustacchi } 498475eba5b6SRobert Mustacchi 498575eba5b6SRobert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL); 498675eba5b6SRobert Mustacchi 498775eba5b6SRobert Mustacchi if (!hw->phy.ops.check_reset_block(hw)) { 498875eba5b6SRobert Mustacchi /* Full-chip reset requires MAC and PHY reset at the same 498975eba5b6SRobert Mustacchi * time to make sure the interface between MAC and the 499075eba5b6SRobert Mustacchi * external PHY is reset. 499175eba5b6SRobert Mustacchi */ 499275eba5b6SRobert Mustacchi ctrl |= E1000_CTRL_PHY_RST; 499375eba5b6SRobert Mustacchi 499475eba5b6SRobert Mustacchi /* Gate automatic PHY configuration by hardware on 499575eba5b6SRobert Mustacchi * non-managed 82579 499675eba5b6SRobert Mustacchi */ 499775eba5b6SRobert Mustacchi if ((hw->mac.type == e1000_pch2lan) && 499875eba5b6SRobert Mustacchi !(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID)) 499975eba5b6SRobert Mustacchi e1000_gate_hw_phy_config_ich8lan(hw, TRUE); 500075eba5b6SRobert Mustacchi } 500175eba5b6SRobert Mustacchi ret_val = e1000_acquire_swflag_ich8lan(hw); 500275eba5b6SRobert Mustacchi DEBUGOUT("Issuing a global reset to ich8lan\n"); 500375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST)); 500475eba5b6SRobert Mustacchi /* cannot issue a flush here because it hangs the hardware */ 500575eba5b6SRobert Mustacchi msec_delay(20); 500675eba5b6SRobert Mustacchi 500775eba5b6SRobert Mustacchi /* Set Phy Config Counter to 50msec */ 500875eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pch2lan) { 500975eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_FEXTNVM3); 501075eba5b6SRobert Mustacchi reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; 501175eba5b6SRobert Mustacchi reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; 501275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM3, reg); 501375eba5b6SRobert Mustacchi } 501475eba5b6SRobert Mustacchi 501575eba5b6SRobert Mustacchi if (!ret_val) 501675eba5b6SRobert Mustacchi E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); 501775eba5b6SRobert Mustacchi 501875eba5b6SRobert Mustacchi if (ctrl & E1000_CTRL_PHY_RST) { 501975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.get_cfg_done(hw); 502075eba5b6SRobert Mustacchi if (ret_val) 502175eba5b6SRobert Mustacchi return ret_val; 502275eba5b6SRobert Mustacchi 502375eba5b6SRobert Mustacchi ret_val = e1000_post_phy_reset_ich8lan(hw); 502475eba5b6SRobert Mustacchi if (ret_val) 502575eba5b6SRobert Mustacchi return ret_val; 502675eba5b6SRobert Mustacchi } 502775eba5b6SRobert Mustacchi 502875eba5b6SRobert Mustacchi /* For PCH, this write will make sure that any noise 502975eba5b6SRobert Mustacchi * will be detected as a CRC error and be dropped rather than show up 503075eba5b6SRobert Mustacchi * as a bad packet to the DMA engine. 503175eba5b6SRobert Mustacchi */ 503275eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pchlan) 503375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CRC_OFFSET, 0x65656565); 503475eba5b6SRobert Mustacchi 503575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 503675eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICR); 503775eba5b6SRobert Mustacchi 503875eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_KABGTXD); 503975eba5b6SRobert Mustacchi reg |= E1000_KABGTXD_BGSQLBIAS; 504075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_KABGTXD, reg); 504175eba5b6SRobert Mustacchi 504275eba5b6SRobert Mustacchi return E1000_SUCCESS; 504375eba5b6SRobert Mustacchi } 504475eba5b6SRobert Mustacchi 504575eba5b6SRobert Mustacchi /** 504675eba5b6SRobert Mustacchi * e1000_init_hw_ich8lan - Initialize the hardware 504775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 504875eba5b6SRobert Mustacchi * 504975eba5b6SRobert Mustacchi * Prepares the hardware for transmit and receive by doing the following: 505075eba5b6SRobert Mustacchi * - initialize hardware bits 505175eba5b6SRobert Mustacchi * - initialize LED identification 505275eba5b6SRobert Mustacchi * - setup receive address registers 505375eba5b6SRobert Mustacchi * - setup flow control 505475eba5b6SRobert Mustacchi * - setup transmit descriptors 505575eba5b6SRobert Mustacchi * - clear statistics 505675eba5b6SRobert Mustacchi **/ 505775eba5b6SRobert Mustacchi static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) 505875eba5b6SRobert Mustacchi { 505975eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 506075eba5b6SRobert Mustacchi u32 ctrl_ext, txdctl, snoop; 506175eba5b6SRobert Mustacchi s32 ret_val; 506275eba5b6SRobert Mustacchi u16 i; 506375eba5b6SRobert Mustacchi 506475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_hw_ich8lan"); 506575eba5b6SRobert Mustacchi 506675eba5b6SRobert Mustacchi e1000_initialize_hw_bits_ich8lan(hw); 506775eba5b6SRobert Mustacchi 506875eba5b6SRobert Mustacchi /* Initialize identification LED */ 506975eba5b6SRobert Mustacchi ret_val = mac->ops.id_led_init(hw); 507075eba5b6SRobert Mustacchi /* An error is not fatal and we should not stop init due to this */ 507175eba5b6SRobert Mustacchi if (ret_val) 507275eba5b6SRobert Mustacchi DEBUGOUT("Error initializing identification LED\n"); 507375eba5b6SRobert Mustacchi 507475eba5b6SRobert Mustacchi /* Setup the receive address. */ 507575eba5b6SRobert Mustacchi e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); 507675eba5b6SRobert Mustacchi 507775eba5b6SRobert Mustacchi /* Zero out the Multicast HASH table */ 507875eba5b6SRobert Mustacchi DEBUGOUT("Zeroing the MTA\n"); 507975eba5b6SRobert Mustacchi for (i = 0; i < mac->mta_reg_count; i++) 508075eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 508175eba5b6SRobert Mustacchi 508275eba5b6SRobert Mustacchi /* The 82578 Rx buffer will stall if wakeup is enabled in host and 508375eba5b6SRobert Mustacchi * the ME. Disable wakeup by clearing the host wakeup bit. 508475eba5b6SRobert Mustacchi * Reset the phy after disabling host wakeup to reset the Rx buffer. 508575eba5b6SRobert Mustacchi */ 508675eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_82578) { 508775eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, BM_PORT_GEN_CFG, &i); 508875eba5b6SRobert Mustacchi i &= ~BM_WUC_HOST_WU_BIT; 508975eba5b6SRobert Mustacchi hw->phy.ops.write_reg(hw, BM_PORT_GEN_CFG, i); 509075eba5b6SRobert Mustacchi ret_val = e1000_phy_hw_reset_ich8lan(hw); 509175eba5b6SRobert Mustacchi if (ret_val) 509275eba5b6SRobert Mustacchi return ret_val; 509375eba5b6SRobert Mustacchi } 509475eba5b6SRobert Mustacchi 509575eba5b6SRobert Mustacchi /* Setup link and flow control */ 509675eba5b6SRobert Mustacchi ret_val = mac->ops.setup_link(hw); 509775eba5b6SRobert Mustacchi 509875eba5b6SRobert Mustacchi /* Set the transmit descriptor write-back policy for both queues */ 509975eba5b6SRobert Mustacchi txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); 5100c124a83eSRobert Mustacchi txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | 5101c124a83eSRobert Mustacchi E1000_TXDCTL_FULL_TX_DESC_WB); 5102c124a83eSRobert Mustacchi txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | 5103c124a83eSRobert Mustacchi E1000_TXDCTL_MAX_TX_DESC_PREFETCH); 510475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); 510575eba5b6SRobert Mustacchi txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1)); 5106c124a83eSRobert Mustacchi txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | 5107c124a83eSRobert Mustacchi E1000_TXDCTL_FULL_TX_DESC_WB); 5108c124a83eSRobert Mustacchi txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | 5109c124a83eSRobert Mustacchi E1000_TXDCTL_MAX_TX_DESC_PREFETCH); 511075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl); 511175eba5b6SRobert Mustacchi 511275eba5b6SRobert Mustacchi /* ICH8 has opposite polarity of no_snoop bits. 511375eba5b6SRobert Mustacchi * By default, we should use snoop behavior. 511475eba5b6SRobert Mustacchi */ 511575eba5b6SRobert Mustacchi if (mac->type == e1000_ich8lan) 511675eba5b6SRobert Mustacchi snoop = PCIE_ICH8_SNOOP_ALL; 511775eba5b6SRobert Mustacchi else 511875eba5b6SRobert Mustacchi snoop = (u32) ~(PCIE_NO_SNOOP_ALL); 511975eba5b6SRobert Mustacchi e1000_set_pcie_no_snoop_generic(hw, snoop); 512075eba5b6SRobert Mustacchi 512175eba5b6SRobert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 512275eba5b6SRobert Mustacchi ctrl_ext |= E1000_CTRL_EXT_RO_DIS; 512375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 512475eba5b6SRobert Mustacchi 512575eba5b6SRobert Mustacchi /* Clear all of the statistics registers (clear on read). It is 512675eba5b6SRobert Mustacchi * important that we do this after we have tried to establish link 512775eba5b6SRobert Mustacchi * because the symbol error count will increment wildly if there 512875eba5b6SRobert Mustacchi * is no link. 512975eba5b6SRobert Mustacchi */ 513075eba5b6SRobert Mustacchi e1000_clear_hw_cntrs_ich8lan(hw); 513175eba5b6SRobert Mustacchi 513275eba5b6SRobert Mustacchi return ret_val; 513375eba5b6SRobert Mustacchi } 513475eba5b6SRobert Mustacchi 513575eba5b6SRobert Mustacchi /** 513675eba5b6SRobert Mustacchi * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits 513775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 513875eba5b6SRobert Mustacchi * 513975eba5b6SRobert Mustacchi * Sets/Clears required hardware bits necessary for correctly setting up the 514075eba5b6SRobert Mustacchi * hardware for transmit and receive. 514175eba5b6SRobert Mustacchi **/ 514275eba5b6SRobert Mustacchi static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) 514375eba5b6SRobert Mustacchi { 514475eba5b6SRobert Mustacchi u32 reg; 514575eba5b6SRobert Mustacchi 514675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_initialize_hw_bits_ich8lan"); 514775eba5b6SRobert Mustacchi 514875eba5b6SRobert Mustacchi /* Extended Device Control */ 514975eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 515075eba5b6SRobert Mustacchi reg |= (1 << 22); 515175eba5b6SRobert Mustacchi /* Enable PHY low-power state when MAC is at D3 w/o WoL */ 515275eba5b6SRobert Mustacchi if (hw->mac.type >= e1000_pchlan) 515375eba5b6SRobert Mustacchi reg |= E1000_CTRL_EXT_PHYPDEN; 515475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); 515575eba5b6SRobert Mustacchi 515675eba5b6SRobert Mustacchi /* Transmit Descriptor Control 0 */ 515775eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); 515875eba5b6SRobert Mustacchi reg |= (1 << 22); 515975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); 516075eba5b6SRobert Mustacchi 516175eba5b6SRobert Mustacchi /* Transmit Descriptor Control 1 */ 516275eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); 516375eba5b6SRobert Mustacchi reg |= (1 << 22); 516475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); 516575eba5b6SRobert Mustacchi 516675eba5b6SRobert Mustacchi /* Transmit Arbitration Control 0 */ 516775eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TARC(0)); 516875eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 516975eba5b6SRobert Mustacchi reg |= (1 << 28) | (1 << 29); 517075eba5b6SRobert Mustacchi reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27); 517175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TARC(0), reg); 517275eba5b6SRobert Mustacchi 517375eba5b6SRobert Mustacchi /* Transmit Arbitration Control 1 */ 517475eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TARC(1)); 517575eba5b6SRobert Mustacchi if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) 517675eba5b6SRobert Mustacchi reg &= ~(1 << 28); 517775eba5b6SRobert Mustacchi else 517875eba5b6SRobert Mustacchi reg |= (1 << 28); 517975eba5b6SRobert Mustacchi reg |= (1 << 24) | (1 << 26) | (1 << 30); 518075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TARC(1), reg); 518175eba5b6SRobert Mustacchi 518275eba5b6SRobert Mustacchi /* Device Status */ 518375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) { 518475eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_STATUS); 518575eba5b6SRobert Mustacchi reg &= ~(1UL << 31); 518675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_STATUS, reg); 518775eba5b6SRobert Mustacchi } 518875eba5b6SRobert Mustacchi 518975eba5b6SRobert Mustacchi /* work-around descriptor data corruption issue during nfs v2 udp 519075eba5b6SRobert Mustacchi * traffic, just disable the nfs filtering capability 519175eba5b6SRobert Mustacchi */ 519275eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_RFCTL); 519375eba5b6SRobert Mustacchi reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); 5194c124a83eSRobert Mustacchi 519575eba5b6SRobert Mustacchi /* Disable IPv6 extension header parsing because some malformed 519675eba5b6SRobert Mustacchi * IPv6 headers can hang the Rx. 519775eba5b6SRobert Mustacchi */ 519875eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 519975eba5b6SRobert Mustacchi reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); 520075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RFCTL, reg); 520175eba5b6SRobert Mustacchi 520275eba5b6SRobert Mustacchi /* Enable ECC on Lynxpoint */ 5203*42cc51e0SRobert Mustacchi if ((hw->mac.type == e1000_pch_lpt) || 5204*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) { 520575eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_PBECCSTS); 520675eba5b6SRobert Mustacchi reg |= E1000_PBECCSTS_ECC_ENABLE; 520775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PBECCSTS, reg); 520875eba5b6SRobert Mustacchi 520975eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL); 521075eba5b6SRobert Mustacchi reg |= E1000_CTRL_MEHE; 521175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, reg); 521275eba5b6SRobert Mustacchi } 521375eba5b6SRobert Mustacchi 521475eba5b6SRobert Mustacchi return; 521575eba5b6SRobert Mustacchi } 521675eba5b6SRobert Mustacchi 521775eba5b6SRobert Mustacchi /** 521875eba5b6SRobert Mustacchi * e1000_setup_link_ich8lan - Setup flow control and link settings 521975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 522075eba5b6SRobert Mustacchi * 522175eba5b6SRobert Mustacchi * Determines which flow control settings to use, then configures flow 522275eba5b6SRobert Mustacchi * control. Calls the appropriate media-specific link configuration 522375eba5b6SRobert Mustacchi * function. Assuming the adapter has a valid link partner, a valid link 522475eba5b6SRobert Mustacchi * should be established. Assumes the hardware has previously been reset 522575eba5b6SRobert Mustacchi * and the transmitter and receiver are not enabled. 522675eba5b6SRobert Mustacchi **/ 522775eba5b6SRobert Mustacchi static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) 522875eba5b6SRobert Mustacchi { 522975eba5b6SRobert Mustacchi s32 ret_val; 523075eba5b6SRobert Mustacchi 523175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_setup_link_ich8lan"); 523275eba5b6SRobert Mustacchi 523375eba5b6SRobert Mustacchi if (hw->phy.ops.check_reset_block(hw)) 523475eba5b6SRobert Mustacchi return E1000_SUCCESS; 523575eba5b6SRobert Mustacchi 523675eba5b6SRobert Mustacchi /* ICH parts do not have a word in the NVM to determine 523775eba5b6SRobert Mustacchi * the default flow control setting, so we explicitly 523875eba5b6SRobert Mustacchi * set it to full. 523975eba5b6SRobert Mustacchi */ 524075eba5b6SRobert Mustacchi if (hw->fc.requested_mode == e1000_fc_default) 524175eba5b6SRobert Mustacchi hw->fc.requested_mode = e1000_fc_full; 524275eba5b6SRobert Mustacchi 524375eba5b6SRobert Mustacchi /* Save off the requested flow control mode for use later. Depending 524475eba5b6SRobert Mustacchi * on the link partner's capabilities, we may or may not use this mode. 524575eba5b6SRobert Mustacchi */ 524675eba5b6SRobert Mustacchi hw->fc.current_mode = hw->fc.requested_mode; 524775eba5b6SRobert Mustacchi 524875eba5b6SRobert Mustacchi DEBUGOUT1("After fix-ups FlowControl is now = %x\n", 524975eba5b6SRobert Mustacchi hw->fc.current_mode); 525075eba5b6SRobert Mustacchi 525175eba5b6SRobert Mustacchi /* Continue to configure the copper link. */ 525275eba5b6SRobert Mustacchi ret_val = hw->mac.ops.setup_physical_interface(hw); 525375eba5b6SRobert Mustacchi if (ret_val) 525475eba5b6SRobert Mustacchi return ret_val; 525575eba5b6SRobert Mustacchi 525675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); 525775eba5b6SRobert Mustacchi if ((hw->phy.type == e1000_phy_82578) || 525875eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_82579) || 525975eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_i217) || 526075eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_82577)) { 526175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FCRTV_PCH, hw->fc.refresh_time); 526275eba5b6SRobert Mustacchi 526375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, 526475eba5b6SRobert Mustacchi PHY_REG(BM_PORT_CTRL_PAGE, 27), 526575eba5b6SRobert Mustacchi hw->fc.pause_time); 526675eba5b6SRobert Mustacchi if (ret_val) 526775eba5b6SRobert Mustacchi return ret_val; 526875eba5b6SRobert Mustacchi } 526975eba5b6SRobert Mustacchi 527075eba5b6SRobert Mustacchi return e1000_set_fc_watermarks_generic(hw); 527175eba5b6SRobert Mustacchi } 527275eba5b6SRobert Mustacchi 527375eba5b6SRobert Mustacchi /** 527475eba5b6SRobert Mustacchi * e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface 527575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 527675eba5b6SRobert Mustacchi * 527775eba5b6SRobert Mustacchi * Configures the kumeran interface to the PHY to wait the appropriate time 527875eba5b6SRobert Mustacchi * when polling the PHY, then call the generic setup_copper_link to finish 527975eba5b6SRobert Mustacchi * configuring the copper link. 528075eba5b6SRobert Mustacchi **/ 528175eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) 528275eba5b6SRobert Mustacchi { 528375eba5b6SRobert Mustacchi u32 ctrl; 528475eba5b6SRobert Mustacchi s32 ret_val; 528575eba5b6SRobert Mustacchi u16 reg_data; 528675eba5b6SRobert Mustacchi 528775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_setup_copper_link_ich8lan"); 528875eba5b6SRobert Mustacchi 528975eba5b6SRobert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL); 529075eba5b6SRobert Mustacchi ctrl |= E1000_CTRL_SLU; 529175eba5b6SRobert Mustacchi ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 529275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 529375eba5b6SRobert Mustacchi 529475eba5b6SRobert Mustacchi /* Set the mac to wait the maximum time between each iteration 529575eba5b6SRobert Mustacchi * and increase the max iterations when polling the phy; 529675eba5b6SRobert Mustacchi * this fixes erroneous timeouts at 10Mbps. 529775eba5b6SRobert Mustacchi */ 529875eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_TIMEOUTS, 529975eba5b6SRobert Mustacchi 0xFFFF); 530075eba5b6SRobert Mustacchi if (ret_val) 530175eba5b6SRobert Mustacchi return ret_val; 530275eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, 530375eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_INBAND_PARAM, 530475eba5b6SRobert Mustacchi ®_data); 530575eba5b6SRobert Mustacchi if (ret_val) 530675eba5b6SRobert Mustacchi return ret_val; 530775eba5b6SRobert Mustacchi reg_data |= 0x3F; 530875eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 530975eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_INBAND_PARAM, 531075eba5b6SRobert Mustacchi reg_data); 531175eba5b6SRobert Mustacchi if (ret_val) 531275eba5b6SRobert Mustacchi return ret_val; 531375eba5b6SRobert Mustacchi 531475eba5b6SRobert Mustacchi switch (hw->phy.type) { 531575eba5b6SRobert Mustacchi case e1000_phy_igp_3: 531675eba5b6SRobert Mustacchi ret_val = e1000_copper_link_setup_igp(hw); 531775eba5b6SRobert Mustacchi if (ret_val) 531875eba5b6SRobert Mustacchi return ret_val; 531975eba5b6SRobert Mustacchi break; 532075eba5b6SRobert Mustacchi case e1000_phy_bm: 532175eba5b6SRobert Mustacchi case e1000_phy_82578: 532275eba5b6SRobert Mustacchi ret_val = e1000_copper_link_setup_m88(hw); 532375eba5b6SRobert Mustacchi if (ret_val) 532475eba5b6SRobert Mustacchi return ret_val; 532575eba5b6SRobert Mustacchi break; 532675eba5b6SRobert Mustacchi case e1000_phy_82577: 532775eba5b6SRobert Mustacchi case e1000_phy_82579: 532875eba5b6SRobert Mustacchi ret_val = e1000_copper_link_setup_82577(hw); 532975eba5b6SRobert Mustacchi if (ret_val) 533075eba5b6SRobert Mustacchi return ret_val; 533175eba5b6SRobert Mustacchi break; 533275eba5b6SRobert Mustacchi case e1000_phy_ife: 533375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, 533475eba5b6SRobert Mustacchi ®_data); 533575eba5b6SRobert Mustacchi if (ret_val) 533675eba5b6SRobert Mustacchi return ret_val; 533775eba5b6SRobert Mustacchi 533875eba5b6SRobert Mustacchi reg_data &= ~IFE_PMC_AUTO_MDIX; 533975eba5b6SRobert Mustacchi 534075eba5b6SRobert Mustacchi switch (hw->phy.mdix) { 534175eba5b6SRobert Mustacchi case 1: 534275eba5b6SRobert Mustacchi reg_data &= ~IFE_PMC_FORCE_MDIX; 534375eba5b6SRobert Mustacchi break; 534475eba5b6SRobert Mustacchi case 2: 534575eba5b6SRobert Mustacchi reg_data |= IFE_PMC_FORCE_MDIX; 534675eba5b6SRobert Mustacchi break; 534775eba5b6SRobert Mustacchi case 0: 534875eba5b6SRobert Mustacchi default: 534975eba5b6SRobert Mustacchi reg_data |= IFE_PMC_AUTO_MDIX; 535075eba5b6SRobert Mustacchi break; 535175eba5b6SRobert Mustacchi } 535275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, 535375eba5b6SRobert Mustacchi reg_data); 535475eba5b6SRobert Mustacchi if (ret_val) 535575eba5b6SRobert Mustacchi return ret_val; 535675eba5b6SRobert Mustacchi break; 535775eba5b6SRobert Mustacchi default: 535875eba5b6SRobert Mustacchi break; 535975eba5b6SRobert Mustacchi } 536075eba5b6SRobert Mustacchi 536175eba5b6SRobert Mustacchi return e1000_setup_copper_link_generic(hw); 536275eba5b6SRobert Mustacchi } 536375eba5b6SRobert Mustacchi 536475eba5b6SRobert Mustacchi /** 536575eba5b6SRobert Mustacchi * e1000_setup_copper_link_pch_lpt - Configure MAC/PHY interface 536675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 536775eba5b6SRobert Mustacchi * 536875eba5b6SRobert Mustacchi * Calls the PHY specific link setup function and then calls the 536975eba5b6SRobert Mustacchi * generic setup_copper_link to finish configuring the link for 537075eba5b6SRobert Mustacchi * Lynxpoint PCH devices 537175eba5b6SRobert Mustacchi **/ 537275eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw) 537375eba5b6SRobert Mustacchi { 537475eba5b6SRobert Mustacchi u32 ctrl; 537575eba5b6SRobert Mustacchi s32 ret_val; 537675eba5b6SRobert Mustacchi 537775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_setup_copper_link_pch_lpt"); 537875eba5b6SRobert Mustacchi 537975eba5b6SRobert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL); 538075eba5b6SRobert Mustacchi ctrl |= E1000_CTRL_SLU; 538175eba5b6SRobert Mustacchi ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 538275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 538375eba5b6SRobert Mustacchi 538475eba5b6SRobert Mustacchi ret_val = e1000_copper_link_setup_82577(hw); 538575eba5b6SRobert Mustacchi if (ret_val) 538675eba5b6SRobert Mustacchi return ret_val; 538775eba5b6SRobert Mustacchi 538875eba5b6SRobert Mustacchi return e1000_setup_copper_link_generic(hw); 538975eba5b6SRobert Mustacchi } 539075eba5b6SRobert Mustacchi 539175eba5b6SRobert Mustacchi /** 539275eba5b6SRobert Mustacchi * e1000_get_link_up_info_ich8lan - Get current link speed and duplex 539375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 539475eba5b6SRobert Mustacchi * @speed: pointer to store current link speed 539575eba5b6SRobert Mustacchi * @duplex: pointer to store the current link duplex 539675eba5b6SRobert Mustacchi * 539775eba5b6SRobert Mustacchi * Calls the generic get_speed_and_duplex to retrieve the current link 539875eba5b6SRobert Mustacchi * information and then calls the Kumeran lock loss workaround for links at 539975eba5b6SRobert Mustacchi * gigabit speeds. 540075eba5b6SRobert Mustacchi **/ 540175eba5b6SRobert Mustacchi static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, 540275eba5b6SRobert Mustacchi u16 *duplex) 540375eba5b6SRobert Mustacchi { 540475eba5b6SRobert Mustacchi s32 ret_val; 540575eba5b6SRobert Mustacchi 540675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_link_up_info_ich8lan"); 540775eba5b6SRobert Mustacchi 540875eba5b6SRobert Mustacchi ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); 540975eba5b6SRobert Mustacchi if (ret_val) 541075eba5b6SRobert Mustacchi return ret_val; 541175eba5b6SRobert Mustacchi 541275eba5b6SRobert Mustacchi if ((hw->mac.type == e1000_ich8lan) && 541375eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_igp_3) && 541475eba5b6SRobert Mustacchi (*speed == SPEED_1000)) { 541575eba5b6SRobert Mustacchi ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw); 541675eba5b6SRobert Mustacchi } 541775eba5b6SRobert Mustacchi 541875eba5b6SRobert Mustacchi return ret_val; 541975eba5b6SRobert Mustacchi } 542075eba5b6SRobert Mustacchi 542175eba5b6SRobert Mustacchi /** 542275eba5b6SRobert Mustacchi * e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround 542375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 542475eba5b6SRobert Mustacchi * 542575eba5b6SRobert Mustacchi * Work-around for 82566 Kumeran PCS lock loss: 542675eba5b6SRobert Mustacchi * On link status change (i.e. PCI reset, speed change) and link is up and 542775eba5b6SRobert Mustacchi * speed is gigabit- 542875eba5b6SRobert Mustacchi * 0) if workaround is optionally disabled do nothing 542975eba5b6SRobert Mustacchi * 1) wait 1ms for Kumeran link to come up 543075eba5b6SRobert Mustacchi * 2) check Kumeran Diagnostic register PCS lock loss bit 543175eba5b6SRobert Mustacchi * 3) if not set the link is locked (all is good), otherwise... 543275eba5b6SRobert Mustacchi * 4) reset the PHY 543375eba5b6SRobert Mustacchi * 5) repeat up to 10 times 543475eba5b6SRobert Mustacchi * Note: this is only called for IGP3 copper when speed is 1gb. 543575eba5b6SRobert Mustacchi **/ 543675eba5b6SRobert Mustacchi static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) 543775eba5b6SRobert Mustacchi { 543875eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 543975eba5b6SRobert Mustacchi u32 phy_ctrl; 544075eba5b6SRobert Mustacchi s32 ret_val; 544175eba5b6SRobert Mustacchi u16 i, data; 544275eba5b6SRobert Mustacchi bool link; 544375eba5b6SRobert Mustacchi 544475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_kmrn_lock_loss_workaround_ich8lan"); 544575eba5b6SRobert Mustacchi 544675eba5b6SRobert Mustacchi if (!dev_spec->kmrn_lock_loss_workaround_enabled) 544775eba5b6SRobert Mustacchi return E1000_SUCCESS; 544875eba5b6SRobert Mustacchi 544975eba5b6SRobert Mustacchi /* Make sure link is up before proceeding. If not just return. 545075eba5b6SRobert Mustacchi * Attempting this while link is negotiating fouled up link 545175eba5b6SRobert Mustacchi * stability 545275eba5b6SRobert Mustacchi */ 545375eba5b6SRobert Mustacchi ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); 545475eba5b6SRobert Mustacchi if (!link) 545575eba5b6SRobert Mustacchi return E1000_SUCCESS; 545675eba5b6SRobert Mustacchi 545775eba5b6SRobert Mustacchi for (i = 0; i < 10; i++) { 545875eba5b6SRobert Mustacchi /* read once to clear */ 545975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); 546075eba5b6SRobert Mustacchi if (ret_val) 546175eba5b6SRobert Mustacchi return ret_val; 546275eba5b6SRobert Mustacchi /* and again to get new status */ 546375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); 546475eba5b6SRobert Mustacchi if (ret_val) 546575eba5b6SRobert Mustacchi return ret_val; 546675eba5b6SRobert Mustacchi 546775eba5b6SRobert Mustacchi /* check for PCS lock */ 546875eba5b6SRobert Mustacchi if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS)) 546975eba5b6SRobert Mustacchi return E1000_SUCCESS; 547075eba5b6SRobert Mustacchi 547175eba5b6SRobert Mustacchi /* Issue PHY reset */ 547275eba5b6SRobert Mustacchi hw->phy.ops.reset(hw); 547375eba5b6SRobert Mustacchi msec_delay_irq(5); 547475eba5b6SRobert Mustacchi } 547575eba5b6SRobert Mustacchi /* Disable GigE link negotiation */ 547675eba5b6SRobert Mustacchi phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); 547775eba5b6SRobert Mustacchi phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE | 547875eba5b6SRobert Mustacchi E1000_PHY_CTRL_NOND0A_GBE_DISABLE); 547975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 548075eba5b6SRobert Mustacchi 548175eba5b6SRobert Mustacchi /* Call gig speed drop workaround on Gig disable before accessing 548275eba5b6SRobert Mustacchi * any PHY registers 548375eba5b6SRobert Mustacchi */ 548475eba5b6SRobert Mustacchi e1000_gig_downshift_workaround_ich8lan(hw); 548575eba5b6SRobert Mustacchi 548675eba5b6SRobert Mustacchi /* unable to acquire PCS lock */ 548775eba5b6SRobert Mustacchi return -E1000_ERR_PHY; 548875eba5b6SRobert Mustacchi } 548975eba5b6SRobert Mustacchi 549075eba5b6SRobert Mustacchi /** 549175eba5b6SRobert Mustacchi * e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state 549275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 549375eba5b6SRobert Mustacchi * @state: boolean value used to set the current Kumeran workaround state 549475eba5b6SRobert Mustacchi * 549575eba5b6SRobert Mustacchi * If ICH8, set the current Kumeran workaround state (enabled - TRUE 549675eba5b6SRobert Mustacchi * /disabled - FALSE). 549775eba5b6SRobert Mustacchi **/ 549875eba5b6SRobert Mustacchi void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, 549975eba5b6SRobert Mustacchi bool state) 550075eba5b6SRobert Mustacchi { 550175eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 550275eba5b6SRobert Mustacchi 550375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_set_kmrn_lock_loss_workaround_ich8lan"); 550475eba5b6SRobert Mustacchi 550575eba5b6SRobert Mustacchi if (hw->mac.type != e1000_ich8lan) { 550675eba5b6SRobert Mustacchi DEBUGOUT("Workaround applies to ICH8 only.\n"); 550775eba5b6SRobert Mustacchi return; 550875eba5b6SRobert Mustacchi } 550975eba5b6SRobert Mustacchi 551075eba5b6SRobert Mustacchi dev_spec->kmrn_lock_loss_workaround_enabled = state; 551175eba5b6SRobert Mustacchi 551275eba5b6SRobert Mustacchi return; 551375eba5b6SRobert Mustacchi } 551475eba5b6SRobert Mustacchi 551575eba5b6SRobert Mustacchi /** 551675eba5b6SRobert Mustacchi * e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3 551775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 551875eba5b6SRobert Mustacchi * 551975eba5b6SRobert Mustacchi * Workaround for 82566 power-down on D3 entry: 552075eba5b6SRobert Mustacchi * 1) disable gigabit link 552175eba5b6SRobert Mustacchi * 2) write VR power-down enable 552275eba5b6SRobert Mustacchi * 3) read it back 552375eba5b6SRobert Mustacchi * Continue if successful, else issue LCD reset and repeat 552475eba5b6SRobert Mustacchi **/ 552575eba5b6SRobert Mustacchi void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) 552675eba5b6SRobert Mustacchi { 552775eba5b6SRobert Mustacchi u32 reg; 552875eba5b6SRobert Mustacchi u16 data; 552975eba5b6SRobert Mustacchi u8 retry = 0; 553075eba5b6SRobert Mustacchi 553175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_igp3_phy_powerdown_workaround_ich8lan"); 553275eba5b6SRobert Mustacchi 553375eba5b6SRobert Mustacchi if (hw->phy.type != e1000_phy_igp_3) 553475eba5b6SRobert Mustacchi return; 553575eba5b6SRobert Mustacchi 553675eba5b6SRobert Mustacchi /* Try the workaround twice (if needed) */ 553775eba5b6SRobert Mustacchi do { 553875eba5b6SRobert Mustacchi /* Disable link */ 553975eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_PHY_CTRL); 554075eba5b6SRobert Mustacchi reg |= (E1000_PHY_CTRL_GBE_DISABLE | 554175eba5b6SRobert Mustacchi E1000_PHY_CTRL_NOND0A_GBE_DISABLE); 554275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg); 554375eba5b6SRobert Mustacchi 554475eba5b6SRobert Mustacchi /* Call gig speed drop workaround on Gig disable before 554575eba5b6SRobert Mustacchi * accessing any PHY registers 554675eba5b6SRobert Mustacchi */ 554775eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 554875eba5b6SRobert Mustacchi e1000_gig_downshift_workaround_ich8lan(hw); 554975eba5b6SRobert Mustacchi 555075eba5b6SRobert Mustacchi /* Write VR power-down enable */ 555175eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); 555275eba5b6SRobert Mustacchi data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; 555375eba5b6SRobert Mustacchi hw->phy.ops.write_reg(hw, IGP3_VR_CTRL, 555475eba5b6SRobert Mustacchi data | IGP3_VR_CTRL_MODE_SHUTDOWN); 555575eba5b6SRobert Mustacchi 555675eba5b6SRobert Mustacchi /* Read it back and test */ 555775eba5b6SRobert Mustacchi hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); 555875eba5b6SRobert Mustacchi data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; 555975eba5b6SRobert Mustacchi if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry) 556075eba5b6SRobert Mustacchi break; 556175eba5b6SRobert Mustacchi 556275eba5b6SRobert Mustacchi /* Issue PHY reset and repeat at most one more time */ 556375eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL); 556475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, reg | E1000_CTRL_PHY_RST); 556575eba5b6SRobert Mustacchi retry++; 556675eba5b6SRobert Mustacchi } while (retry); 556775eba5b6SRobert Mustacchi } 556875eba5b6SRobert Mustacchi 556975eba5b6SRobert Mustacchi /** 557075eba5b6SRobert Mustacchi * e1000_gig_downshift_workaround_ich8lan - WoL from S5 stops working 557175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 557275eba5b6SRobert Mustacchi * 557375eba5b6SRobert Mustacchi * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), 557475eba5b6SRobert Mustacchi * LPLU, Gig disable, MDIC PHY reset): 557575eba5b6SRobert Mustacchi * 1) Set Kumeran Near-end loopback 557675eba5b6SRobert Mustacchi * 2) Clear Kumeran Near-end loopback 557775eba5b6SRobert Mustacchi * Should only be called for ICH8[m] devices with any 1G Phy. 557875eba5b6SRobert Mustacchi **/ 557975eba5b6SRobert Mustacchi void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) 558075eba5b6SRobert Mustacchi { 558175eba5b6SRobert Mustacchi s32 ret_val; 558275eba5b6SRobert Mustacchi u16 reg_data; 558375eba5b6SRobert Mustacchi 558475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan"); 558575eba5b6SRobert Mustacchi 558675eba5b6SRobert Mustacchi if ((hw->mac.type != e1000_ich8lan) || 558775eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_ife)) 558875eba5b6SRobert Mustacchi return; 558975eba5b6SRobert Mustacchi 559075eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, 559175eba5b6SRobert Mustacchi ®_data); 559275eba5b6SRobert Mustacchi if (ret_val) 559375eba5b6SRobert Mustacchi return; 559475eba5b6SRobert Mustacchi reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK; 559575eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_generic(hw, 559675eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_DIAG_OFFSET, 559775eba5b6SRobert Mustacchi reg_data); 559875eba5b6SRobert Mustacchi if (ret_val) 559975eba5b6SRobert Mustacchi return; 560075eba5b6SRobert Mustacchi reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK; 560175eba5b6SRobert Mustacchi e1000_write_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, 560275eba5b6SRobert Mustacchi reg_data); 560375eba5b6SRobert Mustacchi } 560475eba5b6SRobert Mustacchi 560575eba5b6SRobert Mustacchi /** 560675eba5b6SRobert Mustacchi * e1000_suspend_workarounds_ich8lan - workarounds needed during S0->Sx 560775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 560875eba5b6SRobert Mustacchi * 560975eba5b6SRobert Mustacchi * During S0 to Sx transition, it is possible the link remains at gig 561075eba5b6SRobert Mustacchi * instead of negotiating to a lower speed. Before going to Sx, set 561175eba5b6SRobert Mustacchi * 'Gig Disable' to force link speed negotiation to a lower speed based on 561275eba5b6SRobert Mustacchi * the LPLU setting in the NVM or custom setting. For PCH and newer parts, 561375eba5b6SRobert Mustacchi * the OEM bits PHY register (LED, GbE disable and LPLU configurations) also 561475eba5b6SRobert Mustacchi * needs to be written. 561575eba5b6SRobert Mustacchi * Parts that support (and are linked to a partner which support) EEE in 561675eba5b6SRobert Mustacchi * 100Mbps should disable LPLU since 100Mbps w/ EEE requires less power 561775eba5b6SRobert Mustacchi * than 10Mbps w/o EEE. 561875eba5b6SRobert Mustacchi **/ 561975eba5b6SRobert Mustacchi void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) 562075eba5b6SRobert Mustacchi { 562175eba5b6SRobert Mustacchi struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; 562275eba5b6SRobert Mustacchi u32 phy_ctrl; 562375eba5b6SRobert Mustacchi s32 ret_val; 562475eba5b6SRobert Mustacchi 562575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_suspend_workarounds_ich8lan"); 562675eba5b6SRobert Mustacchi 562775eba5b6SRobert Mustacchi phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); 562875eba5b6SRobert Mustacchi phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; 562975eba5b6SRobert Mustacchi 563075eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_i217) { 563175eba5b6SRobert Mustacchi u16 phy_reg, device_id = hw->device_id; 563275eba5b6SRobert Mustacchi 563375eba5b6SRobert Mustacchi if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || 5634c124a83eSRobert Mustacchi (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) || 5635c124a83eSRobert Mustacchi (device_id == E1000_DEV_ID_PCH_I218_LM3) || 5636*42cc51e0SRobert Mustacchi (device_id == E1000_DEV_ID_PCH_I218_V3) || 5637*42cc51e0SRobert Mustacchi (hw->mac.type == e1000_pch_spt)) { 563875eba5b6SRobert Mustacchi u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6); 563975eba5b6SRobert Mustacchi 564075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_FEXTNVM6, 564175eba5b6SRobert Mustacchi fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); 564275eba5b6SRobert Mustacchi } 564375eba5b6SRobert Mustacchi 564475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 564575eba5b6SRobert Mustacchi if (ret_val) 564675eba5b6SRobert Mustacchi goto out; 564775eba5b6SRobert Mustacchi 564875eba5b6SRobert Mustacchi if (!dev_spec->eee_disable) { 564975eba5b6SRobert Mustacchi u16 eee_advert; 565075eba5b6SRobert Mustacchi 565175eba5b6SRobert Mustacchi ret_val = 565275eba5b6SRobert Mustacchi e1000_read_emi_reg_locked(hw, 565375eba5b6SRobert Mustacchi I217_EEE_ADVERTISEMENT, 565475eba5b6SRobert Mustacchi &eee_advert); 565575eba5b6SRobert Mustacchi if (ret_val) 565675eba5b6SRobert Mustacchi goto release; 565775eba5b6SRobert Mustacchi 565875eba5b6SRobert Mustacchi /* Disable LPLU if both link partners support 100BaseT 565975eba5b6SRobert Mustacchi * EEE and 100Full is advertised on both ends of the 5660c124a83eSRobert Mustacchi * link, and enable Auto Enable LPI since there will 5661c124a83eSRobert Mustacchi * be no driver to enable LPI while in Sx. 566275eba5b6SRobert Mustacchi */ 566375eba5b6SRobert Mustacchi if ((eee_advert & I82579_EEE_100_SUPPORTED) && 566475eba5b6SRobert Mustacchi (dev_spec->eee_lp_ability & 566575eba5b6SRobert Mustacchi I82579_EEE_100_SUPPORTED) && 5666c124a83eSRobert Mustacchi (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) { 566775eba5b6SRobert Mustacchi phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU | 566875eba5b6SRobert Mustacchi E1000_PHY_CTRL_NOND0A_LPLU); 5669c124a83eSRobert Mustacchi 5670c124a83eSRobert Mustacchi /* Set Auto Enable LPI after link up */ 5671c124a83eSRobert Mustacchi hw->phy.ops.read_reg_locked(hw, 5672c124a83eSRobert Mustacchi I217_LPI_GPIO_CTRL, 5673c124a83eSRobert Mustacchi &phy_reg); 5674c124a83eSRobert Mustacchi phy_reg |= I217_LPI_GPIO_CTRL_AUTO_EN_LPI; 5675c124a83eSRobert Mustacchi hw->phy.ops.write_reg_locked(hw, 5676c124a83eSRobert Mustacchi I217_LPI_GPIO_CTRL, 5677c124a83eSRobert Mustacchi phy_reg); 5678c124a83eSRobert Mustacchi } 567975eba5b6SRobert Mustacchi } 568075eba5b6SRobert Mustacchi 568175eba5b6SRobert Mustacchi /* For i217 Intel Rapid Start Technology support, 568275eba5b6SRobert Mustacchi * when the system is going into Sx and no manageability engine 568375eba5b6SRobert Mustacchi * is present, the driver must configure proxy to reset only on 568475eba5b6SRobert Mustacchi * power good. LPI (Low Power Idle) state must also reset only 568575eba5b6SRobert Mustacchi * on power good, as well as the MTA (Multicast table array). 568675eba5b6SRobert Mustacchi * The SMBus release must also be disabled on LCD reset. 568775eba5b6SRobert Mustacchi */ 568875eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_FWSM) & 568975eba5b6SRobert Mustacchi E1000_ICH_FWSM_FW_VALID)) { 569075eba5b6SRobert Mustacchi /* Enable proxy to reset only on power good. */ 569175eba5b6SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_PROXY_CTRL, 569275eba5b6SRobert Mustacchi &phy_reg); 569375eba5b6SRobert Mustacchi phy_reg |= I217_PROXY_CTRL_AUTO_DISABLE; 569475eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_PROXY_CTRL, 569575eba5b6SRobert Mustacchi phy_reg); 569675eba5b6SRobert Mustacchi 569775eba5b6SRobert Mustacchi /* Set bit enable LPI (EEE) to reset only on 569875eba5b6SRobert Mustacchi * power good. 569975eba5b6SRobert Mustacchi */ 570075eba5b6SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_SxCTRL, &phy_reg); 570175eba5b6SRobert Mustacchi phy_reg |= I217_SxCTRL_ENABLE_LPI_RESET; 570275eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_SxCTRL, phy_reg); 570375eba5b6SRobert Mustacchi 570475eba5b6SRobert Mustacchi /* Disable the SMB release on LCD reset. */ 570575eba5b6SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_MEMPWR, &phy_reg); 570675eba5b6SRobert Mustacchi phy_reg &= ~I217_MEMPWR_DISABLE_SMB_RELEASE; 570775eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_MEMPWR, phy_reg); 570875eba5b6SRobert Mustacchi } 570975eba5b6SRobert Mustacchi 571075eba5b6SRobert Mustacchi /* Enable MTA to reset for Intel Rapid Start Technology 571175eba5b6SRobert Mustacchi * Support 571275eba5b6SRobert Mustacchi */ 571375eba5b6SRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_CGFREG, &phy_reg); 571475eba5b6SRobert Mustacchi phy_reg |= I217_CGFREG_ENABLE_MTA_RESET; 571575eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_CGFREG, phy_reg); 571675eba5b6SRobert Mustacchi 571775eba5b6SRobert Mustacchi release: 571875eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 571975eba5b6SRobert Mustacchi } 572075eba5b6SRobert Mustacchi out: 572175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); 572275eba5b6SRobert Mustacchi 572375eba5b6SRobert Mustacchi if (hw->mac.type == e1000_ich8lan) 572475eba5b6SRobert Mustacchi e1000_gig_downshift_workaround_ich8lan(hw); 572575eba5b6SRobert Mustacchi 572675eba5b6SRobert Mustacchi if (hw->mac.type >= e1000_pchlan) { 572775eba5b6SRobert Mustacchi e1000_oem_bits_config_ich8lan(hw, FALSE); 572875eba5b6SRobert Mustacchi 572975eba5b6SRobert Mustacchi /* Reset PHY to activate OEM bits on 82577/8 */ 573075eba5b6SRobert Mustacchi if (hw->mac.type == e1000_pchlan) 573175eba5b6SRobert Mustacchi e1000_phy_hw_reset_generic(hw); 573275eba5b6SRobert Mustacchi 573375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 573475eba5b6SRobert Mustacchi if (ret_val) 573575eba5b6SRobert Mustacchi return; 573675eba5b6SRobert Mustacchi e1000_write_smbus_addr(hw); 573775eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 573875eba5b6SRobert Mustacchi } 573975eba5b6SRobert Mustacchi 574075eba5b6SRobert Mustacchi return; 574175eba5b6SRobert Mustacchi } 574275eba5b6SRobert Mustacchi 574375eba5b6SRobert Mustacchi /** 574475eba5b6SRobert Mustacchi * e1000_resume_workarounds_pchlan - workarounds needed during Sx->S0 574575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 574675eba5b6SRobert Mustacchi * 574775eba5b6SRobert Mustacchi * During Sx to S0 transitions on non-managed devices or managed devices 574875eba5b6SRobert Mustacchi * on which PHY resets are not blocked, if the PHY registers cannot be 574975eba5b6SRobert Mustacchi * accessed properly by the s/w toggle the LANPHYPC value to power cycle 575075eba5b6SRobert Mustacchi * the PHY. 575175eba5b6SRobert Mustacchi * On i217, setup Intel Rapid Start Technology. 575275eba5b6SRobert Mustacchi **/ 5753*42cc51e0SRobert Mustacchi u32 e1000_resume_workarounds_pchlan(struct e1000_hw *hw) 575475eba5b6SRobert Mustacchi { 575575eba5b6SRobert Mustacchi s32 ret_val; 575675eba5b6SRobert Mustacchi 575775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_resume_workarounds_pchlan"); 575875eba5b6SRobert Mustacchi if (hw->mac.type < e1000_pch2lan) 5759*42cc51e0SRobert Mustacchi return E1000_SUCCESS; 576075eba5b6SRobert Mustacchi 576175eba5b6SRobert Mustacchi ret_val = e1000_init_phy_workarounds_pchlan(hw); 576275eba5b6SRobert Mustacchi if (ret_val) { 576375eba5b6SRobert Mustacchi DEBUGOUT1("Failed to init PHY flow ret_val=%d\n", ret_val); 5764*42cc51e0SRobert Mustacchi return ret_val; 576575eba5b6SRobert Mustacchi } 576675eba5b6SRobert Mustacchi 576775eba5b6SRobert Mustacchi /* For i217 Intel Rapid Start Technology support when the system 576875eba5b6SRobert Mustacchi * is transitioning from Sx and no manageability engine is present 576975eba5b6SRobert Mustacchi * configure SMBus to restore on reset, disable proxy, and enable 577075eba5b6SRobert Mustacchi * the reset on MTA (Multicast table array). 577175eba5b6SRobert Mustacchi */ 577275eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_i217) { 577375eba5b6SRobert Mustacchi u16 phy_reg; 577475eba5b6SRobert Mustacchi 577575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 577675eba5b6SRobert Mustacchi if (ret_val) { 577775eba5b6SRobert Mustacchi DEBUGOUT("Failed to setup iRST\n"); 5778*42cc51e0SRobert Mustacchi return ret_val; 577975eba5b6SRobert Mustacchi } 578075eba5b6SRobert Mustacchi 5781c124a83eSRobert Mustacchi /* Clear Auto Enable LPI after link up */ 5782c124a83eSRobert Mustacchi hw->phy.ops.read_reg_locked(hw, I217_LPI_GPIO_CTRL, &phy_reg); 5783c124a83eSRobert Mustacchi phy_reg &= ~I217_LPI_GPIO_CTRL_AUTO_EN_LPI; 5784c124a83eSRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_LPI_GPIO_CTRL, phy_reg); 5785c124a83eSRobert Mustacchi 578675eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_FWSM) & 578775eba5b6SRobert Mustacchi E1000_ICH_FWSM_FW_VALID)) { 578875eba5b6SRobert Mustacchi /* Restore clear on SMB if no manageability engine 578975eba5b6SRobert Mustacchi * is present 579075eba5b6SRobert Mustacchi */ 579175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, I217_MEMPWR, 579275eba5b6SRobert Mustacchi &phy_reg); 579375eba5b6SRobert Mustacchi if (ret_val) 579475eba5b6SRobert Mustacchi goto release; 579575eba5b6SRobert Mustacchi phy_reg |= I217_MEMPWR_DISABLE_SMB_RELEASE; 579675eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_MEMPWR, phy_reg); 579775eba5b6SRobert Mustacchi 579875eba5b6SRobert Mustacchi /* Disable Proxy */ 579975eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_PROXY_CTRL, 0); 580075eba5b6SRobert Mustacchi } 580175eba5b6SRobert Mustacchi /* Enable reset on MTA */ 580275eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg_locked(hw, I217_CGFREG, 580375eba5b6SRobert Mustacchi &phy_reg); 580475eba5b6SRobert Mustacchi if (ret_val) 580575eba5b6SRobert Mustacchi goto release; 580675eba5b6SRobert Mustacchi phy_reg &= ~I217_CGFREG_ENABLE_MTA_RESET; 580775eba5b6SRobert Mustacchi hw->phy.ops.write_reg_locked(hw, I217_CGFREG, phy_reg); 580875eba5b6SRobert Mustacchi release: 580975eba5b6SRobert Mustacchi if (ret_val) 581075eba5b6SRobert Mustacchi DEBUGOUT1("Error %d in resume workarounds\n", ret_val); 581175eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 5812*42cc51e0SRobert Mustacchi return ret_val; 581375eba5b6SRobert Mustacchi } 5814*42cc51e0SRobert Mustacchi return E1000_SUCCESS; 581575eba5b6SRobert Mustacchi } 581675eba5b6SRobert Mustacchi 581775eba5b6SRobert Mustacchi /** 581875eba5b6SRobert Mustacchi * e1000_cleanup_led_ich8lan - Restore the default LED operation 581975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 582075eba5b6SRobert Mustacchi * 582175eba5b6SRobert Mustacchi * Return the LED back to the default configuration. 582275eba5b6SRobert Mustacchi **/ 582375eba5b6SRobert Mustacchi static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) 582475eba5b6SRobert Mustacchi { 582575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_cleanup_led_ich8lan"); 582675eba5b6SRobert Mustacchi 582775eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_ife) 582875eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 582975eba5b6SRobert Mustacchi 0); 583075eba5b6SRobert Mustacchi 583175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); 583275eba5b6SRobert Mustacchi return E1000_SUCCESS; 583375eba5b6SRobert Mustacchi } 583475eba5b6SRobert Mustacchi 583575eba5b6SRobert Mustacchi /** 583675eba5b6SRobert Mustacchi * e1000_led_on_ich8lan - Turn LEDs on 583775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 583875eba5b6SRobert Mustacchi * 583975eba5b6SRobert Mustacchi * Turn on the LEDs. 584075eba5b6SRobert Mustacchi **/ 584175eba5b6SRobert Mustacchi static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) 584275eba5b6SRobert Mustacchi { 584375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_led_on_ich8lan"); 584475eba5b6SRobert Mustacchi 584575eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_ife) 584675eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 584775eba5b6SRobert Mustacchi (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); 584875eba5b6SRobert Mustacchi 584975eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); 585075eba5b6SRobert Mustacchi return E1000_SUCCESS; 585175eba5b6SRobert Mustacchi } 585275eba5b6SRobert Mustacchi 585375eba5b6SRobert Mustacchi /** 585475eba5b6SRobert Mustacchi * e1000_led_off_ich8lan - Turn LEDs off 585575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 585675eba5b6SRobert Mustacchi * 585775eba5b6SRobert Mustacchi * Turn off the LEDs. 585875eba5b6SRobert Mustacchi **/ 585975eba5b6SRobert Mustacchi static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) 586075eba5b6SRobert Mustacchi { 586175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_led_off_ich8lan"); 586275eba5b6SRobert Mustacchi 586375eba5b6SRobert Mustacchi if (hw->phy.type == e1000_phy_ife) 586475eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 586575eba5b6SRobert Mustacchi (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); 586675eba5b6SRobert Mustacchi 586775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); 586875eba5b6SRobert Mustacchi return E1000_SUCCESS; 586975eba5b6SRobert Mustacchi } 587075eba5b6SRobert Mustacchi 587175eba5b6SRobert Mustacchi /** 587275eba5b6SRobert Mustacchi * e1000_setup_led_pchlan - Configures SW controllable LED 587375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 587475eba5b6SRobert Mustacchi * 587575eba5b6SRobert Mustacchi * This prepares the SW controllable LED for use. 587675eba5b6SRobert Mustacchi **/ 587775eba5b6SRobert Mustacchi static s32 e1000_setup_led_pchlan(struct e1000_hw *hw) 587875eba5b6SRobert Mustacchi { 587975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_setup_led_pchlan"); 588075eba5b6SRobert Mustacchi 588175eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, 588275eba5b6SRobert Mustacchi (u16)hw->mac.ledctl_mode1); 588375eba5b6SRobert Mustacchi } 588475eba5b6SRobert Mustacchi 588575eba5b6SRobert Mustacchi /** 588675eba5b6SRobert Mustacchi * e1000_cleanup_led_pchlan - Restore the default LED operation 588775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 588875eba5b6SRobert Mustacchi * 588975eba5b6SRobert Mustacchi * Return the LED back to the default configuration. 589075eba5b6SRobert Mustacchi **/ 589175eba5b6SRobert Mustacchi static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw) 589275eba5b6SRobert Mustacchi { 589375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_cleanup_led_pchlan"); 589475eba5b6SRobert Mustacchi 589575eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, 589675eba5b6SRobert Mustacchi (u16)hw->mac.ledctl_default); 589775eba5b6SRobert Mustacchi } 589875eba5b6SRobert Mustacchi 589975eba5b6SRobert Mustacchi /** 590075eba5b6SRobert Mustacchi * e1000_led_on_pchlan - Turn LEDs on 590175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 590275eba5b6SRobert Mustacchi * 590375eba5b6SRobert Mustacchi * Turn on the LEDs. 590475eba5b6SRobert Mustacchi **/ 590575eba5b6SRobert Mustacchi static s32 e1000_led_on_pchlan(struct e1000_hw *hw) 590675eba5b6SRobert Mustacchi { 590775eba5b6SRobert Mustacchi u16 data = (u16)hw->mac.ledctl_mode2; 590875eba5b6SRobert Mustacchi u32 i, led; 590975eba5b6SRobert Mustacchi 591075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_led_on_pchlan"); 591175eba5b6SRobert Mustacchi 591275eba5b6SRobert Mustacchi /* If no link, then turn LED on by setting the invert bit 591375eba5b6SRobert Mustacchi * for each LED that's mode is "link_up" in ledctl_mode2. 591475eba5b6SRobert Mustacchi */ 591575eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { 591675eba5b6SRobert Mustacchi for (i = 0; i < 3; i++) { 591775eba5b6SRobert Mustacchi led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; 591875eba5b6SRobert Mustacchi if ((led & E1000_PHY_LED0_MODE_MASK) != 591975eba5b6SRobert Mustacchi E1000_LEDCTL_MODE_LINK_UP) 592075eba5b6SRobert Mustacchi continue; 592175eba5b6SRobert Mustacchi if (led & E1000_PHY_LED0_IVRT) 592275eba5b6SRobert Mustacchi data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); 592375eba5b6SRobert Mustacchi else 592475eba5b6SRobert Mustacchi data |= (E1000_PHY_LED0_IVRT << (i * 5)); 592575eba5b6SRobert Mustacchi } 592675eba5b6SRobert Mustacchi } 592775eba5b6SRobert Mustacchi 592875eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data); 592975eba5b6SRobert Mustacchi } 593075eba5b6SRobert Mustacchi 593175eba5b6SRobert Mustacchi /** 593275eba5b6SRobert Mustacchi * e1000_led_off_pchlan - Turn LEDs off 593375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 593475eba5b6SRobert Mustacchi * 593575eba5b6SRobert Mustacchi * Turn off the LEDs. 593675eba5b6SRobert Mustacchi **/ 593775eba5b6SRobert Mustacchi static s32 e1000_led_off_pchlan(struct e1000_hw *hw) 593875eba5b6SRobert Mustacchi { 593975eba5b6SRobert Mustacchi u16 data = (u16)hw->mac.ledctl_mode1; 594075eba5b6SRobert Mustacchi u32 i, led; 594175eba5b6SRobert Mustacchi 594275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_led_off_pchlan"); 594375eba5b6SRobert Mustacchi 594475eba5b6SRobert Mustacchi /* If no link, then turn LED off by clearing the invert bit 594575eba5b6SRobert Mustacchi * for each LED that's mode is "link_up" in ledctl_mode1. 594675eba5b6SRobert Mustacchi */ 594775eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { 594875eba5b6SRobert Mustacchi for (i = 0; i < 3; i++) { 594975eba5b6SRobert Mustacchi led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; 595075eba5b6SRobert Mustacchi if ((led & E1000_PHY_LED0_MODE_MASK) != 595175eba5b6SRobert Mustacchi E1000_LEDCTL_MODE_LINK_UP) 595275eba5b6SRobert Mustacchi continue; 595375eba5b6SRobert Mustacchi if (led & E1000_PHY_LED0_IVRT) 595475eba5b6SRobert Mustacchi data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); 595575eba5b6SRobert Mustacchi else 595675eba5b6SRobert Mustacchi data |= (E1000_PHY_LED0_IVRT << (i * 5)); 595775eba5b6SRobert Mustacchi } 595875eba5b6SRobert Mustacchi } 595975eba5b6SRobert Mustacchi 596075eba5b6SRobert Mustacchi return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data); 596175eba5b6SRobert Mustacchi } 596275eba5b6SRobert Mustacchi 596375eba5b6SRobert Mustacchi /** 596475eba5b6SRobert Mustacchi * e1000_get_cfg_done_ich8lan - Read config done bit after Full or PHY reset 596575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 596675eba5b6SRobert Mustacchi * 596775eba5b6SRobert Mustacchi * Read appropriate register for the config done bit for completion status 596875eba5b6SRobert Mustacchi * and configure the PHY through s/w for EEPROM-less parts. 596975eba5b6SRobert Mustacchi * 597075eba5b6SRobert Mustacchi * NOTE: some silicon which is EEPROM-less will fail trying to read the 597175eba5b6SRobert Mustacchi * config done bit, so only an error is logged and continues. If we were 597275eba5b6SRobert Mustacchi * to return with error, EEPROM-less silicon would not be able to be reset 597375eba5b6SRobert Mustacchi * or change link. 597475eba5b6SRobert Mustacchi **/ 597575eba5b6SRobert Mustacchi static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) 597675eba5b6SRobert Mustacchi { 597775eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 597875eba5b6SRobert Mustacchi u32 bank = 0; 597975eba5b6SRobert Mustacchi u32 status; 598075eba5b6SRobert Mustacchi 598175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_cfg_done_ich8lan"); 598275eba5b6SRobert Mustacchi 598375eba5b6SRobert Mustacchi e1000_get_cfg_done_generic(hw); 598475eba5b6SRobert Mustacchi 598575eba5b6SRobert Mustacchi /* Wait for indication from h/w that it has completed basic config */ 598675eba5b6SRobert Mustacchi if (hw->mac.type >= e1000_ich10lan) { 598775eba5b6SRobert Mustacchi e1000_lan_init_done_ich8lan(hw); 598875eba5b6SRobert Mustacchi } else { 598975eba5b6SRobert Mustacchi ret_val = e1000_get_auto_rd_done_generic(hw); 599075eba5b6SRobert Mustacchi if (ret_val) { 599175eba5b6SRobert Mustacchi /* When auto config read does not complete, do not 599275eba5b6SRobert Mustacchi * return with an error. This can happen in situations 599375eba5b6SRobert Mustacchi * where there is no eeprom and prevents getting link. 599475eba5b6SRobert Mustacchi */ 599575eba5b6SRobert Mustacchi DEBUGOUT("Auto Read Done did not complete\n"); 599675eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 599775eba5b6SRobert Mustacchi } 599875eba5b6SRobert Mustacchi } 599975eba5b6SRobert Mustacchi 600075eba5b6SRobert Mustacchi /* Clear PHY Reset Asserted bit */ 600175eba5b6SRobert Mustacchi status = E1000_READ_REG(hw, E1000_STATUS); 6002*42cc51e0SRobert Mustacchi if (status & E1000_STATUS_PHYRA) 600375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_STATUS, status & ~E1000_STATUS_PHYRA); 6004*42cc51e0SRobert Mustacchi else 600575eba5b6SRobert Mustacchi DEBUGOUT("PHY Reset Asserted not set - needs delay\n"); 600675eba5b6SRobert Mustacchi 600775eba5b6SRobert Mustacchi /* If EEPROM is not marked present, init the IGP 3 PHY manually */ 600875eba5b6SRobert Mustacchi if (hw->mac.type <= e1000_ich9lan) { 600975eba5b6SRobert Mustacchi if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) && 601075eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_igp_3)) { 601175eba5b6SRobert Mustacchi e1000_phy_init_script_igp3(hw); 601275eba5b6SRobert Mustacchi } 601375eba5b6SRobert Mustacchi } else { 601475eba5b6SRobert Mustacchi if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) { 601575eba5b6SRobert Mustacchi /* Maybe we should do a basic PHY config */ 601675eba5b6SRobert Mustacchi DEBUGOUT("EEPROM not present\n"); 601775eba5b6SRobert Mustacchi ret_val = -E1000_ERR_CONFIG; 601875eba5b6SRobert Mustacchi } 601975eba5b6SRobert Mustacchi } 602075eba5b6SRobert Mustacchi 602175eba5b6SRobert Mustacchi return ret_val; 602275eba5b6SRobert Mustacchi } 602375eba5b6SRobert Mustacchi 602475eba5b6SRobert Mustacchi /** 602575eba5b6SRobert Mustacchi * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down 602675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 602775eba5b6SRobert Mustacchi * 602875eba5b6SRobert Mustacchi * In the case of a PHY power down to save power, or to turn off link during a 602975eba5b6SRobert Mustacchi * driver unload, or wake on lan is not enabled, remove the link. 603075eba5b6SRobert Mustacchi **/ 603175eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) 603275eba5b6SRobert Mustacchi { 603375eba5b6SRobert Mustacchi /* If the management interface is not enabled, then power down */ 603475eba5b6SRobert Mustacchi if (!(hw->mac.ops.check_mng_mode(hw) || 603575eba5b6SRobert Mustacchi hw->phy.ops.check_reset_block(hw))) 603675eba5b6SRobert Mustacchi e1000_power_down_phy_copper(hw); 603775eba5b6SRobert Mustacchi 603875eba5b6SRobert Mustacchi return; 603975eba5b6SRobert Mustacchi } 604075eba5b6SRobert Mustacchi 604175eba5b6SRobert Mustacchi /** 604275eba5b6SRobert Mustacchi * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters 604375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 604475eba5b6SRobert Mustacchi * 604575eba5b6SRobert Mustacchi * Clears hardware counters specific to the silicon family and calls 604675eba5b6SRobert Mustacchi * clear_hw_cntrs_generic to clear all general purpose counters. 604775eba5b6SRobert Mustacchi **/ 604875eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) 604975eba5b6SRobert Mustacchi { 605075eba5b6SRobert Mustacchi u16 phy_data; 605175eba5b6SRobert Mustacchi s32 ret_val; 605275eba5b6SRobert Mustacchi 605375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_clear_hw_cntrs_ich8lan"); 605475eba5b6SRobert Mustacchi 605575eba5b6SRobert Mustacchi e1000_clear_hw_cntrs_base_generic(hw); 605675eba5b6SRobert Mustacchi 605775eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ALGNERRC); 605875eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_RXERRC); 605975eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TNCRS); 606075eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_CEXTERR); 606175eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TSCTC); 606275eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TSCTFC); 606375eba5b6SRobert Mustacchi 606475eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPRC); 606575eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPDC); 606675eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPTC); 606775eba5b6SRobert Mustacchi 606875eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_IAC); 606975eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICRXOC); 607075eba5b6SRobert Mustacchi 607175eba5b6SRobert Mustacchi /* Clear PHY statistics registers */ 607275eba5b6SRobert Mustacchi if ((hw->phy.type == e1000_phy_82578) || 607375eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_82579) || 607475eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_i217) || 607575eba5b6SRobert Mustacchi (hw->phy.type == e1000_phy_82577)) { 607675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.acquire(hw); 607775eba5b6SRobert Mustacchi if (ret_val) 607875eba5b6SRobert Mustacchi return; 607975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.set_page(hw, 608075eba5b6SRobert Mustacchi HV_STATS_PAGE << IGP_PAGE_SHIFT); 608175eba5b6SRobert Mustacchi if (ret_val) 608275eba5b6SRobert Mustacchi goto release; 608375eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); 608475eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); 608575eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); 608675eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); 608775eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); 608875eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); 608975eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); 609075eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); 609175eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); 609275eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); 609375eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); 609475eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); 609575eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); 609675eba5b6SRobert Mustacchi hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); 609775eba5b6SRobert Mustacchi release: 609875eba5b6SRobert Mustacchi hw->phy.ops.release(hw); 609975eba5b6SRobert Mustacchi } 610075eba5b6SRobert Mustacchi } 610175eba5b6SRobert Mustacchi 6102