1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
251dce24bSJeff Kirsher /* Copyright(c) 1999 - 2018 Intel Corporation. */
3dee1ad47SJeff Kirsher 
4dee1ad47SJeff Kirsher #include "e1000.h"
5cbdbb58bSJamie Gloudon #include <linux/ethtool.h>
6dee1ad47SJeff Kirsher 
7dee1ad47SJeff Kirsher static s32 e1000_wait_autoneg(struct e1000_hw *hw);
8dee1ad47SJeff Kirsher static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
9dee1ad47SJeff Kirsher 					  u16 *data, bool read, bool page_set);
10dee1ad47SJeff Kirsher static u32 e1000_get_phy_addr_for_hv_page(u32 page);
11dee1ad47SJeff Kirsher static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
12dee1ad47SJeff Kirsher 					  u16 *data, bool read);
13dee1ad47SJeff Kirsher 
14dee1ad47SJeff Kirsher /* Cable length tables */
15dee1ad47SJeff Kirsher static const u16 e1000_m88_cable_length_table[] = {
1604e115cfSBruce Allan 	0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED
1704e115cfSBruce Allan };
18fc830b78SBruce Allan 
19dee1ad47SJeff Kirsher #define M88E1000_CABLE_LENGTH_TABLE_SIZE \
20dee1ad47SJeff Kirsher 		ARRAY_SIZE(e1000_m88_cable_length_table)
21dee1ad47SJeff Kirsher 
22dee1ad47SJeff Kirsher static const u16 e1000_igp_2_cable_length_table[] = {
23dee1ad47SJeff Kirsher 	0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
24dee1ad47SJeff Kirsher 	6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
25dee1ad47SJeff Kirsher 	26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
26dee1ad47SJeff Kirsher 	44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
27dee1ad47SJeff Kirsher 	66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
28dee1ad47SJeff Kirsher 	87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
29dee1ad47SJeff Kirsher 	100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
3004e115cfSBruce Allan 	124
3104e115cfSBruce Allan };
32fc830b78SBruce Allan 
33dee1ad47SJeff Kirsher #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
34dee1ad47SJeff Kirsher 		ARRAY_SIZE(e1000_igp_2_cable_length_table)
35dee1ad47SJeff Kirsher 
36dee1ad47SJeff Kirsher /**
37dee1ad47SJeff Kirsher  *  e1000e_check_reset_block_generic - Check if PHY reset is blocked
38dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
39dee1ad47SJeff Kirsher  *
40dee1ad47SJeff Kirsher  *  Read the PHY management control register and check whether a PHY reset
41dee1ad47SJeff Kirsher  *  is blocked.  If a reset is not blocked return 0, otherwise
42dee1ad47SJeff Kirsher  *  return E1000_BLK_PHY_RESET (12).
43dee1ad47SJeff Kirsher  **/
44dee1ad47SJeff Kirsher s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
45dee1ad47SJeff Kirsher {
46dee1ad47SJeff Kirsher 	u32 manc;
47dee1ad47SJeff Kirsher 
48dee1ad47SJeff Kirsher 	manc = er32(MANC);
49dee1ad47SJeff Kirsher 
50e5fe2541SBruce Allan 	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? E1000_BLK_PHY_RESET : 0;
51dee1ad47SJeff Kirsher }
52dee1ad47SJeff Kirsher 
53dee1ad47SJeff Kirsher /**
54dee1ad47SJeff Kirsher  *  e1000e_get_phy_id - Retrieve the PHY ID and revision
55dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
56dee1ad47SJeff Kirsher  *
57dee1ad47SJeff Kirsher  *  Reads the PHY registers and stores the PHY ID and possibly the PHY
58dee1ad47SJeff Kirsher  *  revision in the hardware structure.
59dee1ad47SJeff Kirsher  **/
60dee1ad47SJeff Kirsher s32 e1000e_get_phy_id(struct e1000_hw *hw)
61dee1ad47SJeff Kirsher {
62dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
63dee1ad47SJeff Kirsher 	s32 ret_val = 0;
64dee1ad47SJeff Kirsher 	u16 phy_id;
65dee1ad47SJeff Kirsher 	u16 retry_count = 0;
66dee1ad47SJeff Kirsher 
67668018d7SBruce Allan 	if (!phy->ops.read_reg)
685015e53aSBruce Allan 		return 0;
69dee1ad47SJeff Kirsher 
70dee1ad47SJeff Kirsher 	while (retry_count < 2) {
71c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_PHYSID1, &phy_id);
72dee1ad47SJeff Kirsher 		if (ret_val)
735015e53aSBruce Allan 			return ret_val;
74dee1ad47SJeff Kirsher 
75dee1ad47SJeff Kirsher 		phy->id = (u32)(phy_id << 16);
76ce43a216SBruce Allan 		usleep_range(20, 40);
77c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_PHYSID2, &phy_id);
78dee1ad47SJeff Kirsher 		if (ret_val)
795015e53aSBruce Allan 			return ret_val;
80dee1ad47SJeff Kirsher 
81dee1ad47SJeff Kirsher 		phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
82dee1ad47SJeff Kirsher 		phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
83dee1ad47SJeff Kirsher 
84dee1ad47SJeff Kirsher 		if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
855015e53aSBruce Allan 			return 0;
86dee1ad47SJeff Kirsher 
87dee1ad47SJeff Kirsher 		retry_count++;
88dee1ad47SJeff Kirsher 	}
895015e53aSBruce Allan 
905015e53aSBruce Allan 	return 0;
91dee1ad47SJeff Kirsher }
92dee1ad47SJeff Kirsher 
93dee1ad47SJeff Kirsher /**
94dee1ad47SJeff Kirsher  *  e1000e_phy_reset_dsp - Reset PHY DSP
95dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
96dee1ad47SJeff Kirsher  *
97dee1ad47SJeff Kirsher  *  Reset the digital signal processor.
98dee1ad47SJeff Kirsher  **/
99dee1ad47SJeff Kirsher s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
100dee1ad47SJeff Kirsher {
101dee1ad47SJeff Kirsher 	s32 ret_val;
102dee1ad47SJeff Kirsher 
103dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
104dee1ad47SJeff Kirsher 	if (ret_val)
105dee1ad47SJeff Kirsher 		return ret_val;
106dee1ad47SJeff Kirsher 
107dee1ad47SJeff Kirsher 	return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
108dee1ad47SJeff Kirsher }
109dee1ad47SJeff Kirsher 
110*1d16cd91SVitaly Lifshits void e1000e_disable_phy_retry(struct e1000_hw *hw)
111*1d16cd91SVitaly Lifshits {
112*1d16cd91SVitaly Lifshits 	hw->phy.retry_enabled = false;
113*1d16cd91SVitaly Lifshits }
114*1d16cd91SVitaly Lifshits 
115*1d16cd91SVitaly Lifshits void e1000e_enable_phy_retry(struct e1000_hw *hw)
116*1d16cd91SVitaly Lifshits {
117*1d16cd91SVitaly Lifshits 	hw->phy.retry_enabled = true;
118*1d16cd91SVitaly Lifshits }
119*1d16cd91SVitaly Lifshits 
120dee1ad47SJeff Kirsher /**
121dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_mdic - Read MDI control register
122dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
123dee1ad47SJeff Kirsher  *  @offset: register offset to be read
124dee1ad47SJeff Kirsher  *  @data: pointer to the read data
125dee1ad47SJeff Kirsher  *
126dee1ad47SJeff Kirsher  *  Reads the MDI control register in the PHY at offset and stores the
127dee1ad47SJeff Kirsher  *  information read to data.
128dee1ad47SJeff Kirsher  **/
129dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
130dee1ad47SJeff Kirsher {
131*1d16cd91SVitaly Lifshits 	u32 i, mdic = 0, retry_counter, retry_max;
132dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
133*1d16cd91SVitaly Lifshits 	bool success;
134dee1ad47SJeff Kirsher 
135dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_REG_ADDRESS) {
136dee1ad47SJeff Kirsher 		e_dbg("PHY Address %d is out of range\n", offset);
137dee1ad47SJeff Kirsher 		return -E1000_ERR_PARAM;
138dee1ad47SJeff Kirsher 	}
139dee1ad47SJeff Kirsher 
140*1d16cd91SVitaly Lifshits 	retry_max = phy->retry_enabled ? phy->retry_count : 0;
141*1d16cd91SVitaly Lifshits 
142e921eb1aSBruce Allan 	/* Set up Op-code, Phy Address, and register offset in the MDI
143dee1ad47SJeff Kirsher 	 * Control register.  The MAC will take care of interfacing with the
144dee1ad47SJeff Kirsher 	 * PHY to retrieve the desired data.
145dee1ad47SJeff Kirsher 	 */
146*1d16cd91SVitaly Lifshits 	for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
147*1d16cd91SVitaly Lifshits 		success = true;
148*1d16cd91SVitaly Lifshits 
149dee1ad47SJeff Kirsher 		mdic = ((offset << E1000_MDIC_REG_SHIFT) |
150dee1ad47SJeff Kirsher 			(phy->addr << E1000_MDIC_PHY_SHIFT) |
151dee1ad47SJeff Kirsher 			(E1000_MDIC_OP_READ));
152dee1ad47SJeff Kirsher 
153dee1ad47SJeff Kirsher 		ew32(MDIC, mdic);
154dee1ad47SJeff Kirsher 
155e921eb1aSBruce Allan 		/* Poll the ready bit to see if the MDI read completed
156dee1ad47SJeff Kirsher 		 * Increasing the time out as testing showed failures with
157dee1ad47SJeff Kirsher 		 * the lower time out
158dee1ad47SJeff Kirsher 		 */
159dee1ad47SJeff Kirsher 		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
160*1d16cd91SVitaly Lifshits 			usleep_range(50, 60);
161dee1ad47SJeff Kirsher 			mdic = er32(MDIC);
162dee1ad47SJeff Kirsher 			if (mdic & E1000_MDIC_READY)
163dee1ad47SJeff Kirsher 				break;
164dee1ad47SJeff Kirsher 		}
165dee1ad47SJeff Kirsher 		if (!(mdic & E1000_MDIC_READY)) {
166*1d16cd91SVitaly Lifshits 			e_dbg("MDI Read PHY Reg Address %d did not complete\n",
167*1d16cd91SVitaly Lifshits 			      offset);
168*1d16cd91SVitaly Lifshits 			success = false;
169dee1ad47SJeff Kirsher 		}
170dee1ad47SJeff Kirsher 		if (mdic & E1000_MDIC_ERROR) {
17191ec7792SChen Yu 			e_dbg("MDI Read PHY Reg Address %d Error\n", offset);
172*1d16cd91SVitaly Lifshits 			success = false;
173dee1ad47SJeff Kirsher 		}
174d5752c7bSJesse Brandeburg 		if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
175bb034512SBruce Allan 			e_dbg("MDI Read offset error - requested %d, returned %d\n",
176d5752c7bSJesse Brandeburg 			      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
177*1d16cd91SVitaly Lifshits 			success = false;
178bb034512SBruce Allan 		}
179dee1ad47SJeff Kirsher 
180e921eb1aSBruce Allan 		/* Allow some time after each MDIC transaction to avoid
181dee1ad47SJeff Kirsher 		 * reading duplicate data in the next MDIC transaction.
182dee1ad47SJeff Kirsher 		 */
183dee1ad47SJeff Kirsher 		if (hw->mac.type == e1000_pch2lan)
184*1d16cd91SVitaly Lifshits 			usleep_range(100, 150);
185*1d16cd91SVitaly Lifshits 
186*1d16cd91SVitaly Lifshits 		if (success) {
187*1d16cd91SVitaly Lifshits 			*data = (u16)mdic;
188dee1ad47SJeff Kirsher 			return 0;
189dee1ad47SJeff Kirsher 		}
190dee1ad47SJeff Kirsher 
191*1d16cd91SVitaly Lifshits 		if (retry_counter != retry_max) {
192*1d16cd91SVitaly Lifshits 			e_dbg("Perform retry on PHY transaction...\n");
193*1d16cd91SVitaly Lifshits 			mdelay(10);
194*1d16cd91SVitaly Lifshits 		}
195*1d16cd91SVitaly Lifshits 	}
196*1d16cd91SVitaly Lifshits 
197*1d16cd91SVitaly Lifshits 	return -E1000_ERR_PHY;
198*1d16cd91SVitaly Lifshits }
199*1d16cd91SVitaly Lifshits 
200dee1ad47SJeff Kirsher /**
201dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_mdic - Write MDI control register
202dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
203dee1ad47SJeff Kirsher  *  @offset: register offset to write to
204dee1ad47SJeff Kirsher  *  @data: data to write to register at offset
205dee1ad47SJeff Kirsher  *
206dee1ad47SJeff Kirsher  *  Writes data to MDI control register in the PHY at offset.
207dee1ad47SJeff Kirsher  **/
208dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
209dee1ad47SJeff Kirsher {
210*1d16cd91SVitaly Lifshits 	u32 i, mdic = 0, retry_counter, retry_max;
211dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
212*1d16cd91SVitaly Lifshits 	bool success;
213dee1ad47SJeff Kirsher 
214dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_REG_ADDRESS) {
215dee1ad47SJeff Kirsher 		e_dbg("PHY Address %d is out of range\n", offset);
216dee1ad47SJeff Kirsher 		return -E1000_ERR_PARAM;
217dee1ad47SJeff Kirsher 	}
218dee1ad47SJeff Kirsher 
219*1d16cd91SVitaly Lifshits 	retry_max = phy->retry_enabled ? phy->retry_count : 0;
220*1d16cd91SVitaly Lifshits 
221e921eb1aSBruce Allan 	/* Set up Op-code, Phy Address, and register offset in the MDI
222dee1ad47SJeff Kirsher 	 * Control register.  The MAC will take care of interfacing with the
223dee1ad47SJeff Kirsher 	 * PHY to retrieve the desired data.
224dee1ad47SJeff Kirsher 	 */
225*1d16cd91SVitaly Lifshits 	for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
226*1d16cd91SVitaly Lifshits 		success = true;
227*1d16cd91SVitaly Lifshits 
228dee1ad47SJeff Kirsher 		mdic = (((u32)data) |
229dee1ad47SJeff Kirsher 			(offset << E1000_MDIC_REG_SHIFT) |
230dee1ad47SJeff Kirsher 			(phy->addr << E1000_MDIC_PHY_SHIFT) |
231dee1ad47SJeff Kirsher 			(E1000_MDIC_OP_WRITE));
232dee1ad47SJeff Kirsher 
233dee1ad47SJeff Kirsher 		ew32(MDIC, mdic);
234dee1ad47SJeff Kirsher 
235e921eb1aSBruce Allan 		/* Poll the ready bit to see if the MDI read completed
236dee1ad47SJeff Kirsher 		 * Increasing the time out as testing showed failures with
237dee1ad47SJeff Kirsher 		 * the lower time out
238dee1ad47SJeff Kirsher 		 */
239dee1ad47SJeff Kirsher 		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
240*1d16cd91SVitaly Lifshits 			usleep_range(50, 60);
241dee1ad47SJeff Kirsher 			mdic = er32(MDIC);
242dee1ad47SJeff Kirsher 			if (mdic & E1000_MDIC_READY)
243dee1ad47SJeff Kirsher 				break;
244dee1ad47SJeff Kirsher 		}
245dee1ad47SJeff Kirsher 		if (!(mdic & E1000_MDIC_READY)) {
246*1d16cd91SVitaly Lifshits 			e_dbg("MDI Write PHY Reg Address %d did not complete\n",
247*1d16cd91SVitaly Lifshits 			      offset);
248*1d16cd91SVitaly Lifshits 			success = false;
249dee1ad47SJeff Kirsher 		}
250dee1ad47SJeff Kirsher 		if (mdic & E1000_MDIC_ERROR) {
251*1d16cd91SVitaly Lifshits 			e_dbg("MDI Write PHY Reg Address %d Error\n", offset);
252*1d16cd91SVitaly Lifshits 			success = false;
253dee1ad47SJeff Kirsher 		}
254d5752c7bSJesse Brandeburg 		if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
255bb034512SBruce Allan 			e_dbg("MDI Write offset error - requested %d, returned %d\n",
256d5752c7bSJesse Brandeburg 			      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
257*1d16cd91SVitaly Lifshits 			success = false;
258bb034512SBruce Allan 		}
259dee1ad47SJeff Kirsher 
260e921eb1aSBruce Allan 		/* Allow some time after each MDIC transaction to avoid
261dee1ad47SJeff Kirsher 		 * reading duplicate data in the next MDIC transaction.
262dee1ad47SJeff Kirsher 		 */
263dee1ad47SJeff Kirsher 		if (hw->mac.type == e1000_pch2lan)
264*1d16cd91SVitaly Lifshits 			usleep_range(100, 150);
265dee1ad47SJeff Kirsher 
266*1d16cd91SVitaly Lifshits 		if (success)
267dee1ad47SJeff Kirsher 			return 0;
268*1d16cd91SVitaly Lifshits 
269*1d16cd91SVitaly Lifshits 		if (retry_counter != retry_max) {
270*1d16cd91SVitaly Lifshits 			e_dbg("Perform retry on PHY transaction...\n");
271*1d16cd91SVitaly Lifshits 			mdelay(10);
272*1d16cd91SVitaly Lifshits 		}
273*1d16cd91SVitaly Lifshits 	}
274*1d16cd91SVitaly Lifshits 
275*1d16cd91SVitaly Lifshits 	return -E1000_ERR_PHY;
276dee1ad47SJeff Kirsher }
277dee1ad47SJeff Kirsher 
278dee1ad47SJeff Kirsher /**
279dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_m88 - Read m88 PHY register
280dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
281dee1ad47SJeff Kirsher  *  @offset: register offset to be read
282dee1ad47SJeff Kirsher  *  @data: pointer to the read data
283dee1ad47SJeff Kirsher  *
284dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then reads the PHY register at offset
285dee1ad47SJeff Kirsher  *  and storing the retrieved information in data.  Release any acquired
286dee1ad47SJeff Kirsher  *  semaphores before exiting.
287dee1ad47SJeff Kirsher  **/
288dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
289dee1ad47SJeff Kirsher {
290dee1ad47SJeff Kirsher 	s32 ret_val;
291dee1ad47SJeff Kirsher 
292dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
293dee1ad47SJeff Kirsher 	if (ret_val)
294dee1ad47SJeff Kirsher 		return ret_val;
295dee1ad47SJeff Kirsher 
296dee1ad47SJeff Kirsher 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
297dee1ad47SJeff Kirsher 					   data);
298dee1ad47SJeff Kirsher 
299dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
300dee1ad47SJeff Kirsher 
301dee1ad47SJeff Kirsher 	return ret_val;
302dee1ad47SJeff Kirsher }
303dee1ad47SJeff Kirsher 
304dee1ad47SJeff Kirsher /**
305dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_m88 - Write m88 PHY register
306dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
307dee1ad47SJeff Kirsher  *  @offset: register offset to write to
308dee1ad47SJeff Kirsher  *  @data: data to write at register offset
309dee1ad47SJeff Kirsher  *
310dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then writes the data to PHY register
311dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
312dee1ad47SJeff Kirsher  **/
313dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
314dee1ad47SJeff Kirsher {
315dee1ad47SJeff Kirsher 	s32 ret_val;
316dee1ad47SJeff Kirsher 
317dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
318dee1ad47SJeff Kirsher 	if (ret_val)
319dee1ad47SJeff Kirsher 		return ret_val;
320dee1ad47SJeff Kirsher 
321dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
322dee1ad47SJeff Kirsher 					    data);
323dee1ad47SJeff Kirsher 
324dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
325dee1ad47SJeff Kirsher 
326dee1ad47SJeff Kirsher 	return ret_val;
327dee1ad47SJeff Kirsher }
328dee1ad47SJeff Kirsher 
329dee1ad47SJeff Kirsher /**
330dee1ad47SJeff Kirsher  *  e1000_set_page_igp - Set page as on IGP-like PHY(s)
331dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
332dee1ad47SJeff Kirsher  *  @page: page to set (shifted left when necessary)
333dee1ad47SJeff Kirsher  *
334dee1ad47SJeff Kirsher  *  Sets PHY page required for PHY register access.  Assumes semaphore is
335dee1ad47SJeff Kirsher  *  already acquired.  Note, this function sets phy.addr to 1 so the caller
336dee1ad47SJeff Kirsher  *  must set it appropriately (if necessary) after this function returns.
337dee1ad47SJeff Kirsher  **/
338dee1ad47SJeff Kirsher s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page)
339dee1ad47SJeff Kirsher {
340dee1ad47SJeff Kirsher 	e_dbg("Setting page 0x%x\n", page);
341dee1ad47SJeff Kirsher 
342dee1ad47SJeff Kirsher 	hw->phy.addr = 1;
343dee1ad47SJeff Kirsher 
344dee1ad47SJeff Kirsher 	return e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page);
345dee1ad47SJeff Kirsher }
346dee1ad47SJeff Kirsher 
347dee1ad47SJeff Kirsher /**
348dee1ad47SJeff Kirsher  *  __e1000e_read_phy_reg_igp - Read igp PHY register
349dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
350dee1ad47SJeff Kirsher  *  @offset: register offset to be read
351dee1ad47SJeff Kirsher  *  @data: pointer to the read data
352dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
353dee1ad47SJeff Kirsher  *
354dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then reads the PHY register at offset
355dee1ad47SJeff Kirsher  *  and stores the retrieved information in data.  Release any acquired
356dee1ad47SJeff Kirsher  *  semaphores before exiting.
357dee1ad47SJeff Kirsher  **/
358dee1ad47SJeff Kirsher static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
359dee1ad47SJeff Kirsher 				     bool locked)
360dee1ad47SJeff Kirsher {
361dee1ad47SJeff Kirsher 	s32 ret_val = 0;
362dee1ad47SJeff Kirsher 
363dee1ad47SJeff Kirsher 	if (!locked) {
364668018d7SBruce Allan 		if (!hw->phy.ops.acquire)
3655015e53aSBruce Allan 			return 0;
366dee1ad47SJeff Kirsher 
367dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
368dee1ad47SJeff Kirsher 		if (ret_val)
3695015e53aSBruce Allan 			return ret_val;
370dee1ad47SJeff Kirsher 	}
371dee1ad47SJeff Kirsher 
3725015e53aSBruce Allan 	if (offset > MAX_PHY_MULTI_PAGE_REG)
373dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw,
374dee1ad47SJeff Kirsher 						    IGP01E1000_PHY_PAGE_SELECT,
375dee1ad47SJeff Kirsher 						    (u16)offset);
3765015e53aSBruce Allan 	if (!ret_val)
3775015e53aSBruce Allan 		ret_val = e1000e_read_phy_reg_mdic(hw,
3785015e53aSBruce Allan 						   MAX_PHY_REG_ADDRESS & offset,
379dee1ad47SJeff Kirsher 						   data);
380dee1ad47SJeff Kirsher 	if (!locked)
381dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
3825015e53aSBruce Allan 
383dee1ad47SJeff Kirsher 	return ret_val;
384dee1ad47SJeff Kirsher }
385dee1ad47SJeff Kirsher 
386dee1ad47SJeff Kirsher /**
387dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_igp - Read igp PHY register
388dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
389dee1ad47SJeff Kirsher  *  @offset: register offset to be read
390dee1ad47SJeff Kirsher  *  @data: pointer to the read data
391dee1ad47SJeff Kirsher  *
392dee1ad47SJeff Kirsher  *  Acquires semaphore then reads the PHY register at offset and stores the
393dee1ad47SJeff Kirsher  *  retrieved information in data.
394dee1ad47SJeff Kirsher  *  Release the acquired semaphore before exiting.
395dee1ad47SJeff Kirsher  **/
396dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
397dee1ad47SJeff Kirsher {
398dee1ad47SJeff Kirsher 	return __e1000e_read_phy_reg_igp(hw, offset, data, false);
399dee1ad47SJeff Kirsher }
400dee1ad47SJeff Kirsher 
401dee1ad47SJeff Kirsher /**
402dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_igp_locked - Read igp PHY register
403dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
404dee1ad47SJeff Kirsher  *  @offset: register offset to be read
405dee1ad47SJeff Kirsher  *  @data: pointer to the read data
406dee1ad47SJeff Kirsher  *
407dee1ad47SJeff Kirsher  *  Reads the PHY register at offset and stores the retrieved information
408dee1ad47SJeff Kirsher  *  in data.  Assumes semaphore already acquired.
409dee1ad47SJeff Kirsher  **/
410dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
411dee1ad47SJeff Kirsher {
412dee1ad47SJeff Kirsher 	return __e1000e_read_phy_reg_igp(hw, offset, data, true);
413dee1ad47SJeff Kirsher }
414dee1ad47SJeff Kirsher 
415dee1ad47SJeff Kirsher /**
41639da2cacSSasha Neftin  *  __e1000e_write_phy_reg_igp - Write igp PHY register
417dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
418dee1ad47SJeff Kirsher  *  @offset: register offset to write to
419dee1ad47SJeff Kirsher  *  @data: data to write at register offset
420dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
421dee1ad47SJeff Kirsher  *
422dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then writes the data to PHY register
423dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
424dee1ad47SJeff Kirsher  **/
425dee1ad47SJeff Kirsher static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
426dee1ad47SJeff Kirsher 				      bool locked)
427dee1ad47SJeff Kirsher {
428dee1ad47SJeff Kirsher 	s32 ret_val = 0;
429dee1ad47SJeff Kirsher 
430dee1ad47SJeff Kirsher 	if (!locked) {
431668018d7SBruce Allan 		if (!hw->phy.ops.acquire)
4325015e53aSBruce Allan 			return 0;
433dee1ad47SJeff Kirsher 
434dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
435dee1ad47SJeff Kirsher 		if (ret_val)
4365015e53aSBruce Allan 			return ret_val;
437dee1ad47SJeff Kirsher 	}
438dee1ad47SJeff Kirsher 
4395015e53aSBruce Allan 	if (offset > MAX_PHY_MULTI_PAGE_REG)
440dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw,
441dee1ad47SJeff Kirsher 						    IGP01E1000_PHY_PAGE_SELECT,
442dee1ad47SJeff Kirsher 						    (u16)offset);
4435015e53aSBruce Allan 	if (!ret_val)
4445015e53aSBruce Allan 		ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS &
44517e813ecSBruce Allan 						    offset, data);
446dee1ad47SJeff Kirsher 	if (!locked)
447dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
448dee1ad47SJeff Kirsher 
449dee1ad47SJeff Kirsher 	return ret_val;
450dee1ad47SJeff Kirsher }
451dee1ad47SJeff Kirsher 
452dee1ad47SJeff Kirsher /**
453dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_igp - Write igp PHY register
454dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
455dee1ad47SJeff Kirsher  *  @offset: register offset to write to
456dee1ad47SJeff Kirsher  *  @data: data to write at register offset
457dee1ad47SJeff Kirsher  *
458dee1ad47SJeff Kirsher  *  Acquires semaphore then writes the data to PHY register
459dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
460dee1ad47SJeff Kirsher  **/
461dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
462dee1ad47SJeff Kirsher {
463dee1ad47SJeff Kirsher 	return __e1000e_write_phy_reg_igp(hw, offset, data, false);
464dee1ad47SJeff Kirsher }
465dee1ad47SJeff Kirsher 
466dee1ad47SJeff Kirsher /**
467dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_igp_locked - Write igp PHY register
468dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
469dee1ad47SJeff Kirsher  *  @offset: register offset to write to
470dee1ad47SJeff Kirsher  *  @data: data to write at register offset
471dee1ad47SJeff Kirsher  *
472dee1ad47SJeff Kirsher  *  Writes the data to PHY register at the offset.
473dee1ad47SJeff Kirsher  *  Assumes semaphore already acquired.
474dee1ad47SJeff Kirsher  **/
475dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
476dee1ad47SJeff Kirsher {
477dee1ad47SJeff Kirsher 	return __e1000e_write_phy_reg_igp(hw, offset, data, true);
478dee1ad47SJeff Kirsher }
479dee1ad47SJeff Kirsher 
480dee1ad47SJeff Kirsher /**
481dee1ad47SJeff Kirsher  *  __e1000_read_kmrn_reg - Read kumeran register
482dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
483dee1ad47SJeff Kirsher  *  @offset: register offset to be read
484dee1ad47SJeff Kirsher  *  @data: pointer to the read data
485dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
486dee1ad47SJeff Kirsher  *
487dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary.  Then reads the PHY register at offset
488dee1ad47SJeff Kirsher  *  using the kumeran interface.  The information retrieved is stored in data.
489dee1ad47SJeff Kirsher  *  Release any acquired semaphores before exiting.
490dee1ad47SJeff Kirsher  **/
491dee1ad47SJeff Kirsher static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
492dee1ad47SJeff Kirsher 				 bool locked)
493dee1ad47SJeff Kirsher {
494dee1ad47SJeff Kirsher 	u32 kmrnctrlsta;
495dee1ad47SJeff Kirsher 
496dee1ad47SJeff Kirsher 	if (!locked) {
4975015e53aSBruce Allan 		s32 ret_val = 0;
4985015e53aSBruce Allan 
499668018d7SBruce Allan 		if (!hw->phy.ops.acquire)
5005015e53aSBruce Allan 			return 0;
501dee1ad47SJeff Kirsher 
502dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
503dee1ad47SJeff Kirsher 		if (ret_val)
5045015e53aSBruce Allan 			return ret_val;
505dee1ad47SJeff Kirsher 	}
506dee1ad47SJeff Kirsher 
507dee1ad47SJeff Kirsher 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
508dee1ad47SJeff Kirsher 		       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
509dee1ad47SJeff Kirsher 	ew32(KMRNCTRLSTA, kmrnctrlsta);
510dee1ad47SJeff Kirsher 	e1e_flush();
511dee1ad47SJeff Kirsher 
512dee1ad47SJeff Kirsher 	udelay(2);
513dee1ad47SJeff Kirsher 
514dee1ad47SJeff Kirsher 	kmrnctrlsta = er32(KMRNCTRLSTA);
515dee1ad47SJeff Kirsher 	*data = (u16)kmrnctrlsta;
516dee1ad47SJeff Kirsher 
517dee1ad47SJeff Kirsher 	if (!locked)
518dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
519dee1ad47SJeff Kirsher 
5205015e53aSBruce Allan 	return 0;
521dee1ad47SJeff Kirsher }
522dee1ad47SJeff Kirsher 
523dee1ad47SJeff Kirsher /**
524dee1ad47SJeff Kirsher  *  e1000e_read_kmrn_reg -  Read kumeran register
525dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
526dee1ad47SJeff Kirsher  *  @offset: register offset to be read
527dee1ad47SJeff Kirsher  *  @data: pointer to the read data
528dee1ad47SJeff Kirsher  *
529dee1ad47SJeff Kirsher  *  Acquires semaphore then reads the PHY register at offset using the
530dee1ad47SJeff Kirsher  *  kumeran interface.  The information retrieved is stored in data.
531dee1ad47SJeff Kirsher  *  Release the acquired semaphore before exiting.
532dee1ad47SJeff Kirsher  **/
533dee1ad47SJeff Kirsher s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
534dee1ad47SJeff Kirsher {
535dee1ad47SJeff Kirsher 	return __e1000_read_kmrn_reg(hw, offset, data, false);
536dee1ad47SJeff Kirsher }
537dee1ad47SJeff Kirsher 
538dee1ad47SJeff Kirsher /**
539dee1ad47SJeff Kirsher  *  e1000e_read_kmrn_reg_locked -  Read kumeran register
540dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
541dee1ad47SJeff Kirsher  *  @offset: register offset to be read
542dee1ad47SJeff Kirsher  *  @data: pointer to the read data
543dee1ad47SJeff Kirsher  *
544dee1ad47SJeff Kirsher  *  Reads the PHY register at offset using the kumeran interface.  The
545dee1ad47SJeff Kirsher  *  information retrieved is stored in data.
546dee1ad47SJeff Kirsher  *  Assumes semaphore already acquired.
547dee1ad47SJeff Kirsher  **/
548dee1ad47SJeff Kirsher s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
549dee1ad47SJeff Kirsher {
550dee1ad47SJeff Kirsher 	return __e1000_read_kmrn_reg(hw, offset, data, true);
551dee1ad47SJeff Kirsher }
552dee1ad47SJeff Kirsher 
553dee1ad47SJeff Kirsher /**
554dee1ad47SJeff Kirsher  *  __e1000_write_kmrn_reg - Write kumeran register
555dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
556dee1ad47SJeff Kirsher  *  @offset: register offset to write to
557dee1ad47SJeff Kirsher  *  @data: data to write at register offset
558dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
559dee1ad47SJeff Kirsher  *
560dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary.  Then write the data to PHY register
561dee1ad47SJeff Kirsher  *  at the offset using the kumeran interface.  Release any acquired semaphores
562dee1ad47SJeff Kirsher  *  before exiting.
563dee1ad47SJeff Kirsher  **/
564dee1ad47SJeff Kirsher static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
565dee1ad47SJeff Kirsher 				  bool locked)
566dee1ad47SJeff Kirsher {
567dee1ad47SJeff Kirsher 	u32 kmrnctrlsta;
568dee1ad47SJeff Kirsher 
569dee1ad47SJeff Kirsher 	if (!locked) {
5705015e53aSBruce Allan 		s32 ret_val = 0;
5715015e53aSBruce Allan 
572668018d7SBruce Allan 		if (!hw->phy.ops.acquire)
5735015e53aSBruce Allan 			return 0;
574dee1ad47SJeff Kirsher 
575dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
576dee1ad47SJeff Kirsher 		if (ret_val)
5775015e53aSBruce Allan 			return ret_val;
578dee1ad47SJeff Kirsher 	}
579dee1ad47SJeff Kirsher 
580dee1ad47SJeff Kirsher 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
581dee1ad47SJeff Kirsher 		       E1000_KMRNCTRLSTA_OFFSET) | data;
582dee1ad47SJeff Kirsher 	ew32(KMRNCTRLSTA, kmrnctrlsta);
583dee1ad47SJeff Kirsher 	e1e_flush();
584dee1ad47SJeff Kirsher 
585dee1ad47SJeff Kirsher 	udelay(2);
586dee1ad47SJeff Kirsher 
587dee1ad47SJeff Kirsher 	if (!locked)
588dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
589dee1ad47SJeff Kirsher 
5905015e53aSBruce Allan 	return 0;
591dee1ad47SJeff Kirsher }
592dee1ad47SJeff Kirsher 
593dee1ad47SJeff Kirsher /**
594dee1ad47SJeff Kirsher  *  e1000e_write_kmrn_reg -  Write kumeran register
595dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
596dee1ad47SJeff Kirsher  *  @offset: register offset to write to
597dee1ad47SJeff Kirsher  *  @data: data to write at register offset
598dee1ad47SJeff Kirsher  *
599dee1ad47SJeff Kirsher  *  Acquires semaphore then writes the data to the PHY register at the offset
600dee1ad47SJeff Kirsher  *  using the kumeran interface.  Release the acquired semaphore before exiting.
601dee1ad47SJeff Kirsher  **/
602dee1ad47SJeff Kirsher s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
603dee1ad47SJeff Kirsher {
604dee1ad47SJeff Kirsher 	return __e1000_write_kmrn_reg(hw, offset, data, false);
605dee1ad47SJeff Kirsher }
606dee1ad47SJeff Kirsher 
607dee1ad47SJeff Kirsher /**
608dee1ad47SJeff Kirsher  *  e1000e_write_kmrn_reg_locked -  Write kumeran register
609dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
610dee1ad47SJeff Kirsher  *  @offset: register offset to write to
611dee1ad47SJeff Kirsher  *  @data: data to write at register offset
612dee1ad47SJeff Kirsher  *
613dee1ad47SJeff Kirsher  *  Write the data to PHY register at the offset using the kumeran interface.
614dee1ad47SJeff Kirsher  *  Assumes semaphore already acquired.
615dee1ad47SJeff Kirsher  **/
616dee1ad47SJeff Kirsher s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
617dee1ad47SJeff Kirsher {
618dee1ad47SJeff Kirsher 	return __e1000_write_kmrn_reg(hw, offset, data, true);
619dee1ad47SJeff Kirsher }
620dee1ad47SJeff Kirsher 
621dee1ad47SJeff Kirsher /**
6227b9f7e35SBruce Allan  *  e1000_set_master_slave_mode - Setup PHY for Master/slave mode
6237b9f7e35SBruce Allan  *  @hw: pointer to the HW structure
6247b9f7e35SBruce Allan  *
6257b9f7e35SBruce Allan  *  Sets up Master/slave mode
6267b9f7e35SBruce Allan  **/
6277b9f7e35SBruce Allan static s32 e1000_set_master_slave_mode(struct e1000_hw *hw)
6287b9f7e35SBruce Allan {
6297b9f7e35SBruce Allan 	s32 ret_val;
6307b9f7e35SBruce Allan 	u16 phy_data;
6317b9f7e35SBruce Allan 
6327b9f7e35SBruce Allan 	/* Resolve Master/Slave mode */
633c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_CTRL1000, &phy_data);
6347b9f7e35SBruce Allan 	if (ret_val)
6357b9f7e35SBruce Allan 		return ret_val;
6367b9f7e35SBruce Allan 
6377b9f7e35SBruce Allan 	/* load defaults for future use */
638c2ade1a4SBruce Allan 	hw->phy.original_ms_type = (phy_data & CTL1000_ENABLE_MASTER) ?
639c2ade1a4SBruce Allan 	    ((phy_data & CTL1000_AS_MASTER) ?
6407b9f7e35SBruce Allan 	     e1000_ms_force_master : e1000_ms_force_slave) : e1000_ms_auto;
6417b9f7e35SBruce Allan 
6427b9f7e35SBruce Allan 	switch (hw->phy.ms_type) {
6437b9f7e35SBruce Allan 	case e1000_ms_force_master:
644c2ade1a4SBruce Allan 		phy_data |= (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
6457b9f7e35SBruce Allan 		break;
6467b9f7e35SBruce Allan 	case e1000_ms_force_slave:
647c2ade1a4SBruce Allan 		phy_data |= CTL1000_ENABLE_MASTER;
648c2ade1a4SBruce Allan 		phy_data &= ~(CTL1000_AS_MASTER);
6497b9f7e35SBruce Allan 		break;
6507b9f7e35SBruce Allan 	case e1000_ms_auto:
651c2ade1a4SBruce Allan 		phy_data &= ~CTL1000_ENABLE_MASTER;
6525463fce6SJeff Kirsher 		fallthrough;
6537b9f7e35SBruce Allan 	default:
6547b9f7e35SBruce Allan 		break;
6557b9f7e35SBruce Allan 	}
6567b9f7e35SBruce Allan 
657c2ade1a4SBruce Allan 	return e1e_wphy(hw, MII_CTRL1000, phy_data);
6587b9f7e35SBruce Allan }
6597b9f7e35SBruce Allan 
6607b9f7e35SBruce Allan /**
661dee1ad47SJeff Kirsher  *  e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
662dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
663dee1ad47SJeff Kirsher  *
664dee1ad47SJeff Kirsher  *  Sets up Carrier-sense on Transmit and downshift values.
665dee1ad47SJeff Kirsher  **/
666dee1ad47SJeff Kirsher s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
667dee1ad47SJeff Kirsher {
668dee1ad47SJeff Kirsher 	s32 ret_val;
669dee1ad47SJeff Kirsher 	u16 phy_data;
670dee1ad47SJeff Kirsher 
671dee1ad47SJeff Kirsher 	/* Enable CRS on Tx. This must be set for half-duplex operation. */
672dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data);
673dee1ad47SJeff Kirsher 	if (ret_val)
6745015e53aSBruce Allan 		return ret_val;
675dee1ad47SJeff Kirsher 
676dee1ad47SJeff Kirsher 	phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
677dee1ad47SJeff Kirsher 
678dee1ad47SJeff Kirsher 	/* Enable downshift */
679dee1ad47SJeff Kirsher 	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
680dee1ad47SJeff Kirsher 
6817b9f7e35SBruce Allan 	ret_val = e1e_wphy(hw, I82577_CFG_REG, phy_data);
6827b9f7e35SBruce Allan 	if (ret_val)
6837b9f7e35SBruce Allan 		return ret_val;
6847b9f7e35SBruce Allan 
685e86fd891SBruce W Allan 	/* Set MDI/MDIX mode */
686e86fd891SBruce W Allan 	ret_val = e1e_rphy(hw, I82577_PHY_CTRL_2, &phy_data);
687e86fd891SBruce W Allan 	if (ret_val)
688e86fd891SBruce W Allan 		return ret_val;
689e86fd891SBruce W Allan 	phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
690e921eb1aSBruce Allan 	/* Options:
691e86fd891SBruce W Allan 	 *   0 - Auto (default)
692e86fd891SBruce W Allan 	 *   1 - MDI mode
693e86fd891SBruce W Allan 	 *   2 - MDI-X mode
694e86fd891SBruce W Allan 	 */
695e86fd891SBruce W Allan 	switch (hw->phy.mdix) {
696e86fd891SBruce W Allan 	case 1:
697e86fd891SBruce W Allan 		break;
698e86fd891SBruce W Allan 	case 2:
699e86fd891SBruce W Allan 		phy_data |= I82577_PHY_CTRL2_MANUAL_MDIX;
700e86fd891SBruce W Allan 		break;
701e86fd891SBruce W Allan 	case 0:
702e86fd891SBruce W Allan 	default:
703e86fd891SBruce W Allan 		phy_data |= I82577_PHY_CTRL2_AUTO_MDI_MDIX;
704e86fd891SBruce W Allan 		break;
705e86fd891SBruce W Allan 	}
706e86fd891SBruce W Allan 	ret_val = e1e_wphy(hw, I82577_PHY_CTRL_2, phy_data);
707e86fd891SBruce W Allan 	if (ret_val)
708e86fd891SBruce W Allan 		return ret_val;
709e86fd891SBruce W Allan 
7107b9f7e35SBruce Allan 	return e1000_set_master_slave_mode(hw);
711dee1ad47SJeff Kirsher }
712dee1ad47SJeff Kirsher 
713dee1ad47SJeff Kirsher /**
714dee1ad47SJeff Kirsher  *  e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
715dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
716dee1ad47SJeff Kirsher  *
717dee1ad47SJeff Kirsher  *  Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
718dee1ad47SJeff Kirsher  *  and downshift values are set also.
719dee1ad47SJeff Kirsher  **/
720dee1ad47SJeff Kirsher s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
721dee1ad47SJeff Kirsher {
722dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
723dee1ad47SJeff Kirsher 	s32 ret_val;
724dee1ad47SJeff Kirsher 	u16 phy_data;
725dee1ad47SJeff Kirsher 
726dee1ad47SJeff Kirsher 	/* Enable CRS on Tx. This must be set for half-duplex operation. */
727dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
728dee1ad47SJeff Kirsher 	if (ret_val)
729dee1ad47SJeff Kirsher 		return ret_val;
730dee1ad47SJeff Kirsher 
731dee1ad47SJeff Kirsher 	/* For BM PHY this bit is downshift enable */
732dee1ad47SJeff Kirsher 	if (phy->type != e1000_phy_bm)
733dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
734dee1ad47SJeff Kirsher 
735e921eb1aSBruce Allan 	/* Options:
736dee1ad47SJeff Kirsher 	 *   MDI/MDI-X = 0 (default)
737dee1ad47SJeff Kirsher 	 *   0 - Auto for all speeds
738dee1ad47SJeff Kirsher 	 *   1 - MDI mode
739dee1ad47SJeff Kirsher 	 *   2 - MDI-X mode
740dee1ad47SJeff Kirsher 	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
741dee1ad47SJeff Kirsher 	 */
742dee1ad47SJeff Kirsher 	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
743dee1ad47SJeff Kirsher 
744dee1ad47SJeff Kirsher 	switch (phy->mdix) {
745dee1ad47SJeff Kirsher 	case 1:
746dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
747dee1ad47SJeff Kirsher 		break;
748dee1ad47SJeff Kirsher 	case 2:
749dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
750dee1ad47SJeff Kirsher 		break;
751dee1ad47SJeff Kirsher 	case 3:
752dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
753dee1ad47SJeff Kirsher 		break;
754dee1ad47SJeff Kirsher 	case 0:
755dee1ad47SJeff Kirsher 	default:
756dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
757dee1ad47SJeff Kirsher 		break;
758dee1ad47SJeff Kirsher 	}
759dee1ad47SJeff Kirsher 
760e921eb1aSBruce Allan 	/* Options:
761dee1ad47SJeff Kirsher 	 *   disable_polarity_correction = 0 (default)
762dee1ad47SJeff Kirsher 	 *       Automatic Correction for Reversed Cable Polarity
763dee1ad47SJeff Kirsher 	 *   0 - Disabled
764dee1ad47SJeff Kirsher 	 *   1 - Enabled
765dee1ad47SJeff Kirsher 	 */
766dee1ad47SJeff Kirsher 	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
76704499ec4SBruce Allan 	if (phy->disable_polarity_correction)
768dee1ad47SJeff Kirsher 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
769dee1ad47SJeff Kirsher 
770dee1ad47SJeff Kirsher 	/* Enable downshift on BM (disabled by default) */
771885fe7beSMatthew Vick 	if (phy->type == e1000_phy_bm) {
772885fe7beSMatthew Vick 		/* For 82574/82583, first disable then enable downshift */
773885fe7beSMatthew Vick 		if (phy->id == BME1000_E_PHY_ID_R2) {
774885fe7beSMatthew Vick 			phy_data &= ~BME1000_PSCR_ENABLE_DOWNSHIFT;
775885fe7beSMatthew Vick 			ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL,
776885fe7beSMatthew Vick 					   phy_data);
777885fe7beSMatthew Vick 			if (ret_val)
778885fe7beSMatthew Vick 				return ret_val;
779885fe7beSMatthew Vick 			/* Commit the changes. */
7806b598e1eSBruce Allan 			ret_val = phy->ops.commit(hw);
781885fe7beSMatthew Vick 			if (ret_val) {
782885fe7beSMatthew Vick 				e_dbg("Error committing the PHY changes\n");
783885fe7beSMatthew Vick 				return ret_val;
784885fe7beSMatthew Vick 			}
785885fe7beSMatthew Vick 		}
786885fe7beSMatthew Vick 
787dee1ad47SJeff Kirsher 		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
788885fe7beSMatthew Vick 	}
789dee1ad47SJeff Kirsher 
790dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
791dee1ad47SJeff Kirsher 	if (ret_val)
792dee1ad47SJeff Kirsher 		return ret_val;
793dee1ad47SJeff Kirsher 
794dee1ad47SJeff Kirsher 	if ((phy->type == e1000_phy_m88) &&
795dee1ad47SJeff Kirsher 	    (phy->revision < E1000_REVISION_4) &&
796dee1ad47SJeff Kirsher 	    (phy->id != BME1000_E_PHY_ID_R2)) {
797e921eb1aSBruce Allan 		/* Force TX_CLK in the Extended PHY Specific Control Register
798dee1ad47SJeff Kirsher 		 * to 25MHz clock.
799dee1ad47SJeff Kirsher 		 */
800dee1ad47SJeff Kirsher 		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
801dee1ad47SJeff Kirsher 		if (ret_val)
802dee1ad47SJeff Kirsher 			return ret_val;
803dee1ad47SJeff Kirsher 
804dee1ad47SJeff Kirsher 		phy_data |= M88E1000_EPSCR_TX_CLK_25;
805dee1ad47SJeff Kirsher 
806e5fe2541SBruce Allan 		if ((phy->revision == 2) && (phy->id == M88E1111_I_PHY_ID)) {
807dee1ad47SJeff Kirsher 			/* 82573L PHY - set the downshift counter to 5x. */
808dee1ad47SJeff Kirsher 			phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
809dee1ad47SJeff Kirsher 			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
810dee1ad47SJeff Kirsher 		} else {
811dee1ad47SJeff Kirsher 			/* Configure Master and Slave downshift values */
812dee1ad47SJeff Kirsher 			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
813dee1ad47SJeff Kirsher 				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
814dee1ad47SJeff Kirsher 			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
815dee1ad47SJeff Kirsher 				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
816dee1ad47SJeff Kirsher 		}
817dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
818dee1ad47SJeff Kirsher 		if (ret_val)
819dee1ad47SJeff Kirsher 			return ret_val;
820dee1ad47SJeff Kirsher 	}
821dee1ad47SJeff Kirsher 
822dee1ad47SJeff Kirsher 	if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) {
823dee1ad47SJeff Kirsher 		/* Set PHY page 0, register 29 to 0x0003 */
824dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, 29, 0x0003);
825dee1ad47SJeff Kirsher 		if (ret_val)
826dee1ad47SJeff Kirsher 			return ret_val;
827dee1ad47SJeff Kirsher 
828dee1ad47SJeff Kirsher 		/* Set PHY page 0, register 30 to 0x0000 */
829dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, 30, 0x0000);
830dee1ad47SJeff Kirsher 		if (ret_val)
831dee1ad47SJeff Kirsher 			return ret_val;
832dee1ad47SJeff Kirsher 	}
833dee1ad47SJeff Kirsher 
834dee1ad47SJeff Kirsher 	/* Commit the changes. */
8356b598e1eSBruce Allan 	if (phy->ops.commit) {
8366b598e1eSBruce Allan 		ret_val = phy->ops.commit(hw);
837dee1ad47SJeff Kirsher 		if (ret_val) {
838dee1ad47SJeff Kirsher 			e_dbg("Error committing the PHY changes\n");
839dee1ad47SJeff Kirsher 			return ret_val;
840dee1ad47SJeff Kirsher 		}
8416b598e1eSBruce Allan 	}
842dee1ad47SJeff Kirsher 
843dee1ad47SJeff Kirsher 	if (phy->type == e1000_phy_82578) {
844dee1ad47SJeff Kirsher 		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
845dee1ad47SJeff Kirsher 		if (ret_val)
846dee1ad47SJeff Kirsher 			return ret_val;
847dee1ad47SJeff Kirsher 
848dee1ad47SJeff Kirsher 		/* 82578 PHY - set the downshift count to 1x. */
849dee1ad47SJeff Kirsher 		phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
850dee1ad47SJeff Kirsher 		phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
851dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
852dee1ad47SJeff Kirsher 		if (ret_val)
853dee1ad47SJeff Kirsher 			return ret_val;
854dee1ad47SJeff Kirsher 	}
855dee1ad47SJeff Kirsher 
856dee1ad47SJeff Kirsher 	return 0;
857dee1ad47SJeff Kirsher }
858dee1ad47SJeff Kirsher 
859dee1ad47SJeff Kirsher /**
860dee1ad47SJeff Kirsher  *  e1000e_copper_link_setup_igp - Setup igp PHY's for copper link
861dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
862dee1ad47SJeff Kirsher  *
863dee1ad47SJeff Kirsher  *  Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
864dee1ad47SJeff Kirsher  *  igp PHY's.
865dee1ad47SJeff Kirsher  **/
866dee1ad47SJeff Kirsher s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
867dee1ad47SJeff Kirsher {
868dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
869dee1ad47SJeff Kirsher 	s32 ret_val;
870dee1ad47SJeff Kirsher 	u16 data;
871dee1ad47SJeff Kirsher 
872dee1ad47SJeff Kirsher 	ret_val = e1000_phy_hw_reset(hw);
873dee1ad47SJeff Kirsher 	if (ret_val) {
874dee1ad47SJeff Kirsher 		e_dbg("Error resetting the PHY.\n");
875dee1ad47SJeff Kirsher 		return ret_val;
876dee1ad47SJeff Kirsher 	}
877dee1ad47SJeff Kirsher 
878e921eb1aSBruce Allan 	/* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
879dee1ad47SJeff Kirsher 	 * timeout issues when LFS is enabled.
880dee1ad47SJeff Kirsher 	 */
881dee1ad47SJeff Kirsher 	msleep(100);
882dee1ad47SJeff Kirsher 
883dee1ad47SJeff Kirsher 	/* disable lplu d0 during driver init */
8847de89f05SBruce Allan 	if (hw->phy.ops.set_d0_lplu_state) {
8857de89f05SBruce Allan 		ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
886dee1ad47SJeff Kirsher 		if (ret_val) {
887dee1ad47SJeff Kirsher 			e_dbg("Error Disabling LPLU D0\n");
888dee1ad47SJeff Kirsher 			return ret_val;
889dee1ad47SJeff Kirsher 		}
8907de89f05SBruce Allan 	}
891dee1ad47SJeff Kirsher 	/* Configure mdi-mdix settings */
892dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &data);
893dee1ad47SJeff Kirsher 	if (ret_val)
894dee1ad47SJeff Kirsher 		return ret_val;
895dee1ad47SJeff Kirsher 
896dee1ad47SJeff Kirsher 	data &= ~IGP01E1000_PSCR_AUTO_MDIX;
897dee1ad47SJeff Kirsher 
898dee1ad47SJeff Kirsher 	switch (phy->mdix) {
899dee1ad47SJeff Kirsher 	case 1:
900dee1ad47SJeff Kirsher 		data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
901dee1ad47SJeff Kirsher 		break;
902dee1ad47SJeff Kirsher 	case 2:
903dee1ad47SJeff Kirsher 		data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
904dee1ad47SJeff Kirsher 		break;
905dee1ad47SJeff Kirsher 	case 0:
906dee1ad47SJeff Kirsher 	default:
907dee1ad47SJeff Kirsher 		data |= IGP01E1000_PSCR_AUTO_MDIX;
908dee1ad47SJeff Kirsher 		break;
909dee1ad47SJeff Kirsher 	}
910dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, data);
911dee1ad47SJeff Kirsher 	if (ret_val)
912dee1ad47SJeff Kirsher 		return ret_val;
913dee1ad47SJeff Kirsher 
914dee1ad47SJeff Kirsher 	/* set auto-master slave resolution settings */
915dee1ad47SJeff Kirsher 	if (hw->mac.autoneg) {
916e921eb1aSBruce Allan 		/* when autonegotiation advertisement is only 1000Mbps then we
917dee1ad47SJeff Kirsher 		 * should disable SmartSpeed and enable Auto MasterSlave
918dee1ad47SJeff Kirsher 		 * resolution as hardware default.
919dee1ad47SJeff Kirsher 		 */
920dee1ad47SJeff Kirsher 		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
921dee1ad47SJeff Kirsher 			/* Disable SmartSpeed */
922dee1ad47SJeff Kirsher 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
923dee1ad47SJeff Kirsher 					   &data);
924dee1ad47SJeff Kirsher 			if (ret_val)
925dee1ad47SJeff Kirsher 				return ret_val;
926dee1ad47SJeff Kirsher 
927dee1ad47SJeff Kirsher 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
928dee1ad47SJeff Kirsher 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
929dee1ad47SJeff Kirsher 					   data);
930dee1ad47SJeff Kirsher 			if (ret_val)
931dee1ad47SJeff Kirsher 				return ret_val;
932dee1ad47SJeff Kirsher 
933dee1ad47SJeff Kirsher 			/* Set auto Master/Slave resolution process */
934c2ade1a4SBruce Allan 			ret_val = e1e_rphy(hw, MII_CTRL1000, &data);
935dee1ad47SJeff Kirsher 			if (ret_val)
936dee1ad47SJeff Kirsher 				return ret_val;
937dee1ad47SJeff Kirsher 
938c2ade1a4SBruce Allan 			data &= ~CTL1000_ENABLE_MASTER;
939c2ade1a4SBruce Allan 			ret_val = e1e_wphy(hw, MII_CTRL1000, data);
940dee1ad47SJeff Kirsher 			if (ret_val)
941dee1ad47SJeff Kirsher 				return ret_val;
942dee1ad47SJeff Kirsher 		}
943dee1ad47SJeff Kirsher 
9447b9f7e35SBruce Allan 		ret_val = e1000_set_master_slave_mode(hw);
945dee1ad47SJeff Kirsher 	}
946dee1ad47SJeff Kirsher 
947dee1ad47SJeff Kirsher 	return ret_val;
948dee1ad47SJeff Kirsher }
949dee1ad47SJeff Kirsher 
950dee1ad47SJeff Kirsher /**
951dee1ad47SJeff Kirsher  *  e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
952dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
953dee1ad47SJeff Kirsher  *
954dee1ad47SJeff Kirsher  *  Reads the MII auto-neg advertisement register and/or the 1000T control
955dee1ad47SJeff Kirsher  *  register and if the PHY is already setup for auto-negotiation, then
956dee1ad47SJeff Kirsher  *  return successful.  Otherwise, setup advertisement and flow control to
957dee1ad47SJeff Kirsher  *  the appropriate values for the wanted auto-negotiation.
958dee1ad47SJeff Kirsher  **/
959dee1ad47SJeff Kirsher static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
960dee1ad47SJeff Kirsher {
961dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
962dee1ad47SJeff Kirsher 	s32 ret_val;
963dee1ad47SJeff Kirsher 	u16 mii_autoneg_adv_reg;
964dee1ad47SJeff Kirsher 	u16 mii_1000t_ctrl_reg = 0;
965dee1ad47SJeff Kirsher 
966dee1ad47SJeff Kirsher 	phy->autoneg_advertised &= phy->autoneg_mask;
967dee1ad47SJeff Kirsher 
968dee1ad47SJeff Kirsher 	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
969c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_ADVERTISE, &mii_autoneg_adv_reg);
970dee1ad47SJeff Kirsher 	if (ret_val)
971dee1ad47SJeff Kirsher 		return ret_val;
972dee1ad47SJeff Kirsher 
973dee1ad47SJeff Kirsher 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
974dee1ad47SJeff Kirsher 		/* Read the MII 1000Base-T Control Register (Address 9). */
975c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_CTRL1000, &mii_1000t_ctrl_reg);
976dee1ad47SJeff Kirsher 		if (ret_val)
977dee1ad47SJeff Kirsher 			return ret_val;
978dee1ad47SJeff Kirsher 	}
979dee1ad47SJeff Kirsher 
980e921eb1aSBruce Allan 	/* Need to parse both autoneg_advertised and fc and set up
981dee1ad47SJeff Kirsher 	 * the appropriate PHY registers.  First we will parse for
982dee1ad47SJeff Kirsher 	 * autoneg_advertised software override.  Since we can advertise
983dee1ad47SJeff Kirsher 	 * a plethora of combinations, we need to check each bit
984dee1ad47SJeff Kirsher 	 * individually.
985dee1ad47SJeff Kirsher 	 */
986dee1ad47SJeff Kirsher 
987e921eb1aSBruce Allan 	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
988dee1ad47SJeff Kirsher 	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
989dee1ad47SJeff Kirsher 	 * the  1000Base-T Control Register (Address 9).
990dee1ad47SJeff Kirsher 	 */
991c2ade1a4SBruce Allan 	mii_autoneg_adv_reg &= ~(ADVERTISE_100FULL |
992c2ade1a4SBruce Allan 				 ADVERTISE_100HALF |
993c2ade1a4SBruce Allan 				 ADVERTISE_10FULL | ADVERTISE_10HALF);
994c2ade1a4SBruce Allan 	mii_1000t_ctrl_reg &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
995dee1ad47SJeff Kirsher 
996dee1ad47SJeff Kirsher 	e_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
997dee1ad47SJeff Kirsher 
998dee1ad47SJeff Kirsher 	/* Do we want to advertise 10 Mb Half Duplex? */
999dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
1000dee1ad47SJeff Kirsher 		e_dbg("Advertise 10mb Half duplex\n");
1001c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |= ADVERTISE_10HALF;
1002dee1ad47SJeff Kirsher 	}
1003dee1ad47SJeff Kirsher 
1004dee1ad47SJeff Kirsher 	/* Do we want to advertise 10 Mb Full Duplex? */
1005dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
1006dee1ad47SJeff Kirsher 		e_dbg("Advertise 10mb Full duplex\n");
1007c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |= ADVERTISE_10FULL;
1008dee1ad47SJeff Kirsher 	}
1009dee1ad47SJeff Kirsher 
1010dee1ad47SJeff Kirsher 	/* Do we want to advertise 100 Mb Half Duplex? */
1011dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
1012dee1ad47SJeff Kirsher 		e_dbg("Advertise 100mb Half duplex\n");
1013c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |= ADVERTISE_100HALF;
1014dee1ad47SJeff Kirsher 	}
1015dee1ad47SJeff Kirsher 
1016dee1ad47SJeff Kirsher 	/* Do we want to advertise 100 Mb Full Duplex? */
1017dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
1018dee1ad47SJeff Kirsher 		e_dbg("Advertise 100mb Full duplex\n");
1019c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |= ADVERTISE_100FULL;
1020dee1ad47SJeff Kirsher 	}
1021dee1ad47SJeff Kirsher 
1022dee1ad47SJeff Kirsher 	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
1023dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
1024dee1ad47SJeff Kirsher 		e_dbg("Advertise 1000mb Half duplex request denied!\n");
1025dee1ad47SJeff Kirsher 
1026dee1ad47SJeff Kirsher 	/* Do we want to advertise 1000 Mb Full Duplex? */
1027dee1ad47SJeff Kirsher 	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
1028dee1ad47SJeff Kirsher 		e_dbg("Advertise 1000mb Full duplex\n");
1029c2ade1a4SBruce Allan 		mii_1000t_ctrl_reg |= ADVERTISE_1000FULL;
1030dee1ad47SJeff Kirsher 	}
1031dee1ad47SJeff Kirsher 
1032e921eb1aSBruce Allan 	/* Check for a software override of the flow control settings, and
1033dee1ad47SJeff Kirsher 	 * setup the PHY advertisement registers accordingly.  If
1034dee1ad47SJeff Kirsher 	 * auto-negotiation is enabled, then software will have to set the
1035dee1ad47SJeff Kirsher 	 * "PAUSE" bits to the correct value in the Auto-Negotiation
1036c2ade1a4SBruce Allan 	 * Advertisement Register (MII_ADVERTISE) and re-start auto-
1037dee1ad47SJeff Kirsher 	 * negotiation.
1038dee1ad47SJeff Kirsher 	 *
1039dee1ad47SJeff Kirsher 	 * The possible values of the "fc" parameter are:
1040dee1ad47SJeff Kirsher 	 *      0:  Flow control is completely disabled
1041dee1ad47SJeff Kirsher 	 *      1:  Rx flow control is enabled (we can receive pause frames
1042dee1ad47SJeff Kirsher 	 *          but not send pause frames).
1043dee1ad47SJeff Kirsher 	 *      2:  Tx flow control is enabled (we can send pause frames
1044dee1ad47SJeff Kirsher 	 *          but we do not support receiving pause frames).
1045dee1ad47SJeff Kirsher 	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
1046dee1ad47SJeff Kirsher 	 *  other:  No software override.  The flow control configuration
1047dee1ad47SJeff Kirsher 	 *          in the EEPROM is used.
1048dee1ad47SJeff Kirsher 	 */
1049dee1ad47SJeff Kirsher 	switch (hw->fc.current_mode) {
1050dee1ad47SJeff Kirsher 	case e1000_fc_none:
1051e921eb1aSBruce Allan 		/* Flow control (Rx & Tx) is completely disabled by a
1052dee1ad47SJeff Kirsher 		 * software over-ride.
1053dee1ad47SJeff Kirsher 		 */
1054c2ade1a4SBruce Allan 		mii_autoneg_adv_reg &=
1055c2ade1a4SBruce Allan 		    ~(ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
1056cbdbb58bSJamie Gloudon 		phy->autoneg_advertised &=
1057cbdbb58bSJamie Gloudon 		    ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
1058dee1ad47SJeff Kirsher 		break;
1059dee1ad47SJeff Kirsher 	case e1000_fc_rx_pause:
1060e921eb1aSBruce Allan 		/* Rx Flow control is enabled, and Tx Flow control is
1061dee1ad47SJeff Kirsher 		 * disabled, by a software over-ride.
1062dee1ad47SJeff Kirsher 		 *
1063dee1ad47SJeff Kirsher 		 * Since there really isn't a way to advertise that we are
1064dee1ad47SJeff Kirsher 		 * capable of Rx Pause ONLY, we will advertise that we
1065dee1ad47SJeff Kirsher 		 * support both symmetric and asymmetric Rx PAUSE.  Later
1066dee1ad47SJeff Kirsher 		 * (in e1000e_config_fc_after_link_up) we will disable the
1067dee1ad47SJeff Kirsher 		 * hw's ability to send PAUSE frames.
1068dee1ad47SJeff Kirsher 		 */
1069c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |=
1070c2ade1a4SBruce Allan 		    (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
1071cbdbb58bSJamie Gloudon 		phy->autoneg_advertised |=
1072cbdbb58bSJamie Gloudon 		    (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
1073dee1ad47SJeff Kirsher 		break;
1074dee1ad47SJeff Kirsher 	case e1000_fc_tx_pause:
1075e921eb1aSBruce Allan 		/* Tx Flow control is enabled, and Rx Flow control is
1076dee1ad47SJeff Kirsher 		 * disabled, by a software over-ride.
1077dee1ad47SJeff Kirsher 		 */
1078c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |= ADVERTISE_PAUSE_ASYM;
1079c2ade1a4SBruce Allan 		mii_autoneg_adv_reg &= ~ADVERTISE_PAUSE_CAP;
1080cbdbb58bSJamie Gloudon 		phy->autoneg_advertised |= ADVERTISED_Asym_Pause;
1081cbdbb58bSJamie Gloudon 		phy->autoneg_advertised &= ~ADVERTISED_Pause;
1082dee1ad47SJeff Kirsher 		break;
1083dee1ad47SJeff Kirsher 	case e1000_fc_full:
1084e921eb1aSBruce Allan 		/* Flow control (both Rx and Tx) is enabled by a software
1085dee1ad47SJeff Kirsher 		 * over-ride.
1086dee1ad47SJeff Kirsher 		 */
1087c2ade1a4SBruce Allan 		mii_autoneg_adv_reg |=
1088c2ade1a4SBruce Allan 		    (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
1089cbdbb58bSJamie Gloudon 		phy->autoneg_advertised |=
1090cbdbb58bSJamie Gloudon 		    (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
1091dee1ad47SJeff Kirsher 		break;
1092dee1ad47SJeff Kirsher 	default:
1093dee1ad47SJeff Kirsher 		e_dbg("Flow control param set incorrectly\n");
10947eb61d81SBruce Allan 		return -E1000_ERR_CONFIG;
1095dee1ad47SJeff Kirsher 	}
1096dee1ad47SJeff Kirsher 
1097c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
1098dee1ad47SJeff Kirsher 	if (ret_val)
1099dee1ad47SJeff Kirsher 		return ret_val;
1100dee1ad47SJeff Kirsher 
1101dee1ad47SJeff Kirsher 	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
1102dee1ad47SJeff Kirsher 
1103dee1ad47SJeff Kirsher 	if (phy->autoneg_mask & ADVERTISE_1000_FULL)
1104c2ade1a4SBruce Allan 		ret_val = e1e_wphy(hw, MII_CTRL1000, mii_1000t_ctrl_reg);
1105dee1ad47SJeff Kirsher 
1106dee1ad47SJeff Kirsher 	return ret_val;
1107dee1ad47SJeff Kirsher }
1108dee1ad47SJeff Kirsher 
1109dee1ad47SJeff Kirsher /**
1110dee1ad47SJeff Kirsher  *  e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
1111dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1112dee1ad47SJeff Kirsher  *
1113dee1ad47SJeff Kirsher  *  Performs initial bounds checking on autoneg advertisement parameter, then
1114dee1ad47SJeff Kirsher  *  configure to advertise the full capability.  Setup the PHY to autoneg
1115dee1ad47SJeff Kirsher  *  and restart the negotiation process between the link partner.  If
1116dee1ad47SJeff Kirsher  *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
1117dee1ad47SJeff Kirsher  **/
1118dee1ad47SJeff Kirsher static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
1119dee1ad47SJeff Kirsher {
1120dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1121dee1ad47SJeff Kirsher 	s32 ret_val;
1122dee1ad47SJeff Kirsher 	u16 phy_ctrl;
1123dee1ad47SJeff Kirsher 
1124e921eb1aSBruce Allan 	/* Perform some bounds checking on the autoneg advertisement
1125dee1ad47SJeff Kirsher 	 * parameter.
1126dee1ad47SJeff Kirsher 	 */
1127dee1ad47SJeff Kirsher 	phy->autoneg_advertised &= phy->autoneg_mask;
1128dee1ad47SJeff Kirsher 
1129e921eb1aSBruce Allan 	/* If autoneg_advertised is zero, we assume it was not defaulted
1130dee1ad47SJeff Kirsher 	 * by the calling code so we set to advertise full capability.
1131dee1ad47SJeff Kirsher 	 */
113204499ec4SBruce Allan 	if (!phy->autoneg_advertised)
1133dee1ad47SJeff Kirsher 		phy->autoneg_advertised = phy->autoneg_mask;
1134dee1ad47SJeff Kirsher 
1135dee1ad47SJeff Kirsher 	e_dbg("Reconfiguring auto-neg advertisement params\n");
1136dee1ad47SJeff Kirsher 	ret_val = e1000_phy_setup_autoneg(hw);
1137dee1ad47SJeff Kirsher 	if (ret_val) {
1138dee1ad47SJeff Kirsher 		e_dbg("Error Setting up Auto-Negotiation\n");
1139dee1ad47SJeff Kirsher 		return ret_val;
1140dee1ad47SJeff Kirsher 	}
1141dee1ad47SJeff Kirsher 	e_dbg("Restarting Auto-Neg\n");
1142dee1ad47SJeff Kirsher 
1143e921eb1aSBruce Allan 	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
1144dee1ad47SJeff Kirsher 	 * the Auto Neg Restart bit in the PHY control register.
1145dee1ad47SJeff Kirsher 	 */
1146c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &phy_ctrl);
1147dee1ad47SJeff Kirsher 	if (ret_val)
1148dee1ad47SJeff Kirsher 		return ret_val;
1149dee1ad47SJeff Kirsher 
1150c2ade1a4SBruce Allan 	phy_ctrl |= (BMCR_ANENABLE | BMCR_ANRESTART);
1151c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, phy_ctrl);
1152dee1ad47SJeff Kirsher 	if (ret_val)
1153dee1ad47SJeff Kirsher 		return ret_val;
1154dee1ad47SJeff Kirsher 
1155e921eb1aSBruce Allan 	/* Does the user want to wait for Auto-Neg to complete here, or
1156dee1ad47SJeff Kirsher 	 * check at a later time (for example, callback routine).
1157dee1ad47SJeff Kirsher 	 */
1158dee1ad47SJeff Kirsher 	if (phy->autoneg_wait_to_complete) {
1159dee1ad47SJeff Kirsher 		ret_val = e1000_wait_autoneg(hw);
1160dee1ad47SJeff Kirsher 		if (ret_val) {
1161434f1392SBruce Allan 			e_dbg("Error while waiting for autoneg to complete\n");
1162dee1ad47SJeff Kirsher 			return ret_val;
1163dee1ad47SJeff Kirsher 		}
1164dee1ad47SJeff Kirsher 	}
1165dee1ad47SJeff Kirsher 
1166f92518ddSBruce Allan 	hw->mac.get_link_status = true;
1167dee1ad47SJeff Kirsher 
1168dee1ad47SJeff Kirsher 	return ret_val;
1169dee1ad47SJeff Kirsher }
1170dee1ad47SJeff Kirsher 
1171dee1ad47SJeff Kirsher /**
1172dee1ad47SJeff Kirsher  *  e1000e_setup_copper_link - Configure copper link settings
1173dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1174dee1ad47SJeff Kirsher  *
1175dee1ad47SJeff Kirsher  *  Calls the appropriate function to configure the link for auto-neg or forced
1176dee1ad47SJeff Kirsher  *  speed and duplex.  Then we check for link, once link is established calls
1177dee1ad47SJeff Kirsher  *  to configure collision distance and flow control are called.  If link is
1178dee1ad47SJeff Kirsher  *  not established, we return -E1000_ERR_PHY (-2).
1179dee1ad47SJeff Kirsher  **/
1180dee1ad47SJeff Kirsher s32 e1000e_setup_copper_link(struct e1000_hw *hw)
1181dee1ad47SJeff Kirsher {
1182dee1ad47SJeff Kirsher 	s32 ret_val;
1183dee1ad47SJeff Kirsher 	bool link;
1184dee1ad47SJeff Kirsher 
1185dee1ad47SJeff Kirsher 	if (hw->mac.autoneg) {
1186e921eb1aSBruce Allan 		/* Setup autoneg and flow control advertisement and perform
1187dee1ad47SJeff Kirsher 		 * autonegotiation.
1188dee1ad47SJeff Kirsher 		 */
1189dee1ad47SJeff Kirsher 		ret_val = e1000_copper_link_autoneg(hw);
1190dee1ad47SJeff Kirsher 		if (ret_val)
1191dee1ad47SJeff Kirsher 			return ret_val;
1192dee1ad47SJeff Kirsher 	} else {
1193e921eb1aSBruce Allan 		/* PHY will be set to 10H, 10F, 100H or 100F
1194dee1ad47SJeff Kirsher 		 * depending on user settings.
1195dee1ad47SJeff Kirsher 		 */
1196dee1ad47SJeff Kirsher 		e_dbg("Forcing Speed and Duplex\n");
1197c2c6629bSBruce Allan 		ret_val = hw->phy.ops.force_speed_duplex(hw);
1198dee1ad47SJeff Kirsher 		if (ret_val) {
1199dee1ad47SJeff Kirsher 			e_dbg("Error Forcing Speed and Duplex\n");
1200dee1ad47SJeff Kirsher 			return ret_val;
1201dee1ad47SJeff Kirsher 		}
1202dee1ad47SJeff Kirsher 	}
1203dee1ad47SJeff Kirsher 
1204e921eb1aSBruce Allan 	/* Check link status. Wait up to 100 microseconds for link to become
1205dee1ad47SJeff Kirsher 	 * valid.
1206dee1ad47SJeff Kirsher 	 */
12073d3a1676SBruce Allan 	ret_val = e1000e_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
1208dee1ad47SJeff Kirsher 					      &link);
1209dee1ad47SJeff Kirsher 	if (ret_val)
1210dee1ad47SJeff Kirsher 		return ret_val;
1211dee1ad47SJeff Kirsher 
1212dee1ad47SJeff Kirsher 	if (link) {
1213dee1ad47SJeff Kirsher 		e_dbg("Valid link established!!!\n");
121457cde763SBruce Allan 		hw->mac.ops.config_collision_dist(hw);
1215dee1ad47SJeff Kirsher 		ret_val = e1000e_config_fc_after_link_up(hw);
1216dee1ad47SJeff Kirsher 	} else {
1217dee1ad47SJeff Kirsher 		e_dbg("Unable to establish link!!!\n");
1218dee1ad47SJeff Kirsher 	}
1219dee1ad47SJeff Kirsher 
1220dee1ad47SJeff Kirsher 	return ret_val;
1221dee1ad47SJeff Kirsher }
1222dee1ad47SJeff Kirsher 
1223dee1ad47SJeff Kirsher /**
1224dee1ad47SJeff Kirsher  *  e1000e_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
1225dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1226dee1ad47SJeff Kirsher  *
1227dee1ad47SJeff Kirsher  *  Calls the PHY setup function to force speed and duplex.  Clears the
1228dee1ad47SJeff Kirsher  *  auto-crossover to force MDI manually.  Waits for link and returns
1229dee1ad47SJeff Kirsher  *  successful if link up is successful, else -E1000_ERR_PHY (-2).
1230dee1ad47SJeff Kirsher  **/
1231dee1ad47SJeff Kirsher s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
1232dee1ad47SJeff Kirsher {
1233dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1234dee1ad47SJeff Kirsher 	s32 ret_val;
1235dee1ad47SJeff Kirsher 	u16 phy_data;
1236dee1ad47SJeff Kirsher 	bool link;
1237dee1ad47SJeff Kirsher 
1238c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &phy_data);
1239dee1ad47SJeff Kirsher 	if (ret_val)
1240dee1ad47SJeff Kirsher 		return ret_val;
1241dee1ad47SJeff Kirsher 
1242dee1ad47SJeff Kirsher 	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
1243dee1ad47SJeff Kirsher 
1244c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, phy_data);
1245dee1ad47SJeff Kirsher 	if (ret_val)
1246dee1ad47SJeff Kirsher 		return ret_val;
1247dee1ad47SJeff Kirsher 
1248e921eb1aSBruce Allan 	/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
1249dee1ad47SJeff Kirsher 	 * forced whenever speed and duplex are forced.
1250dee1ad47SJeff Kirsher 	 */
1251dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
1252dee1ad47SJeff Kirsher 	if (ret_val)
1253dee1ad47SJeff Kirsher 		return ret_val;
1254dee1ad47SJeff Kirsher 
1255dee1ad47SJeff Kirsher 	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
1256dee1ad47SJeff Kirsher 	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
1257dee1ad47SJeff Kirsher 
1258dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
1259dee1ad47SJeff Kirsher 	if (ret_val)
1260dee1ad47SJeff Kirsher 		return ret_val;
1261dee1ad47SJeff Kirsher 
1262dee1ad47SJeff Kirsher 	e_dbg("IGP PSCR: %X\n", phy_data);
1263dee1ad47SJeff Kirsher 
1264dee1ad47SJeff Kirsher 	udelay(1);
1265dee1ad47SJeff Kirsher 
1266dee1ad47SJeff Kirsher 	if (phy->autoneg_wait_to_complete) {
1267dee1ad47SJeff Kirsher 		e_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
1268dee1ad47SJeff Kirsher 
12693d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
12703d3a1676SBruce Allan 						      100000, &link);
1271dee1ad47SJeff Kirsher 		if (ret_val)
1272dee1ad47SJeff Kirsher 			return ret_val;
1273dee1ad47SJeff Kirsher 
1274dee1ad47SJeff Kirsher 		if (!link)
1275dee1ad47SJeff Kirsher 			e_dbg("Link taking longer than expected.\n");
1276dee1ad47SJeff Kirsher 
1277dee1ad47SJeff Kirsher 		/* Try once more */
12783d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
12793d3a1676SBruce Allan 						      100000, &link);
1280dee1ad47SJeff Kirsher 	}
1281dee1ad47SJeff Kirsher 
1282dee1ad47SJeff Kirsher 	return ret_val;
1283dee1ad47SJeff Kirsher }
1284dee1ad47SJeff Kirsher 
1285dee1ad47SJeff Kirsher /**
1286dee1ad47SJeff Kirsher  *  e1000e_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
1287dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1288dee1ad47SJeff Kirsher  *
1289dee1ad47SJeff Kirsher  *  Calls the PHY setup function to force speed and duplex.  Clears the
1290dee1ad47SJeff Kirsher  *  auto-crossover to force MDI manually.  Resets the PHY to commit the
1291dee1ad47SJeff Kirsher  *  changes.  If time expires while waiting for link up, we reset the DSP.
1292dee1ad47SJeff Kirsher  *  After reset, TX_CLK and CRS on Tx must be set.  Return successful upon
1293dee1ad47SJeff Kirsher  *  successful completion, else return corresponding error code.
1294dee1ad47SJeff Kirsher  **/
1295dee1ad47SJeff Kirsher s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1296dee1ad47SJeff Kirsher {
1297dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1298dee1ad47SJeff Kirsher 	s32 ret_val;
1299dee1ad47SJeff Kirsher 	u16 phy_data;
1300dee1ad47SJeff Kirsher 	bool link;
1301dee1ad47SJeff Kirsher 
1302e921eb1aSBruce Allan 	/* Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
1303dee1ad47SJeff Kirsher 	 * forced whenever speed and duplex are forced.
1304dee1ad47SJeff Kirsher 	 */
1305dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1306dee1ad47SJeff Kirsher 	if (ret_val)
1307dee1ad47SJeff Kirsher 		return ret_val;
1308dee1ad47SJeff Kirsher 
1309dee1ad47SJeff Kirsher 	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
1310dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
1311dee1ad47SJeff Kirsher 	if (ret_val)
1312dee1ad47SJeff Kirsher 		return ret_val;
1313dee1ad47SJeff Kirsher 
1314dee1ad47SJeff Kirsher 	e_dbg("M88E1000 PSCR: %X\n", phy_data);
1315dee1ad47SJeff Kirsher 
1316c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &phy_data);
1317dee1ad47SJeff Kirsher 	if (ret_val)
1318dee1ad47SJeff Kirsher 		return ret_val;
1319dee1ad47SJeff Kirsher 
1320dee1ad47SJeff Kirsher 	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
1321dee1ad47SJeff Kirsher 
1322c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, phy_data);
1323dee1ad47SJeff Kirsher 	if (ret_val)
1324dee1ad47SJeff Kirsher 		return ret_val;
1325dee1ad47SJeff Kirsher 
1326dee1ad47SJeff Kirsher 	/* Reset the phy to commit changes. */
13276b598e1eSBruce Allan 	if (hw->phy.ops.commit) {
13286b598e1eSBruce Allan 		ret_val = hw->phy.ops.commit(hw);
1329dee1ad47SJeff Kirsher 		if (ret_val)
1330dee1ad47SJeff Kirsher 			return ret_val;
13316b598e1eSBruce Allan 	}
1332dee1ad47SJeff Kirsher 
1333dee1ad47SJeff Kirsher 	if (phy->autoneg_wait_to_complete) {
1334dee1ad47SJeff Kirsher 		e_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
1335dee1ad47SJeff Kirsher 
1336dee1ad47SJeff Kirsher 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
1337dee1ad47SJeff Kirsher 						      100000, &link);
1338dee1ad47SJeff Kirsher 		if (ret_val)
1339dee1ad47SJeff Kirsher 			return ret_val;
1340dee1ad47SJeff Kirsher 
1341dee1ad47SJeff Kirsher 		if (!link) {
1342dee1ad47SJeff Kirsher 			if (hw->phy.type != e1000_phy_m88) {
1343dee1ad47SJeff Kirsher 				e_dbg("Link taking longer than expected.\n");
1344dee1ad47SJeff Kirsher 			} else {
1345e921eb1aSBruce Allan 				/* We didn't get link.
1346dee1ad47SJeff Kirsher 				 * Reset the DSP and cross our fingers.
1347dee1ad47SJeff Kirsher 				 */
1348dee1ad47SJeff Kirsher 				ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT,
1349dee1ad47SJeff Kirsher 						   0x001d);
1350dee1ad47SJeff Kirsher 				if (ret_val)
1351dee1ad47SJeff Kirsher 					return ret_val;
1352dee1ad47SJeff Kirsher 				ret_val = e1000e_phy_reset_dsp(hw);
1353dee1ad47SJeff Kirsher 				if (ret_val)
1354dee1ad47SJeff Kirsher 					return ret_val;
1355dee1ad47SJeff Kirsher 			}
1356dee1ad47SJeff Kirsher 		}
1357dee1ad47SJeff Kirsher 
1358dee1ad47SJeff Kirsher 		/* Try once more */
1359dee1ad47SJeff Kirsher 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
1360dee1ad47SJeff Kirsher 						      100000, &link);
1361dee1ad47SJeff Kirsher 		if (ret_val)
1362dee1ad47SJeff Kirsher 			return ret_val;
1363dee1ad47SJeff Kirsher 	}
1364dee1ad47SJeff Kirsher 
1365dee1ad47SJeff Kirsher 	if (hw->phy.type != e1000_phy_m88)
1366dee1ad47SJeff Kirsher 		return 0;
1367dee1ad47SJeff Kirsher 
1368dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
1369dee1ad47SJeff Kirsher 	if (ret_val)
1370dee1ad47SJeff Kirsher 		return ret_val;
1371dee1ad47SJeff Kirsher 
1372e921eb1aSBruce Allan 	/* Resetting the phy means we need to re-force TX_CLK in the
1373dee1ad47SJeff Kirsher 	 * Extended PHY Specific Control Register to 25MHz clock from
1374dee1ad47SJeff Kirsher 	 * the reset value of 2.5MHz.
1375dee1ad47SJeff Kirsher 	 */
1376dee1ad47SJeff Kirsher 	phy_data |= M88E1000_EPSCR_TX_CLK_25;
1377dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
1378dee1ad47SJeff Kirsher 	if (ret_val)
1379dee1ad47SJeff Kirsher 		return ret_val;
1380dee1ad47SJeff Kirsher 
1381e921eb1aSBruce Allan 	/* In addition, we must re-enable CRS on Tx for both half and full
1382dee1ad47SJeff Kirsher 	 * duplex.
1383dee1ad47SJeff Kirsher 	 */
1384dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1385dee1ad47SJeff Kirsher 	if (ret_val)
1386dee1ad47SJeff Kirsher 		return ret_val;
1387dee1ad47SJeff Kirsher 
1388dee1ad47SJeff Kirsher 	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
1389dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
1390dee1ad47SJeff Kirsher 
1391dee1ad47SJeff Kirsher 	return ret_val;
1392dee1ad47SJeff Kirsher }
1393dee1ad47SJeff Kirsher 
1394dee1ad47SJeff Kirsher /**
1395dee1ad47SJeff Kirsher  *  e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
1396dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1397dee1ad47SJeff Kirsher  *
1398dee1ad47SJeff Kirsher  *  Forces the speed and duplex settings of the PHY.
1399dee1ad47SJeff Kirsher  *  This is a function pointer entry point only called by
1400dee1ad47SJeff Kirsher  *  PHY setup routines.
1401dee1ad47SJeff Kirsher  **/
1402dee1ad47SJeff Kirsher s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
1403dee1ad47SJeff Kirsher {
1404dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1405dee1ad47SJeff Kirsher 	s32 ret_val;
1406dee1ad47SJeff Kirsher 	u16 data;
1407dee1ad47SJeff Kirsher 	bool link;
1408dee1ad47SJeff Kirsher 
1409c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &data);
1410dee1ad47SJeff Kirsher 	if (ret_val)
14115015e53aSBruce Allan 		return ret_val;
1412dee1ad47SJeff Kirsher 
1413dee1ad47SJeff Kirsher 	e1000e_phy_force_speed_duplex_setup(hw, &data);
1414dee1ad47SJeff Kirsher 
1415c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, data);
1416dee1ad47SJeff Kirsher 	if (ret_val)
14175015e53aSBruce Allan 		return ret_val;
1418dee1ad47SJeff Kirsher 
1419dee1ad47SJeff Kirsher 	/* Disable MDI-X support for 10/100 */
1420dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
1421dee1ad47SJeff Kirsher 	if (ret_val)
14225015e53aSBruce Allan 		return ret_val;
1423dee1ad47SJeff Kirsher 
1424dee1ad47SJeff Kirsher 	data &= ~IFE_PMC_AUTO_MDIX;
1425dee1ad47SJeff Kirsher 	data &= ~IFE_PMC_FORCE_MDIX;
1426dee1ad47SJeff Kirsher 
1427dee1ad47SJeff Kirsher 	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
1428dee1ad47SJeff Kirsher 	if (ret_val)
14295015e53aSBruce Allan 		return ret_val;
1430dee1ad47SJeff Kirsher 
1431dee1ad47SJeff Kirsher 	e_dbg("IFE PMC: %X\n", data);
1432dee1ad47SJeff Kirsher 
1433dee1ad47SJeff Kirsher 	udelay(1);
1434dee1ad47SJeff Kirsher 
1435dee1ad47SJeff Kirsher 	if (phy->autoneg_wait_to_complete) {
1436dee1ad47SJeff Kirsher 		e_dbg("Waiting for forced speed/duplex link on IFE phy.\n");
1437dee1ad47SJeff Kirsher 
14383d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
14393d3a1676SBruce Allan 						      100000, &link);
1440dee1ad47SJeff Kirsher 		if (ret_val)
14415015e53aSBruce Allan 			return ret_val;
1442dee1ad47SJeff Kirsher 
1443dee1ad47SJeff Kirsher 		if (!link)
1444dee1ad47SJeff Kirsher 			e_dbg("Link taking longer than expected.\n");
1445dee1ad47SJeff Kirsher 
1446dee1ad47SJeff Kirsher 		/* Try once more */
14473d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
14483d3a1676SBruce Allan 						      100000, &link);
1449dee1ad47SJeff Kirsher 		if (ret_val)
14505015e53aSBruce Allan 			return ret_val;
1451dee1ad47SJeff Kirsher 	}
1452dee1ad47SJeff Kirsher 
14535015e53aSBruce Allan 	return 0;
1454dee1ad47SJeff Kirsher }
1455dee1ad47SJeff Kirsher 
1456dee1ad47SJeff Kirsher /**
1457dee1ad47SJeff Kirsher  *  e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
1458dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1459c2ade1a4SBruce Allan  *  @phy_ctrl: pointer to current value of MII_BMCR
1460dee1ad47SJeff Kirsher  *
1461dee1ad47SJeff Kirsher  *  Forces speed and duplex on the PHY by doing the following: disable flow
1462dee1ad47SJeff Kirsher  *  control, force speed/duplex on the MAC, disable auto speed detection,
1463dee1ad47SJeff Kirsher  *  disable auto-negotiation, configure duplex, configure speed, configure
1464dee1ad47SJeff Kirsher  *  the collision distance, write configuration to CTRL register.  The
1465c2ade1a4SBruce Allan  *  caller must write to the MII_BMCR register for these settings to
1466dee1ad47SJeff Kirsher  *  take affect.
1467dee1ad47SJeff Kirsher  **/
1468dee1ad47SJeff Kirsher void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
1469dee1ad47SJeff Kirsher {
1470dee1ad47SJeff Kirsher 	struct e1000_mac_info *mac = &hw->mac;
1471dee1ad47SJeff Kirsher 	u32 ctrl;
1472dee1ad47SJeff Kirsher 
1473dee1ad47SJeff Kirsher 	/* Turn off flow control when forcing speed/duplex */
1474dee1ad47SJeff Kirsher 	hw->fc.current_mode = e1000_fc_none;
1475dee1ad47SJeff Kirsher 
1476dee1ad47SJeff Kirsher 	/* Force speed/duplex on the mac */
1477dee1ad47SJeff Kirsher 	ctrl = er32(CTRL);
1478dee1ad47SJeff Kirsher 	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
1479dee1ad47SJeff Kirsher 	ctrl &= ~E1000_CTRL_SPD_SEL;
1480dee1ad47SJeff Kirsher 
1481dee1ad47SJeff Kirsher 	/* Disable Auto Speed Detection */
1482dee1ad47SJeff Kirsher 	ctrl &= ~E1000_CTRL_ASDE;
1483dee1ad47SJeff Kirsher 
1484dee1ad47SJeff Kirsher 	/* Disable autoneg on the phy */
1485c2ade1a4SBruce Allan 	*phy_ctrl &= ~BMCR_ANENABLE;
1486dee1ad47SJeff Kirsher 
1487dee1ad47SJeff Kirsher 	/* Forcing Full or Half Duplex? */
1488dee1ad47SJeff Kirsher 	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
1489dee1ad47SJeff Kirsher 		ctrl &= ~E1000_CTRL_FD;
1490c2ade1a4SBruce Allan 		*phy_ctrl &= ~BMCR_FULLDPLX;
1491dee1ad47SJeff Kirsher 		e_dbg("Half Duplex\n");
1492dee1ad47SJeff Kirsher 	} else {
1493dee1ad47SJeff Kirsher 		ctrl |= E1000_CTRL_FD;
1494c2ade1a4SBruce Allan 		*phy_ctrl |= BMCR_FULLDPLX;
1495dee1ad47SJeff Kirsher 		e_dbg("Full Duplex\n");
1496dee1ad47SJeff Kirsher 	}
1497dee1ad47SJeff Kirsher 
1498dee1ad47SJeff Kirsher 	/* Forcing 10mb or 100mb? */
1499dee1ad47SJeff Kirsher 	if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
1500dee1ad47SJeff Kirsher 		ctrl |= E1000_CTRL_SPD_100;
1501c2ade1a4SBruce Allan 		*phy_ctrl |= BMCR_SPEED100;
1502c2ade1a4SBruce Allan 		*phy_ctrl &= ~BMCR_SPEED1000;
1503dee1ad47SJeff Kirsher 		e_dbg("Forcing 100mb\n");
1504dee1ad47SJeff Kirsher 	} else {
1505dee1ad47SJeff Kirsher 		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
1506c2ade1a4SBruce Allan 		*phy_ctrl &= ~(BMCR_SPEED1000 | BMCR_SPEED100);
1507dee1ad47SJeff Kirsher 		e_dbg("Forcing 10mb\n");
1508dee1ad47SJeff Kirsher 	}
1509dee1ad47SJeff Kirsher 
151057cde763SBruce Allan 	hw->mac.ops.config_collision_dist(hw);
1511dee1ad47SJeff Kirsher 
1512dee1ad47SJeff Kirsher 	ew32(CTRL, ctrl);
1513dee1ad47SJeff Kirsher }
1514dee1ad47SJeff Kirsher 
1515dee1ad47SJeff Kirsher /**
1516dee1ad47SJeff Kirsher  *  e1000e_set_d3_lplu_state - Sets low power link up state for D3
1517dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1518dee1ad47SJeff Kirsher  *  @active: boolean used to enable/disable lplu
1519dee1ad47SJeff Kirsher  *
1520dee1ad47SJeff Kirsher  *  Success returns 0, Failure returns 1
1521dee1ad47SJeff Kirsher  *
1522dee1ad47SJeff Kirsher  *  The low power link up (lplu) state is set to the power management level D3
1523dee1ad47SJeff Kirsher  *  and SmartSpeed is disabled when active is true, else clear lplu for D3
1524dee1ad47SJeff Kirsher  *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
1525dee1ad47SJeff Kirsher  *  is used during Dx states where the power conservation is most important.
1526dee1ad47SJeff Kirsher  *  During driver activity, SmartSpeed should be enabled so performance is
1527dee1ad47SJeff Kirsher  *  maintained.
1528dee1ad47SJeff Kirsher  **/
1529dee1ad47SJeff Kirsher s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
1530dee1ad47SJeff Kirsher {
1531dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1532dee1ad47SJeff Kirsher 	s32 ret_val;
1533dee1ad47SJeff Kirsher 	u16 data;
1534dee1ad47SJeff Kirsher 
1535dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);
1536dee1ad47SJeff Kirsher 	if (ret_val)
1537dee1ad47SJeff Kirsher 		return ret_val;
1538dee1ad47SJeff Kirsher 
1539dee1ad47SJeff Kirsher 	if (!active) {
1540dee1ad47SJeff Kirsher 		data &= ~IGP02E1000_PM_D3_LPLU;
1541dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
1542dee1ad47SJeff Kirsher 		if (ret_val)
1543dee1ad47SJeff Kirsher 			return ret_val;
1544e921eb1aSBruce Allan 		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
1545dee1ad47SJeff Kirsher 		 * during Dx states where the power conservation is most
1546dee1ad47SJeff Kirsher 		 * important.  During driver activity we should enable
1547dee1ad47SJeff Kirsher 		 * SmartSpeed, so performance is maintained.
1548dee1ad47SJeff Kirsher 		 */
1549dee1ad47SJeff Kirsher 		if (phy->smart_speed == e1000_smart_speed_on) {
1550dee1ad47SJeff Kirsher 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
1551dee1ad47SJeff Kirsher 					   &data);
1552dee1ad47SJeff Kirsher 			if (ret_val)
1553dee1ad47SJeff Kirsher 				return ret_val;
1554dee1ad47SJeff Kirsher 
1555dee1ad47SJeff Kirsher 			data |= IGP01E1000_PSCFR_SMART_SPEED;
1556dee1ad47SJeff Kirsher 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
1557dee1ad47SJeff Kirsher 					   data);
1558dee1ad47SJeff Kirsher 			if (ret_val)
1559dee1ad47SJeff Kirsher 				return ret_val;
1560dee1ad47SJeff Kirsher 		} else if (phy->smart_speed == e1000_smart_speed_off) {
1561dee1ad47SJeff Kirsher 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
1562dee1ad47SJeff Kirsher 					   &data);
1563dee1ad47SJeff Kirsher 			if (ret_val)
1564dee1ad47SJeff Kirsher 				return ret_val;
1565dee1ad47SJeff Kirsher 
1566dee1ad47SJeff Kirsher 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
1567dee1ad47SJeff Kirsher 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
1568dee1ad47SJeff Kirsher 					   data);
1569dee1ad47SJeff Kirsher 			if (ret_val)
1570dee1ad47SJeff Kirsher 				return ret_val;
1571dee1ad47SJeff Kirsher 		}
1572dee1ad47SJeff Kirsher 	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
1573dee1ad47SJeff Kirsher 		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
1574dee1ad47SJeff Kirsher 		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
1575dee1ad47SJeff Kirsher 		data |= IGP02E1000_PM_D3_LPLU;
1576dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
1577dee1ad47SJeff Kirsher 		if (ret_val)
1578dee1ad47SJeff Kirsher 			return ret_val;
1579dee1ad47SJeff Kirsher 
1580dee1ad47SJeff Kirsher 		/* When LPLU is enabled, we should disable SmartSpeed */
1581dee1ad47SJeff Kirsher 		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
1582dee1ad47SJeff Kirsher 		if (ret_val)
1583dee1ad47SJeff Kirsher 			return ret_val;
1584dee1ad47SJeff Kirsher 
1585dee1ad47SJeff Kirsher 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
1586dee1ad47SJeff Kirsher 		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
1587dee1ad47SJeff Kirsher 	}
1588dee1ad47SJeff Kirsher 
1589dee1ad47SJeff Kirsher 	return ret_val;
1590dee1ad47SJeff Kirsher }
1591dee1ad47SJeff Kirsher 
1592dee1ad47SJeff Kirsher /**
1593dee1ad47SJeff Kirsher  *  e1000e_check_downshift - Checks whether a downshift in speed occurred
1594dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1595dee1ad47SJeff Kirsher  *
1596dee1ad47SJeff Kirsher  *  Success returns 0, Failure returns 1
1597dee1ad47SJeff Kirsher  *
1598dee1ad47SJeff Kirsher  *  A downshift is detected by querying the PHY link health.
1599dee1ad47SJeff Kirsher  **/
1600dee1ad47SJeff Kirsher s32 e1000e_check_downshift(struct e1000_hw *hw)
1601dee1ad47SJeff Kirsher {
1602dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1603dee1ad47SJeff Kirsher 	s32 ret_val;
1604dee1ad47SJeff Kirsher 	u16 phy_data, offset, mask;
1605dee1ad47SJeff Kirsher 
1606dee1ad47SJeff Kirsher 	switch (phy->type) {
1607dee1ad47SJeff Kirsher 	case e1000_phy_m88:
1608dee1ad47SJeff Kirsher 	case e1000_phy_gg82563:
1609dee1ad47SJeff Kirsher 	case e1000_phy_bm:
1610dee1ad47SJeff Kirsher 	case e1000_phy_82578:
1611dee1ad47SJeff Kirsher 		offset = M88E1000_PHY_SPEC_STATUS;
1612dee1ad47SJeff Kirsher 		mask = M88E1000_PSSR_DOWNSHIFT;
1613dee1ad47SJeff Kirsher 		break;
1614dee1ad47SJeff Kirsher 	case e1000_phy_igp_2:
1615dee1ad47SJeff Kirsher 	case e1000_phy_igp_3:
1616dee1ad47SJeff Kirsher 		offset = IGP01E1000_PHY_LINK_HEALTH;
1617dee1ad47SJeff Kirsher 		mask = IGP01E1000_PLHR_SS_DOWNGRADE;
1618dee1ad47SJeff Kirsher 		break;
1619dee1ad47SJeff Kirsher 	default:
1620dee1ad47SJeff Kirsher 		/* speed downshift not supported */
1621dee1ad47SJeff Kirsher 		phy->speed_downgraded = false;
1622dee1ad47SJeff Kirsher 		return 0;
1623dee1ad47SJeff Kirsher 	}
1624dee1ad47SJeff Kirsher 
1625dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, offset, &phy_data);
1626dee1ad47SJeff Kirsher 
1627dee1ad47SJeff Kirsher 	if (!ret_val)
162804499ec4SBruce Allan 		phy->speed_downgraded = !!(phy_data & mask);
1629dee1ad47SJeff Kirsher 
1630dee1ad47SJeff Kirsher 	return ret_val;
1631dee1ad47SJeff Kirsher }
1632dee1ad47SJeff Kirsher 
1633dee1ad47SJeff Kirsher /**
1634dee1ad47SJeff Kirsher  *  e1000_check_polarity_m88 - Checks the polarity.
1635dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1636dee1ad47SJeff Kirsher  *
1637dee1ad47SJeff Kirsher  *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
1638dee1ad47SJeff Kirsher  *
1639dee1ad47SJeff Kirsher  *  Polarity is determined based on the PHY specific status register.
1640dee1ad47SJeff Kirsher  **/
1641dee1ad47SJeff Kirsher s32 e1000_check_polarity_m88(struct e1000_hw *hw)
1642dee1ad47SJeff Kirsher {
1643dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1644dee1ad47SJeff Kirsher 	s32 ret_val;
1645dee1ad47SJeff Kirsher 	u16 data;
1646dee1ad47SJeff Kirsher 
1647dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data);
1648dee1ad47SJeff Kirsher 
1649dee1ad47SJeff Kirsher 	if (!ret_val)
1650f0ff4398SBruce Allan 		phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY)
1651dee1ad47SJeff Kirsher 				       ? e1000_rev_polarity_reversed
1652f0ff4398SBruce Allan 				       : e1000_rev_polarity_normal);
1653dee1ad47SJeff Kirsher 
1654dee1ad47SJeff Kirsher 	return ret_val;
1655dee1ad47SJeff Kirsher }
1656dee1ad47SJeff Kirsher 
1657dee1ad47SJeff Kirsher /**
1658dee1ad47SJeff Kirsher  *  e1000_check_polarity_igp - Checks the polarity.
1659dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1660dee1ad47SJeff Kirsher  *
1661dee1ad47SJeff Kirsher  *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
1662dee1ad47SJeff Kirsher  *
1663dee1ad47SJeff Kirsher  *  Polarity is determined based on the PHY port status register, and the
1664dee1ad47SJeff Kirsher  *  current speed (since there is no polarity at 100Mbps).
1665dee1ad47SJeff Kirsher  **/
1666dee1ad47SJeff Kirsher s32 e1000_check_polarity_igp(struct e1000_hw *hw)
1667dee1ad47SJeff Kirsher {
1668dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1669dee1ad47SJeff Kirsher 	s32 ret_val;
1670dee1ad47SJeff Kirsher 	u16 data, offset, mask;
1671dee1ad47SJeff Kirsher 
1672e921eb1aSBruce Allan 	/* Polarity is determined based on the speed of
1673dee1ad47SJeff Kirsher 	 * our connection.
1674dee1ad47SJeff Kirsher 	 */
1675dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
1676dee1ad47SJeff Kirsher 	if (ret_val)
1677dee1ad47SJeff Kirsher 		return ret_val;
1678dee1ad47SJeff Kirsher 
1679dee1ad47SJeff Kirsher 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
1680dee1ad47SJeff Kirsher 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
1681dee1ad47SJeff Kirsher 		offset = IGP01E1000_PHY_PCS_INIT_REG;
1682dee1ad47SJeff Kirsher 		mask = IGP01E1000_PHY_POLARITY_MASK;
1683dee1ad47SJeff Kirsher 	} else {
1684e921eb1aSBruce Allan 		/* This really only applies to 10Mbps since
1685dee1ad47SJeff Kirsher 		 * there is no polarity for 100Mbps (always 0).
1686dee1ad47SJeff Kirsher 		 */
1687dee1ad47SJeff Kirsher 		offset = IGP01E1000_PHY_PORT_STATUS;
1688dee1ad47SJeff Kirsher 		mask = IGP01E1000_PSSR_POLARITY_REVERSED;
1689dee1ad47SJeff Kirsher 	}
1690dee1ad47SJeff Kirsher 
1691dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, offset, &data);
1692dee1ad47SJeff Kirsher 
1693dee1ad47SJeff Kirsher 	if (!ret_val)
1694f0ff4398SBruce Allan 		phy->cable_polarity = ((data & mask)
1695dee1ad47SJeff Kirsher 				       ? e1000_rev_polarity_reversed
1696f0ff4398SBruce Allan 				       : e1000_rev_polarity_normal);
1697dee1ad47SJeff Kirsher 
1698dee1ad47SJeff Kirsher 	return ret_val;
1699dee1ad47SJeff Kirsher }
1700dee1ad47SJeff Kirsher 
1701dee1ad47SJeff Kirsher /**
1702dee1ad47SJeff Kirsher  *  e1000_check_polarity_ife - Check cable polarity for IFE PHY
1703dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1704dee1ad47SJeff Kirsher  *
1705dee1ad47SJeff Kirsher  *  Polarity is determined on the polarity reversal feature being enabled.
1706dee1ad47SJeff Kirsher  **/
1707dee1ad47SJeff Kirsher s32 e1000_check_polarity_ife(struct e1000_hw *hw)
1708dee1ad47SJeff Kirsher {
1709dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1710dee1ad47SJeff Kirsher 	s32 ret_val;
1711dee1ad47SJeff Kirsher 	u16 phy_data, offset, mask;
1712dee1ad47SJeff Kirsher 
1713e921eb1aSBruce Allan 	/* Polarity is determined based on the reversal feature being enabled.
1714dee1ad47SJeff Kirsher 	 */
1715dee1ad47SJeff Kirsher 	if (phy->polarity_correction) {
1716dee1ad47SJeff Kirsher 		offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
1717dee1ad47SJeff Kirsher 		mask = IFE_PESC_POLARITY_REVERSED;
1718dee1ad47SJeff Kirsher 	} else {
1719dee1ad47SJeff Kirsher 		offset = IFE_PHY_SPECIAL_CONTROL;
1720dee1ad47SJeff Kirsher 		mask = IFE_PSC_FORCE_POLARITY;
1721dee1ad47SJeff Kirsher 	}
1722dee1ad47SJeff Kirsher 
1723dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, offset, &phy_data);
1724dee1ad47SJeff Kirsher 
1725dee1ad47SJeff Kirsher 	if (!ret_val)
1726f0ff4398SBruce Allan 		phy->cable_polarity = ((phy_data & mask)
1727dee1ad47SJeff Kirsher 				       ? e1000_rev_polarity_reversed
1728f0ff4398SBruce Allan 				       : e1000_rev_polarity_normal);
1729dee1ad47SJeff Kirsher 
1730dee1ad47SJeff Kirsher 	return ret_val;
1731dee1ad47SJeff Kirsher }
1732dee1ad47SJeff Kirsher 
1733dee1ad47SJeff Kirsher /**
1734dee1ad47SJeff Kirsher  *  e1000_wait_autoneg - Wait for auto-neg completion
1735dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1736dee1ad47SJeff Kirsher  *
1737dee1ad47SJeff Kirsher  *  Waits for auto-negotiation to complete or for the auto-negotiation time
1738dee1ad47SJeff Kirsher  *  limit to expire, which ever happens first.
1739dee1ad47SJeff Kirsher  **/
1740dee1ad47SJeff Kirsher static s32 e1000_wait_autoneg(struct e1000_hw *hw)
1741dee1ad47SJeff Kirsher {
1742dee1ad47SJeff Kirsher 	s32 ret_val = 0;
1743dee1ad47SJeff Kirsher 	u16 i, phy_status;
1744dee1ad47SJeff Kirsher 
1745dee1ad47SJeff Kirsher 	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
1746dee1ad47SJeff Kirsher 	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
1747c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_BMSR, &phy_status);
1748dee1ad47SJeff Kirsher 		if (ret_val)
1749dee1ad47SJeff Kirsher 			break;
1750c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_BMSR, &phy_status);
1751dee1ad47SJeff Kirsher 		if (ret_val)
1752dee1ad47SJeff Kirsher 			break;
1753c2ade1a4SBruce Allan 		if (phy_status & BMSR_ANEGCOMPLETE)
1754dee1ad47SJeff Kirsher 			break;
1755dee1ad47SJeff Kirsher 		msleep(100);
1756dee1ad47SJeff Kirsher 	}
1757dee1ad47SJeff Kirsher 
1758e921eb1aSBruce Allan 	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
1759dee1ad47SJeff Kirsher 	 * has completed.
1760dee1ad47SJeff Kirsher 	 */
1761dee1ad47SJeff Kirsher 	return ret_val;
1762dee1ad47SJeff Kirsher }
1763dee1ad47SJeff Kirsher 
1764dee1ad47SJeff Kirsher /**
1765dee1ad47SJeff Kirsher  *  e1000e_phy_has_link_generic - Polls PHY for link
1766dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1767dee1ad47SJeff Kirsher  *  @iterations: number of times to poll for link
1768dee1ad47SJeff Kirsher  *  @usec_interval: delay between polling attempts
1769dee1ad47SJeff Kirsher  *  @success: pointer to whether polling was successful or not
1770dee1ad47SJeff Kirsher  *
1771dee1ad47SJeff Kirsher  *  Polls the PHY status register for link, 'iterations' number of times.
1772dee1ad47SJeff Kirsher  **/
1773dee1ad47SJeff Kirsher s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
1774dee1ad47SJeff Kirsher 				u32 usec_interval, bool *success)
1775dee1ad47SJeff Kirsher {
1776dee1ad47SJeff Kirsher 	s32 ret_val = 0;
1777dee1ad47SJeff Kirsher 	u16 i, phy_status;
1778dee1ad47SJeff Kirsher 
1779c4c40e51SBenjamin Poirier 	*success = false;
1780dee1ad47SJeff Kirsher 	for (i = 0; i < iterations; i++) {
1781c2ade1a4SBruce Allan 		/* Some PHYs require the MII_BMSR register to be read
1782dee1ad47SJeff Kirsher 		 * twice due to the link bit being sticky.  No harm doing
1783dee1ad47SJeff Kirsher 		 * it across the board.
1784dee1ad47SJeff Kirsher 		 */
1785c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_BMSR, &phy_status);
17869e6c3b63SDavid Ertman 		if (ret_val) {
1787e921eb1aSBruce Allan 			/* If the first read fails, another entity may have
1788dee1ad47SJeff Kirsher 			 * ownership of the resources, wait and try again to
1789dee1ad47SJeff Kirsher 			 * see if they have relinquished the resources yet.
1790dee1ad47SJeff Kirsher 			 */
17919e6c3b63SDavid Ertman 			if (usec_interval >= 1000)
17929e6c3b63SDavid Ertman 				msleep(usec_interval / 1000);
17939e6c3b63SDavid Ertman 			else
1794dee1ad47SJeff Kirsher 				udelay(usec_interval);
17959e6c3b63SDavid Ertman 		}
1796c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_BMSR, &phy_status);
1797dee1ad47SJeff Kirsher 		if (ret_val)
1798dee1ad47SJeff Kirsher 			break;
1799c4c40e51SBenjamin Poirier 		if (phy_status & BMSR_LSTATUS) {
1800c4c40e51SBenjamin Poirier 			*success = true;
1801dee1ad47SJeff Kirsher 			break;
1802c4c40e51SBenjamin Poirier 		}
1803dee1ad47SJeff Kirsher 		if (usec_interval >= 1000)
18049e6c3b63SDavid Ertman 			msleep(usec_interval / 1000);
1805dee1ad47SJeff Kirsher 		else
1806dee1ad47SJeff Kirsher 			udelay(usec_interval);
1807dee1ad47SJeff Kirsher 	}
1808dee1ad47SJeff Kirsher 
1809dee1ad47SJeff Kirsher 	return ret_val;
1810dee1ad47SJeff Kirsher }
1811dee1ad47SJeff Kirsher 
1812dee1ad47SJeff Kirsher /**
1813dee1ad47SJeff Kirsher  *  e1000e_get_cable_length_m88 - Determine cable length for m88 PHY
1814dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1815dee1ad47SJeff Kirsher  *
1816dee1ad47SJeff Kirsher  *  Reads the PHY specific status register to retrieve the cable length
1817dee1ad47SJeff Kirsher  *  information.  The cable length is determined by averaging the minimum and
1818dee1ad47SJeff Kirsher  *  maximum values to get the "average" cable length.  The m88 PHY has four
1819dee1ad47SJeff Kirsher  *  possible cable length values, which are:
1820dee1ad47SJeff Kirsher  *	Register Value		Cable Length
1821dee1ad47SJeff Kirsher  *	0			< 50 meters
1822dee1ad47SJeff Kirsher  *	1			50 - 80 meters
1823dee1ad47SJeff Kirsher  *	2			80 - 110 meters
1824dee1ad47SJeff Kirsher  *	3			110 - 140 meters
1825dee1ad47SJeff Kirsher  *	4			> 140 meters
1826dee1ad47SJeff Kirsher  **/
1827dee1ad47SJeff Kirsher s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
1828dee1ad47SJeff Kirsher {
1829dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1830dee1ad47SJeff Kirsher 	s32 ret_val;
1831dee1ad47SJeff Kirsher 	u16 phy_data, index;
1832dee1ad47SJeff Kirsher 
1833dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
1834dee1ad47SJeff Kirsher 	if (ret_val)
18355015e53aSBruce Allan 		return ret_val;
1836dee1ad47SJeff Kirsher 
1837d5752c7bSJesse Brandeburg 	index = FIELD_GET(M88E1000_PSSR_CABLE_LENGTH, phy_data);
18385015e53aSBruce Allan 
18395015e53aSBruce Allan 	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
18405015e53aSBruce Allan 		return -E1000_ERR_PHY;
1841dee1ad47SJeff Kirsher 
1842dee1ad47SJeff Kirsher 	phy->min_cable_length = e1000_m88_cable_length_table[index];
1843dee1ad47SJeff Kirsher 	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
1844dee1ad47SJeff Kirsher 
1845dee1ad47SJeff Kirsher 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
1846dee1ad47SJeff Kirsher 
18475015e53aSBruce Allan 	return 0;
1848dee1ad47SJeff Kirsher }
1849dee1ad47SJeff Kirsher 
1850dee1ad47SJeff Kirsher /**
1851dee1ad47SJeff Kirsher  *  e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY
1852dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1853dee1ad47SJeff Kirsher  *
1854dee1ad47SJeff Kirsher  *  The automatic gain control (agc) normalizes the amplitude of the
1855dee1ad47SJeff Kirsher  *  received signal, adjusting for the attenuation produced by the
1856dee1ad47SJeff Kirsher  *  cable.  By reading the AGC registers, which represent the
1857dee1ad47SJeff Kirsher  *  combination of coarse and fine gain value, the value can be put
1858dee1ad47SJeff Kirsher  *  into a lookup table to obtain the approximate cable length
1859dee1ad47SJeff Kirsher  *  for each channel.
1860dee1ad47SJeff Kirsher  **/
1861dee1ad47SJeff Kirsher s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
1862dee1ad47SJeff Kirsher {
1863dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1864dee1ad47SJeff Kirsher 	s32 ret_val;
1865dee1ad47SJeff Kirsher 	u16 phy_data, i, agc_value = 0;
1866dee1ad47SJeff Kirsher 	u16 cur_agc_index, max_agc_index = 0;
1867dee1ad47SJeff Kirsher 	u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
1868dee1ad47SJeff Kirsher 	static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
1869dee1ad47SJeff Kirsher 		IGP02E1000_PHY_AGC_A,
1870dee1ad47SJeff Kirsher 		IGP02E1000_PHY_AGC_B,
1871dee1ad47SJeff Kirsher 		IGP02E1000_PHY_AGC_C,
1872dee1ad47SJeff Kirsher 		IGP02E1000_PHY_AGC_D
1873dee1ad47SJeff Kirsher 	};
1874dee1ad47SJeff Kirsher 
1875dee1ad47SJeff Kirsher 	/* Read the AGC registers for all channels */
1876dee1ad47SJeff Kirsher 	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
1877dee1ad47SJeff Kirsher 		ret_val = e1e_rphy(hw, agc_reg_array[i], &phy_data);
1878dee1ad47SJeff Kirsher 		if (ret_val)
1879dee1ad47SJeff Kirsher 			return ret_val;
1880dee1ad47SJeff Kirsher 
1881e921eb1aSBruce Allan 		/* Getting bits 15:9, which represent the combination of
1882dee1ad47SJeff Kirsher 		 * coarse and fine gain values.  The result is a number
1883dee1ad47SJeff Kirsher 		 * that can be put into the lookup table to obtain the
1884dee1ad47SJeff Kirsher 		 * approximate cable length.
1885dee1ad47SJeff Kirsher 		 */
1886f0ff4398SBruce Allan 		cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
1887f0ff4398SBruce Allan 				 IGP02E1000_AGC_LENGTH_MASK);
1888dee1ad47SJeff Kirsher 
1889dee1ad47SJeff Kirsher 		/* Array index bound check. */
1890dee1ad47SJeff Kirsher 		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
1891dee1ad47SJeff Kirsher 		    (cur_agc_index == 0))
1892dee1ad47SJeff Kirsher 			return -E1000_ERR_PHY;
1893dee1ad47SJeff Kirsher 
1894dee1ad47SJeff Kirsher 		/* Remove min & max AGC values from calculation. */
1895dee1ad47SJeff Kirsher 		if (e1000_igp_2_cable_length_table[min_agc_index] >
1896dee1ad47SJeff Kirsher 		    e1000_igp_2_cable_length_table[cur_agc_index])
1897dee1ad47SJeff Kirsher 			min_agc_index = cur_agc_index;
1898dee1ad47SJeff Kirsher 		if (e1000_igp_2_cable_length_table[max_agc_index] <
1899dee1ad47SJeff Kirsher 		    e1000_igp_2_cable_length_table[cur_agc_index])
1900dee1ad47SJeff Kirsher 			max_agc_index = cur_agc_index;
1901dee1ad47SJeff Kirsher 
1902dee1ad47SJeff Kirsher 		agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
1903dee1ad47SJeff Kirsher 	}
1904dee1ad47SJeff Kirsher 
1905dee1ad47SJeff Kirsher 	agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
1906dee1ad47SJeff Kirsher 		      e1000_igp_2_cable_length_table[max_agc_index]);
1907dee1ad47SJeff Kirsher 	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
1908dee1ad47SJeff Kirsher 
1909dee1ad47SJeff Kirsher 	/* Calculate cable length with the error range of +/- 10 meters. */
1910f0ff4398SBruce Allan 	phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
1911f0ff4398SBruce Allan 				 (agc_value - IGP02E1000_AGC_RANGE) : 0);
1912dee1ad47SJeff Kirsher 	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
1913dee1ad47SJeff Kirsher 
1914dee1ad47SJeff Kirsher 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
1915dee1ad47SJeff Kirsher 
191682607255SBruce Allan 	return 0;
1917dee1ad47SJeff Kirsher }
1918dee1ad47SJeff Kirsher 
1919dee1ad47SJeff Kirsher /**
1920dee1ad47SJeff Kirsher  *  e1000e_get_phy_info_m88 - Retrieve PHY information
1921dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1922dee1ad47SJeff Kirsher  *
1923dee1ad47SJeff Kirsher  *  Valid for only copper links.  Read the PHY status register (sticky read)
1924dee1ad47SJeff Kirsher  *  to verify that link is up.  Read the PHY special control register to
1925dee1ad47SJeff Kirsher  *  determine the polarity and 10base-T extended distance.  Read the PHY
1926dee1ad47SJeff Kirsher  *  special status register to determine MDI/MDIx and current speed.  If
1927dee1ad47SJeff Kirsher  *  speed is 1000, then determine cable length, local and remote receiver.
1928dee1ad47SJeff Kirsher  **/
1929dee1ad47SJeff Kirsher s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
1930dee1ad47SJeff Kirsher {
1931dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
1932dee1ad47SJeff Kirsher 	s32 ret_val;
1933dee1ad47SJeff Kirsher 	u16 phy_data;
1934dee1ad47SJeff Kirsher 	bool link;
1935dee1ad47SJeff Kirsher 
1936dee1ad47SJeff Kirsher 	if (phy->media_type != e1000_media_type_copper) {
1937dee1ad47SJeff Kirsher 		e_dbg("Phy info is only valid for copper media\n");
1938dee1ad47SJeff Kirsher 		return -E1000_ERR_CONFIG;
1939dee1ad47SJeff Kirsher 	}
1940dee1ad47SJeff Kirsher 
1941dee1ad47SJeff Kirsher 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
1942dee1ad47SJeff Kirsher 	if (ret_val)
1943dee1ad47SJeff Kirsher 		return ret_val;
1944dee1ad47SJeff Kirsher 
1945dee1ad47SJeff Kirsher 	if (!link) {
1946dee1ad47SJeff Kirsher 		e_dbg("Phy info is only valid if link is up\n");
1947dee1ad47SJeff Kirsher 		return -E1000_ERR_CONFIG;
1948dee1ad47SJeff Kirsher 	}
1949dee1ad47SJeff Kirsher 
1950dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1951dee1ad47SJeff Kirsher 	if (ret_val)
1952dee1ad47SJeff Kirsher 		return ret_val;
1953dee1ad47SJeff Kirsher 
195404499ec4SBruce Allan 	phy->polarity_correction = !!(phy_data &
1955dee1ad47SJeff Kirsher 				      M88E1000_PSCR_POLARITY_REVERSAL);
1956dee1ad47SJeff Kirsher 
1957dee1ad47SJeff Kirsher 	ret_val = e1000_check_polarity_m88(hw);
1958dee1ad47SJeff Kirsher 	if (ret_val)
1959dee1ad47SJeff Kirsher 		return ret_val;
1960dee1ad47SJeff Kirsher 
1961dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
1962dee1ad47SJeff Kirsher 	if (ret_val)
1963dee1ad47SJeff Kirsher 		return ret_val;
1964dee1ad47SJeff Kirsher 
196504499ec4SBruce Allan 	phy->is_mdix = !!(phy_data & M88E1000_PSSR_MDIX);
1966dee1ad47SJeff Kirsher 
1967dee1ad47SJeff Kirsher 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
1968dde3a574SBruce Allan 		ret_val = hw->phy.ops.get_cable_length(hw);
1969dee1ad47SJeff Kirsher 		if (ret_val)
1970dee1ad47SJeff Kirsher 			return ret_val;
1971dee1ad47SJeff Kirsher 
1972c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_STAT1000, &phy_data);
1973dee1ad47SJeff Kirsher 		if (ret_val)
1974dee1ad47SJeff Kirsher 			return ret_val;
1975dee1ad47SJeff Kirsher 
1976c2ade1a4SBruce Allan 		phy->local_rx = (phy_data & LPA_1000LOCALRXOK)
1977c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
1978dee1ad47SJeff Kirsher 
1979c2ade1a4SBruce Allan 		phy->remote_rx = (phy_data & LPA_1000REMRXOK)
1980c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
1981dee1ad47SJeff Kirsher 	} else {
1982dee1ad47SJeff Kirsher 		/* Set values to "undefined" */
1983dee1ad47SJeff Kirsher 		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
1984dee1ad47SJeff Kirsher 		phy->local_rx = e1000_1000t_rx_status_undefined;
1985dee1ad47SJeff Kirsher 		phy->remote_rx = e1000_1000t_rx_status_undefined;
1986dee1ad47SJeff Kirsher 	}
1987dee1ad47SJeff Kirsher 
1988dee1ad47SJeff Kirsher 	return ret_val;
1989dee1ad47SJeff Kirsher }
1990dee1ad47SJeff Kirsher 
1991dee1ad47SJeff Kirsher /**
1992dee1ad47SJeff Kirsher  *  e1000e_get_phy_info_igp - Retrieve igp PHY information
1993dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
1994dee1ad47SJeff Kirsher  *
1995dee1ad47SJeff Kirsher  *  Read PHY status to determine if link is up.  If link is up, then
1996dee1ad47SJeff Kirsher  *  set/determine 10base-T extended distance and polarity correction.  Read
1997dee1ad47SJeff Kirsher  *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
1998dee1ad47SJeff Kirsher  *  determine on the cable length, local and remote receiver.
1999dee1ad47SJeff Kirsher  **/
2000dee1ad47SJeff Kirsher s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
2001dee1ad47SJeff Kirsher {
2002dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
2003dee1ad47SJeff Kirsher 	s32 ret_val;
2004dee1ad47SJeff Kirsher 	u16 data;
2005dee1ad47SJeff Kirsher 	bool link;
2006dee1ad47SJeff Kirsher 
2007dee1ad47SJeff Kirsher 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2008dee1ad47SJeff Kirsher 	if (ret_val)
2009dee1ad47SJeff Kirsher 		return ret_val;
2010dee1ad47SJeff Kirsher 
2011dee1ad47SJeff Kirsher 	if (!link) {
2012dee1ad47SJeff Kirsher 		e_dbg("Phy info is only valid if link is up\n");
2013dee1ad47SJeff Kirsher 		return -E1000_ERR_CONFIG;
2014dee1ad47SJeff Kirsher 	}
2015dee1ad47SJeff Kirsher 
2016dee1ad47SJeff Kirsher 	phy->polarity_correction = true;
2017dee1ad47SJeff Kirsher 
2018dee1ad47SJeff Kirsher 	ret_val = e1000_check_polarity_igp(hw);
2019dee1ad47SJeff Kirsher 	if (ret_val)
2020dee1ad47SJeff Kirsher 		return ret_val;
2021dee1ad47SJeff Kirsher 
2022dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
2023dee1ad47SJeff Kirsher 	if (ret_val)
2024dee1ad47SJeff Kirsher 		return ret_val;
2025dee1ad47SJeff Kirsher 
202604499ec4SBruce Allan 	phy->is_mdix = !!(data & IGP01E1000_PSSR_MDIX);
2027dee1ad47SJeff Kirsher 
2028dee1ad47SJeff Kirsher 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
2029dee1ad47SJeff Kirsher 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
2030dde3a574SBruce Allan 		ret_val = phy->ops.get_cable_length(hw);
2031dee1ad47SJeff Kirsher 		if (ret_val)
2032dee1ad47SJeff Kirsher 			return ret_val;
2033dee1ad47SJeff Kirsher 
2034c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_STAT1000, &data);
2035dee1ad47SJeff Kirsher 		if (ret_val)
2036dee1ad47SJeff Kirsher 			return ret_val;
2037dee1ad47SJeff Kirsher 
2038c2ade1a4SBruce Allan 		phy->local_rx = (data & LPA_1000LOCALRXOK)
2039c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
2040dee1ad47SJeff Kirsher 
2041c2ade1a4SBruce Allan 		phy->remote_rx = (data & LPA_1000REMRXOK)
2042c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
2043dee1ad47SJeff Kirsher 	} else {
2044dee1ad47SJeff Kirsher 		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2045dee1ad47SJeff Kirsher 		phy->local_rx = e1000_1000t_rx_status_undefined;
2046dee1ad47SJeff Kirsher 		phy->remote_rx = e1000_1000t_rx_status_undefined;
2047dee1ad47SJeff Kirsher 	}
2048dee1ad47SJeff Kirsher 
2049dee1ad47SJeff Kirsher 	return ret_val;
2050dee1ad47SJeff Kirsher }
2051dee1ad47SJeff Kirsher 
2052dee1ad47SJeff Kirsher /**
2053dee1ad47SJeff Kirsher  *  e1000_get_phy_info_ife - Retrieves various IFE PHY states
2054dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2055dee1ad47SJeff Kirsher  *
2056dee1ad47SJeff Kirsher  *  Populates "phy" structure with various feature states.
2057dee1ad47SJeff Kirsher  **/
2058dee1ad47SJeff Kirsher s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
2059dee1ad47SJeff Kirsher {
2060dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
2061dee1ad47SJeff Kirsher 	s32 ret_val;
2062dee1ad47SJeff Kirsher 	u16 data;
2063dee1ad47SJeff Kirsher 	bool link;
2064dee1ad47SJeff Kirsher 
2065dee1ad47SJeff Kirsher 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2066dee1ad47SJeff Kirsher 	if (ret_val)
20675015e53aSBruce Allan 		return ret_val;
2068dee1ad47SJeff Kirsher 
2069dee1ad47SJeff Kirsher 	if (!link) {
2070dee1ad47SJeff Kirsher 		e_dbg("Phy info is only valid if link is up\n");
20715015e53aSBruce Allan 		return -E1000_ERR_CONFIG;
2072dee1ad47SJeff Kirsher 	}
2073dee1ad47SJeff Kirsher 
2074dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
2075dee1ad47SJeff Kirsher 	if (ret_val)
20765015e53aSBruce Allan 		return ret_val;
207704499ec4SBruce Allan 	phy->polarity_correction = !(data & IFE_PSC_AUTO_POLARITY_DISABLE);
2078dee1ad47SJeff Kirsher 
2079dee1ad47SJeff Kirsher 	if (phy->polarity_correction) {
2080dee1ad47SJeff Kirsher 		ret_val = e1000_check_polarity_ife(hw);
2081dee1ad47SJeff Kirsher 		if (ret_val)
20825015e53aSBruce Allan 			return ret_val;
2083dee1ad47SJeff Kirsher 	} else {
2084dee1ad47SJeff Kirsher 		/* Polarity is forced */
2085f0ff4398SBruce Allan 		phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY)
2086dee1ad47SJeff Kirsher 				       ? e1000_rev_polarity_reversed
2087f0ff4398SBruce Allan 				       : e1000_rev_polarity_normal);
2088dee1ad47SJeff Kirsher 	}
2089dee1ad47SJeff Kirsher 
2090dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
2091dee1ad47SJeff Kirsher 	if (ret_val)
20925015e53aSBruce Allan 		return ret_val;
2093dee1ad47SJeff Kirsher 
209404499ec4SBruce Allan 	phy->is_mdix = !!(data & IFE_PMC_MDIX_STATUS);
2095dee1ad47SJeff Kirsher 
2096dee1ad47SJeff Kirsher 	/* The following parameters are undefined for 10/100 operation. */
2097dee1ad47SJeff Kirsher 	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2098dee1ad47SJeff Kirsher 	phy->local_rx = e1000_1000t_rx_status_undefined;
2099dee1ad47SJeff Kirsher 	phy->remote_rx = e1000_1000t_rx_status_undefined;
2100dee1ad47SJeff Kirsher 
21015015e53aSBruce Allan 	return 0;
2102dee1ad47SJeff Kirsher }
2103dee1ad47SJeff Kirsher 
2104dee1ad47SJeff Kirsher /**
2105dee1ad47SJeff Kirsher  *  e1000e_phy_sw_reset - PHY software reset
2106dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2107dee1ad47SJeff Kirsher  *
2108dee1ad47SJeff Kirsher  *  Does a software reset of the PHY by reading the PHY control register and
2109dee1ad47SJeff Kirsher  *  setting/write the control register reset bit to the PHY.
2110dee1ad47SJeff Kirsher  **/
2111dee1ad47SJeff Kirsher s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
2112dee1ad47SJeff Kirsher {
2113dee1ad47SJeff Kirsher 	s32 ret_val;
2114dee1ad47SJeff Kirsher 	u16 phy_ctrl;
2115dee1ad47SJeff Kirsher 
2116c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &phy_ctrl);
2117dee1ad47SJeff Kirsher 	if (ret_val)
2118dee1ad47SJeff Kirsher 		return ret_val;
2119dee1ad47SJeff Kirsher 
2120c2ade1a4SBruce Allan 	phy_ctrl |= BMCR_RESET;
2121c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, phy_ctrl);
2122dee1ad47SJeff Kirsher 	if (ret_val)
2123dee1ad47SJeff Kirsher 		return ret_val;
2124dee1ad47SJeff Kirsher 
2125dee1ad47SJeff Kirsher 	udelay(1);
2126dee1ad47SJeff Kirsher 
2127dee1ad47SJeff Kirsher 	return ret_val;
2128dee1ad47SJeff Kirsher }
2129dee1ad47SJeff Kirsher 
2130dee1ad47SJeff Kirsher /**
2131dee1ad47SJeff Kirsher  *  e1000e_phy_hw_reset_generic - PHY hardware reset
2132dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2133dee1ad47SJeff Kirsher  *
2134dee1ad47SJeff Kirsher  *  Verify the reset block is not blocking us from resetting.  Acquire
2135dee1ad47SJeff Kirsher  *  semaphore (if necessary) and read/set/write the device control reset
2136dee1ad47SJeff Kirsher  *  bit in the PHY.  Wait the appropriate delay time for the device to
2137dee1ad47SJeff Kirsher  *  reset and release the semaphore (if necessary).
2138dee1ad47SJeff Kirsher  **/
2139dee1ad47SJeff Kirsher s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
2140dee1ad47SJeff Kirsher {
2141dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
2142dee1ad47SJeff Kirsher 	s32 ret_val;
2143dee1ad47SJeff Kirsher 	u32 ctrl;
2144dee1ad47SJeff Kirsher 
2145470a5420SBruce Allan 	if (phy->ops.check_reset_block) {
214644abd5c1SBruce Allan 		ret_val = phy->ops.check_reset_block(hw);
2147dee1ad47SJeff Kirsher 		if (ret_val)
2148dee1ad47SJeff Kirsher 			return 0;
2149470a5420SBruce Allan 	}
2150dee1ad47SJeff Kirsher 
2151dee1ad47SJeff Kirsher 	ret_val = phy->ops.acquire(hw);
2152dee1ad47SJeff Kirsher 	if (ret_val)
2153dee1ad47SJeff Kirsher 		return ret_val;
2154dee1ad47SJeff Kirsher 
2155dee1ad47SJeff Kirsher 	ctrl = er32(CTRL);
2156dee1ad47SJeff Kirsher 	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
2157dee1ad47SJeff Kirsher 	e1e_flush();
2158dee1ad47SJeff Kirsher 
2159dee1ad47SJeff Kirsher 	udelay(phy->reset_delay_us);
2160dee1ad47SJeff Kirsher 
2161dee1ad47SJeff Kirsher 	ew32(CTRL, ctrl);
2162dee1ad47SJeff Kirsher 	e1e_flush();
2163dee1ad47SJeff Kirsher 
2164ce43a216SBruce Allan 	usleep_range(150, 300);
2165dee1ad47SJeff Kirsher 
2166dee1ad47SJeff Kirsher 	phy->ops.release(hw);
2167dee1ad47SJeff Kirsher 
216884c1befeSBruce Allan 	return phy->ops.get_cfg_done(hw);
2169dee1ad47SJeff Kirsher }
2170dee1ad47SJeff Kirsher 
2171dee1ad47SJeff Kirsher /**
2172fe90849fSBruce Allan  *  e1000e_get_cfg_done_generic - Generic configuration done
2173dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2174dee1ad47SJeff Kirsher  *
2175dee1ad47SJeff Kirsher  *  Generic function to wait 10 milli-seconds for configuration to complete
2176dee1ad47SJeff Kirsher  *  and return success.
2177dee1ad47SJeff Kirsher  **/
21788bb62869SBruce Allan s32 e1000e_get_cfg_done_generic(struct e1000_hw __always_unused *hw)
2179dee1ad47SJeff Kirsher {
2180dee1ad47SJeff Kirsher 	mdelay(10);
21813d3a1676SBruce Allan 
2182dee1ad47SJeff Kirsher 	return 0;
2183dee1ad47SJeff Kirsher }
2184dee1ad47SJeff Kirsher 
2185dee1ad47SJeff Kirsher /**
2186dee1ad47SJeff Kirsher  *  e1000e_phy_init_script_igp3 - Inits the IGP3 PHY
2187dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2188dee1ad47SJeff Kirsher  *
2189dee1ad47SJeff Kirsher  *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
2190dee1ad47SJeff Kirsher  **/
2191dee1ad47SJeff Kirsher s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw)
2192dee1ad47SJeff Kirsher {
2193dee1ad47SJeff Kirsher 	e_dbg("Running IGP 3 PHY init script\n");
2194dee1ad47SJeff Kirsher 
2195dee1ad47SJeff Kirsher 	/* PHY init IGP 3 */
2196dee1ad47SJeff Kirsher 	/* Enable rise/fall, 10-mode work in class-A */
2197dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2F5B, 0x9018);
2198dee1ad47SJeff Kirsher 	/* Remove all caps from Replica path filter */
2199dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2F52, 0x0000);
2200dee1ad47SJeff Kirsher 	/* Bias trimming for ADC, AFE and Driver (Default) */
2201dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2FB1, 0x8B24);
2202dee1ad47SJeff Kirsher 	/* Increase Hybrid poly bias */
2203dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2FB2, 0xF8F0);
2204dee1ad47SJeff Kirsher 	/* Add 4% to Tx amplitude in Gig mode */
2205dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2010, 0x10B0);
2206dee1ad47SJeff Kirsher 	/* Disable trimming (TTT) */
2207dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2011, 0x0000);
2208dee1ad47SJeff Kirsher 	/* Poly DC correction to 94.6% + 2% for all channels */
2209dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x20DD, 0x249A);
2210dee1ad47SJeff Kirsher 	/* ABS DC correction to 95.9% */
2211dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x20DE, 0x00D3);
2212dee1ad47SJeff Kirsher 	/* BG temp curve trim */
2213dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x28B4, 0x04CE);
2214dee1ad47SJeff Kirsher 	/* Increasing ADC OPAMP stage 1 currents to max */
2215dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x2F70, 0x29E4);
2216dee1ad47SJeff Kirsher 	/* Force 1000 ( required for enabling PHY regs configuration) */
2217dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x0000, 0x0140);
2218dee1ad47SJeff Kirsher 	/* Set upd_freq to 6 */
2219dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F30, 0x1606);
2220dee1ad47SJeff Kirsher 	/* Disable NPDFE */
2221dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F31, 0xB814);
2222dee1ad47SJeff Kirsher 	/* Disable adaptive fixed FFE (Default) */
2223dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F35, 0x002A);
2224dee1ad47SJeff Kirsher 	/* Enable FFE hysteresis */
2225dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F3E, 0x0067);
2226dee1ad47SJeff Kirsher 	/* Fixed FFE for short cable lengths */
2227dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F54, 0x0065);
2228dee1ad47SJeff Kirsher 	/* Fixed FFE for medium cable lengths */
2229dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F55, 0x002A);
2230dee1ad47SJeff Kirsher 	/* Fixed FFE for long cable lengths */
2231dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F56, 0x002A);
2232dee1ad47SJeff Kirsher 	/* Enable Adaptive Clip Threshold */
2233dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F72, 0x3FB0);
2234dee1ad47SJeff Kirsher 	/* AHT reset limit to 1 */
2235dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F76, 0xC0FF);
2236dee1ad47SJeff Kirsher 	/* Set AHT master delay to 127 msec */
2237dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F77, 0x1DEC);
2238dee1ad47SJeff Kirsher 	/* Set scan bits for AHT */
2239dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F78, 0xF9EF);
2240dee1ad47SJeff Kirsher 	/* Set AHT Preset bits */
2241dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1F79, 0x0210);
2242dee1ad47SJeff Kirsher 	/* Change integ_factor of channel A to 3 */
2243dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1895, 0x0003);
2244dee1ad47SJeff Kirsher 	/* Change prop_factor of channels BCD to 8 */
2245dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1796, 0x0008);
2246dee1ad47SJeff Kirsher 	/* Change cg_icount + enable integbp for channels BCD */
2247dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1798, 0xD008);
2248e921eb1aSBruce Allan 	/* Change cg_icount + enable integbp + change prop_factor_master
2249dee1ad47SJeff Kirsher 	 * to 8 for channel A
2250dee1ad47SJeff Kirsher 	 */
2251dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x1898, 0xD918);
2252dee1ad47SJeff Kirsher 	/* Disable AHT in Slave mode on channel A */
2253dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x187A, 0x0800);
2254e921eb1aSBruce Allan 	/* Enable LPLU and disable AN to 1000 in non-D0a states,
2255dee1ad47SJeff Kirsher 	 * Enable SPD+B2B
2256dee1ad47SJeff Kirsher 	 */
2257dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x0019, 0x008D);
2258dee1ad47SJeff Kirsher 	/* Enable restart AN on an1000_dis change */
2259dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x001B, 0x2080);
2260dee1ad47SJeff Kirsher 	/* Enable wh_fifo read clock in 10/100 modes */
2261dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x0014, 0x0045);
2262dee1ad47SJeff Kirsher 	/* Restart AN, Speed selection is 1000 */
2263dee1ad47SJeff Kirsher 	e1e_wphy(hw, 0x0000, 0x1340);
2264dee1ad47SJeff Kirsher 
2265dee1ad47SJeff Kirsher 	return 0;
2266dee1ad47SJeff Kirsher }
2267dee1ad47SJeff Kirsher 
2268dee1ad47SJeff Kirsher /**
2269dee1ad47SJeff Kirsher  *  e1000e_get_phy_type_from_id - Get PHY type from id
2270dee1ad47SJeff Kirsher  *  @phy_id: phy_id read from the phy
2271dee1ad47SJeff Kirsher  *
2272dee1ad47SJeff Kirsher  *  Returns the phy type from the id.
2273dee1ad47SJeff Kirsher  **/
2274dee1ad47SJeff Kirsher enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
2275dee1ad47SJeff Kirsher {
2276dee1ad47SJeff Kirsher 	enum e1000_phy_type phy_type = e1000_phy_unknown;
2277dee1ad47SJeff Kirsher 
2278dee1ad47SJeff Kirsher 	switch (phy_id) {
2279dee1ad47SJeff Kirsher 	case M88E1000_I_PHY_ID:
2280dee1ad47SJeff Kirsher 	case M88E1000_E_PHY_ID:
2281dee1ad47SJeff Kirsher 	case M88E1111_I_PHY_ID:
2282dee1ad47SJeff Kirsher 	case M88E1011_I_PHY_ID:
2283dee1ad47SJeff Kirsher 		phy_type = e1000_phy_m88;
2284dee1ad47SJeff Kirsher 		break;
2285dee1ad47SJeff Kirsher 	case IGP01E1000_I_PHY_ID:	/* IGP 1 & 2 share this */
2286dee1ad47SJeff Kirsher 		phy_type = e1000_phy_igp_2;
2287dee1ad47SJeff Kirsher 		break;
2288dee1ad47SJeff Kirsher 	case GG82563_E_PHY_ID:
2289dee1ad47SJeff Kirsher 		phy_type = e1000_phy_gg82563;
2290dee1ad47SJeff Kirsher 		break;
2291dee1ad47SJeff Kirsher 	case IGP03E1000_E_PHY_ID:
2292dee1ad47SJeff Kirsher 		phy_type = e1000_phy_igp_3;
2293dee1ad47SJeff Kirsher 		break;
2294dee1ad47SJeff Kirsher 	case IFE_E_PHY_ID:
2295dee1ad47SJeff Kirsher 	case IFE_PLUS_E_PHY_ID:
2296dee1ad47SJeff Kirsher 	case IFE_C_E_PHY_ID:
2297dee1ad47SJeff Kirsher 		phy_type = e1000_phy_ife;
2298dee1ad47SJeff Kirsher 		break;
2299dee1ad47SJeff Kirsher 	case BME1000_E_PHY_ID:
2300dee1ad47SJeff Kirsher 	case BME1000_E_PHY_ID_R2:
2301dee1ad47SJeff Kirsher 		phy_type = e1000_phy_bm;
2302dee1ad47SJeff Kirsher 		break;
2303dee1ad47SJeff Kirsher 	case I82578_E_PHY_ID:
2304dee1ad47SJeff Kirsher 		phy_type = e1000_phy_82578;
2305dee1ad47SJeff Kirsher 		break;
2306dee1ad47SJeff Kirsher 	case I82577_E_PHY_ID:
2307dee1ad47SJeff Kirsher 		phy_type = e1000_phy_82577;
2308dee1ad47SJeff Kirsher 		break;
2309dee1ad47SJeff Kirsher 	case I82579_E_PHY_ID:
2310dee1ad47SJeff Kirsher 		phy_type = e1000_phy_82579;
2311dee1ad47SJeff Kirsher 		break;
23122fbe4526SBruce Allan 	case I217_E_PHY_ID:
23132fbe4526SBruce Allan 		phy_type = e1000_phy_i217;
23142fbe4526SBruce Allan 		break;
2315dee1ad47SJeff Kirsher 	default:
2316dee1ad47SJeff Kirsher 		phy_type = e1000_phy_unknown;
2317dee1ad47SJeff Kirsher 		break;
2318dee1ad47SJeff Kirsher 	}
2319dee1ad47SJeff Kirsher 	return phy_type;
2320dee1ad47SJeff Kirsher }
2321dee1ad47SJeff Kirsher 
2322dee1ad47SJeff Kirsher /**
2323dee1ad47SJeff Kirsher  *  e1000e_determine_phy_address - Determines PHY address.
2324dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2325dee1ad47SJeff Kirsher  *
2326dee1ad47SJeff Kirsher  *  This uses a trial and error method to loop through possible PHY
2327dee1ad47SJeff Kirsher  *  addresses. It tests each by reading the PHY ID registers and
2328dee1ad47SJeff Kirsher  *  checking for a match.
2329dee1ad47SJeff Kirsher  **/
2330dee1ad47SJeff Kirsher s32 e1000e_determine_phy_address(struct e1000_hw *hw)
2331dee1ad47SJeff Kirsher {
2332dee1ad47SJeff Kirsher 	u32 phy_addr = 0;
2333dee1ad47SJeff Kirsher 	u32 i;
2334dee1ad47SJeff Kirsher 	enum e1000_phy_type phy_type = e1000_phy_unknown;
2335dee1ad47SJeff Kirsher 
2336dee1ad47SJeff Kirsher 	hw->phy.id = phy_type;
2337dee1ad47SJeff Kirsher 
2338dee1ad47SJeff Kirsher 	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
2339dee1ad47SJeff Kirsher 		hw->phy.addr = phy_addr;
2340dee1ad47SJeff Kirsher 		i = 0;
2341dee1ad47SJeff Kirsher 
2342dee1ad47SJeff Kirsher 		do {
2343dee1ad47SJeff Kirsher 			e1000e_get_phy_id(hw);
2344dee1ad47SJeff Kirsher 			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
2345dee1ad47SJeff Kirsher 
2346e921eb1aSBruce Allan 			/* If phy_type is valid, break - we found our
2347dee1ad47SJeff Kirsher 			 * PHY address
2348dee1ad47SJeff Kirsher 			 */
23495015e53aSBruce Allan 			if (phy_type != e1000_phy_unknown)
23505015e53aSBruce Allan 				return 0;
23515015e53aSBruce Allan 
2352dee1ad47SJeff Kirsher 			usleep_range(1000, 2000);
2353dee1ad47SJeff Kirsher 			i++;
2354dee1ad47SJeff Kirsher 		} while (i < 10);
2355dee1ad47SJeff Kirsher 	}
2356dee1ad47SJeff Kirsher 
23575015e53aSBruce Allan 	return -E1000_ERR_PHY_TYPE;
2358dee1ad47SJeff Kirsher }
2359dee1ad47SJeff Kirsher 
2360dee1ad47SJeff Kirsher /**
2361dee1ad47SJeff Kirsher  *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
2362dee1ad47SJeff Kirsher  *  @page: page to access
2363b50f7bcaSJesse Brandeburg  *  @reg: register to check
2364dee1ad47SJeff Kirsher  *
2365dee1ad47SJeff Kirsher  *  Returns the phy address for the page requested.
2366dee1ad47SJeff Kirsher  **/
2367dee1ad47SJeff Kirsher static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
2368dee1ad47SJeff Kirsher {
2369dee1ad47SJeff Kirsher 	u32 phy_addr = 2;
2370dee1ad47SJeff Kirsher 
2371dee1ad47SJeff Kirsher 	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
2372dee1ad47SJeff Kirsher 		phy_addr = 1;
2373dee1ad47SJeff Kirsher 
2374dee1ad47SJeff Kirsher 	return phy_addr;
2375dee1ad47SJeff Kirsher }
2376dee1ad47SJeff Kirsher 
2377dee1ad47SJeff Kirsher /**
2378dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_bm - Write BM PHY register
2379dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2380dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2381dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2382dee1ad47SJeff Kirsher  *
2383dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then writes the data to PHY register
2384dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
2385dee1ad47SJeff Kirsher  **/
2386dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2387dee1ad47SJeff Kirsher {
2388dee1ad47SJeff Kirsher 	s32 ret_val;
2389dee1ad47SJeff Kirsher 	u32 page = offset >> IGP_PAGE_SHIFT;
2390dee1ad47SJeff Kirsher 
2391dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
2392dee1ad47SJeff Kirsher 	if (ret_val)
2393dee1ad47SJeff Kirsher 		return ret_val;
2394dee1ad47SJeff Kirsher 
2395dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2396dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2397dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2398dee1ad47SJeff Kirsher 							 false, false);
239975ce1532SBruce Allan 		goto release;
2400dee1ad47SJeff Kirsher 	}
2401dee1ad47SJeff Kirsher 
2402dee1ad47SJeff Kirsher 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2403dee1ad47SJeff Kirsher 
2404dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2405dee1ad47SJeff Kirsher 		u32 page_shift, page_select;
2406dee1ad47SJeff Kirsher 
2407e921eb1aSBruce Allan 		/* Page select is register 31 for phy address 1 and 22 for
2408dee1ad47SJeff Kirsher 		 * phy address 2 and 3. Page select is shifted only for
2409dee1ad47SJeff Kirsher 		 * phy address 1.
2410dee1ad47SJeff Kirsher 		 */
2411dee1ad47SJeff Kirsher 		if (hw->phy.addr == 1) {
2412dee1ad47SJeff Kirsher 			page_shift = IGP_PAGE_SHIFT;
2413dee1ad47SJeff Kirsher 			page_select = IGP01E1000_PHY_PAGE_SELECT;
2414dee1ad47SJeff Kirsher 		} else {
2415dee1ad47SJeff Kirsher 			page_shift = 0;
2416dee1ad47SJeff Kirsher 			page_select = BM_PHY_PAGE_SELECT;
2417dee1ad47SJeff Kirsher 		}
2418dee1ad47SJeff Kirsher 
2419dee1ad47SJeff Kirsher 		/* Page is shifted left, PHY expects (page x 32) */
2420dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2421dee1ad47SJeff Kirsher 						    (page << page_shift));
2422dee1ad47SJeff Kirsher 		if (ret_val)
242375ce1532SBruce Allan 			goto release;
2424dee1ad47SJeff Kirsher 	}
2425dee1ad47SJeff Kirsher 
2426dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2427dee1ad47SJeff Kirsher 					    data);
2428dee1ad47SJeff Kirsher 
242975ce1532SBruce Allan release:
2430dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
2431dee1ad47SJeff Kirsher 	return ret_val;
2432dee1ad47SJeff Kirsher }
2433dee1ad47SJeff Kirsher 
2434dee1ad47SJeff Kirsher /**
2435dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_bm - Read BM PHY register
2436dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2437dee1ad47SJeff Kirsher  *  @offset: register offset to be read
2438dee1ad47SJeff Kirsher  *  @data: pointer to the read data
2439dee1ad47SJeff Kirsher  *
2440dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then reads the PHY register at offset
2441dee1ad47SJeff Kirsher  *  and storing the retrieved information in data.  Release any acquired
2442dee1ad47SJeff Kirsher  *  semaphores before exiting.
2443dee1ad47SJeff Kirsher  **/
2444dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2445dee1ad47SJeff Kirsher {
2446dee1ad47SJeff Kirsher 	s32 ret_val;
2447dee1ad47SJeff Kirsher 	u32 page = offset >> IGP_PAGE_SHIFT;
2448dee1ad47SJeff Kirsher 
2449dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
2450dee1ad47SJeff Kirsher 	if (ret_val)
2451dee1ad47SJeff Kirsher 		return ret_val;
2452dee1ad47SJeff Kirsher 
2453dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2454dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2455dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2456dee1ad47SJeff Kirsher 							 true, false);
245775ce1532SBruce Allan 		goto release;
2458dee1ad47SJeff Kirsher 	}
2459dee1ad47SJeff Kirsher 
2460dee1ad47SJeff Kirsher 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2461dee1ad47SJeff Kirsher 
2462dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2463dee1ad47SJeff Kirsher 		u32 page_shift, page_select;
2464dee1ad47SJeff Kirsher 
2465e921eb1aSBruce Allan 		/* Page select is register 31 for phy address 1 and 22 for
2466dee1ad47SJeff Kirsher 		 * phy address 2 and 3. Page select is shifted only for
2467dee1ad47SJeff Kirsher 		 * phy address 1.
2468dee1ad47SJeff Kirsher 		 */
2469dee1ad47SJeff Kirsher 		if (hw->phy.addr == 1) {
2470dee1ad47SJeff Kirsher 			page_shift = IGP_PAGE_SHIFT;
2471dee1ad47SJeff Kirsher 			page_select = IGP01E1000_PHY_PAGE_SELECT;
2472dee1ad47SJeff Kirsher 		} else {
2473dee1ad47SJeff Kirsher 			page_shift = 0;
2474dee1ad47SJeff Kirsher 			page_select = BM_PHY_PAGE_SELECT;
2475dee1ad47SJeff Kirsher 		}
2476dee1ad47SJeff Kirsher 
2477dee1ad47SJeff Kirsher 		/* Page is shifted left, PHY expects (page x 32) */
2478dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2479dee1ad47SJeff Kirsher 						    (page << page_shift));
2480dee1ad47SJeff Kirsher 		if (ret_val)
248175ce1532SBruce Allan 			goto release;
2482dee1ad47SJeff Kirsher 	}
2483dee1ad47SJeff Kirsher 
2484dee1ad47SJeff Kirsher 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2485dee1ad47SJeff Kirsher 					   data);
248675ce1532SBruce Allan release:
2487dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
2488dee1ad47SJeff Kirsher 	return ret_val;
2489dee1ad47SJeff Kirsher }
2490dee1ad47SJeff Kirsher 
2491dee1ad47SJeff Kirsher /**
2492dee1ad47SJeff Kirsher  *  e1000e_read_phy_reg_bm2 - Read BM PHY register
2493dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2494dee1ad47SJeff Kirsher  *  @offset: register offset to be read
2495dee1ad47SJeff Kirsher  *  @data: pointer to the read data
2496dee1ad47SJeff Kirsher  *
2497dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then reads the PHY register at offset
2498dee1ad47SJeff Kirsher  *  and storing the retrieved information in data.  Release any acquired
2499dee1ad47SJeff Kirsher  *  semaphores before exiting.
2500dee1ad47SJeff Kirsher  **/
2501dee1ad47SJeff Kirsher s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2502dee1ad47SJeff Kirsher {
2503dee1ad47SJeff Kirsher 	s32 ret_val;
2504dee1ad47SJeff Kirsher 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2505dee1ad47SJeff Kirsher 
2506dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
2507dee1ad47SJeff Kirsher 	if (ret_val)
2508dee1ad47SJeff Kirsher 		return ret_val;
2509dee1ad47SJeff Kirsher 
2510dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2511dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2512dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2513dee1ad47SJeff Kirsher 							 true, false);
251475ce1532SBruce Allan 		goto release;
2515dee1ad47SJeff Kirsher 	}
2516dee1ad47SJeff Kirsher 
2517dee1ad47SJeff Kirsher 	hw->phy.addr = 1;
2518dee1ad47SJeff Kirsher 
2519dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2520dee1ad47SJeff Kirsher 		/* Page is shifted left, PHY expects (page x 32) */
2521dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2522dee1ad47SJeff Kirsher 						    page);
2523dee1ad47SJeff Kirsher 
2524dee1ad47SJeff Kirsher 		if (ret_val)
252575ce1532SBruce Allan 			goto release;
2526dee1ad47SJeff Kirsher 	}
2527dee1ad47SJeff Kirsher 
2528dee1ad47SJeff Kirsher 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2529dee1ad47SJeff Kirsher 					   data);
253075ce1532SBruce Allan release:
2531dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
2532dee1ad47SJeff Kirsher 	return ret_val;
2533dee1ad47SJeff Kirsher }
2534dee1ad47SJeff Kirsher 
2535dee1ad47SJeff Kirsher /**
2536dee1ad47SJeff Kirsher  *  e1000e_write_phy_reg_bm2 - Write BM PHY register
2537dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2538dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2539dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2540dee1ad47SJeff Kirsher  *
2541dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then writes the data to PHY register
2542dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
2543dee1ad47SJeff Kirsher  **/
2544dee1ad47SJeff Kirsher s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2545dee1ad47SJeff Kirsher {
2546dee1ad47SJeff Kirsher 	s32 ret_val;
2547dee1ad47SJeff Kirsher 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2548dee1ad47SJeff Kirsher 
2549dee1ad47SJeff Kirsher 	ret_val = hw->phy.ops.acquire(hw);
2550dee1ad47SJeff Kirsher 	if (ret_val)
2551dee1ad47SJeff Kirsher 		return ret_val;
2552dee1ad47SJeff Kirsher 
2553dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2554dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2555dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2556dee1ad47SJeff Kirsher 							 false, false);
255775ce1532SBruce Allan 		goto release;
2558dee1ad47SJeff Kirsher 	}
2559dee1ad47SJeff Kirsher 
2560dee1ad47SJeff Kirsher 	hw->phy.addr = 1;
2561dee1ad47SJeff Kirsher 
2562dee1ad47SJeff Kirsher 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2563dee1ad47SJeff Kirsher 		/* Page is shifted left, PHY expects (page x 32) */
2564dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2565dee1ad47SJeff Kirsher 						    page);
2566dee1ad47SJeff Kirsher 
2567dee1ad47SJeff Kirsher 		if (ret_val)
256875ce1532SBruce Allan 			goto release;
2569dee1ad47SJeff Kirsher 	}
2570dee1ad47SJeff Kirsher 
2571dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2572dee1ad47SJeff Kirsher 					    data);
2573dee1ad47SJeff Kirsher 
257475ce1532SBruce Allan release:
2575dee1ad47SJeff Kirsher 	hw->phy.ops.release(hw);
2576dee1ad47SJeff Kirsher 	return ret_val;
2577dee1ad47SJeff Kirsher }
2578dee1ad47SJeff Kirsher 
2579dee1ad47SJeff Kirsher /**
2580dee1ad47SJeff Kirsher  *  e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers
2581dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2582dee1ad47SJeff Kirsher  *  @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG
2583dee1ad47SJeff Kirsher  *
2584dee1ad47SJeff Kirsher  *  Assumes semaphore already acquired and phy_reg points to a valid memory
2585dee1ad47SJeff Kirsher  *  address to store contents of the BM_WUC_ENABLE_REG register.
2586dee1ad47SJeff Kirsher  **/
2587dee1ad47SJeff Kirsher s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
2588dee1ad47SJeff Kirsher {
2589dee1ad47SJeff Kirsher 	s32 ret_val;
2590dee1ad47SJeff Kirsher 	u16 temp;
2591dee1ad47SJeff Kirsher 
2592dee1ad47SJeff Kirsher 	/* All page select, port ctrl and wakeup registers use phy address 1 */
2593dee1ad47SJeff Kirsher 	hw->phy.addr = 1;
2594dee1ad47SJeff Kirsher 
2595dee1ad47SJeff Kirsher 	/* Select Port Control Registers page */
2596dee1ad47SJeff Kirsher 	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2597dee1ad47SJeff Kirsher 	if (ret_val) {
2598dee1ad47SJeff Kirsher 		e_dbg("Could not set Port Control page\n");
25995015e53aSBruce Allan 		return ret_val;
2600dee1ad47SJeff Kirsher 	}
2601dee1ad47SJeff Kirsher 
2602dee1ad47SJeff Kirsher 	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2603dee1ad47SJeff Kirsher 	if (ret_val) {
2604dee1ad47SJeff Kirsher 		e_dbg("Could not read PHY register %d.%d\n",
2605dee1ad47SJeff Kirsher 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
26065015e53aSBruce Allan 		return ret_val;
2607dee1ad47SJeff Kirsher 	}
2608dee1ad47SJeff Kirsher 
2609e921eb1aSBruce Allan 	/* Enable both PHY wakeup mode and Wakeup register page writes.
2610dee1ad47SJeff Kirsher 	 * Prevent a power state change by disabling ME and Host PHY wakeup.
2611dee1ad47SJeff Kirsher 	 */
2612dee1ad47SJeff Kirsher 	temp = *phy_reg;
2613dee1ad47SJeff Kirsher 	temp |= BM_WUC_ENABLE_BIT;
2614dee1ad47SJeff Kirsher 	temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT);
2615dee1ad47SJeff Kirsher 
2616dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp);
2617dee1ad47SJeff Kirsher 	if (ret_val) {
2618dee1ad47SJeff Kirsher 		e_dbg("Could not write PHY register %d.%d\n",
2619dee1ad47SJeff Kirsher 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
26205015e53aSBruce Allan 		return ret_val;
2621dee1ad47SJeff Kirsher 	}
2622dee1ad47SJeff Kirsher 
2623e921eb1aSBruce Allan 	/* Select Host Wakeup Registers page - caller now able to write
26245015e53aSBruce Allan 	 * registers on the Wakeup registers page
26255015e53aSBruce Allan 	 */
26265015e53aSBruce Allan 	return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
2627dee1ad47SJeff Kirsher }
2628dee1ad47SJeff Kirsher 
2629dee1ad47SJeff Kirsher /**
2630dee1ad47SJeff Kirsher  *  e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs
2631dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2632dee1ad47SJeff Kirsher  *  @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG
2633dee1ad47SJeff Kirsher  *
2634dee1ad47SJeff Kirsher  *  Restore BM_WUC_ENABLE_REG to its original value.
2635dee1ad47SJeff Kirsher  *
2636dee1ad47SJeff Kirsher  *  Assumes semaphore already acquired and *phy_reg is the contents of the
2637dee1ad47SJeff Kirsher  *  BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by
2638dee1ad47SJeff Kirsher  *  caller.
2639dee1ad47SJeff Kirsher  **/
2640dee1ad47SJeff Kirsher s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
2641dee1ad47SJeff Kirsher {
264270806a7fSBruce Allan 	s32 ret_val;
2643dee1ad47SJeff Kirsher 
2644dee1ad47SJeff Kirsher 	/* Select Port Control Registers page */
2645dee1ad47SJeff Kirsher 	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2646dee1ad47SJeff Kirsher 	if (ret_val) {
2647dee1ad47SJeff Kirsher 		e_dbg("Could not set Port Control page\n");
26485015e53aSBruce Allan 		return ret_val;
2649dee1ad47SJeff Kirsher 	}
2650dee1ad47SJeff Kirsher 
2651dee1ad47SJeff Kirsher 	/* Restore 769.17 to its original value */
2652dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg);
2653dee1ad47SJeff Kirsher 	if (ret_val)
2654dee1ad47SJeff Kirsher 		e_dbg("Could not restore PHY register %d.%d\n",
2655dee1ad47SJeff Kirsher 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
26565015e53aSBruce Allan 
2657dee1ad47SJeff Kirsher 	return ret_val;
2658dee1ad47SJeff Kirsher }
2659dee1ad47SJeff Kirsher 
2660dee1ad47SJeff Kirsher /**
2661dee1ad47SJeff Kirsher  *  e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register
2662dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2663dee1ad47SJeff Kirsher  *  @offset: register offset to be read or written
2664dee1ad47SJeff Kirsher  *  @data: pointer to the data to read or write
2665dee1ad47SJeff Kirsher  *  @read: determines if operation is read or write
2666dee1ad47SJeff Kirsher  *  @page_set: BM_WUC_PAGE already set and access enabled
2667dee1ad47SJeff Kirsher  *
2668dee1ad47SJeff Kirsher  *  Read the PHY register at offset and store the retrieved information in
2669dee1ad47SJeff Kirsher  *  data, or write data to PHY register at offset.  Note the procedure to
2670dee1ad47SJeff Kirsher  *  access the PHY wakeup registers is different than reading the other PHY
2671dee1ad47SJeff Kirsher  *  registers. It works as such:
2672dee1ad47SJeff Kirsher  *  1) Set 769.17.2 (page 769, register 17, bit 2) = 1
2673dee1ad47SJeff Kirsher  *  2) Set page to 800 for host (801 if we were manageability)
2674dee1ad47SJeff Kirsher  *  3) Write the address using the address opcode (0x11)
2675dee1ad47SJeff Kirsher  *  4) Read or write the data using the data opcode (0x12)
2676dee1ad47SJeff Kirsher  *  5) Restore 769.17.2 to its original value
2677dee1ad47SJeff Kirsher  *
2678dee1ad47SJeff Kirsher  *  Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and
2679dee1ad47SJeff Kirsher  *  step 5 is done by e1000_disable_phy_wakeup_reg_access_bm().
2680dee1ad47SJeff Kirsher  *
2681dee1ad47SJeff Kirsher  *  Assumes semaphore is already acquired.  When page_set==true, assumes
2682dee1ad47SJeff Kirsher  *  the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack
2683dee1ad47SJeff Kirsher  *  is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()).
2684dee1ad47SJeff Kirsher  **/
2685dee1ad47SJeff Kirsher static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2686dee1ad47SJeff Kirsher 					  u16 *data, bool read, bool page_set)
2687dee1ad47SJeff Kirsher {
2688dee1ad47SJeff Kirsher 	s32 ret_val;
2689dee1ad47SJeff Kirsher 	u16 reg = BM_PHY_REG_NUM(offset);
2690dee1ad47SJeff Kirsher 	u16 page = BM_PHY_REG_PAGE(offset);
2691dee1ad47SJeff Kirsher 	u16 phy_reg = 0;
2692dee1ad47SJeff Kirsher 
2693dee1ad47SJeff Kirsher 	/* Gig must be disabled for MDIO accesses to Host Wakeup reg page */
2694dee1ad47SJeff Kirsher 	if ((hw->mac.type == e1000_pchlan) &&
2695dee1ad47SJeff Kirsher 	    (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
2696dee1ad47SJeff Kirsher 		e_dbg("Attempting to access page %d while gig enabled.\n",
2697dee1ad47SJeff Kirsher 		      page);
2698dee1ad47SJeff Kirsher 
2699dee1ad47SJeff Kirsher 	if (!page_set) {
2700dee1ad47SJeff Kirsher 		/* Enable access to PHY wakeup registers */
2701dee1ad47SJeff Kirsher 		ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
2702dee1ad47SJeff Kirsher 		if (ret_val) {
2703dee1ad47SJeff Kirsher 			e_dbg("Could not enable PHY wakeup reg access\n");
27045015e53aSBruce Allan 			return ret_val;
2705dee1ad47SJeff Kirsher 		}
2706dee1ad47SJeff Kirsher 	}
2707dee1ad47SJeff Kirsher 
2708dee1ad47SJeff Kirsher 	e_dbg("Accessing PHY page %d reg 0x%x\n", page, reg);
2709dee1ad47SJeff Kirsher 
2710dee1ad47SJeff Kirsher 	/* Write the Wakeup register page offset value using opcode 0x11 */
2711dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
2712dee1ad47SJeff Kirsher 	if (ret_val) {
2713dee1ad47SJeff Kirsher 		e_dbg("Could not write address opcode to page %d\n", page);
27145015e53aSBruce Allan 		return ret_val;
2715dee1ad47SJeff Kirsher 	}
2716dee1ad47SJeff Kirsher 
2717dee1ad47SJeff Kirsher 	if (read) {
2718dee1ad47SJeff Kirsher 		/* Read the Wakeup register page value using opcode 0x12 */
2719dee1ad47SJeff Kirsher 		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
2720dee1ad47SJeff Kirsher 						   data);
2721dee1ad47SJeff Kirsher 	} else {
2722dee1ad47SJeff Kirsher 		/* Write the Wakeup register page value using opcode 0x12 */
2723dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
2724dee1ad47SJeff Kirsher 						    *data);
2725dee1ad47SJeff Kirsher 	}
2726dee1ad47SJeff Kirsher 
2727dee1ad47SJeff Kirsher 	if (ret_val) {
2728dee1ad47SJeff Kirsher 		e_dbg("Could not access PHY reg %d.%d\n", page, reg);
27295015e53aSBruce Allan 		return ret_val;
2730dee1ad47SJeff Kirsher 	}
2731dee1ad47SJeff Kirsher 
2732dee1ad47SJeff Kirsher 	if (!page_set)
2733dee1ad47SJeff Kirsher 		ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
2734dee1ad47SJeff Kirsher 
2735dee1ad47SJeff Kirsher 	return ret_val;
2736dee1ad47SJeff Kirsher }
2737dee1ad47SJeff Kirsher 
2738dee1ad47SJeff Kirsher /**
2739dee1ad47SJeff Kirsher  * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
2740dee1ad47SJeff Kirsher  * @hw: pointer to the HW structure
2741dee1ad47SJeff Kirsher  *
2742dee1ad47SJeff Kirsher  * In the case of a PHY power down to save power, or to turn off link during a
2743dee1ad47SJeff Kirsher  * driver unload, or wake on lan is not enabled, restore the link to previous
2744dee1ad47SJeff Kirsher  * settings.
2745dee1ad47SJeff Kirsher  **/
2746dee1ad47SJeff Kirsher void e1000_power_up_phy_copper(struct e1000_hw *hw)
2747dee1ad47SJeff Kirsher {
2748dee1ad47SJeff Kirsher 	u16 mii_reg = 0;
2749fb1752c7SLi Zhong 	int ret;
2750dee1ad47SJeff Kirsher 
2751dee1ad47SJeff Kirsher 	/* The PHY will retain its settings across a power down/up cycle */
2752fb1752c7SLi Zhong 	ret = e1e_rphy(hw, MII_BMCR, &mii_reg);
2753fb1752c7SLi Zhong 	if (ret) {
2754fb1752c7SLi Zhong 		e_dbg("Error reading PHY register\n");
2755fb1752c7SLi Zhong 		return;
2756fb1752c7SLi Zhong 	}
2757c2ade1a4SBruce Allan 	mii_reg &= ~BMCR_PDOWN;
2758c2ade1a4SBruce Allan 	e1e_wphy(hw, MII_BMCR, mii_reg);
2759dee1ad47SJeff Kirsher }
2760dee1ad47SJeff Kirsher 
2761dee1ad47SJeff Kirsher /**
2762dee1ad47SJeff Kirsher  * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
2763dee1ad47SJeff Kirsher  * @hw: pointer to the HW structure
2764dee1ad47SJeff Kirsher  *
2765dee1ad47SJeff Kirsher  * In the case of a PHY power down to save power, or to turn off link during a
2766dee1ad47SJeff Kirsher  * driver unload, or wake on lan is not enabled, restore the link to previous
2767dee1ad47SJeff Kirsher  * settings.
2768dee1ad47SJeff Kirsher  **/
2769dee1ad47SJeff Kirsher void e1000_power_down_phy_copper(struct e1000_hw *hw)
2770dee1ad47SJeff Kirsher {
2771dee1ad47SJeff Kirsher 	u16 mii_reg = 0;
2772fb1752c7SLi Zhong 	int ret;
2773dee1ad47SJeff Kirsher 
2774dee1ad47SJeff Kirsher 	/* The PHY will retain its settings across a power down/up cycle */
2775fb1752c7SLi Zhong 	ret = e1e_rphy(hw, MII_BMCR, &mii_reg);
2776fb1752c7SLi Zhong 	if (ret) {
2777fb1752c7SLi Zhong 		e_dbg("Error reading PHY register\n");
2778fb1752c7SLi Zhong 		return;
2779fb1752c7SLi Zhong 	}
2780c2ade1a4SBruce Allan 	mii_reg |= BMCR_PDOWN;
2781c2ade1a4SBruce Allan 	e1e_wphy(hw, MII_BMCR, mii_reg);
2782dee1ad47SJeff Kirsher 	usleep_range(1000, 2000);
2783dee1ad47SJeff Kirsher }
2784dee1ad47SJeff Kirsher 
2785dee1ad47SJeff Kirsher /**
2786dee1ad47SJeff Kirsher  *  __e1000_read_phy_reg_hv -  Read HV PHY register
2787dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2788dee1ad47SJeff Kirsher  *  @offset: register offset to be read
2789dee1ad47SJeff Kirsher  *  @data: pointer to the read data
2790dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
2791b50f7bcaSJesse Brandeburg  *  @page_set: BM_WUC_PAGE already set and access enabled
2792dee1ad47SJeff Kirsher  *
2793dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then reads the PHY register at offset
2794dee1ad47SJeff Kirsher  *  and stores the retrieved information in data.  Release any acquired
2795dee1ad47SJeff Kirsher  *  semaphore before exiting.
2796dee1ad47SJeff Kirsher  **/
2797dee1ad47SJeff Kirsher static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2798dee1ad47SJeff Kirsher 				   bool locked, bool page_set)
2799dee1ad47SJeff Kirsher {
2800dee1ad47SJeff Kirsher 	s32 ret_val;
2801dee1ad47SJeff Kirsher 	u16 page = BM_PHY_REG_PAGE(offset);
2802dee1ad47SJeff Kirsher 	u16 reg = BM_PHY_REG_NUM(offset);
2803dee1ad47SJeff Kirsher 	u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2804dee1ad47SJeff Kirsher 
2805dee1ad47SJeff Kirsher 	if (!locked) {
2806dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
2807dee1ad47SJeff Kirsher 		if (ret_val)
2808dee1ad47SJeff Kirsher 			return ret_val;
2809dee1ad47SJeff Kirsher 	}
2810dee1ad47SJeff Kirsher 
2811dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2812dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2813dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2814dee1ad47SJeff Kirsher 							 true, page_set);
2815dee1ad47SJeff Kirsher 		goto out;
2816dee1ad47SJeff Kirsher 	}
2817dee1ad47SJeff Kirsher 
2818dee1ad47SJeff Kirsher 	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
2819dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
2820dee1ad47SJeff Kirsher 							 data, true);
2821dee1ad47SJeff Kirsher 		goto out;
2822dee1ad47SJeff Kirsher 	}
2823dee1ad47SJeff Kirsher 
2824dee1ad47SJeff Kirsher 	if (!page_set) {
2825dee1ad47SJeff Kirsher 		if (page == HV_INTC_FC_PAGE_START)
2826dee1ad47SJeff Kirsher 			page = 0;
2827dee1ad47SJeff Kirsher 
2828dee1ad47SJeff Kirsher 		if (reg > MAX_PHY_MULTI_PAGE_REG) {
2829dee1ad47SJeff Kirsher 			/* Page is shifted left, PHY expects (page x 32) */
2830dee1ad47SJeff Kirsher 			ret_val = e1000_set_page_igp(hw,
2831dee1ad47SJeff Kirsher 						     (page << IGP_PAGE_SHIFT));
2832dee1ad47SJeff Kirsher 
2833dee1ad47SJeff Kirsher 			hw->phy.addr = phy_addr;
2834dee1ad47SJeff Kirsher 
2835dee1ad47SJeff Kirsher 			if (ret_val)
2836dee1ad47SJeff Kirsher 				goto out;
2837dee1ad47SJeff Kirsher 		}
2838dee1ad47SJeff Kirsher 	}
2839dee1ad47SJeff Kirsher 
2840dee1ad47SJeff Kirsher 	e_dbg("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
2841dee1ad47SJeff Kirsher 	      page << IGP_PAGE_SHIFT, reg);
2842dee1ad47SJeff Kirsher 
2843f0ff4398SBruce Allan 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data);
2844dee1ad47SJeff Kirsher out:
2845dee1ad47SJeff Kirsher 	if (!locked)
2846dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
2847dee1ad47SJeff Kirsher 
2848dee1ad47SJeff Kirsher 	return ret_val;
2849dee1ad47SJeff Kirsher }
2850dee1ad47SJeff Kirsher 
2851dee1ad47SJeff Kirsher /**
2852dee1ad47SJeff Kirsher  *  e1000_read_phy_reg_hv -  Read HV PHY register
2853dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2854dee1ad47SJeff Kirsher  *  @offset: register offset to be read
2855dee1ad47SJeff Kirsher  *  @data: pointer to the read data
2856dee1ad47SJeff Kirsher  *
2857dee1ad47SJeff Kirsher  *  Acquires semaphore then reads the PHY register at offset and stores
2858dee1ad47SJeff Kirsher  *  the retrieved information in data.  Release the acquired semaphore
2859dee1ad47SJeff Kirsher  *  before exiting.
2860dee1ad47SJeff Kirsher  **/
2861dee1ad47SJeff Kirsher s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2862dee1ad47SJeff Kirsher {
2863dee1ad47SJeff Kirsher 	return __e1000_read_phy_reg_hv(hw, offset, data, false, false);
2864dee1ad47SJeff Kirsher }
2865dee1ad47SJeff Kirsher 
2866dee1ad47SJeff Kirsher /**
2867dee1ad47SJeff Kirsher  *  e1000_read_phy_reg_hv_locked -  Read HV PHY register
2868dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2869dee1ad47SJeff Kirsher  *  @offset: register offset to be read
2870dee1ad47SJeff Kirsher  *  @data: pointer to the read data
2871dee1ad47SJeff Kirsher  *
2872dee1ad47SJeff Kirsher  *  Reads the PHY register at offset and stores the retrieved information
2873dee1ad47SJeff Kirsher  *  in data.  Assumes semaphore already acquired.
2874dee1ad47SJeff Kirsher  **/
2875dee1ad47SJeff Kirsher s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2876dee1ad47SJeff Kirsher {
2877dee1ad47SJeff Kirsher 	return __e1000_read_phy_reg_hv(hw, offset, data, true, false);
2878dee1ad47SJeff Kirsher }
2879dee1ad47SJeff Kirsher 
2880dee1ad47SJeff Kirsher /**
2881dee1ad47SJeff Kirsher  *  e1000_read_phy_reg_page_hv - Read HV PHY register
2882dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2883dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2884dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2885dee1ad47SJeff Kirsher  *
2886dee1ad47SJeff Kirsher  *  Reads the PHY register at offset and stores the retrieved information
2887dee1ad47SJeff Kirsher  *  in data.  Assumes semaphore already acquired and page already set.
2888dee1ad47SJeff Kirsher  **/
2889dee1ad47SJeff Kirsher s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2890dee1ad47SJeff Kirsher {
2891dee1ad47SJeff Kirsher 	return __e1000_read_phy_reg_hv(hw, offset, data, true, true);
2892dee1ad47SJeff Kirsher }
2893dee1ad47SJeff Kirsher 
2894dee1ad47SJeff Kirsher /**
2895dee1ad47SJeff Kirsher  *  __e1000_write_phy_reg_hv - Write HV PHY register
2896dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2897dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2898dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2899dee1ad47SJeff Kirsher  *  @locked: semaphore has already been acquired or not
2900b50f7bcaSJesse Brandeburg  *  @page_set: BM_WUC_PAGE already set and access enabled
2901dee1ad47SJeff Kirsher  *
2902dee1ad47SJeff Kirsher  *  Acquires semaphore, if necessary, then writes the data to PHY register
2903dee1ad47SJeff Kirsher  *  at the offset.  Release any acquired semaphores before exiting.
2904dee1ad47SJeff Kirsher  **/
2905dee1ad47SJeff Kirsher static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2906dee1ad47SJeff Kirsher 				    bool locked, bool page_set)
2907dee1ad47SJeff Kirsher {
2908dee1ad47SJeff Kirsher 	s32 ret_val;
2909dee1ad47SJeff Kirsher 	u16 page = BM_PHY_REG_PAGE(offset);
2910dee1ad47SJeff Kirsher 	u16 reg = BM_PHY_REG_NUM(offset);
2911dee1ad47SJeff Kirsher 	u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2912dee1ad47SJeff Kirsher 
2913dee1ad47SJeff Kirsher 	if (!locked) {
2914dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.acquire(hw);
2915dee1ad47SJeff Kirsher 		if (ret_val)
2916dee1ad47SJeff Kirsher 			return ret_val;
2917dee1ad47SJeff Kirsher 	}
2918dee1ad47SJeff Kirsher 
2919dee1ad47SJeff Kirsher 	/* Page 800 works differently than the rest so it has its own func */
2920dee1ad47SJeff Kirsher 	if (page == BM_WUC_PAGE) {
2921dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2922dee1ad47SJeff Kirsher 							 false, page_set);
2923dee1ad47SJeff Kirsher 		goto out;
2924dee1ad47SJeff Kirsher 	}
2925dee1ad47SJeff Kirsher 
2926dee1ad47SJeff Kirsher 	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
2927dee1ad47SJeff Kirsher 		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
2928dee1ad47SJeff Kirsher 							 &data, false);
2929dee1ad47SJeff Kirsher 		goto out;
2930dee1ad47SJeff Kirsher 	}
2931dee1ad47SJeff Kirsher 
2932dee1ad47SJeff Kirsher 	if (!page_set) {
2933dee1ad47SJeff Kirsher 		if (page == HV_INTC_FC_PAGE_START)
2934dee1ad47SJeff Kirsher 			page = 0;
2935dee1ad47SJeff Kirsher 
2936e921eb1aSBruce Allan 		/* Workaround MDIO accesses being disabled after entering IEEE
2937dee1ad47SJeff Kirsher 		 * Power Down (when bit 11 of the PHY Control register is set)
2938dee1ad47SJeff Kirsher 		 */
2939dee1ad47SJeff Kirsher 		if ((hw->phy.type == e1000_phy_82578) &&
2940dee1ad47SJeff Kirsher 		    (hw->phy.revision >= 1) &&
2941dee1ad47SJeff Kirsher 		    (hw->phy.addr == 2) &&
294218dd2392SJacob Keller 		    !(MAX_PHY_REG_ADDRESS & reg) && (data & BIT(11))) {
2943dee1ad47SJeff Kirsher 			u16 data2 = 0x7EFF;
29446cf08d1cSDavid Ertman 
2945dee1ad47SJeff Kirsher 			ret_val = e1000_access_phy_debug_regs_hv(hw,
294618dd2392SJacob Keller 								 BIT(6) | 0x3,
2947dee1ad47SJeff Kirsher 								 &data2, false);
2948dee1ad47SJeff Kirsher 			if (ret_val)
2949dee1ad47SJeff Kirsher 				goto out;
2950dee1ad47SJeff Kirsher 		}
2951dee1ad47SJeff Kirsher 
2952dee1ad47SJeff Kirsher 		if (reg > MAX_PHY_MULTI_PAGE_REG) {
2953dee1ad47SJeff Kirsher 			/* Page is shifted left, PHY expects (page x 32) */
2954dee1ad47SJeff Kirsher 			ret_val = e1000_set_page_igp(hw,
2955dee1ad47SJeff Kirsher 						     (page << IGP_PAGE_SHIFT));
2956dee1ad47SJeff Kirsher 
2957dee1ad47SJeff Kirsher 			hw->phy.addr = phy_addr;
2958dee1ad47SJeff Kirsher 
2959dee1ad47SJeff Kirsher 			if (ret_val)
2960dee1ad47SJeff Kirsher 				goto out;
2961dee1ad47SJeff Kirsher 		}
2962dee1ad47SJeff Kirsher 	}
2963dee1ad47SJeff Kirsher 
2964dee1ad47SJeff Kirsher 	e_dbg("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
2965dee1ad47SJeff Kirsher 	      page << IGP_PAGE_SHIFT, reg);
2966dee1ad47SJeff Kirsher 
2967dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2968dee1ad47SJeff Kirsher 					    data);
2969dee1ad47SJeff Kirsher 
2970dee1ad47SJeff Kirsher out:
2971dee1ad47SJeff Kirsher 	if (!locked)
2972dee1ad47SJeff Kirsher 		hw->phy.ops.release(hw);
2973dee1ad47SJeff Kirsher 
2974dee1ad47SJeff Kirsher 	return ret_val;
2975dee1ad47SJeff Kirsher }
2976dee1ad47SJeff Kirsher 
2977dee1ad47SJeff Kirsher /**
2978dee1ad47SJeff Kirsher  *  e1000_write_phy_reg_hv - Write HV PHY register
2979dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2980dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2981dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2982dee1ad47SJeff Kirsher  *
2983dee1ad47SJeff Kirsher  *  Acquires semaphore then writes the data to PHY register at the offset.
2984dee1ad47SJeff Kirsher  *  Release the acquired semaphores before exiting.
2985dee1ad47SJeff Kirsher  **/
2986dee1ad47SJeff Kirsher s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2987dee1ad47SJeff Kirsher {
2988dee1ad47SJeff Kirsher 	return __e1000_write_phy_reg_hv(hw, offset, data, false, false);
2989dee1ad47SJeff Kirsher }
2990dee1ad47SJeff Kirsher 
2991dee1ad47SJeff Kirsher /**
2992dee1ad47SJeff Kirsher  *  e1000_write_phy_reg_hv_locked - Write HV PHY register
2993dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
2994dee1ad47SJeff Kirsher  *  @offset: register offset to write to
2995dee1ad47SJeff Kirsher  *  @data: data to write at register offset
2996dee1ad47SJeff Kirsher  *
2997dee1ad47SJeff Kirsher  *  Writes the data to PHY register at the offset.  Assumes semaphore
2998dee1ad47SJeff Kirsher  *  already acquired.
2999dee1ad47SJeff Kirsher  **/
3000dee1ad47SJeff Kirsher s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
3001dee1ad47SJeff Kirsher {
3002dee1ad47SJeff Kirsher 	return __e1000_write_phy_reg_hv(hw, offset, data, true, false);
3003dee1ad47SJeff Kirsher }
3004dee1ad47SJeff Kirsher 
3005dee1ad47SJeff Kirsher /**
3006dee1ad47SJeff Kirsher  *  e1000_write_phy_reg_page_hv - Write HV PHY register
3007dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3008dee1ad47SJeff Kirsher  *  @offset: register offset to write to
3009dee1ad47SJeff Kirsher  *  @data: data to write at register offset
3010dee1ad47SJeff Kirsher  *
3011dee1ad47SJeff Kirsher  *  Writes the data to PHY register at the offset.  Assumes semaphore
3012dee1ad47SJeff Kirsher  *  already acquired and page already set.
3013dee1ad47SJeff Kirsher  **/
3014dee1ad47SJeff Kirsher s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data)
3015dee1ad47SJeff Kirsher {
3016dee1ad47SJeff Kirsher 	return __e1000_write_phy_reg_hv(hw, offset, data, true, true);
3017dee1ad47SJeff Kirsher }
3018dee1ad47SJeff Kirsher 
3019dee1ad47SJeff Kirsher /**
3020dee1ad47SJeff Kirsher  *  e1000_get_phy_addr_for_hv_page - Get PHY address based on page
3021dee1ad47SJeff Kirsher  *  @page: page to be accessed
3022dee1ad47SJeff Kirsher  **/
3023dee1ad47SJeff Kirsher static u32 e1000_get_phy_addr_for_hv_page(u32 page)
3024dee1ad47SJeff Kirsher {
3025dee1ad47SJeff Kirsher 	u32 phy_addr = 2;
3026dee1ad47SJeff Kirsher 
3027dee1ad47SJeff Kirsher 	if (page >= HV_INTC_FC_PAGE_START)
3028dee1ad47SJeff Kirsher 		phy_addr = 1;
3029dee1ad47SJeff Kirsher 
3030dee1ad47SJeff Kirsher 	return phy_addr;
3031dee1ad47SJeff Kirsher }
3032dee1ad47SJeff Kirsher 
3033dee1ad47SJeff Kirsher /**
3034dee1ad47SJeff Kirsher  *  e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
3035dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3036dee1ad47SJeff Kirsher  *  @offset: register offset to be read or written
3037dee1ad47SJeff Kirsher  *  @data: pointer to the data to be read or written
3038dee1ad47SJeff Kirsher  *  @read: determines if operation is read or write
3039dee1ad47SJeff Kirsher  *
30400d27895bSHao Chen  *  Reads the PHY register at offset and stores the retrieved information
3041dee1ad47SJeff Kirsher  *  in data.  Assumes semaphore already acquired.  Note that the procedure
3042dee1ad47SJeff Kirsher  *  to access these regs uses the address port and data port to read/write.
3043dee1ad47SJeff Kirsher  *  These accesses done with PHY address 2 and without using pages.
3044dee1ad47SJeff Kirsher  **/
3045dee1ad47SJeff Kirsher static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
3046dee1ad47SJeff Kirsher 					  u16 *data, bool read)
3047dee1ad47SJeff Kirsher {
3048dee1ad47SJeff Kirsher 	s32 ret_val;
304970806a7fSBruce Allan 	u32 addr_reg;
305070806a7fSBruce Allan 	u32 data_reg;
3051dee1ad47SJeff Kirsher 
3052dee1ad47SJeff Kirsher 	/* This takes care of the difference with desktop vs mobile phy */
3053f0ff4398SBruce Allan 	addr_reg = ((hw->phy.type == e1000_phy_82578) ?
3054f0ff4398SBruce Allan 		    I82578_ADDR_REG : I82577_ADDR_REG);
3055dee1ad47SJeff Kirsher 	data_reg = addr_reg + 1;
3056dee1ad47SJeff Kirsher 
3057dee1ad47SJeff Kirsher 	/* All operations in this function are phy address 2 */
3058dee1ad47SJeff Kirsher 	hw->phy.addr = 2;
3059dee1ad47SJeff Kirsher 
3060dee1ad47SJeff Kirsher 	/* masking with 0x3F to remove the page from offset */
3061dee1ad47SJeff Kirsher 	ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
3062dee1ad47SJeff Kirsher 	if (ret_val) {
3063dee1ad47SJeff Kirsher 		e_dbg("Could not write the Address Offset port register\n");
30645015e53aSBruce Allan 		return ret_val;
3065dee1ad47SJeff Kirsher 	}
3066dee1ad47SJeff Kirsher 
3067dee1ad47SJeff Kirsher 	/* Read or write the data value next */
3068dee1ad47SJeff Kirsher 	if (read)
3069dee1ad47SJeff Kirsher 		ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data);
3070dee1ad47SJeff Kirsher 	else
3071dee1ad47SJeff Kirsher 		ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
3072dee1ad47SJeff Kirsher 
30735015e53aSBruce Allan 	if (ret_val)
3074dee1ad47SJeff Kirsher 		e_dbg("Could not access the Data port register\n");
3075dee1ad47SJeff Kirsher 
3076dee1ad47SJeff Kirsher 	return ret_val;
3077dee1ad47SJeff Kirsher }
3078dee1ad47SJeff Kirsher 
3079dee1ad47SJeff Kirsher /**
3080dee1ad47SJeff Kirsher  *  e1000_link_stall_workaround_hv - Si workaround
3081dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3082dee1ad47SJeff Kirsher  *
3083dee1ad47SJeff Kirsher  *  This function works around a Si bug where the link partner can get
3084dee1ad47SJeff Kirsher  *  a link up indication before the PHY does.  If small packets are sent
3085dee1ad47SJeff Kirsher  *  by the link partner they can be placed in the packet buffer without
3086dee1ad47SJeff Kirsher  *  being properly accounted for by the PHY and will stall preventing
3087dee1ad47SJeff Kirsher  *  further packets from being received.  The workaround is to clear the
3088dee1ad47SJeff Kirsher  *  packet buffer after the PHY detects link up.
3089dee1ad47SJeff Kirsher  **/
3090dee1ad47SJeff Kirsher s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
3091dee1ad47SJeff Kirsher {
3092dee1ad47SJeff Kirsher 	s32 ret_val = 0;
3093dee1ad47SJeff Kirsher 	u16 data;
3094dee1ad47SJeff Kirsher 
3095dee1ad47SJeff Kirsher 	if (hw->phy.type != e1000_phy_82578)
30965015e53aSBruce Allan 		return 0;
3097dee1ad47SJeff Kirsher 
3098dee1ad47SJeff Kirsher 	/* Do not apply workaround if in PHY loopback bit 14 set */
3099fb1752c7SLi Zhong 	ret_val = e1e_rphy(hw, MII_BMCR, &data);
3100fb1752c7SLi Zhong 	if (ret_val) {
3101fb1752c7SLi Zhong 		e_dbg("Error reading PHY register\n");
3102fb1752c7SLi Zhong 		return ret_val;
3103fb1752c7SLi Zhong 	}
3104c2ade1a4SBruce Allan 	if (data & BMCR_LOOPBACK)
31055015e53aSBruce Allan 		return 0;
3106dee1ad47SJeff Kirsher 
3107dee1ad47SJeff Kirsher 	/* check if link is up and at 1Gbps */
3108dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, BM_CS_STATUS, &data);
3109dee1ad47SJeff Kirsher 	if (ret_val)
31105015e53aSBruce Allan 		return ret_val;
3111dee1ad47SJeff Kirsher 
3112f0ff4398SBruce Allan 	data &= (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
3113f0ff4398SBruce Allan 		 BM_CS_STATUS_SPEED_MASK);
3114dee1ad47SJeff Kirsher 
31153d3a1676SBruce Allan 	if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
3116dee1ad47SJeff Kirsher 		     BM_CS_STATUS_SPEED_1000))
31175015e53aSBruce Allan 		return 0;
3118dee1ad47SJeff Kirsher 
3119bb9c5ee1SBruce Allan 	msleep(200);
3120dee1ad47SJeff Kirsher 
3121dee1ad47SJeff Kirsher 	/* flush the packets in the fifo buffer */
3122c063f606SBruce Allan 	ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL,
3123c063f606SBruce Allan 			   (HV_MUX_DATA_CTRL_GEN_TO_MAC |
3124c063f606SBruce Allan 			    HV_MUX_DATA_CTRL_FORCE_SPEED));
3125dee1ad47SJeff Kirsher 	if (ret_val)
3126dee1ad47SJeff Kirsher 		return ret_val;
31275015e53aSBruce Allan 
31285015e53aSBruce Allan 	return e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC);
3129dee1ad47SJeff Kirsher }
3130dee1ad47SJeff Kirsher 
3131dee1ad47SJeff Kirsher /**
3132dee1ad47SJeff Kirsher  *  e1000_check_polarity_82577 - Checks the polarity.
3133dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3134dee1ad47SJeff Kirsher  *
3135dee1ad47SJeff Kirsher  *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
3136dee1ad47SJeff Kirsher  *
3137dee1ad47SJeff Kirsher  *  Polarity is determined based on the PHY specific status register.
3138dee1ad47SJeff Kirsher  **/
3139dee1ad47SJeff Kirsher s32 e1000_check_polarity_82577(struct e1000_hw *hw)
3140dee1ad47SJeff Kirsher {
3141dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
3142dee1ad47SJeff Kirsher 	s32 ret_val;
3143dee1ad47SJeff Kirsher 	u16 data;
3144dee1ad47SJeff Kirsher 
3145dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data);
3146dee1ad47SJeff Kirsher 
3147dee1ad47SJeff Kirsher 	if (!ret_val)
3148f0ff4398SBruce Allan 		phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY)
3149dee1ad47SJeff Kirsher 				       ? e1000_rev_polarity_reversed
3150f0ff4398SBruce Allan 				       : e1000_rev_polarity_normal);
3151dee1ad47SJeff Kirsher 
3152dee1ad47SJeff Kirsher 	return ret_val;
3153dee1ad47SJeff Kirsher }
3154dee1ad47SJeff Kirsher 
3155dee1ad47SJeff Kirsher /**
3156dee1ad47SJeff Kirsher  *  e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
3157dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3158dee1ad47SJeff Kirsher  *
3159dee1ad47SJeff Kirsher  *  Calls the PHY setup function to force speed and duplex.
3160dee1ad47SJeff Kirsher  **/
3161dee1ad47SJeff Kirsher s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
3162dee1ad47SJeff Kirsher {
3163dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
3164dee1ad47SJeff Kirsher 	s32 ret_val;
3165dee1ad47SJeff Kirsher 	u16 phy_data;
3166dee1ad47SJeff Kirsher 	bool link;
3167dee1ad47SJeff Kirsher 
3168c2ade1a4SBruce Allan 	ret_val = e1e_rphy(hw, MII_BMCR, &phy_data);
3169dee1ad47SJeff Kirsher 	if (ret_val)
31705015e53aSBruce Allan 		return ret_val;
3171dee1ad47SJeff Kirsher 
3172dee1ad47SJeff Kirsher 	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
3173dee1ad47SJeff Kirsher 
3174c2ade1a4SBruce Allan 	ret_val = e1e_wphy(hw, MII_BMCR, phy_data);
3175dee1ad47SJeff Kirsher 	if (ret_val)
31765015e53aSBruce Allan 		return ret_val;
3177dee1ad47SJeff Kirsher 
3178dee1ad47SJeff Kirsher 	udelay(1);
3179dee1ad47SJeff Kirsher 
3180dee1ad47SJeff Kirsher 	if (phy->autoneg_wait_to_complete) {
3181dee1ad47SJeff Kirsher 		e_dbg("Waiting for forced speed/duplex link on 82577 phy\n");
3182dee1ad47SJeff Kirsher 
31833d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
31843d3a1676SBruce Allan 						      100000, &link);
3185dee1ad47SJeff Kirsher 		if (ret_val)
31865015e53aSBruce Allan 			return ret_val;
3187dee1ad47SJeff Kirsher 
3188dee1ad47SJeff Kirsher 		if (!link)
3189dee1ad47SJeff Kirsher 			e_dbg("Link taking longer than expected.\n");
3190dee1ad47SJeff Kirsher 
3191dee1ad47SJeff Kirsher 		/* Try once more */
31923d3a1676SBruce Allan 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
31933d3a1676SBruce Allan 						      100000, &link);
3194dee1ad47SJeff Kirsher 	}
3195dee1ad47SJeff Kirsher 
3196dee1ad47SJeff Kirsher 	return ret_val;
3197dee1ad47SJeff Kirsher }
3198dee1ad47SJeff Kirsher 
3199dee1ad47SJeff Kirsher /**
3200dee1ad47SJeff Kirsher  *  e1000_get_phy_info_82577 - Retrieve I82577 PHY information
3201dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3202dee1ad47SJeff Kirsher  *
3203dee1ad47SJeff Kirsher  *  Read PHY status to determine if link is up.  If link is up, then
3204dee1ad47SJeff Kirsher  *  set/determine 10base-T extended distance and polarity correction.  Read
3205dee1ad47SJeff Kirsher  *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
3206dee1ad47SJeff Kirsher  *  determine on the cable length, local and remote receiver.
3207dee1ad47SJeff Kirsher  **/
3208dee1ad47SJeff Kirsher s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
3209dee1ad47SJeff Kirsher {
3210dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
3211dee1ad47SJeff Kirsher 	s32 ret_val;
3212dee1ad47SJeff Kirsher 	u16 data;
3213dee1ad47SJeff Kirsher 	bool link;
3214dee1ad47SJeff Kirsher 
3215dee1ad47SJeff Kirsher 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
3216dee1ad47SJeff Kirsher 	if (ret_val)
32175015e53aSBruce Allan 		return ret_val;
3218dee1ad47SJeff Kirsher 
3219dee1ad47SJeff Kirsher 	if (!link) {
3220dee1ad47SJeff Kirsher 		e_dbg("Phy info is only valid if link is up\n");
32215015e53aSBruce Allan 		return -E1000_ERR_CONFIG;
3222dee1ad47SJeff Kirsher 	}
3223dee1ad47SJeff Kirsher 
3224dee1ad47SJeff Kirsher 	phy->polarity_correction = true;
3225dee1ad47SJeff Kirsher 
3226dee1ad47SJeff Kirsher 	ret_val = e1000_check_polarity_82577(hw);
3227dee1ad47SJeff Kirsher 	if (ret_val)
32285015e53aSBruce Allan 		return ret_val;
3229dee1ad47SJeff Kirsher 
3230dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data);
3231dee1ad47SJeff Kirsher 	if (ret_val)
32325015e53aSBruce Allan 		return ret_val;
3233dee1ad47SJeff Kirsher 
323404499ec4SBruce Allan 	phy->is_mdix = !!(data & I82577_PHY_STATUS2_MDIX);
3235dee1ad47SJeff Kirsher 
3236dee1ad47SJeff Kirsher 	if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
3237dee1ad47SJeff Kirsher 	    I82577_PHY_STATUS2_SPEED_1000MBPS) {
3238dee1ad47SJeff Kirsher 		ret_val = hw->phy.ops.get_cable_length(hw);
3239dee1ad47SJeff Kirsher 		if (ret_val)
32405015e53aSBruce Allan 			return ret_val;
3241dee1ad47SJeff Kirsher 
3242c2ade1a4SBruce Allan 		ret_val = e1e_rphy(hw, MII_STAT1000, &data);
3243dee1ad47SJeff Kirsher 		if (ret_val)
32445015e53aSBruce Allan 			return ret_val;
3245dee1ad47SJeff Kirsher 
3246c2ade1a4SBruce Allan 		phy->local_rx = (data & LPA_1000LOCALRXOK)
3247c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
3248dee1ad47SJeff Kirsher 
3249c2ade1a4SBruce Allan 		phy->remote_rx = (data & LPA_1000REMRXOK)
3250c2ade1a4SBruce Allan 		    ? e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
3251dee1ad47SJeff Kirsher 	} else {
3252dee1ad47SJeff Kirsher 		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
3253dee1ad47SJeff Kirsher 		phy->local_rx = e1000_1000t_rx_status_undefined;
3254dee1ad47SJeff Kirsher 		phy->remote_rx = e1000_1000t_rx_status_undefined;
3255dee1ad47SJeff Kirsher 	}
3256dee1ad47SJeff Kirsher 
32575015e53aSBruce Allan 	return 0;
3258dee1ad47SJeff Kirsher }
3259dee1ad47SJeff Kirsher 
3260dee1ad47SJeff Kirsher /**
3261dee1ad47SJeff Kirsher  *  e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
3262dee1ad47SJeff Kirsher  *  @hw: pointer to the HW structure
3263dee1ad47SJeff Kirsher  *
3264dee1ad47SJeff Kirsher  * Reads the diagnostic status register and verifies result is valid before
3265dee1ad47SJeff Kirsher  * placing it in the phy_cable_length field.
3266dee1ad47SJeff Kirsher  **/
3267dee1ad47SJeff Kirsher s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
3268dee1ad47SJeff Kirsher {
3269dee1ad47SJeff Kirsher 	struct e1000_phy_info *phy = &hw->phy;
3270dee1ad47SJeff Kirsher 	s32 ret_val;
3271dee1ad47SJeff Kirsher 	u16 phy_data, length;
3272dee1ad47SJeff Kirsher 
3273dee1ad47SJeff Kirsher 	ret_val = e1e_rphy(hw, I82577_PHY_DIAG_STATUS, &phy_data);
3274dee1ad47SJeff Kirsher 	if (ret_val)
32755015e53aSBruce Allan 		return ret_val;
3276dee1ad47SJeff Kirsher 
3277d5752c7bSJesse Brandeburg 	length = FIELD_GET(I82577_DSTATUS_CABLE_LENGTH, phy_data);
3278dee1ad47SJeff Kirsher 
3279dee1ad47SJeff Kirsher 	if (length == E1000_CABLE_LENGTH_UNDEFINED)
32807dbbe5d5SBruce Allan 		return -E1000_ERR_PHY;
3281dee1ad47SJeff Kirsher 
3282dee1ad47SJeff Kirsher 	phy->cable_length = length;
3283dee1ad47SJeff Kirsher 
32845015e53aSBruce Allan 	return 0;
3285dee1ad47SJeff Kirsher }
3286