X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000%2Fbase%2Fe1000_ich8lan.c;h=b79e3bad880b4bc78bf107878bee7edee03302b3;hb=4e408146c8a1036ad8d6c2c1f72f9c97a7d6537d;hp=7ab0f7cc05edcb4eb6c08c8947b2211e7266e394;hpb=a3358d942fa97ddb3b9461543896a55f60b5e782;p=dpdk.git diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c index 7ab0f7cc05..b79e3bad88 100644 --- a/drivers/net/e1000/base/e1000_ich8lan.c +++ b/drivers/net/e1000/base/e1000_ich8lan.c @@ -1,35 +1,6 @@ -/******************************************************************************* - -Copyright (c) 2001-2015, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -***************************************************************************/ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2001 - 2015 Intel Corporation + */ /* 82562G 10/100 Network Connection * 82562G-2 10/100 Network Connection @@ -346,6 +317,7 @@ STATIC s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: if (e1000_phy_is_accessible_pchlan(hw)) break; @@ -494,6 +466,7 @@ STATIC s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: /* In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ @@ -798,6 +771,7 @@ STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /* fall-through */ case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: #ifndef NO_NON_BLOCKING_PHY_MTA_UPDATE_SUPPORT /* multicast address update for pch2 */ mac->ops.update_mc_addr_list = @@ -848,7 +822,7 @@ STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /** * __e1000_access_emi_reg_locked - Read/write EMI register * @hw: pointer to the HW structure - * @addr: EMI address to program + * @address: EMI address to program * @data: pointer to value to read/write from/to the EMI address * @read: boolean flag to indicate read or write * @@ -1294,6 +1268,7 @@ out: s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) { s32 ret_val = E1000_SUCCESS; + u8 ulp_exit_timeout = 30; u32 mac_reg; u16 phy_reg; int i = 0; @@ -1315,10 +1290,12 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); } - /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */ + if (hw->mac.type == e1000_pch_cnp) + ulp_exit_timeout = 100; + while (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_ULP_CFG_DONE) { - if (i++ == 30) { + if (i++ == ulp_exit_timeout) { ret_val = -E1000_ERR_PHY; goto out; } @@ -1572,8 +1549,6 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (hw->mac.type >= e1000_pch_lpt) { - u16 phy_reg; - hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG, &phy_reg); phy_reg &= ~I217_PLL_CLOCK_GATE_MASK; @@ -1584,6 +1559,16 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) hw->phy.ops.write_reg_locked(hw, I217_PLL_CLOCK_GATE_REG, phy_reg); + + if (speed == SPEED_1000) { + hw->phy.ops.read_reg_locked(hw, HV_PM_CTRL, + &phy_reg); + + phy_reg |= HV_PM_CTRL_K1_CLK_REQ; + + hw->phy.ops.write_reg_locked(hw, HV_PM_CTRL, + phy_reg); + } } hw->phy.ops.release(hw); @@ -1678,6 +1663,9 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; } + if (hw->dev_spec.ich8lan.disable_k1_off == true) + fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; + E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6); } @@ -1775,6 +1763,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: hw->phy.ops.init_params = e1000_init_phy_params_pchlan; break; default: @@ -2241,6 +2230,7 @@ STATIC s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; break; default: @@ -2412,7 +2402,7 @@ release: /** * e1000_configure_k1_ich8lan - Configure K1 power state * @hw: pointer to the HW structure - * @enable: K1 state to configure + * @k1_enable: K1 state to configure * * Configure the K1 power state based on the provided parameter. * Assumes semaphore already acquired. @@ -2560,6 +2550,7 @@ STATIC s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) /** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. + * @hw: pointer to the HW structure **/ STATIC s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) { @@ -2886,6 +2877,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) /** * e1000_lv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. + * @hw: pointer to the HW structure **/ STATIC s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) { @@ -3365,6 +3357,7 @@ STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) switch (hw->mac.type) { case e1000_pch_spt: + case e1000_pch_cnp: bank1_offset = nvm->flash_bank_size; act_offset = E1000_ICH_NVM_SIG_WORD; @@ -3489,8 +3482,9 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words, for (i = 0; i < words; i += 2) { if (words - i == 1) { - if (dev_spec->shadow_ram[offset+i].modified) { - data[i] = dev_spec->shadow_ram[offset+i].value; + if (dev_spec->shadow_ram[offset + i].modified) { + data[i] = + dev_spec->shadow_ram[offset + i].value; } else { offset_to_read = act_offset + i - ((act_offset + i) % 2); @@ -3507,8 +3501,8 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words, } } else { offset_to_read = act_offset + i; - if (!(dev_spec->shadow_ram[offset+i].modified) || - !(dev_spec->shadow_ram[offset+i+1].modified)) { + if (!(dev_spec->shadow_ram[offset + i].modified) || + !(dev_spec->shadow_ram[offset + i + 1].modified)) { ret_val = e1000_read_flash_dword_ich8lan(hw, offset_to_read, @@ -3516,15 +3510,16 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words, if (ret_val) break; } - if (dev_spec->shadow_ram[offset+i].modified) - data[i] = dev_spec->shadow_ram[offset+i].value; + if (dev_spec->shadow_ram[offset + i].modified) + data[i] = + dev_spec->shadow_ram[offset + i].value; else - data[i] = (u16) (dword & 0xFFFF); - if (dev_spec->shadow_ram[offset+i].modified) - data[i+1] = - dev_spec->shadow_ram[offset+i+1].value; + data[i] = (u16)(dword & 0xFFFF); + if (dev_spec->shadow_ram[offset + i + 1].modified) + data[i + 1] = + dev_spec->shadow_ram[offset + i + 1].value; else - data[i+1] = (u16) (dword >> 16 & 0xFFFF); + data[i + 1] = (u16)(dword >> 16 & 0xFFFF); } } @@ -3578,8 +3573,8 @@ STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, ret_val = E1000_SUCCESS; for (i = 0; i < words; i++) { - if (dev_spec->shadow_ram[offset+i].modified) { - data[i] = dev_spec->shadow_ram[offset+i].value; + if (dev_spec->shadow_ram[offset + i].modified) { + data[i] = dev_spec->shadow_ram[offset + i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, act_offset + i, @@ -3984,8 +3979,8 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, nvm->ops.acquire(hw); for (i = 0; i < words; i++) { - dev_spec->shadow_ram[offset+i].modified = true; - dev_spec->shadow_ram[offset+i].value = data[i]; + dev_spec->shadow_ram[offset + i].modified = true; + dev_spec->shadow_ram[offset + i].value = data[i]; } nvm->ops.release(hw); @@ -4340,6 +4335,7 @@ STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: word = NVM_COMPAT; valid_csum_mask = NVM_COMPAT_VALID_CSUM; break; @@ -4868,7 +4864,7 @@ STATIC s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) * @hw: pointer to the HW structure * * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability - * register, so the the bus width is hard coded. + * register, so the bus width is hard coded. **/ STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) { @@ -4903,6 +4899,7 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) u16 kum_cfg; u32 ctrl, reg; s32 ret_val; + u16 pci_cfg; DEBUGFUNC("e1000_reset_hw_ich8lan"); @@ -4963,11 +4960,28 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) e1000_gate_hw_phy_config_ich8lan(hw, true); } ret_val = e1000_acquire_swflag_ich8lan(hw); + + /* Read from EXTCNF_CTRL in e1000_acquire_swflag_ich8lan function + * may occur during global reset and cause system hang. + * Configuration space access creates the needed delay. + * Write to E1000_STRAP RO register E1000_PCI_VENDOR_ID_REGISTER value + * insures configuration space read is done before global reset. + */ + e1000_read_pci_cfg(hw, E1000_PCI_VENDOR_ID_REGISTER, &pci_cfg); + E1000_WRITE_REG(hw, E1000_STRAP, pci_cfg); DEBUGOUT("Issuing a global reset to ich8lan\n"); E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST)); /* cannot issue a flush here because it hangs the hardware */ msec_delay(20); + /* Configuration space access improve HW level time sync mechanism. + * Write to E1000_STRAP RO register E1000_PCI_VENDOR_ID_REGISTER + * value to insure configuration space read is done + * before any access to mac register. + */ + e1000_read_pci_cfg(hw, E1000_PCI_VENDOR_ID_REGISTER, &pci_cfg); + E1000_WRITE_REG(hw, E1000_STRAP, pci_cfg); + /* Set Phy Config Counter to 50msec */ if (hw->mac.type == e1000_pch2lan) { reg = E1000_READ_REG(hw, E1000_FEXTNVM3); @@ -5146,7 +5160,7 @@ STATIC void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) /* Device Status */ if (hw->mac.type == e1000_ich8lan) { reg = E1000_READ_REG(hw, E1000_STATUS); - reg &= ~(1 << 31); + reg &= ~(1U << 31); E1000_WRITE_REG(hw, E1000_STATUS, reg); } @@ -5542,7 +5556,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) { s32 ret_val; - u16 reg_data; + u16 reg_data = 0; DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan");