16b9d35faSGuinan Sun /****************************************************************************** 26b9d35faSGuinan Sun SPDX-License-Identifier: BSD-3-Clause 36b9d35faSGuinan Sun 46b9d35faSGuinan Sun Copyright (c) 2001-2020, Intel Corporation 56b9d35faSGuinan Sun All rights reserved. 66b9d35faSGuinan Sun 76b9d35faSGuinan Sun Redistribution and use in source and binary forms, with or without 86b9d35faSGuinan Sun modification, are permitted provided that the following conditions are met: 96b9d35faSGuinan Sun 106b9d35faSGuinan Sun 1. Redistributions of source code must retain the above copyright notice, 116b9d35faSGuinan Sun this list of conditions and the following disclaimer. 126b9d35faSGuinan Sun 136b9d35faSGuinan Sun 2. Redistributions in binary form must reproduce the above copyright 146b9d35faSGuinan Sun notice, this list of conditions and the following disclaimer in the 156b9d35faSGuinan Sun documentation and/or other materials provided with the distribution. 166b9d35faSGuinan Sun 176b9d35faSGuinan Sun 3. Neither the name of the Intel Corporation nor the names of its 186b9d35faSGuinan Sun contributors may be used to endorse or promote products derived from 196b9d35faSGuinan Sun this software without specific prior written permission. 206b9d35faSGuinan Sun 216b9d35faSGuinan Sun THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 226b9d35faSGuinan Sun AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 236b9d35faSGuinan Sun IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 246b9d35faSGuinan Sun ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 256b9d35faSGuinan Sun LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 266b9d35faSGuinan Sun CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 276b9d35faSGuinan Sun SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 286b9d35faSGuinan Sun INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 296b9d35faSGuinan Sun CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 306b9d35faSGuinan Sun ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 316b9d35faSGuinan Sun POSSIBILITY OF SUCH DAMAGE. 326b9d35faSGuinan Sun 336b9d35faSGuinan Sun ******************************************************************************/ 346b9d35faSGuinan Sun 356b9d35faSGuinan Sun #include "e1000_hw.h" 366b9d35faSGuinan Sun #include "e1000_82575.h" 376b9d35faSGuinan Sun #include "e1000_mac.h" 386b9d35faSGuinan Sun #include "e1000_base.h" 396b9d35faSGuinan Sun #include "e1000_manage.h" 406b9d35faSGuinan Sun 416b9d35faSGuinan Sun /** 426b9d35faSGuinan Sun * e1000_acquire_phy_base - Acquire rights to access PHY 436b9d35faSGuinan Sun * @hw: pointer to the HW structure 446b9d35faSGuinan Sun * 456b9d35faSGuinan Sun * Acquire access rights to the correct PHY. 466b9d35faSGuinan Sun **/ 476b9d35faSGuinan Sun s32 e1000_acquire_phy_base(struct e1000_hw *hw) 486b9d35faSGuinan Sun { 496b9d35faSGuinan Sun u16 mask = E1000_SWFW_PHY0_SM; 506b9d35faSGuinan Sun 516b9d35faSGuinan Sun DEBUGFUNC("e1000_acquire_phy_base"); 526b9d35faSGuinan Sun 536b9d35faSGuinan Sun if (hw->bus.func == E1000_FUNC_1) 546b9d35faSGuinan Sun mask = E1000_SWFW_PHY1_SM; 556b9d35faSGuinan Sun else if (hw->bus.func == E1000_FUNC_2) 566b9d35faSGuinan Sun mask = E1000_SWFW_PHY2_SM; 576b9d35faSGuinan Sun else if (hw->bus.func == E1000_FUNC_3) 586b9d35faSGuinan Sun mask = E1000_SWFW_PHY3_SM; 596b9d35faSGuinan Sun 606b9d35faSGuinan Sun return hw->mac.ops.acquire_swfw_sync(hw, mask); 616b9d35faSGuinan Sun } 626b9d35faSGuinan Sun 636b9d35faSGuinan Sun /** 646b9d35faSGuinan Sun * e1000_release_phy_base - Release rights to access PHY 656b9d35faSGuinan Sun * @hw: pointer to the HW structure 666b9d35faSGuinan Sun * 676b9d35faSGuinan Sun * A wrapper to release access rights to the correct PHY. 686b9d35faSGuinan Sun **/ 696b9d35faSGuinan Sun void e1000_release_phy_base(struct e1000_hw *hw) 706b9d35faSGuinan Sun { 716b9d35faSGuinan Sun u16 mask = E1000_SWFW_PHY0_SM; 726b9d35faSGuinan Sun 736b9d35faSGuinan Sun DEBUGFUNC("e1000_release_phy_base"); 746b9d35faSGuinan Sun 756b9d35faSGuinan Sun if (hw->bus.func == E1000_FUNC_1) 766b9d35faSGuinan Sun mask = E1000_SWFW_PHY1_SM; 776b9d35faSGuinan Sun else if (hw->bus.func == E1000_FUNC_2) 786b9d35faSGuinan Sun mask = E1000_SWFW_PHY2_SM; 796b9d35faSGuinan Sun else if (hw->bus.func == E1000_FUNC_3) 806b9d35faSGuinan Sun mask = E1000_SWFW_PHY3_SM; 816b9d35faSGuinan Sun 826b9d35faSGuinan Sun hw->mac.ops.release_swfw_sync(hw, mask); 836b9d35faSGuinan Sun } 846b9d35faSGuinan Sun 856b9d35faSGuinan Sun /** 866b9d35faSGuinan Sun * e1000_init_hw_base - Initialize hardware 876b9d35faSGuinan Sun * @hw: pointer to the HW structure 886b9d35faSGuinan Sun * 896b9d35faSGuinan Sun * This inits the hardware readying it for operation. 906b9d35faSGuinan Sun **/ 916b9d35faSGuinan Sun s32 e1000_init_hw_base(struct e1000_hw *hw) 926b9d35faSGuinan Sun { 936b9d35faSGuinan Sun struct e1000_mac_info *mac = &hw->mac; 946b9d35faSGuinan Sun s32 ret_val; 956b9d35faSGuinan Sun u16 i, rar_count = mac->rar_entry_count; 966b9d35faSGuinan Sun 976b9d35faSGuinan Sun DEBUGFUNC("e1000_init_hw_base"); 986b9d35faSGuinan Sun 996b9d35faSGuinan Sun /* Setup the receive address */ 1006b9d35faSGuinan Sun e1000_init_rx_addrs_generic(hw, rar_count); 1016b9d35faSGuinan Sun 1026b9d35faSGuinan Sun /* Zero out the Multicast HASH table */ 1036b9d35faSGuinan Sun DEBUGOUT("Zeroing the MTA\n"); 1046b9d35faSGuinan Sun for (i = 0; i < mac->mta_reg_count; i++) 1056b9d35faSGuinan Sun E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 1066b9d35faSGuinan Sun 1076b9d35faSGuinan Sun /* Zero out the Unicast HASH table */ 1086b9d35faSGuinan Sun DEBUGOUT("Zeroing the UTA\n"); 1096b9d35faSGuinan Sun for (i = 0; i < mac->uta_reg_count; i++) 1106b9d35faSGuinan Sun E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0); 1116b9d35faSGuinan Sun 1126b9d35faSGuinan Sun /* Setup link and flow control */ 1136b9d35faSGuinan Sun ret_val = mac->ops.setup_link(hw); 1146b9d35faSGuinan Sun 1156b9d35faSGuinan Sun /* Clear all of the statistics registers (clear on read). It is 1166b9d35faSGuinan Sun * important that we do this after we have tried to establish link 1176b9d35faSGuinan Sun * because the symbol error count will increment wildly if there 1186b9d35faSGuinan Sun * is no link. 1196b9d35faSGuinan Sun */ 1206b9d35faSGuinan Sun e1000_clear_hw_cntrs_base_generic(hw); 1216b9d35faSGuinan Sun 1226b9d35faSGuinan Sun return ret_val; 1236b9d35faSGuinan Sun } 1246b9d35faSGuinan Sun 1256b9d35faSGuinan Sun /** 1266b9d35faSGuinan Sun * e1000_power_down_phy_copper_base - Remove link during PHY power down 1276b9d35faSGuinan Sun * @hw: pointer to the HW structure 1286b9d35faSGuinan Sun * 1296b9d35faSGuinan Sun * In the case of a PHY power down to save power, or to turn off link during a 1306b9d35faSGuinan Sun * driver unload, or wake on lan is not enabled, remove the link. 1316b9d35faSGuinan Sun **/ 1326b9d35faSGuinan Sun void e1000_power_down_phy_copper_base(struct e1000_hw *hw) 1336b9d35faSGuinan Sun { 1346b9d35faSGuinan Sun struct e1000_phy_info *phy = &hw->phy; 1356b9d35faSGuinan Sun 1366b9d35faSGuinan Sun if (!(phy->ops.check_reset_block)) 1376b9d35faSGuinan Sun return; 1386b9d35faSGuinan Sun 1396b9d35faSGuinan Sun /* If the management interface is not enabled, then power down */ 140811912c4SAnatoly Burakov if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw))) 1416b9d35faSGuinan Sun e1000_power_down_phy_copper(hw); 1426b9d35faSGuinan Sun } 1436b9d35faSGuinan Sun 1446b9d35faSGuinan Sun /** 1456b9d35faSGuinan Sun * e1000_rx_fifo_flush_base - Clean Rx FIFO after Rx enable 1466b9d35faSGuinan Sun * @hw: pointer to the HW structure 1476b9d35faSGuinan Sun * 1486b9d35faSGuinan Sun * After Rx enable, if manageability is enabled then there is likely some 1496b9d35faSGuinan Sun * bad data at the start of the FIFO and possibly in the DMA FIFO. This 1506b9d35faSGuinan Sun * function clears the FIFOs and flushes any packets that came in as Rx was 1516b9d35faSGuinan Sun * being enabled. 1526b9d35faSGuinan Sun **/ 1536b9d35faSGuinan Sun void e1000_rx_fifo_flush_base(struct e1000_hw *hw) 1546b9d35faSGuinan Sun { 1556b9d35faSGuinan Sun u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled; 1566b9d35faSGuinan Sun int i, ms_wait; 1576b9d35faSGuinan Sun 1586b9d35faSGuinan Sun DEBUGFUNC("e1000_rx_fifo_flush_base"); 1596b9d35faSGuinan Sun 1606b9d35faSGuinan Sun /* disable IPv6 options as per hardware errata */ 1616b9d35faSGuinan Sun rfctl = E1000_READ_REG(hw, E1000_RFCTL); 1626b9d35faSGuinan Sun rfctl |= E1000_RFCTL_IPV6_EX_DIS; 1636b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); 1646b9d35faSGuinan Sun 165*ddfec1fbSKevin Bowling if (hw->mac.type != e1000_82575 || 166*ddfec1fbSKevin Bowling !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN)) 1676b9d35faSGuinan Sun return; 1686b9d35faSGuinan Sun 1696b9d35faSGuinan Sun /* Disable all Rx queues */ 1706b9d35faSGuinan Sun for (i = 0; i < 4; i++) { 1716b9d35faSGuinan Sun rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i)); 1726b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RXDCTL(i), 1736b9d35faSGuinan Sun rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); 1746b9d35faSGuinan Sun } 1756b9d35faSGuinan Sun /* Poll all queues to verify they have shut down */ 1766b9d35faSGuinan Sun for (ms_wait = 0; ms_wait < 10; ms_wait++) { 1776b9d35faSGuinan Sun msec_delay(1); 1786b9d35faSGuinan Sun rx_enabled = 0; 1796b9d35faSGuinan Sun for (i = 0; i < 4; i++) 1806b9d35faSGuinan Sun rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i)); 1816b9d35faSGuinan Sun if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE)) 1826b9d35faSGuinan Sun break; 1836b9d35faSGuinan Sun } 1846b9d35faSGuinan Sun 1856b9d35faSGuinan Sun if (ms_wait == 10) 1866b9d35faSGuinan Sun DEBUGOUT("Queue disable timed out after 10ms\n"); 1876b9d35faSGuinan Sun 1886b9d35faSGuinan Sun /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all 1896b9d35faSGuinan Sun * incoming packets are rejected. Set enable and wait 2ms so that 1906b9d35faSGuinan Sun * any packet that was coming in as RCTL.EN was set is flushed 1916b9d35faSGuinan Sun */ 1926b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF); 1936b9d35faSGuinan Sun 1946b9d35faSGuinan Sun rlpml = E1000_READ_REG(hw, E1000_RLPML); 1956b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RLPML, 0); 1966b9d35faSGuinan Sun 1976b9d35faSGuinan Sun rctl = E1000_READ_REG(hw, E1000_RCTL); 1986b9d35faSGuinan Sun temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP); 1996b9d35faSGuinan Sun temp_rctl |= E1000_RCTL_LPE; 2006b9d35faSGuinan Sun 2016b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl); 2026b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN); 2036b9d35faSGuinan Sun E1000_WRITE_FLUSH(hw); 2046b9d35faSGuinan Sun msec_delay(2); 2056b9d35faSGuinan Sun 2066b9d35faSGuinan Sun /* Enable Rx queues that were previously enabled and restore our 2076b9d35faSGuinan Sun * previous state 2086b9d35faSGuinan Sun */ 2096b9d35faSGuinan Sun for (i = 0; i < 4; i++) 2106b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]); 2116b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RCTL, rctl); 2126b9d35faSGuinan Sun E1000_WRITE_FLUSH(hw); 2136b9d35faSGuinan Sun 2146b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RLPML, rlpml); 2156b9d35faSGuinan Sun E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); 2166b9d35faSGuinan Sun 2176b9d35faSGuinan Sun /* Flush receive errors generated by workaround */ 2186b9d35faSGuinan Sun E1000_READ_REG(hw, E1000_ROC); 2196b9d35faSGuinan Sun E1000_READ_REG(hw, E1000_RNBC); 2206b9d35faSGuinan Sun E1000_READ_REG(hw, E1000_MPC); 2216b9d35faSGuinan Sun } 222