X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000%2Fbase%2Fe1000_i210.c;h=5c2fe8a3ebe51d1093f75213ac544b6c1efc2bbf;hb=df01c0ee277d51f81d7d72501dba97550d3b6c4a;hp=1f5600d5d7cf4f2bd34ff53aefe99c9e43603ec8;hpb=d15fcf76c8b76e12c4050609cd31927ee0864c5a;p=dpdk.git diff --git a/drivers/net/e1000/base/e1000_i210.c b/drivers/net/e1000/base/e1000_i210.c index 1f5600d5d7..5c2fe8a3eb 100644 --- a/drivers/net/e1000/base/e1000_i210.c +++ b/drivers/net/e1000/base/e1000_i210.c @@ -1,35 +1,6 @@ -/******************************************************************************* - -Copyright (c) 2001-2014, 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 + */ #include "e1000_api.h" @@ -844,77 +815,6 @@ out: return ret_val; } -/** - * __e1000_access_xmdio_reg - Read/write XMDIO register - * @hw: pointer to the HW structure - * @address: XMDIO address to program - * @dev_addr: device address to program - * @data: pointer to value to read/write from/to the XMDIO address - * @read: boolean flag to indicate read or write - **/ -STATIC s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address, - u8 dev_addr, u16 *data, bool read) -{ - s32 ret_val; - - DEBUGFUNC("__e1000_access_xmdio_reg"); - - ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr); - if (ret_val) - return ret_val; - - ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address); - if (ret_val) - return ret_val; - - ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA | - dev_addr); - if (ret_val) - return ret_val; - - if (read) - ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data); - else - ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data); - if (ret_val) - return ret_val; - - /* Recalibrate the device back to 0 */ - ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0); - if (ret_val) - return ret_val; - - return ret_val; -} - -/** - * e1000_read_xmdio_reg - Read XMDIO register - * @hw: pointer to the HW structure - * @addr: XMDIO address to program - * @dev_addr: device address to program - * @data: value to be read from the EMI address - **/ -s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data) -{ - DEBUGFUNC("e1000_read_xmdio_reg"); - - return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, true); -} - -/** - * e1000_write_xmdio_reg - Write XMDIO register - * @hw: pointer to the HW structure - * @addr: XMDIO address to program - * @dev_addr: device address to program - * @data: value to be written to the XMDIO address - **/ -s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data) -{ - DEBUGFUNC("e1000_read_xmdio_reg"); - - return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, false); -} - /** * e1000_pll_workaround_i210 * @hw: pointer to the HW structure @@ -925,10 +825,12 @@ s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data) STATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw) { s32 ret_val; - u32 wuc, mdicnfg, ctrl_ext, reg_val; + u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val; u16 nvm_word, phy_word, pci_word, tmp_nvm; int i; + /* Get PHY semaphore */ + hw->phy.ops.acquire(hw); /* Get and set needed register values */ wuc = E1000_READ_REG(hw, E1000_WUC); mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG); @@ -941,10 +843,14 @@ STATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw) if (ret_val != E1000_SUCCESS) nvm_word = E1000_INVM_DEFAULT_AL; tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL; + phy_word = E1000_PHY_PLL_UNCONF; for (i = 0; i < E1000_MAX_PLL_TRIES; i++) { - /* check current state */ - hw->phy.ops.read_reg(hw, (E1000_PHY_PLL_FREQ_PAGE | - E1000_PHY_PLL_FREQ_REG), &phy_word); + /* check current state directly from internal PHY */ + e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, 0xFC); + usec_delay(20); + e1000_read_phy_reg_mdic(hw, E1000_PHY_PLL_FREQ_REG, &phy_word); + usec_delay(20); + e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, 0); if ((phy_word & E1000_PHY_PLL_UNCONF) != E1000_PHY_PLL_UNCONF) { ret_val = E1000_SUCCESS; @@ -952,14 +858,17 @@ STATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw) } else { ret_val = -E1000_ERR_PHY; } - hw->phy.ops.reset(hw); + /* directly reset the internal PHY */ + ctrl = E1000_READ_REG(hw, E1000_CTRL); + E1000_WRITE_REG(hw, E1000_CTRL, ctrl|E1000_CTRL_PHY_RST); + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE); E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); E1000_WRITE_REG(hw, E1000_WUC, 0); reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16); - E1000_WRITE_REG(hw, E1000_EEARBC, reg_val); + E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val); e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); pci_word |= E1000_PCI_PMCSR_D3; @@ -968,16 +877,47 @@ STATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw) pci_word &= ~E1000_PCI_PMCSR_D3; e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16); - E1000_WRITE_REG(hw, E1000_EEARBC, reg_val); + E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val); /* restore WUC register */ E1000_WRITE_REG(hw, E1000_WUC, wuc); } /* restore MDICNFG setting */ E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg); + /* Release PHY semaphore */ + hw->phy.ops.release(hw); return ret_val; } +/** + * e1000_get_cfg_done_i210 - Read config done bit + * @hw: pointer to the HW structure + * + * Read the management control register for the config done bit for + * completion status. NOTE: silicon which is EEPROM-less will fail trying + * to read the config done bit, so an error is *ONLY* logged and returns + * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon + * would not be able to be reset or change link. + **/ +STATIC s32 e1000_get_cfg_done_i210(struct e1000_hw *hw) +{ + s32 timeout = PHY_CFG_TIMEOUT; + u32 mask = E1000_NVM_CFG_DONE_PORT_0; + + DEBUGFUNC("e1000_get_cfg_done_i210"); + + while (timeout) { + if (E1000_READ_REG(hw, E1000_EEMNGCTL_I210) & mask) + break; + msec_delay(1); + timeout--; + } + if (!timeout) + DEBUGOUT("MNG configuration cycle has not completed.\n"); + + return E1000_SUCCESS; +} + /** * e1000_init_hw_i210 - Init hw for I210/I211 * @hw: pointer to the HW structure @@ -995,6 +935,7 @@ s32 e1000_init_hw_i210(struct e1000_hw *hw) if (ret_val != E1000_SUCCESS) return ret_val; } + hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i210; ret_val = e1000_init_hw_82575(hw); return ret_val; }