xref: /onnv-gate/usr/src/uts/common/io/igb/igb_phy.c (revision 5779:e875a8701bfc)
1*5779Sxy150489 /*
2*5779Sxy150489  * CDDL HEADER START
3*5779Sxy150489  *
4*5779Sxy150489  * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
5*5779Sxy150489  * The contents of this file are subject to the terms of the
6*5779Sxy150489  * Common Development and Distribution License (the "License").
7*5779Sxy150489  * You may not use this file except in compliance with the License.
8*5779Sxy150489  *
9*5779Sxy150489  * You can obtain a copy of the license at:
10*5779Sxy150489  *	http://www.opensolaris.org/os/licensing.
11*5779Sxy150489  * See the License for the specific language governing permissions
12*5779Sxy150489  * and limitations under the License.
13*5779Sxy150489  *
14*5779Sxy150489  * When using or redistributing this file, you may do so under the
15*5779Sxy150489  * License only. No other modification of this header is permitted.
16*5779Sxy150489  *
17*5779Sxy150489  * If applicable, add the following below this CDDL HEADER, with the
18*5779Sxy150489  * fields enclosed by brackets "[]" replaced with your own identifying
19*5779Sxy150489  * information: Portions Copyright [yyyy] [name of copyright owner]
20*5779Sxy150489  *
21*5779Sxy150489  * CDDL HEADER END
22*5779Sxy150489  */
23*5779Sxy150489 
24*5779Sxy150489 /*
25*5779Sxy150489  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26*5779Sxy150489  * Use is subject to license terms of the CDDL.
27*5779Sxy150489  */
28*5779Sxy150489 
29*5779Sxy150489 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*5779Sxy150489 
31*5779Sxy150489 #include "igb_api.h"
32*5779Sxy150489 #include "igb_phy.h"
33*5779Sxy150489 
34*5779Sxy150489 static s32  e1000_get_phy_cfg_done(struct e1000_hw *hw);
35*5779Sxy150489 static void e1000_release_phy(struct e1000_hw *hw);
36*5779Sxy150489 static s32  e1000_acquire_phy(struct e1000_hw *hw);
37*5779Sxy150489 static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
38*5779Sxy150489 
39*5779Sxy150489 /* Cable length tables */
40*5779Sxy150489 static const u16 e1000_m88_cable_length_table[] =
41*5779Sxy150489 	{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
42*5779Sxy150489 
43*5779Sxy150489 #define	M88E1000_CABLE_LENGTH_TABLE_SIZE \
44*5779Sxy150489 	(sizeof (e1000_m88_cable_length_table) / \
45*5779Sxy150489 	sizeof (e1000_m88_cable_length_table[0]))
46*5779Sxy150489 
47*5779Sxy150489 static const u16 e1000_igp_2_cable_length_table[] =
48*5779Sxy150489 	{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
49*5779Sxy150489 	0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
50*5779Sxy150489 	6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
51*5779Sxy150489 	21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
52*5779Sxy150489 	40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
53*5779Sxy150489 	60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
54*5779Sxy150489 	83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
55*5779Sxy150489 	104, 109, 114, 118, 121, 124};
56*5779Sxy150489 
57*5779Sxy150489 #define	IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
58*5779Sxy150489 	(sizeof (e1000_igp_2_cable_length_table) / \
59*5779Sxy150489 	sizeof (e1000_igp_2_cable_length_table[0]))
60*5779Sxy150489 
61*5779Sxy150489 /*
62*5779Sxy150489  * e1000_check_reset_block_generic - Check if PHY reset is blocked
63*5779Sxy150489  * @hw: pointer to the HW structure
64*5779Sxy150489  *
65*5779Sxy150489  * Read the PHY management control register and check whether a PHY reset
66*5779Sxy150489  * is blocked.  If a reset is not blocked return E1000_SUCCESS, otherwise
67*5779Sxy150489  * return E1000_BLK_PHY_RESET (12).
68*5779Sxy150489  */
69*5779Sxy150489 s32
70*5779Sxy150489 e1000_check_reset_block_generic(struct e1000_hw *hw)
71*5779Sxy150489 {
72*5779Sxy150489 	u32 manc;
73*5779Sxy150489 
74*5779Sxy150489 	DEBUGFUNC("e1000_check_reset_block");
75*5779Sxy150489 
76*5779Sxy150489 	manc = E1000_READ_REG(hw, E1000_MANC);
77*5779Sxy150489 
78*5779Sxy150489 	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
79*5779Sxy150489 	    E1000_BLK_PHY_RESET : E1000_SUCCESS;
80*5779Sxy150489 }
81*5779Sxy150489 
82*5779Sxy150489 /*
83*5779Sxy150489  * e1000_get_phy_id - Retrieve the PHY ID and revision
84*5779Sxy150489  * @hw: pointer to the HW structure
85*5779Sxy150489  *
86*5779Sxy150489  * Reads the PHY registers and stores the PHY ID and possibly the PHY
87*5779Sxy150489  * revision in the hardware structure.
88*5779Sxy150489  */
89*5779Sxy150489 s32
90*5779Sxy150489 e1000_get_phy_id(struct e1000_hw *hw)
91*5779Sxy150489 {
92*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
93*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
94*5779Sxy150489 	u16 phy_id;
95*5779Sxy150489 
96*5779Sxy150489 	DEBUGFUNC("e1000_get_phy_id");
97*5779Sxy150489 
98*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id);
99*5779Sxy150489 	if (ret_val)
100*5779Sxy150489 		goto out;
101*5779Sxy150489 
102*5779Sxy150489 	phy->id = (u32)(phy_id << 16);
103*5779Sxy150489 	usec_delay(20);
104*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id);
105*5779Sxy150489 	if (ret_val)
106*5779Sxy150489 		goto out;
107*5779Sxy150489 
108*5779Sxy150489 	phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
109*5779Sxy150489 	phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
110*5779Sxy150489 
111*5779Sxy150489 out:
112*5779Sxy150489 	return (ret_val);
113*5779Sxy150489 }
114*5779Sxy150489 
115*5779Sxy150489 /*
116*5779Sxy150489  * e1000_phy_reset_dsp_generic - Reset PHY DSP
117*5779Sxy150489  * @hw: pointer to the HW structure
118*5779Sxy150489  *
119*5779Sxy150489  * Reset the digital signal processor.
120*5779Sxy150489  */
121*5779Sxy150489 s32
122*5779Sxy150489 e1000_phy_reset_dsp_generic(struct e1000_hw *hw)
123*5779Sxy150489 {
124*5779Sxy150489 	s32 ret_val;
125*5779Sxy150489 
126*5779Sxy150489 	DEBUGFUNC("e1000_phy_reset_dsp_generic");
127*5779Sxy150489 
128*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
129*5779Sxy150489 	if (ret_val)
130*5779Sxy150489 		goto out;
131*5779Sxy150489 
132*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
133*5779Sxy150489 
134*5779Sxy150489 out:
135*5779Sxy150489 	return (ret_val);
136*5779Sxy150489 }
137*5779Sxy150489 
138*5779Sxy150489 /*
139*5779Sxy150489  * e1000_read_phy_reg_mdic - Read MDI control register
140*5779Sxy150489  * @hw: pointer to the HW structure
141*5779Sxy150489  * @offset: register offset to be read
142*5779Sxy150489  * @data: pointer to the read data
143*5779Sxy150489  *
144*5779Sxy150489  * Reads the MDI control regsiter in the PHY at offset and stores the
145*5779Sxy150489  * information read to data.
146*5779Sxy150489  */
147*5779Sxy150489 s32
148*5779Sxy150489 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
149*5779Sxy150489 {
150*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
151*5779Sxy150489 	u32 i, mdic = 0;
152*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
153*5779Sxy150489 
154*5779Sxy150489 	DEBUGFUNC("e1000_read_phy_reg_mdic");
155*5779Sxy150489 
156*5779Sxy150489 	if (offset > MAX_PHY_REG_ADDRESS) {
157*5779Sxy150489 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
158*5779Sxy150489 		ret_val = -E1000_ERR_PARAM;
159*5779Sxy150489 		goto out;
160*5779Sxy150489 	}
161*5779Sxy150489 
162*5779Sxy150489 	/*
163*5779Sxy150489 	 * Set up Op-code, Phy Address, and register offset in the MDI
164*5779Sxy150489 	 * Control register.  The MAC will take care of interfacing with the
165*5779Sxy150489 	 * PHY to retrieve the desired data.
166*5779Sxy150489 	 */
167*5779Sxy150489 	mdic = ((offset << E1000_MDIC_REG_SHIFT) |
168*5779Sxy150489 	    (phy->addr << E1000_MDIC_PHY_SHIFT) |
169*5779Sxy150489 	    (E1000_MDIC_OP_READ));
170*5779Sxy150489 
171*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_MDIC, mdic);
172*5779Sxy150489 
173*5779Sxy150489 	/*
174*5779Sxy150489 	 * Poll the ready bit to see if the MDI read completed
175*5779Sxy150489 	 * Increasing the time out as testing showed failures with
176*5779Sxy150489 	 * the lower time out
177*5779Sxy150489 	 */
178*5779Sxy150489 	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
179*5779Sxy150489 		usec_delay(50);
180*5779Sxy150489 		mdic = E1000_READ_REG(hw, E1000_MDIC);
181*5779Sxy150489 		if (mdic & E1000_MDIC_READY)
182*5779Sxy150489 			break;
183*5779Sxy150489 	}
184*5779Sxy150489 	if (!(mdic & E1000_MDIC_READY)) {
185*5779Sxy150489 		DEBUGOUT("MDI Read did not complete\n");
186*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
187*5779Sxy150489 		goto out;
188*5779Sxy150489 	}
189*5779Sxy150489 	if (mdic & E1000_MDIC_ERROR) {
190*5779Sxy150489 		DEBUGOUT("MDI Error\n");
191*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
192*5779Sxy150489 		goto out;
193*5779Sxy150489 	}
194*5779Sxy150489 	*data = (u16) mdic;
195*5779Sxy150489 
196*5779Sxy150489 out:
197*5779Sxy150489 	return (ret_val);
198*5779Sxy150489 }
199*5779Sxy150489 
200*5779Sxy150489 /*
201*5779Sxy150489  * e1000_write_phy_reg_mdic - Write MDI control register
202*5779Sxy150489  * @hw: pointer to the HW structure
203*5779Sxy150489  * @offset: register offset to write to
204*5779Sxy150489  * @data: data to write to register at offset
205*5779Sxy150489  *
206*5779Sxy150489  * Writes data to MDI control register in the PHY at offset.
207*5779Sxy150489  */
208*5779Sxy150489 s32
209*5779Sxy150489 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
210*5779Sxy150489 {
211*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
212*5779Sxy150489 	u32 i, mdic = 0;
213*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
214*5779Sxy150489 
215*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_mdic");
216*5779Sxy150489 
217*5779Sxy150489 	if (offset > MAX_PHY_REG_ADDRESS) {
218*5779Sxy150489 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
219*5779Sxy150489 		ret_val = -E1000_ERR_PARAM;
220*5779Sxy150489 		goto out;
221*5779Sxy150489 	}
222*5779Sxy150489 
223*5779Sxy150489 	/*
224*5779Sxy150489 	 * Set up Op-code, Phy Address, and register offset in the MDI
225*5779Sxy150489 	 * Control register.  The MAC will take care of interfacing with the
226*5779Sxy150489 	 * PHY to retrieve the desired data.
227*5779Sxy150489 	 */
228*5779Sxy150489 	mdic = (((u32)data) |
229*5779Sxy150489 	    (offset << E1000_MDIC_REG_SHIFT) |
230*5779Sxy150489 	    (phy->addr << E1000_MDIC_PHY_SHIFT) |
231*5779Sxy150489 	    (E1000_MDIC_OP_WRITE));
232*5779Sxy150489 
233*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_MDIC, mdic);
234*5779Sxy150489 
235*5779Sxy150489 	/*
236*5779Sxy150489 	 * Poll the ready bit to see if the MDI read completed
237*5779Sxy150489 	 * Increasing the time out as testing showed failures with
238*5779Sxy150489 	 * the lower time out
239*5779Sxy150489 	 */
240*5779Sxy150489 	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
241*5779Sxy150489 		usec_delay(50);
242*5779Sxy150489 		mdic = E1000_READ_REG(hw, E1000_MDIC);
243*5779Sxy150489 		if (mdic & E1000_MDIC_READY)
244*5779Sxy150489 			break;
245*5779Sxy150489 	}
246*5779Sxy150489 	if (!(mdic & E1000_MDIC_READY)) {
247*5779Sxy150489 		DEBUGOUT("MDI Write did not complete\n");
248*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
249*5779Sxy150489 		goto out;
250*5779Sxy150489 	}
251*5779Sxy150489 	if (mdic & E1000_MDIC_ERROR) {
252*5779Sxy150489 		DEBUGOUT("MDI Error\n");
253*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
254*5779Sxy150489 		goto out;
255*5779Sxy150489 	}
256*5779Sxy150489 
257*5779Sxy150489 out:
258*5779Sxy150489 	return (ret_val);
259*5779Sxy150489 }
260*5779Sxy150489 
261*5779Sxy150489 /*
262*5779Sxy150489  * e1000_read_phy_reg_m88 - Read m88 PHY register
263*5779Sxy150489  * @hw: pointer to the HW structure
264*5779Sxy150489  * @offset: register offset to be read
265*5779Sxy150489  * @data: pointer to the read data
266*5779Sxy150489  *
267*5779Sxy150489  * Acquires semaphore, if necessary, then reads the PHY register at offset
268*5779Sxy150489  * and storing the retrieved information in data.  Release any acquired
269*5779Sxy150489  * semaphores before exiting.
270*5779Sxy150489  */
271*5779Sxy150489 s32
272*5779Sxy150489 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
273*5779Sxy150489 {
274*5779Sxy150489 	s32 ret_val;
275*5779Sxy150489 
276*5779Sxy150489 	DEBUGFUNC("e1000_read_phy_reg_m88");
277*5779Sxy150489 
278*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
279*5779Sxy150489 	if (ret_val)
280*5779Sxy150489 		goto out;
281*5779Sxy150489 
282*5779Sxy150489 	ret_val = e1000_read_phy_reg_mdic(hw,
283*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset, data);
284*5779Sxy150489 
285*5779Sxy150489 	e1000_release_phy(hw);
286*5779Sxy150489 
287*5779Sxy150489 out:
288*5779Sxy150489 	return (ret_val);
289*5779Sxy150489 }
290*5779Sxy150489 
291*5779Sxy150489 /*
292*5779Sxy150489  * e1000_write_phy_reg_m88 - Write m88 PHY register
293*5779Sxy150489  * @hw: pointer to the HW structure
294*5779Sxy150489  * @offset: register offset to write to
295*5779Sxy150489  * @data: data to write at register offset
296*5779Sxy150489  *
297*5779Sxy150489  * Acquires semaphore, if necessary, then writes the data to PHY register
298*5779Sxy150489  * at the offset.  Release any acquired semaphores before exiting.
299*5779Sxy150489  */
300*5779Sxy150489 s32
301*5779Sxy150489 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
302*5779Sxy150489 {
303*5779Sxy150489 	s32 ret_val;
304*5779Sxy150489 
305*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_m88");
306*5779Sxy150489 
307*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
308*5779Sxy150489 	if (ret_val)
309*5779Sxy150489 		goto out;
310*5779Sxy150489 
311*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw,
312*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset, data);
313*5779Sxy150489 
314*5779Sxy150489 	e1000_release_phy(hw);
315*5779Sxy150489 
316*5779Sxy150489 out:
317*5779Sxy150489 	return (ret_val);
318*5779Sxy150489 }
319*5779Sxy150489 
320*5779Sxy150489 /*
321*5779Sxy150489  * e1000_read_phy_reg_igp - Read igp PHY register
322*5779Sxy150489  * @hw: pointer to the HW structure
323*5779Sxy150489  * @offset: register offset to be read
324*5779Sxy150489  * @data: pointer to the read data
325*5779Sxy150489  *
326*5779Sxy150489  * Acquires semaphore, if necessary, then reads the PHY register at offset
327*5779Sxy150489  * and storing the retrieved information in data.  Release any acquired
328*5779Sxy150489  * semaphores before exiting.
329*5779Sxy150489  */
330*5779Sxy150489 s32
331*5779Sxy150489 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
332*5779Sxy150489 {
333*5779Sxy150489 	s32 ret_val;
334*5779Sxy150489 
335*5779Sxy150489 	DEBUGFUNC("e1000_read_phy_reg_igp");
336*5779Sxy150489 
337*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
338*5779Sxy150489 	if (ret_val)
339*5779Sxy150489 		goto out;
340*5779Sxy150489 
341*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
342*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw,
343*5779Sxy150489 		    IGP01E1000_PHY_PAGE_SELECT, (u16)offset);
344*5779Sxy150489 		if (ret_val) {
345*5779Sxy150489 			e1000_release_phy(hw);
346*5779Sxy150489 			goto out;
347*5779Sxy150489 		}
348*5779Sxy150489 	}
349*5779Sxy150489 
350*5779Sxy150489 	ret_val = e1000_read_phy_reg_mdic(hw,
351*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset, data);
352*5779Sxy150489 
353*5779Sxy150489 	e1000_release_phy(hw);
354*5779Sxy150489 
355*5779Sxy150489 out:
356*5779Sxy150489 	return (ret_val);
357*5779Sxy150489 }
358*5779Sxy150489 
359*5779Sxy150489 /*
360*5779Sxy150489  * e1000_write_phy_reg_igp - Write igp PHY register
361*5779Sxy150489  * @hw: pointer to the HW structure
362*5779Sxy150489  * @offset: register offset to write to
363*5779Sxy150489  * @data: data to write at register offset
364*5779Sxy150489  *
365*5779Sxy150489  * Acquires semaphore, if necessary, then writes the data to PHY register
366*5779Sxy150489  * at the offset.  Release any acquired semaphores before exiting.
367*5779Sxy150489  */
368*5779Sxy150489 s32
369*5779Sxy150489 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
370*5779Sxy150489 {
371*5779Sxy150489 	s32 ret_val;
372*5779Sxy150489 
373*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_igp");
374*5779Sxy150489 
375*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
376*5779Sxy150489 	if (ret_val)
377*5779Sxy150489 		goto out;
378*5779Sxy150489 
379*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
380*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw,
381*5779Sxy150489 		    IGP01E1000_PHY_PAGE_SELECT, (u16)offset);
382*5779Sxy150489 		if (ret_val) {
383*5779Sxy150489 			e1000_release_phy(hw);
384*5779Sxy150489 			goto out;
385*5779Sxy150489 		}
386*5779Sxy150489 	}
387*5779Sxy150489 
388*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw,
389*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset, data);
390*5779Sxy150489 
391*5779Sxy150489 	e1000_release_phy(hw);
392*5779Sxy150489 
393*5779Sxy150489 out:
394*5779Sxy150489 	return (ret_val);
395*5779Sxy150489 }
396*5779Sxy150489 
397*5779Sxy150489 /*
398*5779Sxy150489  * e1000_read_kmrn_reg_generic - Read kumeran register
399*5779Sxy150489  * @hw: pointer to the HW structure
400*5779Sxy150489  * @offset: register offset to be read
401*5779Sxy150489  * @data: pointer to the read data
402*5779Sxy150489  *
403*5779Sxy150489  * Acquires semaphore, if necessary.  Then reads the PHY register at offset
404*5779Sxy150489  * using the kumeran interface.  The information retrieved is stored in data.
405*5779Sxy150489  * Release any acquired semaphores before exiting.
406*5779Sxy150489  */
407*5779Sxy150489 s32
408*5779Sxy150489 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data)
409*5779Sxy150489 {
410*5779Sxy150489 	u32 kmrnctrlsta;
411*5779Sxy150489 	s32 ret_val;
412*5779Sxy150489 
413*5779Sxy150489 	DEBUGFUNC("e1000_read_kmrn_reg_generic");
414*5779Sxy150489 
415*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
416*5779Sxy150489 	if (ret_val)
417*5779Sxy150489 		goto out;
418*5779Sxy150489 
419*5779Sxy150489 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
420*5779Sxy150489 	    E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
421*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
422*5779Sxy150489 
423*5779Sxy150489 	usec_delay(2);
424*5779Sxy150489 
425*5779Sxy150489 	kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
426*5779Sxy150489 	*data = (u16)kmrnctrlsta;
427*5779Sxy150489 
428*5779Sxy150489 	e1000_release_phy(hw);
429*5779Sxy150489 
430*5779Sxy150489 out:
431*5779Sxy150489 	return (ret_val);
432*5779Sxy150489 }
433*5779Sxy150489 
434*5779Sxy150489 /*
435*5779Sxy150489  * e1000_write_kmrn_reg_generic - Write kumeran register
436*5779Sxy150489  * @hw: pointer to the HW structure
437*5779Sxy150489  * @offset: register offset to write to
438*5779Sxy150489  * @data: data to write at register offset
439*5779Sxy150489  *
440*5779Sxy150489  * Acquires semaphore, if necessary.  Then write the data to PHY register
441*5779Sxy150489  * at the offset using the kumeran interface.  Release any acquired semaphores
442*5779Sxy150489  * before exiting.
443*5779Sxy150489  */
444*5779Sxy150489 s32
445*5779Sxy150489 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
446*5779Sxy150489 {
447*5779Sxy150489 	u32 kmrnctrlsta;
448*5779Sxy150489 	s32 ret_val;
449*5779Sxy150489 
450*5779Sxy150489 	DEBUGFUNC("e1000_write_kmrn_reg_generic");
451*5779Sxy150489 
452*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
453*5779Sxy150489 	if (ret_val)
454*5779Sxy150489 		goto out;
455*5779Sxy150489 
456*5779Sxy150489 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
457*5779Sxy150489 	    E1000_KMRNCTRLSTA_OFFSET) | data;
458*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
459*5779Sxy150489 
460*5779Sxy150489 	usec_delay(2);
461*5779Sxy150489 	e1000_release_phy(hw);
462*5779Sxy150489 
463*5779Sxy150489 out:
464*5779Sxy150489 	return (ret_val);
465*5779Sxy150489 }
466*5779Sxy150489 
467*5779Sxy150489 /*
468*5779Sxy150489  * e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
469*5779Sxy150489  * @hw: pointer to the HW structure
470*5779Sxy150489  *
471*5779Sxy150489  * Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
472*5779Sxy150489  * and downshift values are set also.
473*5779Sxy150489  */
474*5779Sxy150489 s32
475*5779Sxy150489 e1000_copper_link_setup_m88(struct e1000_hw *hw)
476*5779Sxy150489 {
477*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
478*5779Sxy150489 	s32 ret_val;
479*5779Sxy150489 	u16 phy_data;
480*5779Sxy150489 
481*5779Sxy150489 	DEBUGFUNC("e1000_copper_link_setup_m88");
482*5779Sxy150489 
483*5779Sxy150489 	if (phy->reset_disable) {
484*5779Sxy150489 		ret_val = E1000_SUCCESS;
485*5779Sxy150489 		goto out;
486*5779Sxy150489 	}
487*5779Sxy150489 
488*5779Sxy150489 	/* Enable CRS on TX. This must be set for half-duplex operation. */
489*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
490*5779Sxy150489 	if (ret_val)
491*5779Sxy150489 		goto out;
492*5779Sxy150489 
493*5779Sxy150489 	/* For newer PHYs this bit is downshift enable */
494*5779Sxy150489 	if (phy->type == e1000_phy_m88)
495*5779Sxy150489 		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
496*5779Sxy150489 
497*5779Sxy150489 	/*
498*5779Sxy150489 	 * Options:
499*5779Sxy150489 	 *   MDI/MDI-X = 0 (default)
500*5779Sxy150489 	 *   0 - Auto for all speeds
501*5779Sxy150489 	 *   1 - MDI mode
502*5779Sxy150489 	 *   2 - MDI-X mode
503*5779Sxy150489 	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
504*5779Sxy150489 	 */
505*5779Sxy150489 	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
506*5779Sxy150489 
507*5779Sxy150489 	switch (phy->mdix) {
508*5779Sxy150489 		case 1:
509*5779Sxy150489 			phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
510*5779Sxy150489 			break;
511*5779Sxy150489 		case 2:
512*5779Sxy150489 			phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
513*5779Sxy150489 			break;
514*5779Sxy150489 		case 3:
515*5779Sxy150489 			phy_data |= M88E1000_PSCR_AUTO_X_1000T;
516*5779Sxy150489 			break;
517*5779Sxy150489 		case 0:
518*5779Sxy150489 		default:
519*5779Sxy150489 			phy_data |= M88E1000_PSCR_AUTO_X_MODE;
520*5779Sxy150489 			break;
521*5779Sxy150489 	}
522*5779Sxy150489 
523*5779Sxy150489 	/*
524*5779Sxy150489 	 * Options:
525*5779Sxy150489 	 *   disable_polarity_correction = 0 (default)
526*5779Sxy150489 	 *	Automatic Correction for Reversed Cable Polarity
527*5779Sxy150489 	 *   0 - Disabled
528*5779Sxy150489 	 *   1 - Enabled
529*5779Sxy150489 	 */
530*5779Sxy150489 	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
531*5779Sxy150489 	if (phy->disable_polarity_correction == 1)
532*5779Sxy150489 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
533*5779Sxy150489 
534*5779Sxy150489 	/* Enable downshift on BM (disabled by default) */
535*5779Sxy150489 	if (phy->type == e1000_phy_bm)
536*5779Sxy150489 		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
537*5779Sxy150489 
538*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
539*5779Sxy150489 	if (ret_val)
540*5779Sxy150489 		goto out;
541*5779Sxy150489 
542*5779Sxy150489 	if ((phy->type == e1000_phy_m88) &&
543*5779Sxy150489 	    (phy->revision < E1000_REVISION_4) &&
544*5779Sxy150489 	    (phy->id != BME1000_E_PHY_ID_R2)) {
545*5779Sxy150489 		/*
546*5779Sxy150489 		 * Force TX_CLK in the Extended PHY Specific Control Register
547*5779Sxy150489 		 * to 25MHz clock.
548*5779Sxy150489 		 */
549*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw,
550*5779Sxy150489 		    M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
551*5779Sxy150489 		if (ret_val)
552*5779Sxy150489 			goto out;
553*5779Sxy150489 
554*5779Sxy150489 		phy_data |= M88E1000_EPSCR_TX_CLK_25;
555*5779Sxy150489 
556*5779Sxy150489 		if ((phy->revision == E1000_REVISION_2) &&
557*5779Sxy150489 		    (phy->id == M88E1111_I_PHY_ID)) {
558*5779Sxy150489 			/* 82573L PHY - set the downshift counter to 5x. */
559*5779Sxy150489 			phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
560*5779Sxy150489 			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
561*5779Sxy150489 		} else {
562*5779Sxy150489 			/* Configure Master and Slave downshift values */
563*5779Sxy150489 			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
564*5779Sxy150489 			    M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
565*5779Sxy150489 			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
566*5779Sxy150489 			    M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
567*5779Sxy150489 		}
568*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
569*5779Sxy150489 		    M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
570*5779Sxy150489 		if (ret_val)
571*5779Sxy150489 			goto out;
572*5779Sxy150489 	}
573*5779Sxy150489 
574*5779Sxy150489 	/* Commit the changes. */
575*5779Sxy150489 	ret_val = e1000_phy_commit(hw);
576*5779Sxy150489 	if (ret_val) {
577*5779Sxy150489 		DEBUGOUT("Error committing the PHY changes\n");
578*5779Sxy150489 		goto out;
579*5779Sxy150489 	}
580*5779Sxy150489 
581*5779Sxy150489 out:
582*5779Sxy150489 	return (ret_val);
583*5779Sxy150489 }
584*5779Sxy150489 
585*5779Sxy150489 /*
586*5779Sxy150489  * e1000_copper_link_setup_igp - Setup igp PHY's for copper link
587*5779Sxy150489  * @hw: pointer to the HW structure
588*5779Sxy150489  *
589*5779Sxy150489  * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
590*5779Sxy150489  * igp PHY's.
591*5779Sxy150489  */
592*5779Sxy150489 s32
593*5779Sxy150489 e1000_copper_link_setup_igp(struct e1000_hw *hw)
594*5779Sxy150489 {
595*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
596*5779Sxy150489 	s32 ret_val;
597*5779Sxy150489 	u16 data;
598*5779Sxy150489 
599*5779Sxy150489 	DEBUGFUNC("e1000_copper_link_setup_igp");
600*5779Sxy150489 
601*5779Sxy150489 	if (phy->reset_disable) {
602*5779Sxy150489 		ret_val = E1000_SUCCESS;
603*5779Sxy150489 		goto out;
604*5779Sxy150489 	}
605*5779Sxy150489 
606*5779Sxy150489 	ret_val = e1000_phy_hw_reset(hw);
607*5779Sxy150489 	if (ret_val) {
608*5779Sxy150489 		DEBUGOUT("Error resetting the PHY.\n");
609*5779Sxy150489 		goto out;
610*5779Sxy150489 	}
611*5779Sxy150489 
612*5779Sxy150489 	/* Wait 15ms for MAC to configure PHY from NVM settings. */
613*5779Sxy150489 	msec_delay(15);
614*5779Sxy150489 
615*5779Sxy150489 	/*
616*5779Sxy150489 	 * The NVM settings will configure LPLU in D3 for
617*5779Sxy150489 	 * non-IGP1 PHYs.
618*5779Sxy150489 	 */
619*5779Sxy150489 	if (phy->type == e1000_phy_igp) {
620*5779Sxy150489 		/* disable lplu d3 during driver init */
621*5779Sxy150489 		ret_val = e1000_set_d3_lplu_state(hw, FALSE);
622*5779Sxy150489 		if (ret_val) {
623*5779Sxy150489 			DEBUGOUT("Error Disabling LPLU D3\n");
624*5779Sxy150489 			goto out;
625*5779Sxy150489 		}
626*5779Sxy150489 	}
627*5779Sxy150489 
628*5779Sxy150489 	/* disable lplu d0 during driver init */
629*5779Sxy150489 	ret_val = e1000_set_d0_lplu_state(hw, FALSE);
630*5779Sxy150489 	if (ret_val) {
631*5779Sxy150489 		DEBUGOUT("Error Disabling LPLU D0\n");
632*5779Sxy150489 		goto out;
633*5779Sxy150489 	}
634*5779Sxy150489 	/* Configure mdi-mdix settings */
635*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
636*5779Sxy150489 	if (ret_val)
637*5779Sxy150489 		goto out;
638*5779Sxy150489 
639*5779Sxy150489 	data &= ~IGP01E1000_PSCR_AUTO_MDIX;
640*5779Sxy150489 
641*5779Sxy150489 	switch (phy->mdix) {
642*5779Sxy150489 	case 1:
643*5779Sxy150489 		data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
644*5779Sxy150489 		break;
645*5779Sxy150489 	case 2:
646*5779Sxy150489 		data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
647*5779Sxy150489 		break;
648*5779Sxy150489 	case 0:
649*5779Sxy150489 	default:
650*5779Sxy150489 		data |= IGP01E1000_PSCR_AUTO_MDIX;
651*5779Sxy150489 		break;
652*5779Sxy150489 	}
653*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
654*5779Sxy150489 	if (ret_val)
655*5779Sxy150489 		goto out;
656*5779Sxy150489 
657*5779Sxy150489 	/* set auto-master slave resolution settings */
658*5779Sxy150489 	if (hw->mac.autoneg) {
659*5779Sxy150489 		/*
660*5779Sxy150489 		 * when autonegotiation advertisement is only 1000Mbps then we
661*5779Sxy150489 		 * should disable SmartSpeed and enable Auto MasterSlave
662*5779Sxy150489 		 * resolution as hardware default.
663*5779Sxy150489 		 */
664*5779Sxy150489 		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
665*5779Sxy150489 			/* Disable SmartSpeed */
666*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw,
667*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG, &data);
668*5779Sxy150489 			if (ret_val)
669*5779Sxy150489 				goto out;
670*5779Sxy150489 
671*5779Sxy150489 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
672*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
673*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG, data);
674*5779Sxy150489 			if (ret_val)
675*5779Sxy150489 				goto out;
676*5779Sxy150489 
677*5779Sxy150489 			/* Set auto Master/Slave resolution process */
678*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data);
679*5779Sxy150489 			if (ret_val)
680*5779Sxy150489 				goto out;
681*5779Sxy150489 
682*5779Sxy150489 			data &= ~CR_1000T_MS_ENABLE;
683*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data);
684*5779Sxy150489 			if (ret_val)
685*5779Sxy150489 				goto out;
686*5779Sxy150489 		}
687*5779Sxy150489 
688*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data);
689*5779Sxy150489 		if (ret_val)
690*5779Sxy150489 			goto out;
691*5779Sxy150489 
692*5779Sxy150489 		/* load defaults for future use */
693*5779Sxy150489 		phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ?
694*5779Sxy150489 		    ((data & CR_1000T_MS_VALUE) ?
695*5779Sxy150489 		    e1000_ms_force_master :
696*5779Sxy150489 		    e1000_ms_force_slave) :
697*5779Sxy150489 		    e1000_ms_auto;
698*5779Sxy150489 
699*5779Sxy150489 		switch (phy->ms_type) {
700*5779Sxy150489 		case e1000_ms_force_master:
701*5779Sxy150489 			data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
702*5779Sxy150489 			break;
703*5779Sxy150489 		case e1000_ms_force_slave:
704*5779Sxy150489 			data |= CR_1000T_MS_ENABLE;
705*5779Sxy150489 			data &= ~(CR_1000T_MS_VALUE);
706*5779Sxy150489 			break;
707*5779Sxy150489 		case e1000_ms_auto:
708*5779Sxy150489 			data &= ~CR_1000T_MS_ENABLE;
709*5779Sxy150489 		default:
710*5779Sxy150489 			break;
711*5779Sxy150489 		}
712*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data);
713*5779Sxy150489 		if (ret_val)
714*5779Sxy150489 			goto out;
715*5779Sxy150489 	}
716*5779Sxy150489 
717*5779Sxy150489 out:
718*5779Sxy150489 	return (ret_val);
719*5779Sxy150489 }
720*5779Sxy150489 
721*5779Sxy150489 /*
722*5779Sxy150489  * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
723*5779Sxy150489  * @hw: pointer to the HW structure
724*5779Sxy150489  *
725*5779Sxy150489  * Performs initial bounds checking on autoneg advertisement parameter, then
726*5779Sxy150489  * configure to advertise the full capability.  Setup the PHY to autoneg
727*5779Sxy150489  * and restart the negotiation process between the link partner.  If
728*5779Sxy150489  * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
729*5779Sxy150489  */
730*5779Sxy150489 s32
731*5779Sxy150489 e1000_copper_link_autoneg(struct e1000_hw *hw)
732*5779Sxy150489 {
733*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
734*5779Sxy150489 	s32 ret_val;
735*5779Sxy150489 	u16 phy_ctrl;
736*5779Sxy150489 
737*5779Sxy150489 	DEBUGFUNC("e1000_copper_link_autoneg");
738*5779Sxy150489 
739*5779Sxy150489 	/*
740*5779Sxy150489 	 * Perform some bounds checking on the autoneg advertisement
741*5779Sxy150489 	 * parameter.
742*5779Sxy150489 	 */
743*5779Sxy150489 	phy->autoneg_advertised &= phy->autoneg_mask;
744*5779Sxy150489 
745*5779Sxy150489 	/*
746*5779Sxy150489 	 * If autoneg_advertised is zero, we assume it was not defaulted
747*5779Sxy150489 	 * by the calling code so we set to advertise full capability.
748*5779Sxy150489 	 */
749*5779Sxy150489 	if (phy->autoneg_advertised == 0)
750*5779Sxy150489 		phy->autoneg_advertised = phy->autoneg_mask;
751*5779Sxy150489 
752*5779Sxy150489 	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
753*5779Sxy150489 	ret_val = e1000_phy_setup_autoneg(hw);
754*5779Sxy150489 	if (ret_val) {
755*5779Sxy150489 		DEBUGOUT("Error Setting up Auto-Negotiation\n");
756*5779Sxy150489 		goto out;
757*5779Sxy150489 	}
758*5779Sxy150489 	DEBUGOUT("Restarting Auto-Neg\n");
759*5779Sxy150489 
760*5779Sxy150489 	/*
761*5779Sxy150489 	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
762*5779Sxy150489 	 * the Auto Neg Restart bit in the PHY control register.
763*5779Sxy150489 	 */
764*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
765*5779Sxy150489 	if (ret_val)
766*5779Sxy150489 		goto out;
767*5779Sxy150489 
768*5779Sxy150489 	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
769*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
770*5779Sxy150489 	if (ret_val)
771*5779Sxy150489 		goto out;
772*5779Sxy150489 
773*5779Sxy150489 	/*
774*5779Sxy150489 	 * Does the user want to wait for Auto-Neg to complete here, or
775*5779Sxy150489 	 * check at a later time (for example, callback routine).
776*5779Sxy150489 	 */
777*5779Sxy150489 	if (phy->autoneg_wait_to_complete) {
778*5779Sxy150489 		ret_val = e1000_wait_autoneg(hw);
779*5779Sxy150489 		if (ret_val) {
780*5779Sxy150489 			DEBUGOUT("Error while waiting for "
781*5779Sxy150489 			    "autoneg to complete\n");
782*5779Sxy150489 			goto out;
783*5779Sxy150489 		}
784*5779Sxy150489 	}
785*5779Sxy150489 
786*5779Sxy150489 	hw->mac.get_link_status = TRUE;
787*5779Sxy150489 
788*5779Sxy150489 out:
789*5779Sxy150489 	return (ret_val);
790*5779Sxy150489 }
791*5779Sxy150489 
792*5779Sxy150489 /*
793*5779Sxy150489  * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
794*5779Sxy150489  * @hw: pointer to the HW structure
795*5779Sxy150489  *
796*5779Sxy150489  * Reads the MII auto-neg advertisement register and/or the 1000T control
797*5779Sxy150489  * register and if the PHY is already setup for auto-negotiation, then
798*5779Sxy150489  * return successful.  Otherwise, setup advertisement and flow control to
799*5779Sxy150489  * the appropriate values for the wanted auto-negotiation.
800*5779Sxy150489  */
801*5779Sxy150489 s32
802*5779Sxy150489 e1000_phy_setup_autoneg(struct e1000_hw *hw)
803*5779Sxy150489 {
804*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
805*5779Sxy150489 	s32 ret_val;
806*5779Sxy150489 	u16 mii_autoneg_adv_reg;
807*5779Sxy150489 	u16 mii_1000t_ctrl_reg = 0;
808*5779Sxy150489 
809*5779Sxy150489 	DEBUGFUNC("e1000_phy_setup_autoneg");
810*5779Sxy150489 
811*5779Sxy150489 	phy->autoneg_advertised &= phy->autoneg_mask;
812*5779Sxy150489 
813*5779Sxy150489 	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
814*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
815*5779Sxy150489 	if (ret_val)
816*5779Sxy150489 		goto out;
817*5779Sxy150489 
818*5779Sxy150489 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
819*5779Sxy150489 		/* Read the MII 1000Base-T Control Register (Address 9). */
820*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw,
821*5779Sxy150489 		    PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
822*5779Sxy150489 		if (ret_val)
823*5779Sxy150489 			goto out;
824*5779Sxy150489 	}
825*5779Sxy150489 
826*5779Sxy150489 	/*
827*5779Sxy150489 	 * Need to parse both autoneg_advertised and fc and set up
828*5779Sxy150489 	 * the appropriate PHY registers.  First we will parse for
829*5779Sxy150489 	 * autoneg_advertised software override.  Since we can advertise
830*5779Sxy150489 	 * a plethora of combinations, we need to check each bit
831*5779Sxy150489 	 * individually.
832*5779Sxy150489 	 */
833*5779Sxy150489 
834*5779Sxy150489 	/*
835*5779Sxy150489 	 * First we clear all the 10/100 mb speed bits in the Auto-Neg
836*5779Sxy150489 	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
837*5779Sxy150489 	 * the  1000Base-T Control Register (Address 9).
838*5779Sxy150489 	 */
839*5779Sxy150489 	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
840*5779Sxy150489 	    NWAY_AR_100TX_HD_CAPS |
841*5779Sxy150489 	    NWAY_AR_10T_FD_CAPS   |
842*5779Sxy150489 	    NWAY_AR_10T_HD_CAPS);
843*5779Sxy150489 	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
844*5779Sxy150489 
845*5779Sxy150489 	DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
846*5779Sxy150489 
847*5779Sxy150489 	/* Do we want to advertise 10 Mb Half Duplex? */
848*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
849*5779Sxy150489 		DEBUGOUT("Advertise 10mb Half duplex\n");
850*5779Sxy150489 		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
851*5779Sxy150489 	}
852*5779Sxy150489 
853*5779Sxy150489 	/* Do we want to advertise 10 Mb Full Duplex? */
854*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
855*5779Sxy150489 		DEBUGOUT("Advertise 10mb Full duplex\n");
856*5779Sxy150489 		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
857*5779Sxy150489 	}
858*5779Sxy150489 
859*5779Sxy150489 	/* Do we want to advertise 100 Mb Half Duplex? */
860*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
861*5779Sxy150489 		DEBUGOUT("Advertise 100mb Half duplex\n");
862*5779Sxy150489 		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
863*5779Sxy150489 	}
864*5779Sxy150489 
865*5779Sxy150489 	/* Do we want to advertise 100 Mb Full Duplex? */
866*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
867*5779Sxy150489 		DEBUGOUT("Advertise 100mb Full duplex\n");
868*5779Sxy150489 		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
869*5779Sxy150489 	}
870*5779Sxy150489 
871*5779Sxy150489 	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
872*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_1000_HALF) {
873*5779Sxy150489 		DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
874*5779Sxy150489 	}
875*5779Sxy150489 
876*5779Sxy150489 	/* Do we want to advertise 1000 Mb Full Duplex? */
877*5779Sxy150489 	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
878*5779Sxy150489 		DEBUGOUT("Advertise 1000mb Full duplex\n");
879*5779Sxy150489 		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
880*5779Sxy150489 	}
881*5779Sxy150489 
882*5779Sxy150489 	/*
883*5779Sxy150489 	 * Check for a software override of the flow control settings, and
884*5779Sxy150489 	 * setup the PHY advertisement registers accordingly.  If
885*5779Sxy150489 	 * auto-negotiation is enabled, then software will have to set the
886*5779Sxy150489 	 * "PAUSE" bits to the correct value in the Auto-Negotiation
887*5779Sxy150489 	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
888*5779Sxy150489 	 * negotiation.
889*5779Sxy150489 	 *
890*5779Sxy150489 	 * The possible values of the "fc" parameter are:
891*5779Sxy150489 	 * 0:	Flow control is completely disabled
892*5779Sxy150489 	 * 1:	Rx flow control is enabled (we can receive pause frames
893*5779Sxy150489 	 *	but not send pause frames).
894*5779Sxy150489 	 * 2:	Tx flow control is enabled (we can send pause frames
895*5779Sxy150489 	 *	but we do not support receiving pause frames).
896*5779Sxy150489 	 * 3:	Both Rx and Tx flow control (symmetric) are enabled.
897*5779Sxy150489 	 * other: No software override.  The flow control configuration
898*5779Sxy150489 	 *	in the EEPROM is used.
899*5779Sxy150489 	 */
900*5779Sxy150489 	switch (hw->fc.type) {
901*5779Sxy150489 	case e1000_fc_none:
902*5779Sxy150489 		/*
903*5779Sxy150489 		 * Flow control (Rx & Tx) is completely disabled by a
904*5779Sxy150489 		 * software over-ride.
905*5779Sxy150489 		 */
906*5779Sxy150489 		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
907*5779Sxy150489 		break;
908*5779Sxy150489 	case e1000_fc_rx_pause:
909*5779Sxy150489 		/*
910*5779Sxy150489 		 * Rx Flow control is enabled, and Tx Flow control is
911*5779Sxy150489 		 * disabled, by a software over-ride.
912*5779Sxy150489 		 *
913*5779Sxy150489 		 * Since there really isn't a way to advertise that we are
914*5779Sxy150489 		 * capable of Rx Pause ONLY, we will advertise that we
915*5779Sxy150489 		 * support both symmetric and asymmetric Rx PAUSE.  Later
916*5779Sxy150489 		 * (in e1000_config_fc_after_link_up) we will disable the
917*5779Sxy150489 		 * hw's ability to send PAUSE frames.
918*5779Sxy150489 		 */
919*5779Sxy150489 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
920*5779Sxy150489 		break;
921*5779Sxy150489 	case e1000_fc_tx_pause:
922*5779Sxy150489 		/*
923*5779Sxy150489 		 * Tx Flow control is enabled, and Rx Flow control is
924*5779Sxy150489 		 * disabled, by a software over-ride.
925*5779Sxy150489 		 */
926*5779Sxy150489 		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
927*5779Sxy150489 		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
928*5779Sxy150489 		break;
929*5779Sxy150489 	case e1000_fc_full:
930*5779Sxy150489 		/*
931*5779Sxy150489 		 * Flow control (both Rx and Tx) is enabled by a software
932*5779Sxy150489 		 * over-ride.
933*5779Sxy150489 		 */
934*5779Sxy150489 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
935*5779Sxy150489 		break;
936*5779Sxy150489 	default:
937*5779Sxy150489 		DEBUGOUT("Flow control param set incorrectly\n");
938*5779Sxy150489 		ret_val = -E1000_ERR_CONFIG;
939*5779Sxy150489 		goto out;
940*5779Sxy150489 	}
941*5779Sxy150489 
942*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
943*5779Sxy150489 	if (ret_val)
944*5779Sxy150489 		goto out;
945*5779Sxy150489 
946*5779Sxy150489 	DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
947*5779Sxy150489 
948*5779Sxy150489 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
949*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
950*5779Sxy150489 		    PHY_1000T_CTRL, mii_1000t_ctrl_reg);
951*5779Sxy150489 		if (ret_val)
952*5779Sxy150489 			goto out;
953*5779Sxy150489 	}
954*5779Sxy150489 
955*5779Sxy150489 out:
956*5779Sxy150489 	return (ret_val);
957*5779Sxy150489 }
958*5779Sxy150489 
959*5779Sxy150489 /*
960*5779Sxy150489  * e1000_setup_copper_link_generic - Configure copper link settings
961*5779Sxy150489  * @hw: pointer to the HW structure
962*5779Sxy150489  *
963*5779Sxy150489  * Calls the appropriate function to configure the link for auto-neg or forced
964*5779Sxy150489  * speed and duplex.  Then we check for link, once link is established calls
965*5779Sxy150489  * to configure collision distance and flow control are called.  If link is
966*5779Sxy150489  * not established, we return -E1000_ERR_PHY (-2).
967*5779Sxy150489  */
968*5779Sxy150489 s32
969*5779Sxy150489 e1000_setup_copper_link_generic(struct e1000_hw *hw)
970*5779Sxy150489 {
971*5779Sxy150489 	s32 ret_val;
972*5779Sxy150489 	bool link;
973*5779Sxy150489 
974*5779Sxy150489 	DEBUGFUNC("e1000_setup_copper_link_generic");
975*5779Sxy150489 
976*5779Sxy150489 	if (hw->mac.autoneg) {
977*5779Sxy150489 		/*
978*5779Sxy150489 		 * Setup autoneg and flow control advertisement and perform
979*5779Sxy150489 		 * autonegotiation.
980*5779Sxy150489 		 */
981*5779Sxy150489 		ret_val = e1000_copper_link_autoneg(hw);
982*5779Sxy150489 		if (ret_val)
983*5779Sxy150489 			goto out;
984*5779Sxy150489 	} else {
985*5779Sxy150489 		/*
986*5779Sxy150489 		 * PHY will be set to 10H, 10F, 100H or 100F
987*5779Sxy150489 		 * depending on user settings.
988*5779Sxy150489 		 */
989*5779Sxy150489 		DEBUGOUT("Forcing Speed and Duplex\n");
990*5779Sxy150489 		ret_val = e1000_phy_force_speed_duplex(hw);
991*5779Sxy150489 		if (ret_val) {
992*5779Sxy150489 			DEBUGOUT("Error Forcing Speed and Duplex\n");
993*5779Sxy150489 			goto out;
994*5779Sxy150489 		}
995*5779Sxy150489 	}
996*5779Sxy150489 
997*5779Sxy150489 	/*
998*5779Sxy150489 	 * Check link status. Wait up to 100 microseconds for link to become
999*5779Sxy150489 	 * valid.
1000*5779Sxy150489 	 */
1001*5779Sxy150489 	ret_val = e1000_phy_has_link_generic(hw,
1002*5779Sxy150489 	    COPPER_LINK_UP_LIMIT,
1003*5779Sxy150489 	    10,
1004*5779Sxy150489 	    &link);
1005*5779Sxy150489 	if (ret_val)
1006*5779Sxy150489 		goto out;
1007*5779Sxy150489 
1008*5779Sxy150489 	if (link) {
1009*5779Sxy150489 		DEBUGOUT("Valid link established!!!\n");
1010*5779Sxy150489 		e1000_config_collision_dist_generic(hw);
1011*5779Sxy150489 		ret_val = e1000_config_fc_after_link_up_generic(hw);
1012*5779Sxy150489 	} else {
1013*5779Sxy150489 		DEBUGOUT("Unable to establish link!!!\n");
1014*5779Sxy150489 	}
1015*5779Sxy150489 
1016*5779Sxy150489 out:
1017*5779Sxy150489 	return (ret_val);
1018*5779Sxy150489 }
1019*5779Sxy150489 
1020*5779Sxy150489 /*
1021*5779Sxy150489  * e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
1022*5779Sxy150489  * @hw: pointer to the HW structure
1023*5779Sxy150489  *
1024*5779Sxy150489  * Calls the PHY setup function to force speed and duplex.  Clears the
1025*5779Sxy150489  * auto-crossover to force MDI manually.  Waits for link and returns
1026*5779Sxy150489  * successful if link up is successful, else -E1000_ERR_PHY (-2).
1027*5779Sxy150489  */
1028*5779Sxy150489 s32
1029*5779Sxy150489 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
1030*5779Sxy150489 {
1031*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1032*5779Sxy150489 	s32 ret_val;
1033*5779Sxy150489 	u16 phy_data;
1034*5779Sxy150489 	bool link;
1035*5779Sxy150489 
1036*5779Sxy150489 	DEBUGFUNC("e1000_phy_force_speed_duplex_igp");
1037*5779Sxy150489 
1038*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data);
1039*5779Sxy150489 	if (ret_val)
1040*5779Sxy150489 		goto out;
1041*5779Sxy150489 
1042*5779Sxy150489 	e1000_phy_force_speed_duplex_setup(hw, &phy_data);
1043*5779Sxy150489 
1044*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data);
1045*5779Sxy150489 	if (ret_val)
1046*5779Sxy150489 		goto out;
1047*5779Sxy150489 
1048*5779Sxy150489 	/*
1049*5779Sxy150489 	 * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
1050*5779Sxy150489 	 * forced whenever speed and duplex are forced.
1051*5779Sxy150489 	 */
1052*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
1053*5779Sxy150489 	if (ret_val)
1054*5779Sxy150489 		goto out;
1055*5779Sxy150489 
1056*5779Sxy150489 	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
1057*5779Sxy150489 	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
1058*5779Sxy150489 
1059*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
1060*5779Sxy150489 	if (ret_val)
1061*5779Sxy150489 		goto out;
1062*5779Sxy150489 
1063*5779Sxy150489 	DEBUGOUT1("IGP PSCR: %X\n", phy_data);
1064*5779Sxy150489 
1065*5779Sxy150489 	usec_delay(1);
1066*5779Sxy150489 
1067*5779Sxy150489 	if (phy->autoneg_wait_to_complete) {
1068*5779Sxy150489 		DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n");
1069*5779Sxy150489 
1070*5779Sxy150489 		ret_val = e1000_phy_has_link_generic(hw,
1071*5779Sxy150489 		    PHY_FORCE_LIMIT,
1072*5779Sxy150489 		    100000,
1073*5779Sxy150489 		    &link);
1074*5779Sxy150489 		if (ret_val)
1075*5779Sxy150489 			goto out;
1076*5779Sxy150489 
1077*5779Sxy150489 		if (!link) {
1078*5779Sxy150489 			DEBUGOUT("Link taking longer than expected.\n");
1079*5779Sxy150489 		}
1080*5779Sxy150489 
1081*5779Sxy150489 		/* Try once more */
1082*5779Sxy150489 		ret_val = e1000_phy_has_link_generic(hw,
1083*5779Sxy150489 		    PHY_FORCE_LIMIT,
1084*5779Sxy150489 		    100000,
1085*5779Sxy150489 		    &link);
1086*5779Sxy150489 		if (ret_val)
1087*5779Sxy150489 			goto out;
1088*5779Sxy150489 	}
1089*5779Sxy150489 
1090*5779Sxy150489 out:
1091*5779Sxy150489 	return (ret_val);
1092*5779Sxy150489 }
1093*5779Sxy150489 
1094*5779Sxy150489 /*
1095*5779Sxy150489  * e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
1096*5779Sxy150489  * @hw: pointer to the HW structure
1097*5779Sxy150489  *
1098*5779Sxy150489  * Calls the PHY setup function to force speed and duplex.  Clears the
1099*5779Sxy150489  * auto-crossover to force MDI manually.  Resets the PHY to commit the
1100*5779Sxy150489  * changes.  If time expires while waiting for link up, we reset the DSP.
1101*5779Sxy150489  * After reset, TX_CLK and CRS on Tx must be set.  Return successful upon
1102*5779Sxy150489  * successful completion, else return corresponding error code.
1103*5779Sxy150489  */
1104*5779Sxy150489 s32
1105*5779Sxy150489 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1106*5779Sxy150489 {
1107*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1108*5779Sxy150489 	s32 ret_val;
1109*5779Sxy150489 	u16 phy_data;
1110*5779Sxy150489 	bool link;
1111*5779Sxy150489 
1112*5779Sxy150489 	DEBUGFUNC("e1000_phy_force_speed_duplex_m88");
1113*5779Sxy150489 
1114*5779Sxy150489 	/*
1115*5779Sxy150489 	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
1116*5779Sxy150489 	 * forced whenever speed and duplex are forced.
1117*5779Sxy150489 	 */
1118*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1119*5779Sxy150489 	if (ret_val)
1120*5779Sxy150489 		goto out;
1121*5779Sxy150489 
1122*5779Sxy150489 	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
1123*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
1124*5779Sxy150489 	if (ret_val)
1125*5779Sxy150489 		goto out;
1126*5779Sxy150489 
1127*5779Sxy150489 	DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
1128*5779Sxy150489 
1129*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data);
1130*5779Sxy150489 	if (ret_val)
1131*5779Sxy150489 		goto out;
1132*5779Sxy150489 
1133*5779Sxy150489 	e1000_phy_force_speed_duplex_setup(hw, &phy_data);
1134*5779Sxy150489 
1135*5779Sxy150489 	/* Reset the phy to commit changes. */
1136*5779Sxy150489 	phy_data |= MII_CR_RESET;
1137*5779Sxy150489 
1138*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data);
1139*5779Sxy150489 	if (ret_val)
1140*5779Sxy150489 		goto out;
1141*5779Sxy150489 
1142*5779Sxy150489 	usec_delay(1);
1143*5779Sxy150489 
1144*5779Sxy150489 	if (phy->autoneg_wait_to_complete) {
1145*5779Sxy150489 		DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n");
1146*5779Sxy150489 
1147*5779Sxy150489 		ret_val = e1000_phy_has_link_generic(hw,
1148*5779Sxy150489 		    PHY_FORCE_LIMIT,
1149*5779Sxy150489 		    100000,
1150*5779Sxy150489 		    &link);
1151*5779Sxy150489 		if (ret_val)
1152*5779Sxy150489 			goto out;
1153*5779Sxy150489 
1154*5779Sxy150489 		if (!link) {
1155*5779Sxy150489 			/*
1156*5779Sxy150489 			 * We didn't get link.
1157*5779Sxy150489 			 * Reset the DSP and cross our fingers.
1158*5779Sxy150489 			 */
1159*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
1160*5779Sxy150489 			    M88E1000_PHY_PAGE_SELECT,
1161*5779Sxy150489 			    0x001d);
1162*5779Sxy150489 			if (ret_val)
1163*5779Sxy150489 				goto out;
1164*5779Sxy150489 			ret_val = e1000_phy_reset_dsp_generic(hw);
1165*5779Sxy150489 			if (ret_val)
1166*5779Sxy150489 				goto out;
1167*5779Sxy150489 		}
1168*5779Sxy150489 
1169*5779Sxy150489 		/* Try once more */
1170*5779Sxy150489 		ret_val = e1000_phy_has_link_generic(hw,
1171*5779Sxy150489 		    PHY_FORCE_LIMIT,
1172*5779Sxy150489 		    100000,
1173*5779Sxy150489 		    &link);
1174*5779Sxy150489 		if (ret_val)
1175*5779Sxy150489 			goto out;
1176*5779Sxy150489 	}
1177*5779Sxy150489 
1178*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
1179*5779Sxy150489 	if (ret_val)
1180*5779Sxy150489 		goto out;
1181*5779Sxy150489 
1182*5779Sxy150489 	/*
1183*5779Sxy150489 	 * Resetting the phy means we need to re-force TX_CLK in the
1184*5779Sxy150489 	 * Extended PHY Specific Control Register to 25MHz clock from
1185*5779Sxy150489 	 * the reset value of 2.5MHz.
1186*5779Sxy150489 	 */
1187*5779Sxy150489 	phy_data |= M88E1000_EPSCR_TX_CLK_25;
1188*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
1189*5779Sxy150489 	if (ret_val)
1190*5779Sxy150489 		goto out;
1191*5779Sxy150489 
1192*5779Sxy150489 	/*
1193*5779Sxy150489 	 * In addition, we must re-enable CRS on Tx for both half and full
1194*5779Sxy150489 	 * duplex.
1195*5779Sxy150489 	 */
1196*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1197*5779Sxy150489 	if (ret_val)
1198*5779Sxy150489 		goto out;
1199*5779Sxy150489 
1200*5779Sxy150489 	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
1201*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
1202*5779Sxy150489 
1203*5779Sxy150489 out:
1204*5779Sxy150489 	return (ret_val);
1205*5779Sxy150489 }
1206*5779Sxy150489 
1207*5779Sxy150489 /*
1208*5779Sxy150489  * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
1209*5779Sxy150489  * @hw: pointer to the HW structure
1210*5779Sxy150489  * @phy_ctrl: pointer to current value of PHY_CONTROL
1211*5779Sxy150489  *
1212*5779Sxy150489  * Forces speed and duplex on the PHY by doing the following: disable flow
1213*5779Sxy150489  * control, force speed/duplex on the MAC, disable auto speed detection,
1214*5779Sxy150489  * disable auto-negotiation, configure duplex, configure speed, configure
1215*5779Sxy150489  * the collision distance, write configuration to CTRL register.  The
1216*5779Sxy150489  * caller must write to the PHY_CONTROL register for these settings to
1217*5779Sxy150489  * take affect.
1218*5779Sxy150489  */
1219*5779Sxy150489 void
1220*5779Sxy150489 e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
1221*5779Sxy150489 {
1222*5779Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1223*5779Sxy150489 	u32 ctrl;
1224*5779Sxy150489 
1225*5779Sxy150489 	DEBUGFUNC("e1000_phy_force_speed_duplex_setup");
1226*5779Sxy150489 
1227*5779Sxy150489 	/* Turn off flow control when forcing speed/duplex */
1228*5779Sxy150489 	hw->fc.type = e1000_fc_none;
1229*5779Sxy150489 
1230*5779Sxy150489 	/* Force speed/duplex on the mac */
1231*5779Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1232*5779Sxy150489 	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
1233*5779Sxy150489 	ctrl &= ~E1000_CTRL_SPD_SEL;
1234*5779Sxy150489 
1235*5779Sxy150489 	/* Disable Auto Speed Detection */
1236*5779Sxy150489 	ctrl &= ~E1000_CTRL_ASDE;
1237*5779Sxy150489 
1238*5779Sxy150489 	/* Disable autoneg on the phy */
1239*5779Sxy150489 	*phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
1240*5779Sxy150489 
1241*5779Sxy150489 	/* Forcing Full or Half Duplex? */
1242*5779Sxy150489 	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
1243*5779Sxy150489 		ctrl &= ~E1000_CTRL_FD;
1244*5779Sxy150489 		*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
1245*5779Sxy150489 		DEBUGOUT("Half Duplex\n");
1246*5779Sxy150489 	} else {
1247*5779Sxy150489 		ctrl |= E1000_CTRL_FD;
1248*5779Sxy150489 		*phy_ctrl |= MII_CR_FULL_DUPLEX;
1249*5779Sxy150489 		DEBUGOUT("Full Duplex\n");
1250*5779Sxy150489 	}
1251*5779Sxy150489 
1252*5779Sxy150489 	/* Forcing 10mb or 100mb? */
1253*5779Sxy150489 	if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
1254*5779Sxy150489 		ctrl |= E1000_CTRL_SPD_100;
1255*5779Sxy150489 		*phy_ctrl |= MII_CR_SPEED_100;
1256*5779Sxy150489 		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
1257*5779Sxy150489 		DEBUGOUT("Forcing 100mb\n");
1258*5779Sxy150489 	} else {
1259*5779Sxy150489 		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
1260*5779Sxy150489 		/* LINTED */
1261*5779Sxy150489 		*phy_ctrl |= MII_CR_SPEED_10;
1262*5779Sxy150489 		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
1263*5779Sxy150489 		DEBUGOUT("Forcing 10mb\n");
1264*5779Sxy150489 	}
1265*5779Sxy150489 
1266*5779Sxy150489 	e1000_config_collision_dist_generic(hw);
1267*5779Sxy150489 
1268*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1269*5779Sxy150489 }
1270*5779Sxy150489 
1271*5779Sxy150489 /*
1272*5779Sxy150489  * e1000_set_d3_lplu_state_generic - Sets low power link up state for D3
1273*5779Sxy150489  * @hw: pointer to the HW structure
1274*5779Sxy150489  * @active: boolean used to enable/disable lplu
1275*5779Sxy150489  *
1276*5779Sxy150489  * Success returns 0, Failure returns 1
1277*5779Sxy150489  *
1278*5779Sxy150489  * The low power link up (lplu) state is set to the power management level D3
1279*5779Sxy150489  * and SmartSpeed is disabled when active is true, else clear lplu for D3
1280*5779Sxy150489  * and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
1281*5779Sxy150489  * is used during Dx states where the power conservation is most important.
1282*5779Sxy150489  * During driver activity, SmartSpeed should be enabled so performance is
1283*5779Sxy150489  * maintained.
1284*5779Sxy150489  */
1285*5779Sxy150489 s32
1286*5779Sxy150489 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
1287*5779Sxy150489 {
1288*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1289*5779Sxy150489 	s32 ret_val;
1290*5779Sxy150489 	u16 data;
1291*5779Sxy150489 
1292*5779Sxy150489 	DEBUGFUNC("e1000_set_d3_lplu_state_generic");
1293*5779Sxy150489 
1294*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
1295*5779Sxy150489 	if (ret_val)
1296*5779Sxy150489 		goto out;
1297*5779Sxy150489 
1298*5779Sxy150489 	if (!active) {
1299*5779Sxy150489 		data &= ~IGP02E1000_PM_D3_LPLU;
1300*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
1301*5779Sxy150489 		    IGP02E1000_PHY_POWER_MGMT,
1302*5779Sxy150489 		    data);
1303*5779Sxy150489 		if (ret_val)
1304*5779Sxy150489 			goto out;
1305*5779Sxy150489 		/*
1306*5779Sxy150489 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
1307*5779Sxy150489 		 * during Dx states where the power conservation is most
1308*5779Sxy150489 		 * important.  During driver activity we should enable
1309*5779Sxy150489 		 * SmartSpeed, so performance is maintained.
1310*5779Sxy150489 		 */
1311*5779Sxy150489 		if (phy->smart_speed == e1000_smart_speed_on) {
1312*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw,
1313*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
1314*5779Sxy150489 			    &data);
1315*5779Sxy150489 			if (ret_val)
1316*5779Sxy150489 				goto out;
1317*5779Sxy150489 
1318*5779Sxy150489 			data |= IGP01E1000_PSCFR_SMART_SPEED;
1319*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
1320*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
1321*5779Sxy150489 			    data);
1322*5779Sxy150489 			if (ret_val)
1323*5779Sxy150489 				goto out;
1324*5779Sxy150489 		} else if (phy->smart_speed == e1000_smart_speed_off) {
1325*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw,
1326*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
1327*5779Sxy150489 			    &data);
1328*5779Sxy150489 			if (ret_val)
1329*5779Sxy150489 				goto out;
1330*5779Sxy150489 
1331*5779Sxy150489 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
1332*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
1333*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
1334*5779Sxy150489 			    data);
1335*5779Sxy150489 			if (ret_val)
1336*5779Sxy150489 				goto out;
1337*5779Sxy150489 		}
1338*5779Sxy150489 	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
1339*5779Sxy150489 	    (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
1340*5779Sxy150489 	    (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
1341*5779Sxy150489 		data |= IGP02E1000_PM_D3_LPLU;
1342*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
1343*5779Sxy150489 		    IGP02E1000_PHY_POWER_MGMT,
1344*5779Sxy150489 		    data);
1345*5779Sxy150489 		if (ret_val)
1346*5779Sxy150489 			goto out;
1347*5779Sxy150489 
1348*5779Sxy150489 		/* When LPLU is enabled, we should disable SmartSpeed */
1349*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw,
1350*5779Sxy150489 		    IGP01E1000_PHY_PORT_CONFIG,
1351*5779Sxy150489 		    &data);
1352*5779Sxy150489 		if (ret_val)
1353*5779Sxy150489 			goto out;
1354*5779Sxy150489 
1355*5779Sxy150489 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
1356*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
1357*5779Sxy150489 		    IGP01E1000_PHY_PORT_CONFIG,
1358*5779Sxy150489 		    data);
1359*5779Sxy150489 	}
1360*5779Sxy150489 
1361*5779Sxy150489 out:
1362*5779Sxy150489 	return (ret_val);
1363*5779Sxy150489 }
1364*5779Sxy150489 
1365*5779Sxy150489 /*
1366*5779Sxy150489  * e1000_check_downshift_generic - Checks whether a downshift in speed occured
1367*5779Sxy150489  * @hw: pointer to the HW structure
1368*5779Sxy150489  *
1369*5779Sxy150489  * Success returns 0, Failure returns 1
1370*5779Sxy150489  *
1371*5779Sxy150489  * A downshift is detected by querying the PHY link health.
1372*5779Sxy150489  */
1373*5779Sxy150489 s32
1374*5779Sxy150489 e1000_check_downshift_generic(struct e1000_hw *hw)
1375*5779Sxy150489 {
1376*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1377*5779Sxy150489 	s32 ret_val;
1378*5779Sxy150489 	u16 phy_data, offset, mask;
1379*5779Sxy150489 
1380*5779Sxy150489 	DEBUGFUNC("e1000_check_downshift_generic");
1381*5779Sxy150489 
1382*5779Sxy150489 	switch (phy->type) {
1383*5779Sxy150489 	case e1000_phy_m88:
1384*5779Sxy150489 	case e1000_phy_gg82563:
1385*5779Sxy150489 	case e1000_phy_bm:
1386*5779Sxy150489 		offset	= M88E1000_PHY_SPEC_STATUS;
1387*5779Sxy150489 		mask	= M88E1000_PSSR_DOWNSHIFT;
1388*5779Sxy150489 		break;
1389*5779Sxy150489 	case e1000_phy_igp_2:
1390*5779Sxy150489 	case e1000_phy_igp:
1391*5779Sxy150489 	case e1000_phy_igp_3:
1392*5779Sxy150489 		offset	= IGP01E1000_PHY_LINK_HEALTH;
1393*5779Sxy150489 		mask	= IGP01E1000_PLHR_SS_DOWNGRADE;
1394*5779Sxy150489 		break;
1395*5779Sxy150489 	default:
1396*5779Sxy150489 		/* speed downshift not supported */
1397*5779Sxy150489 		phy->speed_downgraded = FALSE;
1398*5779Sxy150489 		ret_val = E1000_SUCCESS;
1399*5779Sxy150489 		goto out;
1400*5779Sxy150489 	}
1401*5779Sxy150489 
1402*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, offset, &phy_data);
1403*5779Sxy150489 
1404*5779Sxy150489 	if (!ret_val)
1405*5779Sxy150489 		phy->speed_downgraded = (phy_data & mask) ? TRUE : FALSE;
1406*5779Sxy150489 
1407*5779Sxy150489 out:
1408*5779Sxy150489 	return (ret_val);
1409*5779Sxy150489 }
1410*5779Sxy150489 
1411*5779Sxy150489 /*
1412*5779Sxy150489  * e1000_check_polarity_m88 - Checks the polarity.
1413*5779Sxy150489  * @hw: pointer to the HW structure
1414*5779Sxy150489  *
1415*5779Sxy150489  * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
1416*5779Sxy150489  *
1417*5779Sxy150489  * Polarity is determined based on the PHY specific status register.
1418*5779Sxy150489  */
1419*5779Sxy150489 s32
1420*5779Sxy150489 e1000_check_polarity_m88(struct e1000_hw *hw)
1421*5779Sxy150489 {
1422*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1423*5779Sxy150489 	s32 ret_val;
1424*5779Sxy150489 	u16 data;
1425*5779Sxy150489 
1426*5779Sxy150489 	DEBUGFUNC("e1000_check_polarity_m88");
1427*5779Sxy150489 
1428*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
1429*5779Sxy150489 
1430*5779Sxy150489 	if (!ret_val)
1431*5779Sxy150489 		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
1432*5779Sxy150489 		    ? e1000_rev_polarity_reversed
1433*5779Sxy150489 		    : e1000_rev_polarity_normal;
1434*5779Sxy150489 
1435*5779Sxy150489 	return (ret_val);
1436*5779Sxy150489 }
1437*5779Sxy150489 
1438*5779Sxy150489 /*
1439*5779Sxy150489  * e1000_check_polarity_igp - Checks the polarity.
1440*5779Sxy150489  * @hw: pointer to the HW structure
1441*5779Sxy150489  *
1442*5779Sxy150489  * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
1443*5779Sxy150489  *
1444*5779Sxy150489  * Polarity is determined based on the PHY port status register, and the
1445*5779Sxy150489  * current speed (since there is no polarity at 100Mbps).
1446*5779Sxy150489  */
1447*5779Sxy150489 s32
1448*5779Sxy150489 e1000_check_polarity_igp(struct e1000_hw *hw)
1449*5779Sxy150489 {
1450*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1451*5779Sxy150489 	s32 ret_val;
1452*5779Sxy150489 	u16 data, offset, mask;
1453*5779Sxy150489 
1454*5779Sxy150489 	DEBUGFUNC("e1000_check_polarity_igp");
1455*5779Sxy150489 
1456*5779Sxy150489 	/*
1457*5779Sxy150489 	 * Polarity is determined based on the speed of
1458*5779Sxy150489 	 * our connection.
1459*5779Sxy150489 	 */
1460*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
1461*5779Sxy150489 	if (ret_val)
1462*5779Sxy150489 		goto out;
1463*5779Sxy150489 
1464*5779Sxy150489 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
1465*5779Sxy150489 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
1466*5779Sxy150489 		offset	= IGP01E1000_PHY_PCS_INIT_REG;
1467*5779Sxy150489 		mask	= IGP01E1000_PHY_POLARITY_MASK;
1468*5779Sxy150489 	} else {
1469*5779Sxy150489 		/*
1470*5779Sxy150489 		 * This really only applies to 10Mbps since
1471*5779Sxy150489 		 * there is no polarity for 100Mbps (always 0).
1472*5779Sxy150489 		 */
1473*5779Sxy150489 		offset	= IGP01E1000_PHY_PORT_STATUS;
1474*5779Sxy150489 		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
1475*5779Sxy150489 	}
1476*5779Sxy150489 
1477*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, offset, &data);
1478*5779Sxy150489 
1479*5779Sxy150489 	if (!ret_val)
1480*5779Sxy150489 		phy->cable_polarity = (data & mask)
1481*5779Sxy150489 		    ? e1000_rev_polarity_reversed
1482*5779Sxy150489 		    : e1000_rev_polarity_normal;
1483*5779Sxy150489 
1484*5779Sxy150489 out:
1485*5779Sxy150489 	return (ret_val);
1486*5779Sxy150489 }
1487*5779Sxy150489 
1488*5779Sxy150489 /*
1489*5779Sxy150489  * e1000_wait_autoneg_generic - Wait for auto-neg compeletion
1490*5779Sxy150489  * @hw: pointer to the HW structure
1491*5779Sxy150489  *
1492*5779Sxy150489  * Waits for auto-negotiation to complete or for the auto-negotiation time
1493*5779Sxy150489  * limit to expire, which ever happens first.
1494*5779Sxy150489  */
1495*5779Sxy150489 s32
1496*5779Sxy150489 e1000_wait_autoneg_generic(struct e1000_hw *hw)
1497*5779Sxy150489 {
1498*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
1499*5779Sxy150489 	u16 i, phy_status;
1500*5779Sxy150489 
1501*5779Sxy150489 	DEBUGFUNC("e1000_wait_autoneg_generic");
1502*5779Sxy150489 
1503*5779Sxy150489 	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
1504*5779Sxy150489 	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
1505*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1506*5779Sxy150489 		if (ret_val)
1507*5779Sxy150489 			break;
1508*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1509*5779Sxy150489 		if (ret_val)
1510*5779Sxy150489 			break;
1511*5779Sxy150489 		if (phy_status & MII_SR_AUTONEG_COMPLETE)
1512*5779Sxy150489 			break;
1513*5779Sxy150489 		msec_delay(100);
1514*5779Sxy150489 	}
1515*5779Sxy150489 
1516*5779Sxy150489 	/*
1517*5779Sxy150489 	 * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
1518*5779Sxy150489 	 * has completed.
1519*5779Sxy150489 	 */
1520*5779Sxy150489 	return (ret_val);
1521*5779Sxy150489 }
1522*5779Sxy150489 
1523*5779Sxy150489 /*
1524*5779Sxy150489  * e1000_phy_has_link_generic - Polls PHY for link
1525*5779Sxy150489  * @hw: pointer to the HW structure
1526*5779Sxy150489  * @iterations: number of times to poll for link
1527*5779Sxy150489  * @usec_interval: delay between polling attempts
1528*5779Sxy150489  * @success: pointer to whether polling was successful or not
1529*5779Sxy150489  *
1530*5779Sxy150489  * Polls the PHY status register for link, 'iterations' number of times.
1531*5779Sxy150489  */
1532*5779Sxy150489 s32
1533*5779Sxy150489 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
1534*5779Sxy150489     u32 usec_interval, bool *success)
1535*5779Sxy150489 {
1536*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
1537*5779Sxy150489 	u16 i, phy_status;
1538*5779Sxy150489 
1539*5779Sxy150489 	DEBUGFUNC("e1000_phy_has_link_generic");
1540*5779Sxy150489 
1541*5779Sxy150489 	for (i = 0; i < iterations; i++) {
1542*5779Sxy150489 		/*
1543*5779Sxy150489 		 * Some PHYs require the PHY_STATUS register to be read
1544*5779Sxy150489 		 * twice due to the link bit being sticky.  No harm doing
1545*5779Sxy150489 		 * it across the board.
1546*5779Sxy150489 		 */
1547*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1548*5779Sxy150489 		if (ret_val)
1549*5779Sxy150489 			break;
1550*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1551*5779Sxy150489 		if (ret_val)
1552*5779Sxy150489 			break;
1553*5779Sxy150489 		if (phy_status & MII_SR_LINK_STATUS)
1554*5779Sxy150489 			break;
1555*5779Sxy150489 		if (usec_interval >= 1000)
1556*5779Sxy150489 			msec_delay_irq(usec_interval/1000);
1557*5779Sxy150489 		else
1558*5779Sxy150489 			usec_delay(usec_interval);
1559*5779Sxy150489 	}
1560*5779Sxy150489 
1561*5779Sxy150489 	*success = (i < iterations) ? TRUE : FALSE;
1562*5779Sxy150489 
1563*5779Sxy150489 	return (ret_val);
1564*5779Sxy150489 }
1565*5779Sxy150489 
1566*5779Sxy150489 /*
1567*5779Sxy150489  * e1000_get_cable_length_m88 - Determine cable length for m88 PHY
1568*5779Sxy150489  * @hw: pointer to the HW structure
1569*5779Sxy150489  *
1570*5779Sxy150489  * Reads the PHY specific status register to retrieve the cable length
1571*5779Sxy150489  * information.  The cable length is determined by averaging the minimum and
1572*5779Sxy150489  * maximum values to get the "average" cable length.  The m88 PHY has four
1573*5779Sxy150489  * possible cable length values, which are:
1574*5779Sxy150489  *	Register Value		Cable Length
1575*5779Sxy150489  *	0			< 50 meters
1576*5779Sxy150489  *	1			50 - 80 meters
1577*5779Sxy150489  *	2			80 - 110 meters
1578*5779Sxy150489  *	3			110 - 140 meters
1579*5779Sxy150489  *	4			> 140 meters
1580*5779Sxy150489  */
1581*5779Sxy150489 s32
1582*5779Sxy150489 e1000_get_cable_length_m88(struct e1000_hw *hw)
1583*5779Sxy150489 {
1584*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1585*5779Sxy150489 	s32 ret_val;
1586*5779Sxy150489 	u16 phy_data, index;
1587*5779Sxy150489 
1588*5779Sxy150489 	DEBUGFUNC("e1000_get_cable_length_m88");
1589*5779Sxy150489 
1590*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
1591*5779Sxy150489 	if (ret_val)
1592*5779Sxy150489 		goto out;
1593*5779Sxy150489 
1594*5779Sxy150489 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
1595*5779Sxy150489 	    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
1596*5779Sxy150489 	phy->min_cable_length = e1000_m88_cable_length_table[index];
1597*5779Sxy150489 	phy->max_cable_length = e1000_m88_cable_length_table[index+1];
1598*5779Sxy150489 
1599*5779Sxy150489 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
1600*5779Sxy150489 
1601*5779Sxy150489 out:
1602*5779Sxy150489 	return (ret_val);
1603*5779Sxy150489 }
1604*5779Sxy150489 
1605*5779Sxy150489 /*
1606*5779Sxy150489  * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
1607*5779Sxy150489  * @hw: pointer to the HW structure
1608*5779Sxy150489  *
1609*5779Sxy150489  * The automatic gain control (agc) normalizes the amplitude of the
1610*5779Sxy150489  * received signal, adjusting for the attenuation produced by the
1611*5779Sxy150489  * cable.  By reading the AGC registers, which reperesent the
1612*5779Sxy150489  * cobination of course and fine gain value, the value can be put
1613*5779Sxy150489  * into a lookup table to obtain the approximate cable length
1614*5779Sxy150489  * for each channel.
1615*5779Sxy150489  */
1616*5779Sxy150489 s32
1617*5779Sxy150489 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
1618*5779Sxy150489 {
1619*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1620*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
1621*5779Sxy150489 	u16 phy_data, i, agc_value = 0;
1622*5779Sxy150489 	u16 cur_agc_index, max_agc_index = 0;
1623*5779Sxy150489 	u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
1624*5779Sxy150489 	u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
1625*5779Sxy150489 		{IGP02E1000_PHY_AGC_A,
1626*5779Sxy150489 		IGP02E1000_PHY_AGC_B,
1627*5779Sxy150489 		IGP02E1000_PHY_AGC_C,
1628*5779Sxy150489 		IGP02E1000_PHY_AGC_D};
1629*5779Sxy150489 
1630*5779Sxy150489 	DEBUGFUNC("e1000_get_cable_length_igp_2");
1631*5779Sxy150489 
1632*5779Sxy150489 	/* Read the AGC registers for all channels */
1633*5779Sxy150489 	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
1634*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
1635*5779Sxy150489 		if (ret_val)
1636*5779Sxy150489 			goto out;
1637*5779Sxy150489 
1638*5779Sxy150489 		/*
1639*5779Sxy150489 		 * Getting bits 15:9, which represent the combination of
1640*5779Sxy150489 		 * course and fine gain values.  The result is a number
1641*5779Sxy150489 		 * that can be put into the lookup table to obtain the
1642*5779Sxy150489 		 * approximate cable length.
1643*5779Sxy150489 		 */
1644*5779Sxy150489 		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
1645*5779Sxy150489 		    IGP02E1000_AGC_LENGTH_MASK;
1646*5779Sxy150489 
1647*5779Sxy150489 		/* Array index bound check. */
1648*5779Sxy150489 		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
1649*5779Sxy150489 		    (cur_agc_index == 0)) {
1650*5779Sxy150489 			ret_val = -E1000_ERR_PHY;
1651*5779Sxy150489 			goto out;
1652*5779Sxy150489 		}
1653*5779Sxy150489 
1654*5779Sxy150489 		/* Remove min & max AGC values from calculation. */
1655*5779Sxy150489 		if (e1000_igp_2_cable_length_table[min_agc_index] >
1656*5779Sxy150489 		    e1000_igp_2_cable_length_table[cur_agc_index])
1657*5779Sxy150489 			min_agc_index = cur_agc_index;
1658*5779Sxy150489 		if (e1000_igp_2_cable_length_table[max_agc_index] <
1659*5779Sxy150489 		    e1000_igp_2_cable_length_table[cur_agc_index])
1660*5779Sxy150489 			max_agc_index = cur_agc_index;
1661*5779Sxy150489 
1662*5779Sxy150489 		agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
1663*5779Sxy150489 	}
1664*5779Sxy150489 
1665*5779Sxy150489 	agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
1666*5779Sxy150489 	    e1000_igp_2_cable_length_table[max_agc_index]);
1667*5779Sxy150489 	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
1668*5779Sxy150489 
1669*5779Sxy150489 	/* Calculate cable length with the error range of +/- 10 meters. */
1670*5779Sxy150489 	phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
1671*5779Sxy150489 	    (agc_value - IGP02E1000_AGC_RANGE) : 0;
1672*5779Sxy150489 	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
1673*5779Sxy150489 
1674*5779Sxy150489 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
1675*5779Sxy150489 
1676*5779Sxy150489 out:
1677*5779Sxy150489 	return (ret_val);
1678*5779Sxy150489 }
1679*5779Sxy150489 
1680*5779Sxy150489 /*
1681*5779Sxy150489  * e1000_get_phy_info_m88 - Retrieve PHY information
1682*5779Sxy150489  * @hw: pointer to the HW structure
1683*5779Sxy150489  *
1684*5779Sxy150489  * Valid for only copper links.  Read the PHY status register (sticky read)
1685*5779Sxy150489  * to verify that link is up.  Read the PHY special control register to
1686*5779Sxy150489  * determine the polarity and 10base-T extended distance.  Read the PHY
1687*5779Sxy150489  * special status register to determine MDI/MDIx and current speed.  If
1688*5779Sxy150489  * speed is 1000, then determine cable length, local and remote receiver.
1689*5779Sxy150489  */
1690*5779Sxy150489 s32
1691*5779Sxy150489 e1000_get_phy_info_m88(struct e1000_hw *hw)
1692*5779Sxy150489 {
1693*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1694*5779Sxy150489 	s32  ret_val;
1695*5779Sxy150489 	u16 phy_data;
1696*5779Sxy150489 	bool link;
1697*5779Sxy150489 
1698*5779Sxy150489 	DEBUGFUNC("e1000_get_phy_info_m88");
1699*5779Sxy150489 
1700*5779Sxy150489 	if (hw->phy.media_type != e1000_media_type_copper) {
1701*5779Sxy150489 		DEBUGOUT("Phy info is only valid for copper media\n");
1702*5779Sxy150489 		ret_val = -E1000_ERR_CONFIG;
1703*5779Sxy150489 		goto out;
1704*5779Sxy150489 	}
1705*5779Sxy150489 
1706*5779Sxy150489 	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
1707*5779Sxy150489 	if (ret_val)
1708*5779Sxy150489 		goto out;
1709*5779Sxy150489 
1710*5779Sxy150489 	if (!link) {
1711*5779Sxy150489 		DEBUGOUT("Phy info is only valid if link is up\n");
1712*5779Sxy150489 		ret_val = -E1000_ERR_CONFIG;
1713*5779Sxy150489 		goto out;
1714*5779Sxy150489 	}
1715*5779Sxy150489 
1716*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
1717*5779Sxy150489 	if (ret_val)
1718*5779Sxy150489 		goto out;
1719*5779Sxy150489 
1720*5779Sxy150489 	phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
1721*5779Sxy150489 	    ? TRUE
1722*5779Sxy150489 	    : FALSE;
1723*5779Sxy150489 
1724*5779Sxy150489 	ret_val = e1000_check_polarity_m88(hw);
1725*5779Sxy150489 	if (ret_val)
1726*5779Sxy150489 		goto out;
1727*5779Sxy150489 
1728*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
1729*5779Sxy150489 	if (ret_val)
1730*5779Sxy150489 		goto out;
1731*5779Sxy150489 
1732*5779Sxy150489 	phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? TRUE : FALSE;
1733*5779Sxy150489 
1734*5779Sxy150489 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
1735*5779Sxy150489 		ret_val = e1000_get_cable_length(hw);
1736*5779Sxy150489 		if (ret_val)
1737*5779Sxy150489 			goto out;
1738*5779Sxy150489 
1739*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
1740*5779Sxy150489 		if (ret_val)
1741*5779Sxy150489 			goto out;
1742*5779Sxy150489 
1743*5779Sxy150489 		phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
1744*5779Sxy150489 		    ? e1000_1000t_rx_status_ok
1745*5779Sxy150489 		    : e1000_1000t_rx_status_not_ok;
1746*5779Sxy150489 
1747*5779Sxy150489 		phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
1748*5779Sxy150489 		    ? e1000_1000t_rx_status_ok
1749*5779Sxy150489 		    : e1000_1000t_rx_status_not_ok;
1750*5779Sxy150489 	} else {
1751*5779Sxy150489 		/* Set values to "undefined" */
1752*5779Sxy150489 		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
1753*5779Sxy150489 		phy->local_rx = e1000_1000t_rx_status_undefined;
1754*5779Sxy150489 		phy->remote_rx = e1000_1000t_rx_status_undefined;
1755*5779Sxy150489 	}
1756*5779Sxy150489 
1757*5779Sxy150489 out:
1758*5779Sxy150489 	return (ret_val);
1759*5779Sxy150489 }
1760*5779Sxy150489 
1761*5779Sxy150489 /*
1762*5779Sxy150489  * e1000_get_phy_info_igp - Retrieve igp PHY information
1763*5779Sxy150489  * @hw: pointer to the HW structure
1764*5779Sxy150489  *
1765*5779Sxy150489  * Read PHY status to determine if link is up.  If link is up, then
1766*5779Sxy150489  * set/determine 10base-T extended distance and polarity correction.  Read
1767*5779Sxy150489  * PHY port status to determine MDI/MDIx and speed.  Based on the speed,
1768*5779Sxy150489  * determine on the cable length, local and remote receiver.
1769*5779Sxy150489  */
1770*5779Sxy150489 s32
1771*5779Sxy150489 e1000_get_phy_info_igp(struct e1000_hw *hw)
1772*5779Sxy150489 {
1773*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1774*5779Sxy150489 	s32 ret_val;
1775*5779Sxy150489 	u16 data;
1776*5779Sxy150489 	bool link;
1777*5779Sxy150489 
1778*5779Sxy150489 	DEBUGFUNC("e1000_get_phy_info_igp");
1779*5779Sxy150489 
1780*5779Sxy150489 	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
1781*5779Sxy150489 	if (ret_val)
1782*5779Sxy150489 		goto out;
1783*5779Sxy150489 
1784*5779Sxy150489 	if (!link) {
1785*5779Sxy150489 		DEBUGOUT("Phy info is only valid if link is up\n");
1786*5779Sxy150489 		ret_val = -E1000_ERR_CONFIG;
1787*5779Sxy150489 		goto out;
1788*5779Sxy150489 	}
1789*5779Sxy150489 
1790*5779Sxy150489 	phy->polarity_correction = TRUE;
1791*5779Sxy150489 
1792*5779Sxy150489 	ret_val = e1000_check_polarity_igp(hw);
1793*5779Sxy150489 	if (ret_val)
1794*5779Sxy150489 		goto out;
1795*5779Sxy150489 
1796*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
1797*5779Sxy150489 	if (ret_val)
1798*5779Sxy150489 		goto out;
1799*5779Sxy150489 
1800*5779Sxy150489 	phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? TRUE : FALSE;
1801*5779Sxy150489 
1802*5779Sxy150489 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
1803*5779Sxy150489 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
1804*5779Sxy150489 		ret_val = e1000_get_cable_length(hw);
1805*5779Sxy150489 		if (ret_val)
1806*5779Sxy150489 			goto out;
1807*5779Sxy150489 
1808*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &data);
1809*5779Sxy150489 		if (ret_val)
1810*5779Sxy150489 			goto out;
1811*5779Sxy150489 
1812*5779Sxy150489 		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
1813*5779Sxy150489 		    ? e1000_1000t_rx_status_ok
1814*5779Sxy150489 		    : e1000_1000t_rx_status_not_ok;
1815*5779Sxy150489 
1816*5779Sxy150489 		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
1817*5779Sxy150489 		    ? e1000_1000t_rx_status_ok
1818*5779Sxy150489 		    : e1000_1000t_rx_status_not_ok;
1819*5779Sxy150489 	} else {
1820*5779Sxy150489 		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
1821*5779Sxy150489 		phy->local_rx = e1000_1000t_rx_status_undefined;
1822*5779Sxy150489 		phy->remote_rx = e1000_1000t_rx_status_undefined;
1823*5779Sxy150489 	}
1824*5779Sxy150489 
1825*5779Sxy150489 out:
1826*5779Sxy150489 	return (ret_val);
1827*5779Sxy150489 }
1828*5779Sxy150489 
1829*5779Sxy150489 /*
1830*5779Sxy150489  * e1000_phy_sw_reset_generic - PHY software reset
1831*5779Sxy150489  * @hw: pointer to the HW structure
1832*5779Sxy150489  *
1833*5779Sxy150489  * Does a software reset of the PHY by reading the PHY control register and
1834*5779Sxy150489  * setting/write the control register reset bit to the PHY.
1835*5779Sxy150489  */
1836*5779Sxy150489 s32
1837*5779Sxy150489 e1000_phy_sw_reset_generic(struct e1000_hw *hw)
1838*5779Sxy150489 {
1839*5779Sxy150489 	s32 ret_val;
1840*5779Sxy150489 	u16 phy_ctrl;
1841*5779Sxy150489 
1842*5779Sxy150489 	DEBUGFUNC("e1000_phy_sw_reset_generic");
1843*5779Sxy150489 
1844*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
1845*5779Sxy150489 	if (ret_val)
1846*5779Sxy150489 		goto out;
1847*5779Sxy150489 
1848*5779Sxy150489 	phy_ctrl |= MII_CR_RESET;
1849*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
1850*5779Sxy150489 	if (ret_val)
1851*5779Sxy150489 		goto out;
1852*5779Sxy150489 
1853*5779Sxy150489 	usec_delay(1);
1854*5779Sxy150489 
1855*5779Sxy150489 out:
1856*5779Sxy150489 	return (ret_val);
1857*5779Sxy150489 }
1858*5779Sxy150489 
1859*5779Sxy150489 /*
1860*5779Sxy150489  * e1000_phy_hw_reset_generic - PHY hardware reset
1861*5779Sxy150489  * @hw: pointer to the HW structure
1862*5779Sxy150489  *
1863*5779Sxy150489  * Verify the reset block is not blocking us from resetting.  Acquire
1864*5779Sxy150489  * semaphore (if necessary) and read/set/write the device control reset
1865*5779Sxy150489  * bit in the PHY.  Wait the appropriate delay time for the device to
1866*5779Sxy150489  * reset and relase the semaphore (if necessary).
1867*5779Sxy150489  */
1868*5779Sxy150489 s32
1869*5779Sxy150489 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
1870*5779Sxy150489 {
1871*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
1872*5779Sxy150489 	s32  ret_val;
1873*5779Sxy150489 	u32 ctrl;
1874*5779Sxy150489 
1875*5779Sxy150489 	DEBUGFUNC("e1000_phy_hw_reset_generic");
1876*5779Sxy150489 
1877*5779Sxy150489 	ret_val = e1000_check_reset_block(hw);
1878*5779Sxy150489 	if (ret_val) {
1879*5779Sxy150489 		ret_val = E1000_SUCCESS;
1880*5779Sxy150489 		goto out;
1881*5779Sxy150489 	}
1882*5779Sxy150489 
1883*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
1884*5779Sxy150489 	if (ret_val)
1885*5779Sxy150489 		goto out;
1886*5779Sxy150489 
1887*5779Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1888*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
1889*5779Sxy150489 	E1000_WRITE_FLUSH(hw);
1890*5779Sxy150489 
1891*5779Sxy150489 	usec_delay(phy->reset_delay_us);
1892*5779Sxy150489 
1893*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1894*5779Sxy150489 	E1000_WRITE_FLUSH(hw);
1895*5779Sxy150489 
1896*5779Sxy150489 	usec_delay(150);
1897*5779Sxy150489 
1898*5779Sxy150489 	e1000_release_phy(hw);
1899*5779Sxy150489 
1900*5779Sxy150489 	ret_val = e1000_get_phy_cfg_done(hw);
1901*5779Sxy150489 
1902*5779Sxy150489 out:
1903*5779Sxy150489 	return (ret_val);
1904*5779Sxy150489 }
1905*5779Sxy150489 
1906*5779Sxy150489 /*
1907*5779Sxy150489  * e1000_get_cfg_done_generic - Generic configuration done
1908*5779Sxy150489  * @hw: pointer to the HW structure
1909*5779Sxy150489  *
1910*5779Sxy150489  * Generic function to wait 10 milli-seconds for configuration to complete
1911*5779Sxy150489  * and return success.
1912*5779Sxy150489  */
1913*5779Sxy150489 s32
1914*5779Sxy150489 e1000_get_cfg_done_generic(struct e1000_hw *hw)
1915*5779Sxy150489 {
1916*5779Sxy150489 	DEBUGFUNC("e1000_get_cfg_done_generic");
1917*5779Sxy150489 	UNREFERENCED_PARAMETER(hw);
1918*5779Sxy150489 
1919*5779Sxy150489 	msec_delay_irq(10);
1920*5779Sxy150489 
1921*5779Sxy150489 	return (E1000_SUCCESS);
1922*5779Sxy150489 }
1923*5779Sxy150489 
1924*5779Sxy150489 /* Internal function pointers */
1925*5779Sxy150489 
1926*5779Sxy150489 /*
1927*5779Sxy150489  * e1000_get_phy_cfg_done - Generic PHY configuration done
1928*5779Sxy150489  * @hw: pointer to the HW structure
1929*5779Sxy150489  *
1930*5779Sxy150489  * Return success if silicon family did not implement a family specific
1931*5779Sxy150489  * get_cfg_done function.
1932*5779Sxy150489  */
1933*5779Sxy150489 static s32
1934*5779Sxy150489 e1000_get_phy_cfg_done(struct e1000_hw *hw)
1935*5779Sxy150489 {
1936*5779Sxy150489 	if (hw->func.get_cfg_done)
1937*5779Sxy150489 		return (hw->func.get_cfg_done(hw));
1938*5779Sxy150489 
1939*5779Sxy150489 	return (E1000_SUCCESS);
1940*5779Sxy150489 }
1941*5779Sxy150489 
1942*5779Sxy150489 /*
1943*5779Sxy150489  * e1000_release_phy - Generic release PHY
1944*5779Sxy150489  * @hw: pointer to the HW structure
1945*5779Sxy150489  *
1946*5779Sxy150489  * Return if silicon family does not require a semaphore when accessing the
1947*5779Sxy150489  * PHY.
1948*5779Sxy150489  */
1949*5779Sxy150489 static void
1950*5779Sxy150489 e1000_release_phy(struct e1000_hw *hw)
1951*5779Sxy150489 {
1952*5779Sxy150489 	if (hw->func.release_phy)
1953*5779Sxy150489 		hw->func.release_phy(hw);
1954*5779Sxy150489 }
1955*5779Sxy150489 
1956*5779Sxy150489 /*
1957*5779Sxy150489  * e1000_acquire_phy - Generic acquire PHY
1958*5779Sxy150489  * @hw: pointer to the HW structure
1959*5779Sxy150489  *
1960*5779Sxy150489  * Return success if silicon family does not require a semaphore when
1961*5779Sxy150489  * accessing the PHY.
1962*5779Sxy150489  */
1963*5779Sxy150489 static s32
1964*5779Sxy150489 e1000_acquire_phy(struct e1000_hw *hw)
1965*5779Sxy150489 {
1966*5779Sxy150489 	if (hw->func.acquire_phy)
1967*5779Sxy150489 		return (hw->func.acquire_phy(hw));
1968*5779Sxy150489 
1969*5779Sxy150489 	return (E1000_SUCCESS);
1970*5779Sxy150489 }
1971*5779Sxy150489 
1972*5779Sxy150489 /*
1973*5779Sxy150489  * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
1974*5779Sxy150489  * @hw: pointer to the HW structure
1975*5779Sxy150489  *
1976*5779Sxy150489  * When the silicon family has not implemented a forced speed/duplex
1977*5779Sxy150489  * function for the PHY, simply return (E1000_SUCCESS).
1978*5779Sxy150489  */
1979*5779Sxy150489 s32
1980*5779Sxy150489 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
1981*5779Sxy150489 {
1982*5779Sxy150489 	if (hw->func.force_speed_duplex)
1983*5779Sxy150489 		return (hw->func.force_speed_duplex(hw));
1984*5779Sxy150489 
1985*5779Sxy150489 	return (E1000_SUCCESS);
1986*5779Sxy150489 }
1987*5779Sxy150489 
1988*5779Sxy150489 /*
1989*5779Sxy150489  * e1000_phy_init_script_igp3 - Inits the IGP3 PHY
1990*5779Sxy150489  * @hw: pointer to the HW structure
1991*5779Sxy150489  *
1992*5779Sxy150489  * Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
1993*5779Sxy150489  */
1994*5779Sxy150489 s32
1995*5779Sxy150489 e1000_phy_init_script_igp3(struct e1000_hw *hw)
1996*5779Sxy150489 {
1997*5779Sxy150489 	DEBUGOUT("Running IGP 3 PHY init script\n");
1998*5779Sxy150489 
1999*5779Sxy150489 	/* PHY init IGP 3 */
2000*5779Sxy150489 	/* Enable rise/fall, 10-mode work in class-A */
2001*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2F5B, 0x9018);
2002*5779Sxy150489 	/* Remove all caps from Replica path filter */
2003*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2F52, 0x0000);
2004*5779Sxy150489 	/* Bias trimming for ADC, AFE and Driver (Default) */
2005*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2FB1, 0x8B24);
2006*5779Sxy150489 	/* Increase Hybrid poly bias */
2007*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2FB2, 0xF8F0);
2008*5779Sxy150489 	/* Add 4% to Tx amplitude in Giga mode */
2009*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2010, 0x10B0);
2010*5779Sxy150489 	/* Disable trimming (TTT) */
2011*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2011, 0x0000);
2012*5779Sxy150489 	/* Poly DC correction to 94.6% + 2% for all channels */
2013*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x20DD, 0x249A);
2014*5779Sxy150489 	/* ABS DC correction to 95.9% */
2015*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x20DE, 0x00D3);
2016*5779Sxy150489 	/* BG temp curve trim */
2017*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x28B4, 0x04CE);
2018*5779Sxy150489 	/* Increasing ADC OPAMP stage 1 currents to max */
2019*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x2F70, 0x29E4);
2020*5779Sxy150489 	/* Force 1000 ( required for enabling PHY regs configuration) */
2021*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x0000, 0x0140);
2022*5779Sxy150489 	/* Set upd_freq to 6 */
2023*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F30, 0x1606);
2024*5779Sxy150489 	/* Disable NPDFE */
2025*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F31, 0xB814);
2026*5779Sxy150489 	/* Disable adaptive fixed FFE (Default) */
2027*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F35, 0x002A);
2028*5779Sxy150489 	/* Enable FFE hysteresis */
2029*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F3E, 0x0067);
2030*5779Sxy150489 	/* Fixed FFE for short cable lengths */
2031*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F54, 0x0065);
2032*5779Sxy150489 	/* Fixed FFE for medium cable lengths */
2033*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F55, 0x002A);
2034*5779Sxy150489 	/* Fixed FFE for long cable lengths */
2035*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F56, 0x002A);
2036*5779Sxy150489 	/* Enable Adaptive Clip Threshold */
2037*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F72, 0x3FB0);
2038*5779Sxy150489 	/* AHT reset limit to 1 */
2039*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F76, 0xC0FF);
2040*5779Sxy150489 	/* Set AHT master delay to 127 msec */
2041*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F77, 0x1DEC);
2042*5779Sxy150489 	/* Set scan bits for AHT */
2043*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F78, 0xF9EF);
2044*5779Sxy150489 	/* Set AHT Preset bits */
2045*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1F79, 0x0210);
2046*5779Sxy150489 	/* Change integ_factor of channel A to 3 */
2047*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1895, 0x0003);
2048*5779Sxy150489 	/* Change prop_factor of channels BCD to 8 */
2049*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1796, 0x0008);
2050*5779Sxy150489 	/* Change cg_icount + enable integbp for channels BCD */
2051*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1798, 0xD008);
2052*5779Sxy150489 	/*
2053*5779Sxy150489 	 * Change cg_icount + enable integbp + change prop_factor_master
2054*5779Sxy150489 	 * to 8 for channel A
2055*5779Sxy150489 	 */
2056*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x1898, 0xD918);
2057*5779Sxy150489 	/* Disable AHT in Slave mode on channel A */
2058*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x187A, 0x0800);
2059*5779Sxy150489 	/*
2060*5779Sxy150489 	 * Enable LPLU and disable AN to 1000 in non-D0a states,
2061*5779Sxy150489 	 * Enable SPD+B2B
2062*5779Sxy150489 	 */
2063*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x0019, 0x008D);
2064*5779Sxy150489 	/* Enable restart AN on an1000_dis change */
2065*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x001B, 0x2080);
2066*5779Sxy150489 	/* Enable wh_fifo read clock in 10/100 modes */
2067*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x0014, 0x0045);
2068*5779Sxy150489 	/* Restart AN, Speed selection is 1000 */
2069*5779Sxy150489 	(void) e1000_write_phy_reg(hw, 0x0000, 0x1340);
2070*5779Sxy150489 
2071*5779Sxy150489 	return (E1000_SUCCESS);
2072*5779Sxy150489 }
2073*5779Sxy150489 
2074*5779Sxy150489 /*
2075*5779Sxy150489  * e1000_get_phy_type_from_id - Get PHY type from id
2076*5779Sxy150489  * @phy_id: phy_id read from the phy
2077*5779Sxy150489  *
2078*5779Sxy150489  * Returns the phy type from the id.
2079*5779Sxy150489  */
2080*5779Sxy150489 e1000_phy_type
2081*5779Sxy150489 e1000_get_phy_type_from_id(u32 phy_id)
2082*5779Sxy150489 {
2083*5779Sxy150489 	e1000_phy_type phy_type = e1000_phy_unknown;
2084*5779Sxy150489 
2085*5779Sxy150489 	switch (phy_id)	{
2086*5779Sxy150489 	case M88E1000_I_PHY_ID:
2087*5779Sxy150489 	case M88E1000_E_PHY_ID:
2088*5779Sxy150489 	case M88E1111_I_PHY_ID:
2089*5779Sxy150489 	case M88E1011_I_PHY_ID:
2090*5779Sxy150489 		phy_type = e1000_phy_m88;
2091*5779Sxy150489 		break;
2092*5779Sxy150489 	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
2093*5779Sxy150489 		phy_type = e1000_phy_igp_2;
2094*5779Sxy150489 		break;
2095*5779Sxy150489 	case GG82563_E_PHY_ID:
2096*5779Sxy150489 		phy_type = e1000_phy_gg82563;
2097*5779Sxy150489 		break;
2098*5779Sxy150489 	case IGP03E1000_E_PHY_ID:
2099*5779Sxy150489 		phy_type = e1000_phy_igp_3;
2100*5779Sxy150489 		break;
2101*5779Sxy150489 	case IFE_E_PHY_ID:
2102*5779Sxy150489 	case IFE_PLUS_E_PHY_ID:
2103*5779Sxy150489 	case IFE_C_E_PHY_ID:
2104*5779Sxy150489 		phy_type = e1000_phy_ife;
2105*5779Sxy150489 		break;
2106*5779Sxy150489 	case BME1000_E_PHY_ID:
2107*5779Sxy150489 	case BME1000_E_PHY_ID_R2:
2108*5779Sxy150489 		phy_type = e1000_phy_bm;
2109*5779Sxy150489 		break;
2110*5779Sxy150489 	default:
2111*5779Sxy150489 		phy_type = e1000_phy_unknown;
2112*5779Sxy150489 		break;
2113*5779Sxy150489 	}
2114*5779Sxy150489 	return (phy_type);
2115*5779Sxy150489 }
2116*5779Sxy150489 
2117*5779Sxy150489 /*
2118*5779Sxy150489  * e1000_determine_phy_address - Determines PHY address.
2119*5779Sxy150489  * @hw: pointer to the HW structure
2120*5779Sxy150489  *
2121*5779Sxy150489  * This uses a trial and error method to loop through possible PHY
2122*5779Sxy150489  * addresses. It tests each by reading the PHY ID registers and
2123*5779Sxy150489  * checking for a match.
2124*5779Sxy150489  */
2125*5779Sxy150489 s32
2126*5779Sxy150489 e1000_determine_phy_address(struct e1000_hw *hw)
2127*5779Sxy150489 {
2128*5779Sxy150489 	s32 ret_val = -E1000_ERR_PHY_TYPE;
2129*5779Sxy150489 	u32 phy_addr = 0;
2130*5779Sxy150489 	u32 i = 0;
2131*5779Sxy150489 	e1000_phy_type phy_type = e1000_phy_unknown;
2132*5779Sxy150489 
2133*5779Sxy150489 	do {
2134*5779Sxy150489 		for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
2135*5779Sxy150489 			hw->phy.addr = phy_addr;
2136*5779Sxy150489 			(void) e1000_get_phy_id(hw);
2137*5779Sxy150489 			phy_type = e1000_get_phy_type_from_id(hw->phy.id);
2138*5779Sxy150489 
2139*5779Sxy150489 			/*
2140*5779Sxy150489 			 * If phy_type is valid, break - we found our
2141*5779Sxy150489 			 * PHY address
2142*5779Sxy150489 			 */
2143*5779Sxy150489 			if (phy_type  != e1000_phy_unknown) {
2144*5779Sxy150489 				ret_val = E1000_SUCCESS;
2145*5779Sxy150489 				break;
2146*5779Sxy150489 			}
2147*5779Sxy150489 		}
2148*5779Sxy150489 		i++;
2149*5779Sxy150489 	} while ((ret_val != E1000_SUCCESS) && (i < 100));
2150*5779Sxy150489 
2151*5779Sxy150489 	return (ret_val);
2152*5779Sxy150489 }
2153*5779Sxy150489 
2154*5779Sxy150489 /*
2155*5779Sxy150489  * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
2156*5779Sxy150489  * @page: page to access
2157*5779Sxy150489  *
2158*5779Sxy150489  * Returns the phy address for the page requested.
2159*5779Sxy150489  */
2160*5779Sxy150489 static u32
2161*5779Sxy150489 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
2162*5779Sxy150489 {
2163*5779Sxy150489 	u32 phy_addr = 2;
2164*5779Sxy150489 
2165*5779Sxy150489 	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
2166*5779Sxy150489 		phy_addr = 1;
2167*5779Sxy150489 
2168*5779Sxy150489 	return (phy_addr);
2169*5779Sxy150489 }
2170*5779Sxy150489 
2171*5779Sxy150489 /*
2172*5779Sxy150489  * e1000_write_phy_reg_bm - Write BM PHY register
2173*5779Sxy150489  * @hw: pointer to the HW structure
2174*5779Sxy150489  * @offset: register offset to write to
2175*5779Sxy150489  * @data: data to write at register offset
2176*5779Sxy150489  *
2177*5779Sxy150489  * Acquires semaphore, if necessary, then writes the data to PHY register
2178*5779Sxy150489  * at the offset.  Release any acquired semaphores before exiting.
2179*5779Sxy150489  */
2180*5779Sxy150489 s32
2181*5779Sxy150489 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2182*5779Sxy150489 {
2183*5779Sxy150489 	s32 ret_val;
2184*5779Sxy150489 	u32 page_select = 0;
2185*5779Sxy150489 	u32 page = offset >> IGP_PAGE_SHIFT;
2186*5779Sxy150489 	u32 page_shift = 0;
2187*5779Sxy150489 
2188*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_bm");
2189*5779Sxy150489 
2190*5779Sxy150489 	/* Page 800 works differently than the rest so it has its own func */
2191*5779Sxy150489 	if (page == BM_WUC_PAGE) {
2192*5779Sxy150489 		ret_val = e1000_access_phy_wakeup_reg_bm(hw,
2193*5779Sxy150489 		    offset, &data, FALSE);
2194*5779Sxy150489 		goto out;
2195*5779Sxy150489 	}
2196*5779Sxy150489 
2197*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
2198*5779Sxy150489 	if (ret_val)
2199*5779Sxy150489 		goto out;
2200*5779Sxy150489 
2201*5779Sxy150489 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2202*5779Sxy150489 
2203*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2204*5779Sxy150489 		/*
2205*5779Sxy150489 		 * Page select is register 31 for phy address 1 and 22 for
2206*5779Sxy150489 		 * phy address 2 and 3. Page select is shifted only for
2207*5779Sxy150489 		 * phy address 1.
2208*5779Sxy150489 		 */
2209*5779Sxy150489 		if (hw->phy.addr == 1) {
2210*5779Sxy150489 			page_shift = IGP_PAGE_SHIFT;
2211*5779Sxy150489 			page_select = IGP01E1000_PHY_PAGE_SELECT;
2212*5779Sxy150489 		} else {
2213*5779Sxy150489 			page_shift = 0;
2214*5779Sxy150489 			page_select = BM_PHY_PAGE_SELECT;
2215*5779Sxy150489 		}
2216*5779Sxy150489 
2217*5779Sxy150489 		/* Page is shifted left, PHY expects (page x 32) */
2218*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw, page_select,
2219*5779Sxy150489 		    (page << page_shift));
2220*5779Sxy150489 		if (ret_val) {
2221*5779Sxy150489 			e1000_release_phy(hw);
2222*5779Sxy150489 			goto out;
2223*5779Sxy150489 		}
2224*5779Sxy150489 	}
2225*5779Sxy150489 
2226*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw,
2227*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset,
2228*5779Sxy150489 	    data);
2229*5779Sxy150489 
2230*5779Sxy150489 	e1000_release_phy(hw);
2231*5779Sxy150489 
2232*5779Sxy150489 out:
2233*5779Sxy150489 	return (ret_val);
2234*5779Sxy150489 }
2235*5779Sxy150489 
2236*5779Sxy150489 /*
2237*5779Sxy150489  * e1000_read_phy_reg_bm - Read BM PHY register
2238*5779Sxy150489  * @hw: pointer to the HW structure
2239*5779Sxy150489  * @offset: register offset to be read
2240*5779Sxy150489  * @data: pointer to the read data
2241*5779Sxy150489  *
2242*5779Sxy150489  * Acquires semaphore, if necessary, then reads the PHY register at offset
2243*5779Sxy150489  * and storing the retrieved information in data.  Release any acquired
2244*5779Sxy150489  * semaphores before exiting.
2245*5779Sxy150489  */
2246*5779Sxy150489 s32
2247*5779Sxy150489 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2248*5779Sxy150489 {
2249*5779Sxy150489 	s32 ret_val;
2250*5779Sxy150489 	u32 page_select = 0;
2251*5779Sxy150489 	u32 page = offset >> IGP_PAGE_SHIFT;
2252*5779Sxy150489 	u32 page_shift = 0;
2253*5779Sxy150489 
2254*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_bm");
2255*5779Sxy150489 
2256*5779Sxy150489 	/* Page 800 works differently than the rest so it has its own func */
2257*5779Sxy150489 	if (page == BM_WUC_PAGE) {
2258*5779Sxy150489 		ret_val = e1000_access_phy_wakeup_reg_bm(hw,
2259*5779Sxy150489 		    offset, data, TRUE);
2260*5779Sxy150489 		goto out;
2261*5779Sxy150489 	}
2262*5779Sxy150489 
2263*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
2264*5779Sxy150489 	if (ret_val)
2265*5779Sxy150489 		goto out;
2266*5779Sxy150489 
2267*5779Sxy150489 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2268*5779Sxy150489 
2269*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2270*5779Sxy150489 		/*
2271*5779Sxy150489 		 * Page select is register 31 for phy address 1 and 22 for
2272*5779Sxy150489 		 * phy address 2 and 3. Page select is shifted only for
2273*5779Sxy150489 		 * phy address 1.
2274*5779Sxy150489 		 */
2275*5779Sxy150489 		if (hw->phy.addr == 1) {
2276*5779Sxy150489 			page_shift = IGP_PAGE_SHIFT;
2277*5779Sxy150489 			page_select = IGP01E1000_PHY_PAGE_SELECT;
2278*5779Sxy150489 		} else {
2279*5779Sxy150489 			page_shift = 0;
2280*5779Sxy150489 			page_select = BM_PHY_PAGE_SELECT;
2281*5779Sxy150489 		}
2282*5779Sxy150489 
2283*5779Sxy150489 		/* Page is shifted left, PHY expects (page x 32) */
2284*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw, page_select,
2285*5779Sxy150489 		    (page << page_shift));
2286*5779Sxy150489 		if (ret_val) {
2287*5779Sxy150489 			e1000_release_phy(hw);
2288*5779Sxy150489 			goto out;
2289*5779Sxy150489 		}
2290*5779Sxy150489 	}
2291*5779Sxy150489 
2292*5779Sxy150489 	ret_val = e1000_read_phy_reg_mdic(hw,
2293*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset,
2294*5779Sxy150489 	    data);
2295*5779Sxy150489 	e1000_release_phy(hw);
2296*5779Sxy150489 
2297*5779Sxy150489 out:
2298*5779Sxy150489 	return (ret_val);
2299*5779Sxy150489 }
2300*5779Sxy150489 
2301*5779Sxy150489 /*
2302*5779Sxy150489  * e1000_read_phy_reg_bm2 - Read BM PHY register
2303*5779Sxy150489  * @hw: pointer to the HW structure
2304*5779Sxy150489  * @offset: register offset to be read
2305*5779Sxy150489  * @data: pointer to the read data
2306*5779Sxy150489  *
2307*5779Sxy150489  * Acquires semaphore, if necessary, then reads the PHY register at offset
2308*5779Sxy150489  * and storing the retrieved information in data.  Release any acquired
2309*5779Sxy150489  * semaphores before exiting.
2310*5779Sxy150489  */
2311*5779Sxy150489 s32
2312*5779Sxy150489 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2313*5779Sxy150489 {
2314*5779Sxy150489 	s32 ret_val;
2315*5779Sxy150489 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2316*5779Sxy150489 
2317*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_bm2");
2318*5779Sxy150489 
2319*5779Sxy150489 	/* Page 800 works differently than the rest so it has its own func */
2320*5779Sxy150489 	if (page == BM_WUC_PAGE) {
2321*5779Sxy150489 		ret_val = e1000_access_phy_wakeup_reg_bm(hw,
2322*5779Sxy150489 		    offset, data, TRUE);
2323*5779Sxy150489 		goto out;
2324*5779Sxy150489 	}
2325*5779Sxy150489 
2326*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
2327*5779Sxy150489 	if (ret_val)
2328*5779Sxy150489 		goto out;
2329*5779Sxy150489 
2330*5779Sxy150489 	hw->phy.addr = 1;
2331*5779Sxy150489 
2332*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2333*5779Sxy150489 
2334*5779Sxy150489 		/* Page is shifted left, PHY expects (page x 32) */
2335*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw,
2336*5779Sxy150489 		    BM_PHY_PAGE_SELECT,
2337*5779Sxy150489 		    page);
2338*5779Sxy150489 
2339*5779Sxy150489 		if (ret_val) {
2340*5779Sxy150489 			e1000_release_phy(hw);
2341*5779Sxy150489 			goto out;
2342*5779Sxy150489 		}
2343*5779Sxy150489 	}
2344*5779Sxy150489 
2345*5779Sxy150489 	ret_val = e1000_read_phy_reg_mdic(hw,
2346*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset,
2347*5779Sxy150489 	    data);
2348*5779Sxy150489 	e1000_release_phy(hw);
2349*5779Sxy150489 
2350*5779Sxy150489 out:
2351*5779Sxy150489 	return (ret_val);
2352*5779Sxy150489 }
2353*5779Sxy150489 
2354*5779Sxy150489 /*
2355*5779Sxy150489  * e1000_write_phy_reg_bm2 - Write BM PHY register
2356*5779Sxy150489  * @hw: pointer to the HW structure
2357*5779Sxy150489  * @offset: register offset to write to
2358*5779Sxy150489  * @data: data to write at register offset
2359*5779Sxy150489  *
2360*5779Sxy150489  * Acquires semaphore, if necessary, then writes the data to PHY register
2361*5779Sxy150489  * at the offset.  Release any acquired semaphores before exiting.
2362*5779Sxy150489  */
2363*5779Sxy150489 s32
2364*5779Sxy150489 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2365*5779Sxy150489 {
2366*5779Sxy150489 	s32 ret_val;
2367*5779Sxy150489 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2368*5779Sxy150489 
2369*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_bm2");
2370*5779Sxy150489 
2371*5779Sxy150489 	/* Page 800 works differently than the rest so it has its own func */
2372*5779Sxy150489 	if (page == BM_WUC_PAGE) {
2373*5779Sxy150489 		ret_val = e1000_access_phy_wakeup_reg_bm(hw,
2374*5779Sxy150489 		    offset, &data, FALSE);
2375*5779Sxy150489 		goto out;
2376*5779Sxy150489 	}
2377*5779Sxy150489 
2378*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
2379*5779Sxy150489 	if (ret_val)
2380*5779Sxy150489 		goto out;
2381*5779Sxy150489 
2382*5779Sxy150489 	hw->phy.addr = 1;
2383*5779Sxy150489 
2384*5779Sxy150489 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2385*5779Sxy150489 		/* Page is shifted left, PHY expects (page x 32) */
2386*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw,
2387*5779Sxy150489 		    BM_PHY_PAGE_SELECT,
2388*5779Sxy150489 		    page);
2389*5779Sxy150489 
2390*5779Sxy150489 		if (ret_val) {
2391*5779Sxy150489 			e1000_release_phy(hw);
2392*5779Sxy150489 			goto out;
2393*5779Sxy150489 		}
2394*5779Sxy150489 	}
2395*5779Sxy150489 
2396*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw,
2397*5779Sxy150489 	    MAX_PHY_REG_ADDRESS & offset,
2398*5779Sxy150489 	    data);
2399*5779Sxy150489 
2400*5779Sxy150489 	e1000_release_phy(hw);
2401*5779Sxy150489 
2402*5779Sxy150489 out:
2403*5779Sxy150489 	return (ret_val);
2404*5779Sxy150489 }
2405*5779Sxy150489 
2406*5779Sxy150489 /*
2407*5779Sxy150489  * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
2408*5779Sxy150489  * @hw: pointer to the HW structure
2409*5779Sxy150489  * @offset: register offset to be read or written
2410*5779Sxy150489  * @data: pointer to the data to read or write
2411*5779Sxy150489  * @read: determines if operation is read or write
2412*5779Sxy150489  *
2413*5779Sxy150489  * Acquires semaphore, if necessary, then reads the PHY register at offset
2414*5779Sxy150489  * and storing the retrieved information in data.  Release any acquired
2415*5779Sxy150489  * semaphores before exiting. Note that procedure to read the wakeup
2416*5779Sxy150489  * registers are different. It works as such:
2417*5779Sxy150489  * 1) Set page 769, register 17, bit 2 = 1
2418*5779Sxy150489  * 2) Set page to 800 for host (801 if we were manageability)
2419*5779Sxy150489  * 3) Write the address using the address opcode (0x11)
2420*5779Sxy150489  * 4) Read or write the data using the data opcode (0x12)
2421*5779Sxy150489  * 5) Restore 769_17.2 to its original value
2422*5779Sxy150489  */
2423*5779Sxy150489 s32
2424*5779Sxy150489 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw,
2425*5779Sxy150489     u32 offset, u16 *data, bool read)
2426*5779Sxy150489 {
2427*5779Sxy150489 	s32 ret_val;
2428*5779Sxy150489 	u16 reg = ((u16)offset) & PHY_REG_MASK;
2429*5779Sxy150489 	u16 phy_reg = 0;
2430*5779Sxy150489 	u8  phy_acquired = 1;
2431*5779Sxy150489 
2432*5779Sxy150489 	DEBUGFUNC("e1000_read_phy_wakeup_reg_bm");
2433*5779Sxy150489 
2434*5779Sxy150489 	ret_val = e1000_acquire_phy(hw);
2435*5779Sxy150489 	if (ret_val) {
2436*5779Sxy150489 		DEBUGOUT("Couldnt acquire PHY\n");
2437*5779Sxy150489 		phy_acquired = 0;
2438*5779Sxy150489 		goto out;
2439*5779Sxy150489 	}
2440*5779Sxy150489 
2441*5779Sxy150489 	/* All operations in this function are phy address 1 */
2442*5779Sxy150489 	hw->phy.addr = 1;
2443*5779Sxy150489 
2444*5779Sxy150489 	/* Set page 769 */
2445*5779Sxy150489 	(void) e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
2446*5779Sxy150489 	    (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
2447*5779Sxy150489 
2448*5779Sxy150489 	ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
2449*5779Sxy150489 	if (ret_val) {
2450*5779Sxy150489 		DEBUGOUT("Couldnt read PHY page 769\n");
2451*5779Sxy150489 		goto out;
2452*5779Sxy150489 	}
2453*5779Sxy150489 
2454*5779Sxy150489 	/* First clear bit 4 to avoid a power state change */
2455*5779Sxy150489 	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
2456*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2457*5779Sxy150489 	if (ret_val) {
2458*5779Sxy150489 		DEBUGOUT("Couldnt clear PHY page 769 bit 4\n");
2459*5779Sxy150489 		goto out;
2460*5779Sxy150489 	}
2461*5779Sxy150489 
2462*5779Sxy150489 	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
2463*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
2464*5779Sxy150489 	    phy_reg | BM_WUC_ENABLE_BIT);
2465*5779Sxy150489 	if (ret_val) {
2466*5779Sxy150489 		DEBUGOUT("Couldnt write PHY page 769 bit 2\n");
2467*5779Sxy150489 		goto out;
2468*5779Sxy150489 	}
2469*5779Sxy150489 
2470*5779Sxy150489 	/* Select page 800 */
2471*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw,
2472*5779Sxy150489 	    IGP01E1000_PHY_PAGE_SELECT,
2473*5779Sxy150489 	    (BM_WUC_PAGE << IGP_PAGE_SHIFT));
2474*5779Sxy150489 
2475*5779Sxy150489 	/* Write the page 800 offset value using opcode 0x11 */
2476*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
2477*5779Sxy150489 	if (ret_val) {
2478*5779Sxy150489 		DEBUGOUT("Couldnt write address opcode to page 800\n");
2479*5779Sxy150489 		goto out;
2480*5779Sxy150489 	}
2481*5779Sxy150489 
2482*5779Sxy150489 	if (read) {
2483*5779Sxy150489 		/* Read the page 800 value using opcode 0x12 */
2484*5779Sxy150489 		ret_val = e1000_read_phy_reg_mdic(hw,
2485*5779Sxy150489 		    BM_WUC_DATA_OPCODE,
2486*5779Sxy150489 		    data);
2487*5779Sxy150489 	} else {
2488*5779Sxy150489 		/* Read the page 800 value using opcode 0x12 */
2489*5779Sxy150489 		ret_val = e1000_write_phy_reg_mdic(hw,
2490*5779Sxy150489 		    BM_WUC_DATA_OPCODE,
2491*5779Sxy150489 		    *data);
2492*5779Sxy150489 	}
2493*5779Sxy150489 
2494*5779Sxy150489 	if (ret_val) {
2495*5779Sxy150489 		DEBUGOUT("Couldnt read data value from page 800\n");
2496*5779Sxy150489 		goto out;
2497*5779Sxy150489 	}
2498*5779Sxy150489 
2499*5779Sxy150489 	/*
2500*5779Sxy150489 	 * Restore 769_17.2 to its original value
2501*5779Sxy150489 	 * Set page 769
2502*5779Sxy150489 	 */
2503*5779Sxy150489 	(void) e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
2504*5779Sxy150489 	    (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
2505*5779Sxy150489 
2506*5779Sxy150489 	/* Clear 769_17.2 */
2507*5779Sxy150489 	ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2508*5779Sxy150489 	if (ret_val) {
2509*5779Sxy150489 		DEBUGOUT("Couldnt clear PHY page 769 bit 2\n");
2510*5779Sxy150489 		goto out;
2511*5779Sxy150489 	}
2512*5779Sxy150489 
2513*5779Sxy150489 out:
2514*5779Sxy150489 	if (phy_acquired == 1)
2515*5779Sxy150489 		e1000_release_phy(hw);
2516*5779Sxy150489 	return (ret_val);
2517*5779Sxy150489 }
2518*5779Sxy150489 
2519*5779Sxy150489 /*
2520*5779Sxy150489  * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
2521*5779Sxy150489  * @hw: pointer to the HW structure
2522*5779Sxy150489  *
2523*5779Sxy150489  * In the case of a PHY power down to save power, or to turn off link during a
2524*5779Sxy150489  * driver unload, or wake on lan is not enabled, restore the link to previous
2525*5779Sxy150489  * settings.
2526*5779Sxy150489  */
2527*5779Sxy150489 void
2528*5779Sxy150489 e1000_power_up_phy_copper(struct e1000_hw *hw)
2529*5779Sxy150489 {
2530*5779Sxy150489 	u16 mii_reg = 0;
2531*5779Sxy150489 
2532*5779Sxy150489 	/* The PHY will retain its settings across a power down/up cycle */
2533*5779Sxy150489 	(void) e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
2534*5779Sxy150489 	mii_reg &= ~MII_CR_POWER_DOWN;
2535*5779Sxy150489 	(void) e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg);
2536*5779Sxy150489 }
2537*5779Sxy150489 
2538*5779Sxy150489 /*
2539*5779Sxy150489  * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
2540*5779Sxy150489  * @hw: pointer to the HW structure
2541*5779Sxy150489  *
2542*5779Sxy150489  * In the case of a PHY power down to save power, or to turn off link during a
2543*5779Sxy150489  * driver unload, or wake on lan is not enabled, restore the link to previous
2544*5779Sxy150489  * settings.
2545*5779Sxy150489  */
2546*5779Sxy150489 void
2547*5779Sxy150489 e1000_power_down_phy_copper(struct e1000_hw *hw)
2548*5779Sxy150489 {
2549*5779Sxy150489 	u16 mii_reg = 0;
2550*5779Sxy150489 
2551*5779Sxy150489 	/* The PHY will retain its settings across a power down/up cycle */
2552*5779Sxy150489 	(void) e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
2553*5779Sxy150489 	mii_reg |= MII_CR_POWER_DOWN;
2554*5779Sxy150489 	(void) e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg);
2555*5779Sxy150489 	msec_delay(1);
2556*5779Sxy150489 }
2557