Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2020 Intel Corporation
3 : : */
4 : :
5 : : #include "e1000_hw.h"
6 : : #include "e1000_82575.h"
7 : : #include "e1000_mac.h"
8 : : #include "e1000_base.h"
9 : : #include "e1000_manage.h"
10 : :
11 : : /**
12 : : * e1000_acquire_phy_base - Acquire rights to access PHY
13 : : * @hw: pointer to the HW structure
14 : : *
15 : : * Acquire access rights to the correct PHY.
16 : : **/
17 : 0 : s32 e1000_acquire_phy_base(struct e1000_hw *hw)
18 : : {
19 : : u16 mask = E1000_SWFW_PHY0_SM;
20 : :
21 : 0 : DEBUGFUNC("e1000_acquire_phy_base");
22 : :
23 [ # # ]: 0 : if (hw->bus.func == E1000_FUNC_1)
24 : : mask = E1000_SWFW_PHY1_SM;
25 [ # # ]: 0 : else if (hw->bus.func == E1000_FUNC_2)
26 : : mask = E1000_SWFW_PHY2_SM;
27 [ # # ]: 0 : else if (hw->bus.func == E1000_FUNC_3)
28 : : mask = E1000_SWFW_PHY3_SM;
29 : :
30 : 0 : return hw->mac.ops.acquire_swfw_sync(hw, mask);
31 : : }
32 : :
33 : : /**
34 : : * e1000_release_phy_base - Release rights to access PHY
35 : : * @hw: pointer to the HW structure
36 : : *
37 : : * A wrapper to release access rights to the correct PHY.
38 : : **/
39 : 0 : void e1000_release_phy_base(struct e1000_hw *hw)
40 : : {
41 : : u16 mask = E1000_SWFW_PHY0_SM;
42 : :
43 : 0 : DEBUGFUNC("e1000_release_phy_base");
44 : :
45 [ # # ]: 0 : if (hw->bus.func == E1000_FUNC_1)
46 : : mask = E1000_SWFW_PHY1_SM;
47 [ # # ]: 0 : else if (hw->bus.func == E1000_FUNC_2)
48 : : mask = E1000_SWFW_PHY2_SM;
49 [ # # ]: 0 : else if (hw->bus.func == E1000_FUNC_3)
50 : : mask = E1000_SWFW_PHY3_SM;
51 : :
52 : 0 : hw->mac.ops.release_swfw_sync(hw, mask);
53 : 0 : }
54 : :
55 : : /**
56 : : * e1000_init_hw_base - Initialize hardware
57 : : * @hw: pointer to the HW structure
58 : : *
59 : : * This inits the hardware readying it for operation.
60 : : **/
61 : 0 : s32 e1000_init_hw_base(struct e1000_hw *hw)
62 : : {
63 : : struct e1000_mac_info *mac = &hw->mac;
64 : : s32 ret_val;
65 : 0 : u16 i, rar_count = mac->rar_entry_count;
66 : :
67 : 0 : DEBUGFUNC("e1000_init_hw_base");
68 : :
69 : : /* Setup the receive address */
70 : 0 : e1000_init_rx_addrs_generic(hw, rar_count);
71 : :
72 : : /* Zero out the Multicast HASH table */
73 : 0 : DEBUGOUT("Zeroing the MTA\n");
74 [ # # ]: 0 : for (i = 0; i < mac->mta_reg_count; i++)
75 : 0 : E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
76 : :
77 : : /* Zero out the Unicast HASH table */
78 : 0 : DEBUGOUT("Zeroing the UTA\n");
79 [ # # ]: 0 : for (i = 0; i < mac->uta_reg_count; i++)
80 : 0 : E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
81 : :
82 : : /* Setup link and flow control */
83 : 0 : ret_val = mac->ops.setup_link(hw);
84 : :
85 : : /* Clear all of the statistics registers (clear on read). It is
86 : : * important that we do this after we have tried to establish link
87 : : * because the symbol error count will increment wildly if there
88 : : * is no link.
89 : : */
90 : 0 : e1000_clear_hw_cntrs_base_generic(hw);
91 : :
92 : 0 : return ret_val;
93 : : }
94 : :
95 : : /**
96 : : * e1000_power_down_phy_copper_base - Remove link during PHY power down
97 : : * @hw: pointer to the HW structure
98 : : *
99 : : * In the case of a PHY power down to save power, or to turn off link during a
100 : : * driver unload, or wake on lan is not enabled, remove the link.
101 : : **/
102 : 0 : void e1000_power_down_phy_copper_base(struct e1000_hw *hw)
103 : : {
104 : : struct e1000_phy_info *phy = &hw->phy;
105 : :
106 [ # # ]: 0 : if (!(phy->ops.check_reset_block))
107 : : return;
108 : :
109 : : /* If the management interface is not enabled, then power down */
110 [ # # # # ]: 0 : if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
111 : 0 : e1000_power_down_phy_copper(hw);
112 : : }
113 : :
114 : : /**
115 : : * e1000_rx_fifo_flush_base - Clean Rx FIFO after Rx enable
116 : : * @hw: pointer to the HW structure
117 : : *
118 : : * After Rx enable, if manageability is enabled then there is likely some
119 : : * bad data at the start of the FIFO and possibly in the DMA FIFO. This
120 : : * function clears the FIFOs and flushes any packets that came in as Rx was
121 : : * being enabled.
122 : : **/
123 : 0 : void e1000_rx_fifo_flush_base(struct e1000_hw *hw)
124 : : {
125 : : u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
126 : : int i, ms_wait;
127 : :
128 : 0 : DEBUGFUNC("e1000_rx_fifo_flush_base");
129 : :
130 : : /* disable IPv6 options as per hardware errata */
131 : 0 : rfctl = E1000_READ_REG(hw, E1000_RFCTL);
132 : 0 : rfctl |= E1000_RFCTL_IPV6_EX_DIS;
133 : 0 : E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
134 : :
135 [ # # ]: 0 : if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
136 : 0 : return;
137 : :
138 : : /* Disable all Rx queues */
139 [ # # ]: 0 : for (i = 0; i < 4; i++) {
140 : 0 : rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
141 : 0 : E1000_WRITE_REG(hw, E1000_RXDCTL(i),
142 : : rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
143 : : }
144 : : /* Poll all queues to verify they have shut down */
145 [ # # ]: 0 : for (ms_wait = 0; ms_wait < 10; ms_wait++) {
146 : 0 : msec_delay(1);
147 : : rx_enabled = 0;
148 [ # # ]: 0 : for (i = 0; i < 4; i++)
149 : 0 : rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
150 [ # # ]: 0 : if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
151 : : break;
152 : : }
153 : :
154 [ # # ]: 0 : if (ms_wait == 10)
155 : 0 : DEBUGOUT("Queue disable timed out after 10ms\n");
156 : :
157 : : /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
158 : : * incoming packets are rejected. Set enable and wait 2ms so that
159 : : * any packet that was coming in as RCTL.EN was set is flushed
160 : : */
161 : 0 : E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
162 : :
163 : 0 : rlpml = E1000_READ_REG(hw, E1000_RLPML);
164 : 0 : E1000_WRITE_REG(hw, E1000_RLPML, 0);
165 : :
166 : 0 : rctl = E1000_READ_REG(hw, E1000_RCTL);
167 : 0 : temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
168 : 0 : temp_rctl |= E1000_RCTL_LPE;
169 : :
170 : 0 : E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
171 : 0 : E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
172 : 0 : E1000_WRITE_FLUSH(hw);
173 : 0 : msec_delay(2);
174 : :
175 : : /* Enable Rx queues that were previously enabled and restore our
176 : : * previous state
177 : : */
178 [ # # ]: 0 : for (i = 0; i < 4; i++)
179 : 0 : E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
180 : 0 : E1000_WRITE_REG(hw, E1000_RCTL, rctl);
181 : 0 : E1000_WRITE_FLUSH(hw);
182 : :
183 : 0 : E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
184 : 0 : E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
185 : :
186 : : /* Flush receive errors generated by workaround */
187 : 0 : E1000_READ_REG(hw, E1000_ROC);
188 : 0 : E1000_READ_REG(hw, E1000_RNBC);
189 : 0 : E1000_READ_REG(hw, E1000_MPC);
190 : : }
|