xref: /freebsd-src/sys/dev/e1000/e1000_base.c (revision ddfec1fb6814088abc5805f45c4a18c5731d51b9)
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