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