xref: /titanic_52/usr/src/uts/common/io/bge/bge_mii.c (revision 7eea693d6b672899726e75993fddc4e95b52647f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include "bge_impl.h"
28 
29 /*
30  * Bit test macros, returning boolean_t values
31  */
32 #define	BIS(w, b)	(((w) & (b)) ? B_TRUE : B_FALSE)
33 #define	BIC(w, b)	(((w) & (b)) ? B_FALSE : B_TRUE)
34 #define	UPORDOWN(x)	((x) ? "up" : "down")
35 
36 /*
37  * ========== Copper (PHY) support ==========
38  */
39 
40 #define	BGE_DBG		BGE_DBG_PHY	/* debug flag for this code	*/
41 
42 /*
43  * #defines:
44  *	BGE_COPPER_WIRESPEED controls whether the Broadcom WireSpeed(tm)
45  *	feature is enabled.  We need to recheck whether this can be
46  *	enabled; at one time it seemed to interact unpleasantly with the
47  *	loopback modes.
48  *
49  *	BGE_COPPER_IDLEOFF controls whether the (copper) PHY power is
50  *	turned off when the PHY is idled i.e. during driver suspend().
51  *	For now this is disabled because the chip doesn't seem to
52  *	resume cleanly if the PHY power is turned off.
53  */
54 #define	BGE_COPPER_WIRESPEED	B_TRUE
55 #define	BGE_COPPER_IDLEOFF	B_FALSE
56 
57 /*
58  * The arrays below can be indexed by the MODE bits from the Auxiliary
59  * Status register to determine the current speed/duplex settings.
60  */
61 static const int16_t bge_copper_link_speed[] = {
62 	0,				/* MII_AUX_STATUS_MODE_NONE	*/
63 	10,				/* MII_AUX_STATUS_MODE_10_H	*/
64 	10,				/* MII_AUX_STATUS_MODE_10_F	*/
65 	100,				/* MII_AUX_STATUS_MODE_100_H	*/
66 	0,				/* MII_AUX_STATUS_MODE_100_4	*/
67 	100,				/* MII_AUX_STATUS_MODE_100_F	*/
68 	1000,				/* MII_AUX_STATUS_MODE_1000_H	*/
69 	1000				/* MII_AUX_STATUS_MODE_1000_F	*/
70 };
71 
72 static const int8_t bge_copper_link_duplex[] = {
73 	LINK_DUPLEX_UNKNOWN,		/* MII_AUX_STATUS_MODE_NONE	*/
74 	LINK_DUPLEX_HALF,		/* MII_AUX_STATUS_MODE_10_H	*/
75 	LINK_DUPLEX_FULL,		/* MII_AUX_STATUS_MODE_10_F	*/
76 	LINK_DUPLEX_HALF,		/* MII_AUX_STATUS_MODE_100_H	*/
77 	LINK_DUPLEX_UNKNOWN,		/* MII_AUX_STATUS_MODE_100_4	*/
78 	LINK_DUPLEX_FULL,		/* MII_AUX_STATUS_MODE_100_F	*/
79 	LINK_DUPLEX_HALF,		/* MII_AUX_STATUS_MODE_1000_H	*/
80 	LINK_DUPLEX_FULL		/* MII_AUX_STATUS_MODE_1000_F	*/
81 };
82 
83 static const int16_t bge_copper_link_speed_5906[] = {
84 	0,				/* MII_AUX_STATUS_MODE_NONE	*/
85 	10,				/* MII_AUX_STATUS_MODE_10_H	*/
86 	10,				/* MII_AUX_STATUS_MODE_10_F	*/
87 	100,				/* MII_AUX_STATUS_MODE_100_H	*/
88 	0,				/* MII_AUX_STATUS_MODE_100_4	*/
89 	100,				/* MII_AUX_STATUS_MODE_100_F	*/
90 	0,				/* MII_AUX_STATUS_MODE_1000_H	*/
91 	0				/* MII_AUX_STATUS_MODE_1000_F	*/
92 };
93 
94 static const int8_t bge_copper_link_duplex_5906[] = {
95 	LINK_DUPLEX_UNKNOWN,		/* MII_AUX_STATUS_MODE_NONE	*/
96 	LINK_DUPLEX_HALF,		/* MII_AUX_STATUS_MODE_10_H	*/
97 	LINK_DUPLEX_FULL,		/* MII_AUX_STATUS_MODE_10_F	*/
98 	LINK_DUPLEX_HALF,		/* MII_AUX_STATUS_MODE_100_H	*/
99 	LINK_DUPLEX_UNKNOWN,		/* MII_AUX_STATUS_MODE_100_4	*/
100 	LINK_DUPLEX_FULL,		/* MII_AUX_STATUS_MODE_100_F	*/
101 	LINK_DUPLEX_UNKNOWN,		/* MII_AUX_STATUS_MODE_1000_H	*/
102 	LINK_DUPLEX_UNKNOWN		/* MII_AUX_STATUS_MODE_1000_F	*/
103 };
104 
105 #if	BGE_DEBUGGING
106 
107 static void
108 bge_phydump(bge_t *bgep, uint16_t mii_status, uint16_t aux)
109 {
110 	uint16_t regs[32];
111 	int i;
112 
113 	ASSERT(mutex_owned(bgep->genlock));
114 
115 	for (i = 0; i < 32; ++i)
116 		switch (i) {
117 		default:
118 			regs[i] = bge_mii_get16(bgep, i);
119 			break;
120 
121 		case MII_STATUS:
122 			regs[i] = mii_status;
123 			break;
124 
125 		case MII_AUX_STATUS:
126 			regs[i] = aux;
127 			break;
128 
129 		case 0x0b: case 0x0c: case 0x0d: case 0x0e:
130 		case 0x15: case 0x16: case 0x17:
131 		case 0x1c:
132 		case 0x1f:
133 			/* reserved registers -- don't read these */
134 			regs[i] = 0;
135 			break;
136 		}
137 
138 	for (i = 0; i < 32; i += 8)
139 		BGE_DEBUG(("bge_phydump: "
140 		    "0x%04x %04x %04x %04x %04x %04x %04x %04x",
141 		    regs[i+0], regs[i+1], regs[i+2], regs[i+3],
142 		    regs[i+4], regs[i+5], regs[i+6], regs[i+7]));
143 }
144 
145 #endif	/* BGE_DEBUGGING */
146 
147 /*
148  * Basic low-level function to probe for a PHY
149  *
150  * Returns TRUE if the PHY responds with valid data, FALSE otherwise
151  */
152 static boolean_t
153 bge_phy_probe(bge_t *bgep)
154 {
155 	uint16_t miicfg;
156 	uint32_t nicsig, niccfg;
157 
158 	BGE_TRACE(("bge_phy_probe($%p)", (void *)bgep));
159 
160 	ASSERT(mutex_owned(bgep->genlock));
161 
162 	nicsig = bge_nic_read32(bgep, BGE_NIC_DATA_SIG_ADDR);
163 	if (nicsig == BGE_NIC_DATA_SIG) {
164 		niccfg = bge_nic_read32(bgep, BGE_NIC_DATA_NIC_CFG_ADDR);
165 		switch (niccfg & BGE_NIC_CFG_PHY_TYPE_MASK) {
166 		default:
167 		case BGE_NIC_CFG_PHY_TYPE_COPPER:
168 			return (B_TRUE);
169 		case BGE_NIC_CFG_PHY_TYPE_FIBER:
170 			return (B_FALSE);
171 		}
172 	} else {
173 		/*
174 		 * Read the MII_STATUS register twice, in
175 		 * order to clear any sticky bits (but they should
176 		 * have been cleared by the RESET, I think).
177 		 */
178 		miicfg = bge_mii_get16(bgep, MII_STATUS);
179 		miicfg = bge_mii_get16(bgep, MII_STATUS);
180 		BGE_DEBUG(("bge_phy_probe: status 0x%x", miicfg));
181 
182 		/*
183 		 * Now check the value read; it should have at least one bit set
184 		 * (for the device capabilities) and at least one clear (one of
185 		 * the error bits). So if we see all 0s or all 1s, there's a
186 		 * problem.  In particular, bge_mii_get16() returns all 1s if
187 		 * communications fails ...
188 		 */
189 		switch (miicfg) {
190 		case 0x0000:
191 		case 0xffff:
192 			return (B_FALSE);
193 
194 		default :
195 			return (B_TRUE);
196 		}
197 	}
198 }
199 
200 /*
201  * Basic low-level function to reset the PHY.
202  * Doesn't incorporate any special-case workarounds.
203  *
204  * Returns TRUE on success, FALSE if the RESET bit doesn't clear
205  */
206 static boolean_t
207 bge_phy_reset(bge_t *bgep)
208 {
209 	uint16_t control;
210 	uint_t count;
211 
212 	BGE_TRACE(("bge_phy_reset($%p)", (void *)bgep));
213 
214 	ASSERT(mutex_owned(bgep->genlock));
215 
216 	if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
217 		drv_usecwait(40);
218 		/* put PHY into ready state */
219 		bge_reg_clr32(bgep, MISC_CONFIG_REG, MISC_CONFIG_EPHY_IDDQ);
220 		(void) bge_reg_get32(bgep, MISC_CONFIG_REG); /* flush */
221 		drv_usecwait(40);
222 	}
223 
224 	/*
225 	 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
226 	 */
227 	bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_RESET);
228 	for (count = 0; ++count < 1000; ) {
229 		drv_usecwait(5);
230 		control = bge_mii_get16(bgep, MII_CONTROL);
231 		if (BIC(control, MII_CONTROL_RESET))
232 			return (B_TRUE);
233 	}
234 
235 	/* Adjust output voltage (From bsd driver) */
236 	if (DEVICE_5906_SERIES_CHIPSETS(bgep))
237 		bge_mii_put16(bgep, 0x17, 0x12);
238 
239 	BGE_DEBUG(("bge_phy_reset: FAILED, control now 0x%x", control));
240 
241 	return (B_FALSE);
242 }
243 
244 /*
245  * Basic low-level function to powerdown the PHY, if supported
246  * If powerdown support is compiled out, this function does nothing.
247  */
248 static void
249 bge_phy_powerdown(bge_t *bgep)
250 {
251 	BGE_TRACE(("bge_phy_powerdown"));
252 #if	BGE_COPPER_IDLEOFF
253 	bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_PWRDN);
254 #endif	/* BGE_COPPER_IDLEOFF */
255 }
256 
257 /*
258  * The following functions are based on sample code provided by
259  * Broadcom (20-June-2003), and implement workarounds said to be
260  * required on the early revisions of the BCM5703/4C.
261  *
262  * The registers and values used are mostly UNDOCUMENTED, and
263  * therefore don't have symbolic names ;-(
264  *
265  * Many of the comments are straight out of the Broadcom code:
266  * even where the code has been restructured, the original
267  * comments have been preserved in order to explain what these
268  * undocumented registers & values are all about ...
269  */
270 
271 static void
272 bge_phy_macro_wait(bge_t *bgep)
273 {
274 	uint_t count;
275 
276 	for (count = 100; --count; )
277 		if ((bge_mii_get16(bgep, 0x16) & 0x1000) == 0)
278 			break;
279 }
280 
281 /*
282  * PHY test data pattern:
283  *
284  * For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
285  * For 5705,    each DFE TAP has 19-bits (low word 15, hi word 4)
286  * For simplicity, we check only 19-bits, so we don't have to
287  * distinguish which chip it is.
288  * the LO word contains 15 bits, make sure pattern data is < 0x7fff
289  * the HI word contains  6 bits, make sure pattern data is < 0x003f
290  */
291 #define	N_CHANNELS	4
292 #define	N_TAPS		3
293 
294 static struct {
295 	uint16_t	lo;
296 	uint16_t	hi;
297 } tap_data[N_CHANNELS][N_TAPS] = {
298 	{
299 		{ 0x5555, 0x0005 },	/* ch0, TAP 0, LO/HI pattern */
300 		{ 0x2aaa, 0x000a },	/* ch0, TAP 1, LO/HI pattern */
301 		{ 0x3456, 0x0003 }	/* ch0, TAP 2, LO/HI pattern */
302 	},
303 	{
304 		{ 0x2aaa, 0x000a },	/* ch1, TAP 0, LO/HI pattern */
305 		{ 0x3333, 0x0003 },	/* ch1, TAP 1, LO/HI pattern */
306 		{ 0x789a, 0x0005 }	/* ch1, TAP 2, LO/HI pattern */
307 	},
308 	{
309 		{ 0x5a5a, 0x0005 },	/* ch2, TAP 0, LO/HI pattern */
310 		{ 0x2a6a, 0x000a },	/* ch2, TAP 1, LO/HI pattern */
311 		{ 0x1bcd, 0x0003 }	/* ch2, TAP 2, LO/HI pattern */
312 	},
313 	{
314 		{ 0x2a5a, 0x000a },	/* ch3, TAP 0, LO/HI pattern */
315 		{ 0x33c3, 0x0003 },	/* ch3, TAP 1, LO/HI pattern */
316 		{ 0x2ef1, 0x0005 }	/* ch3, TAP 2, LO/HI pattern */
317 	}
318 };
319 
320 /*
321  * Check whether the PHY has locked up after a RESET.
322  *
323  * Returns TRUE if it did, FALSE is it's OK ;-)
324  */
325 static boolean_t
326 bge_phy_locked_up(bge_t *bgep)
327 {
328 	uint16_t dataLo;
329 	uint16_t dataHi;
330 	uint_t chan;
331 	uint_t tap;
332 
333 	/*
334 	 * Check TAPs for all 4 channels, as soon as we see a lockup
335 	 * we'll stop checking.
336 	 */
337 	for (chan = 0; chan < N_CHANNELS; ++chan) {
338 		/* Select channel and set TAP index to 0 */
339 		bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200);
340 		/* Freeze filter again just to be safe */
341 		bge_mii_put16(bgep, 0x16, 0x0002);
342 
343 		/*
344 		 * Write fixed pattern to the RAM, 3 TAPs for
345 		 * each channel, each TAP have 2 WORDs (LO/HI)
346 		 */
347 		for (tap = 0; tap < N_TAPS; ++tap) {
348 			bge_mii_put16(bgep, 0x15, tap_data[chan][tap].lo);
349 			bge_mii_put16(bgep, 0x15, tap_data[chan][tap].hi);
350 		}
351 
352 		/*
353 		 * Active PHY's Macro operation to write DFE
354 		 * TAP from RAM, and wait for Macro to complete.
355 		 */
356 		bge_mii_put16(bgep, 0x16, 0x0202);
357 		bge_phy_macro_wait(bgep);
358 
359 		/*
360 		 * Done with write phase, now begin read phase.
361 		 */
362 
363 		/* Select channel and set TAP index to 0 */
364 		bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200);
365 
366 		/*
367 		 * Active PHY's Macro operation to load DFE
368 		 * TAP to RAM, and wait for Macro to complete
369 		 */
370 		bge_mii_put16(bgep, 0x16, 0x0082);
371 		bge_phy_macro_wait(bgep);
372 
373 		/* Enable "pre-fetch" */
374 		bge_mii_put16(bgep, 0x16, 0x0802);
375 		bge_phy_macro_wait(bgep);
376 
377 		/*
378 		 * Read back the TAP values.  3 TAPs for each
379 		 * channel, each TAP have 2 WORDs (LO/HI)
380 		 */
381 		for (tap = 0; tap < N_TAPS; ++tap) {
382 			/*
383 			 * Read Lo/Hi then wait for 'done' is faster.
384 			 * For DFE TAP, the HI word contains 6 bits,
385 			 * LO word contains 15 bits
386 			 */
387 			dataLo = bge_mii_get16(bgep, 0x15) & 0x7fff;
388 			dataHi = bge_mii_get16(bgep, 0x15) & 0x003f;
389 			bge_phy_macro_wait(bgep);
390 
391 			/*
392 			 * Check if what we wrote is what we read back.
393 			 * If failed, then the PHY is locked up, we need
394 			 * to do PHY reset again
395 			 */
396 			if (dataLo != tap_data[chan][tap].lo)
397 				return (B_TRUE);	/* wedged!	*/
398 
399 			if (dataHi != tap_data[chan][tap].hi)
400 				return (B_TRUE);	/* wedged!	*/
401 		}
402 	}
403 
404 	/*
405 	 * The PHY isn't locked up ;-)
406 	 */
407 	return (B_FALSE);
408 }
409 
410 /*
411  * Special-case code to reset the PHY on the 5702/5703/5704C/5705/5782.
412  * Tries up to 5 times to recover from failure to reset or PHY lockup.
413  *
414  * Returns TRUE on success, FALSE if there's an unrecoverable problem
415  */
416 static boolean_t
417 bge_phy_reset_and_check(bge_t *bgep)
418 {
419 	boolean_t reset_success;
420 	boolean_t phy_locked;
421 	uint16_t extctrl;
422 	uint_t retries;
423 
424 	for (retries = 0; retries < 5; ++retries) {
425 		/* Issue a phy reset, and wait for reset to complete */
426 		/* Assuming reset is successful first */
427 		reset_success = bge_phy_reset(bgep);
428 
429 		/*
430 		 * Now go check the DFE TAPs to see if locked up, but
431 		 * first, we need to set up PHY so we can read DFE
432 		 * TAPs.
433 		 */
434 
435 		/*
436 		 * Disable Transmitter and Interrupt, while we play
437 		 * with the PHY registers, so the link partner won't
438 		 * see any strange data and the Driver won't see any
439 		 * interrupts.
440 		 */
441 		extctrl = bge_mii_get16(bgep, 0x10);
442 		bge_mii_put16(bgep, 0x10, extctrl | 0x3000);
443 
444 		/* Setup Full-Duplex, 1000 mbps */
445 		bge_mii_put16(bgep, 0x0, 0x0140);
446 
447 		/* Set to Master mode */
448 		bge_mii_put16(bgep, 0x9, 0x1800);
449 
450 		/* Enable SM_DSP_CLOCK & 6dB */
451 		bge_mii_put16(bgep, 0x18, 0x0c00);	/* "the ADC fix" */
452 
453 		/* Work-arounds */
454 		bge_mii_put16(bgep, 0x17, 0x201f);
455 		bge_mii_put16(bgep, 0x15, 0x2aaa);
456 
457 		/* More workarounds */
458 		bge_mii_put16(bgep, 0x17, 0x000a);
459 		bge_mii_put16(bgep, 0x15, 0x0323);	/* "the Gamma fix" */
460 
461 		/* Blocks the PHY control access */
462 		bge_mii_put16(bgep, 0x17, 0x8005);
463 		bge_mii_put16(bgep, 0x15, 0x0800);
464 
465 		/* Test whether PHY locked up ;-( */
466 		phy_locked = bge_phy_locked_up(bgep);
467 		if (reset_success && !phy_locked)
468 			break;
469 
470 		/*
471 		 * Some problem here ... log it & retry
472 		 */
473 		if (!reset_success)
474 			BGE_REPORT((bgep, "PHY didn't reset!"));
475 		if (phy_locked)
476 			BGE_REPORT((bgep, "PHY locked up!"));
477 	}
478 
479 	/* Remove block phy control */
480 	bge_mii_put16(bgep, 0x17, 0x8005);
481 	bge_mii_put16(bgep, 0x15, 0x0000);
482 
483 	/* Unfreeze DFE TAP filter for all channels */
484 	bge_mii_put16(bgep, 0x17, 0x8200);
485 	bge_mii_put16(bgep, 0x16, 0x0000);
486 
487 	/* Restore PHY back to operating state */
488 	bge_mii_put16(bgep, 0x18, 0x0400);
489 
490 	/* Enable transmitter and interrupt */
491 	extctrl = bge_mii_get16(bgep, 0x10);
492 	bge_mii_put16(bgep, 0x10, extctrl & ~0x3000);
493 
494 	/* Adjust output voltage (From bsd driver) */
495 	if (DEVICE_5906_SERIES_CHIPSETS(bgep))
496 		bge_mii_put16(bgep, 0x17, 0x12);
497 
498 	if (!reset_success)
499 		bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
500 	else if (phy_locked)
501 		bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
502 	return (reset_success && !phy_locked);
503 }
504 
505 static void
506 bge_phy_tweak_gmii(bge_t *bgep)
507 {
508 	/* Tweak GMII timing */
509 	bge_mii_put16(bgep, 0x1c, 0x8d68);
510 	bge_mii_put16(bgep, 0x1c, 0x8d68);
511 }
512 
513 /* Bit Error Rate reduction fix */
514 static void
515 bge_phy_bit_err_fix(bge_t *bgep)
516 {
517 	bge_mii_put16(bgep, 0x18, 0x0c00);
518 	bge_mii_put16(bgep, 0x17, 0x000a);
519 	bge_mii_put16(bgep, 0x15, 0x310b);
520 	bge_mii_put16(bgep, 0x17, 0x201f);
521 	bge_mii_put16(bgep, 0x15, 0x9506);
522 	bge_mii_put16(bgep, 0x17, 0x401f);
523 	bge_mii_put16(bgep, 0x15, 0x14e2);
524 	bge_mii_put16(bgep, 0x18, 0x0400);
525 }
526 
527 /*
528  * End of Broadcom-derived workaround code				*
529  */
530 
531 static int
532 bge_restart_copper(bge_t *bgep, boolean_t powerdown)
533 {
534 	uint16_t phy_status;
535 	boolean_t reset_ok;
536 
537 	BGE_TRACE(("bge_restart_copper($%p, %d)", (void *)bgep, powerdown));
538 
539 	ASSERT(mutex_owned(bgep->genlock));
540 
541 	switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
542 	default:
543 		/*
544 		 * Shouldn't happen; it means we don't recognise this chip.
545 		 * It's probably a new one, so we'll try our best anyway ...
546 		 */
547 	case MHCR_CHIP_ASIC_REV_5703:
548 	case MHCR_CHIP_ASIC_REV_5704:
549 	case MHCR_CHIP_ASIC_REV_5705:
550 	case MHCR_CHIP_ASIC_REV_5721_5751:
551 	case MHCR_CHIP_ASIC_REV_5752:
552 	case MHCR_CHIP_ASIC_REV_5714:
553 	case MHCR_CHIP_ASIC_REV_5715:
554 		reset_ok = bge_phy_reset_and_check(bgep);
555 		break;
556 
557 	case MHCR_CHIP_ASIC_REV_5906:
558 	case MHCR_CHIP_ASIC_REV_5700:
559 	case MHCR_CHIP_ASIC_REV_5701:
560 		/*
561 		 * Just a plain reset; the "check" code breaks these chips
562 		 */
563 		reset_ok = bge_phy_reset(bgep);
564 		if (!reset_ok)
565 			bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
566 		break;
567 	}
568 	if (!reset_ok) {
569 		BGE_REPORT((bgep, "PHY failed to reset correctly"));
570 		return (DDI_FAILURE);
571 	}
572 
573 	/*
574 	 * Step 5: disable WOL (not required after RESET)
575 	 *
576 	 * Step 6: refer to errata
577 	 */
578 	switch (bgep->chipid.asic_rev) {
579 	default:
580 		break;
581 
582 	case MHCR_CHIP_REV_5704_A0:
583 		bge_phy_tweak_gmii(bgep);
584 		break;
585 	}
586 
587 	switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
588 	case MHCR_CHIP_ASIC_REV_5705:
589 	case MHCR_CHIP_ASIC_REV_5721_5751:
590 		bge_phy_bit_err_fix(bgep);
591 		break;
592 	}
593 
594 	/*
595 	 * Step 7: read the MII_INTR_STATUS register twice,
596 	 * in order to clear any sticky bits (but they should
597 	 * have been cleared by the RESET, I think), and we're
598 	 * not using PHY interrupts anyway.
599 	 *
600 	 * Step 8: enable the PHY to interrupt on link status
601 	 * change (not required)
602 	 *
603 	 * Step 9: configure PHY LED Mode - not applicable?
604 	 *
605 	 * Step 10: read the MII_STATUS register twice, in
606 	 * order to clear any sticky bits (but they should
607 	 * have been cleared by the RESET, I think).
608 	 */
609 	phy_status = bge_mii_get16(bgep, MII_STATUS);
610 	phy_status = bge_mii_get16(bgep, MII_STATUS);
611 	BGE_DEBUG(("bge_restart_copper: status 0x%x", phy_status));
612 
613 	/*
614 	 * Finally, shut down the PHY, if required
615 	 */
616 	if (powerdown)
617 		bge_phy_powerdown(bgep);
618 	return (DDI_SUCCESS);
619 }
620 
621 /*
622  * Synchronise the (copper) PHY's speed/duplex/autonegotiation capabilities
623  * and advertisements with the required settings as specified by the various
624  * param_* variables that can be poked via the NDD interface.
625  *
626  * We always reset the PHY and reprogram *all* the relevant registers,
627  * not just those changed.  This should cause the link to go down, and then
628  * back up again once the link is stable and autonegotiation (if enabled)
629  * is complete.  We should get a link state change interrupt somewhere along
630  * the way ...
631  *
632  * NOTE: <genlock> must already be held by the caller
633  */
634 static int
635 bge_update_copper(bge_t *bgep)
636 {
637 	boolean_t adv_autoneg;
638 	boolean_t adv_pause;
639 	boolean_t adv_asym_pause;
640 	boolean_t adv_1000fdx;
641 	boolean_t adv_1000hdx;
642 	boolean_t adv_100fdx;
643 	boolean_t adv_100hdx;
644 	boolean_t adv_10fdx;
645 	boolean_t adv_10hdx;
646 
647 	uint16_t control;
648 	uint16_t gigctrl;
649 	uint16_t auxctrl;
650 	uint16_t anar;
651 
652 	BGE_TRACE(("bge_update_copper($%p)", (void *)bgep));
653 
654 	ASSERT(mutex_owned(bgep->genlock));
655 
656 	BGE_DEBUG(("bge_update_copper: autoneg %d "
657 	    "pause %d asym_pause %d "
658 	    "1000fdx %d 1000hdx %d "
659 	    "100fdx %d 100hdx %d "
660 	    "10fdx %d 10hdx %d ",
661 	    bgep->param_adv_autoneg,
662 	    bgep->param_adv_pause, bgep->param_adv_asym_pause,
663 	    bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
664 	    bgep->param_adv_100fdx, bgep->param_adv_100hdx,
665 	    bgep->param_adv_10fdx, bgep->param_adv_10hdx));
666 
667 	control = gigctrl = auxctrl = anar = 0;
668 
669 	/*
670 	 * PHY settings are normally based on the param_* variables,
671 	 * but if any loopback mode is in effect, that takes precedence.
672 	 *
673 	 * BGE supports MAC-internal loopback, PHY-internal loopback,
674 	 * and External loopback at a variety of speeds (with a special
675 	 * cable).  In all cases, autoneg is turned OFF, full-duplex
676 	 * is turned ON, and the speed/mastership is forced.
677 	 */
678 	switch (bgep->param_loop_mode) {
679 	case BGE_LOOP_NONE:
680 	default:
681 		adv_autoneg = bgep->param_adv_autoneg;
682 		adv_pause = bgep->param_adv_pause;
683 		adv_asym_pause = bgep->param_adv_asym_pause;
684 		adv_1000fdx = bgep->param_adv_1000fdx;
685 		adv_1000hdx = bgep->param_adv_1000hdx;
686 		adv_100fdx = bgep->param_adv_100fdx;
687 		adv_100hdx = bgep->param_adv_100hdx;
688 		adv_10fdx = bgep->param_adv_10fdx;
689 		adv_10hdx = bgep->param_adv_10hdx;
690 		break;
691 
692 	case BGE_LOOP_EXTERNAL_1000:
693 	case BGE_LOOP_EXTERNAL_100:
694 	case BGE_LOOP_EXTERNAL_10:
695 	case BGE_LOOP_INTERNAL_PHY:
696 	case BGE_LOOP_INTERNAL_MAC:
697 		adv_autoneg = adv_pause = adv_asym_pause = B_FALSE;
698 		adv_1000fdx = adv_100fdx = adv_10fdx = B_FALSE;
699 		adv_1000hdx = adv_100hdx = adv_10hdx = B_FALSE;
700 		bgep->param_link_duplex = LINK_DUPLEX_FULL;
701 
702 		switch (bgep->param_loop_mode) {
703 		case BGE_LOOP_EXTERNAL_1000:
704 			bgep->param_link_speed = 1000;
705 			adv_1000fdx = B_TRUE;
706 			auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
707 			gigctrl |= MII_1000BT_CTL_MASTER_CFG;
708 			gigctrl |= MII_1000BT_CTL_MASTER_SEL;
709 			break;
710 
711 		case BGE_LOOP_EXTERNAL_100:
712 			bgep->param_link_speed = 100;
713 			adv_100fdx = B_TRUE;
714 			auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
715 			break;
716 
717 		case BGE_LOOP_EXTERNAL_10:
718 			bgep->param_link_speed = 10;
719 			adv_10fdx = B_TRUE;
720 			auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
721 			break;
722 
723 		case BGE_LOOP_INTERNAL_PHY:
724 			bgep->param_link_speed = 1000;
725 			adv_1000fdx = B_TRUE;
726 			control = MII_CONTROL_LOOPBACK;
727 			break;
728 
729 		case BGE_LOOP_INTERNAL_MAC:
730 			bgep->param_link_speed = 1000;
731 			adv_1000fdx = B_TRUE;
732 			break;
733 		}
734 	}
735 
736 	BGE_DEBUG(("bge_update_copper: autoneg %d "
737 	    "pause %d asym_pause %d "
738 	    "1000fdx %d 1000hdx %d "
739 	    "100fdx %d 100hdx %d "
740 	    "10fdx %d 10hdx %d ",
741 	    adv_autoneg,
742 	    adv_pause, adv_asym_pause,
743 	    adv_1000fdx, adv_1000hdx,
744 	    adv_100fdx, adv_100hdx,
745 	    adv_10fdx, adv_10hdx));
746 
747 	/*
748 	 * We should have at least one technology capability set;
749 	 * if not, we select a default of 1000Mb/s full-duplex
750 	 */
751 	if (!adv_1000fdx && !adv_100fdx && !adv_10fdx &&
752 	    !adv_1000hdx && !adv_100hdx && !adv_10hdx)
753 		adv_1000fdx = B_TRUE;
754 
755 	/*
756 	 * Now transform the adv_* variables into the proper settings
757 	 * of the PHY registers ...
758 	 *
759 	 * If autonegotiation is (now) enabled, we want to trigger
760 	 * a new autonegotiation cycle once the PHY has been
761 	 * programmed with the capabilities to be advertised.
762 	 */
763 	if (adv_autoneg)
764 		control |= MII_CONTROL_ANE|MII_CONTROL_RSAN;
765 
766 	if (adv_1000fdx)
767 		control |= MII_CONTROL_1000MB|MII_CONTROL_FDUPLEX;
768 	else if (adv_1000hdx)
769 		control |= MII_CONTROL_1000MB;
770 	else if (adv_100fdx)
771 		control |= MII_CONTROL_100MB|MII_CONTROL_FDUPLEX;
772 	else if (adv_100hdx)
773 		control |= MII_CONTROL_100MB;
774 	else if (adv_10fdx)
775 		control |= MII_CONTROL_FDUPLEX;
776 	else if (adv_10hdx)
777 		control |= 0;
778 	else
779 		{ _NOTE(EMPTY); }	/* Can't get here anyway ...	*/
780 
781 	if (adv_1000fdx)
782 		gigctrl |= MII_1000BT_CTL_ADV_FDX;
783 	if (adv_1000hdx)
784 		gigctrl |= MII_1000BT_CTL_ADV_HDX;
785 
786 	if (adv_100fdx)
787 		anar |= MII_ABILITY_100BASE_TX_FD;
788 	if (adv_100hdx)
789 		anar |= MII_ABILITY_100BASE_TX;
790 	if (adv_10fdx)
791 		anar |= MII_ABILITY_10BASE_T_FD;
792 	if (adv_10hdx)
793 		anar |= MII_ABILITY_10BASE_T;
794 
795 	if (adv_pause)
796 		anar |= MII_ABILITY_PAUSE;
797 	if (adv_asym_pause)
798 		anar |= MII_ABILITY_ASYM_PAUSE;
799 
800 	/*
801 	 * Munge in any other fixed bits we require ...
802 	 */
803 	anar |= MII_AN_SELECTOR_8023;
804 	auxctrl |= MII_AUX_CTRL_NORM_TX_MODE;
805 	auxctrl |= MII_AUX_CTRL_NORMAL;
806 
807 	/*
808 	 * Restart the PHY and write the new values.  Note the
809 	 * time, so that we can say whether subsequent link state
810 	 * changes can be attributed to our reprogramming the PHY
811 	 */
812 	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) == DDI_FAILURE)
813 		return (DDI_FAILURE);
814 	bge_mii_put16(bgep, MII_AN_ADVERT, anar);
815 	bge_mii_put16(bgep, MII_CONTROL, control);
816 	bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl);
817 	bge_mii_put16(bgep, MII_1000BASE_T_CONTROL, gigctrl);
818 
819 	BGE_DEBUG(("bge_update_copper: anar <- 0x%x", anar));
820 	BGE_DEBUG(("bge_update_copper: control <- 0x%x", control));
821 	BGE_DEBUG(("bge_update_copper: auxctrl <- 0x%x", auxctrl));
822 	BGE_DEBUG(("bge_update_copper: gigctrl <- 0x%x", gigctrl));
823 
824 #if	BGE_COPPER_WIRESPEED
825 	/*
826 	 * Enable the 'wire-speed' feature, if the chip supports it
827 	 * and we haven't got (any) loopback mode selected.
828 	 */
829 	switch (bgep->chipid.device) {
830 	case DEVICE_ID_5700:
831 	case DEVICE_ID_5700x:
832 	case DEVICE_ID_5705C:
833 	case DEVICE_ID_5782:
834 		/*
835 		 * These chips are known or assumed not to support it
836 		 */
837 		break;
838 
839 	default:
840 		/*
841 		 * All other Broadcom chips are expected to support it.
842 		 */
843 		if (bgep->param_loop_mode == BGE_LOOP_NONE)
844 			bge_mii_put16(bgep, MII_AUX_CONTROL,
845 			    MII_AUX_CTRL_MISC_WRITE_ENABLE |
846 			    MII_AUX_CTRL_MISC_WIRE_SPEED |
847 			    MII_AUX_CTRL_MISC);
848 		break;
849 	}
850 #endif	/* BGE_COPPER_WIRESPEED */
851 	return (DDI_SUCCESS);
852 }
853 
854 static boolean_t
855 bge_check_copper(bge_t *bgep, boolean_t recheck)
856 {
857 	uint32_t emac_status;
858 	uint16_t mii_status;
859 	uint16_t aux;
860 	uint_t mode;
861 	boolean_t linkup;
862 
863 	/*
864 	 * Step 10: read the status from the PHY (which is self-clearing
865 	 * on read!); also read & clear the main (Ethernet) MAC status
866 	 * (the relevant bits of this are write-one-to-clear).
867 	 */
868 	mii_status = bge_mii_get16(bgep, MII_STATUS);
869 	emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG);
870 	bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, emac_status);
871 
872 	BGE_DEBUG(("bge_check_copper: link %d/%s, MII status 0x%x "
873 	    "(was 0x%x), Ethernet MAC status 0x%x",
874 	    bgep->link_state, UPORDOWN(bgep->param_link_up), mii_status,
875 	    bgep->phy_gen_status, emac_status));
876 
877 	/*
878 	 * If the PHY status hasn't changed since last we looked, and
879 	 * we not forcing a recheck (i.e. the link state was already
880 	 * known), there's nothing to do.
881 	 */
882 	if (mii_status == bgep->phy_gen_status && !recheck)
883 		return (B_FALSE);
884 
885 	do {
886 		/*
887 		 * Step 11: read AUX STATUS register to find speed/duplex
888 		 */
889 		aux = bge_mii_get16(bgep, MII_AUX_STATUS);
890 		BGE_CDB(bge_phydump, (bgep, mii_status, aux));
891 
892 		/*
893 		 * We will only consider the link UP if all the readings
894 		 * are consistent and give meaningful results ...
895 		 */
896 		mode = aux & MII_AUX_STATUS_MODE_MASK;
897 		mode >>= MII_AUX_STATUS_MODE_SHIFT;
898 		if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
899 			linkup = BIS(aux, MII_AUX_STATUS_LINKUP);
900 			linkup &= BIS(mii_status, MII_STATUS_LINKUP);
901 		} else {
902 			linkup = bge_copper_link_speed[mode] > 0;
903 			linkup &= bge_copper_link_duplex[mode] !=
904 			    LINK_DUPLEX_UNKNOWN;
905 			linkup &= BIS(aux, MII_AUX_STATUS_LINKUP);
906 			linkup &= BIS(mii_status, MII_STATUS_LINKUP);
907 		}
908 
909 		BGE_DEBUG(("bge_check_copper: MII status 0x%x aux 0x%x "
910 		    "=> mode %d (%s)",
911 		    mii_status, aux,
912 		    mode, UPORDOWN(linkup)));
913 
914 		/*
915 		 * Record current register values, then reread status
916 		 * register & loop until it stabilises ...
917 		 */
918 		bgep->phy_aux_status = aux;
919 		bgep->phy_gen_status = mii_status;
920 		mii_status = bge_mii_get16(bgep, MII_STATUS);
921 	} while (mii_status != bgep->phy_gen_status);
922 
923 	/*
924 	 * Assume very little ...
925 	 */
926 	bgep->param_lp_autoneg = B_FALSE;
927 	bgep->param_lp_1000fdx = B_FALSE;
928 	bgep->param_lp_1000hdx = B_FALSE;
929 	bgep->param_lp_100fdx = B_FALSE;
930 	bgep->param_lp_100hdx = B_FALSE;
931 	bgep->param_lp_10fdx = B_FALSE;
932 	bgep->param_lp_10hdx = B_FALSE;
933 	bgep->param_lp_pause = B_FALSE;
934 	bgep->param_lp_asym_pause = B_FALSE;
935 	bgep->param_link_autoneg = B_FALSE;
936 	bgep->param_link_tx_pause = B_FALSE;
937 	if (bgep->param_adv_autoneg)
938 		bgep->param_link_rx_pause = B_FALSE;
939 	else
940 		bgep->param_link_rx_pause = bgep->param_adv_pause;
941 
942 	/*
943 	 * Discover all the link partner's abilities.
944 	 * These are scattered through various registers ...
945 	 */
946 	if (BIS(aux, MII_AUX_STATUS_LP_ANEG_ABLE)) {
947 		bgep->param_lp_autoneg = B_TRUE;
948 		bgep->param_link_autoneg = B_TRUE;
949 		bgep->param_link_tx_pause = BIS(aux, MII_AUX_STATUS_TX_PAUSE);
950 		bgep->param_link_rx_pause = BIS(aux, MII_AUX_STATUS_RX_PAUSE);
951 
952 		aux = bge_mii_get16(bgep, MII_1000BASE_T_STATUS);
953 		bgep->param_lp_1000fdx = BIS(aux, MII_1000BT_STAT_LP_FDX_CAP);
954 		bgep->param_lp_1000hdx = BIS(aux, MII_1000BT_STAT_LP_HDX_CAP);
955 
956 		aux = bge_mii_get16(bgep, MII_AN_LPABLE);
957 		bgep->param_lp_100fdx = BIS(aux, MII_ABILITY_100BASE_TX_FD);
958 		bgep->param_lp_100hdx = BIS(aux, MII_ABILITY_100BASE_TX);
959 		bgep->param_lp_10fdx = BIS(aux, MII_ABILITY_10BASE_T_FD);
960 		bgep->param_lp_10hdx = BIS(aux, MII_ABILITY_10BASE_T);
961 		bgep->param_lp_pause = BIS(aux, MII_ABILITY_PAUSE);
962 		bgep->param_lp_asym_pause = BIS(aux, MII_ABILITY_ASYM_PAUSE);
963 	}
964 
965 	/*
966 	 * Step 12: update ndd-visible state parameters, BUT!
967 	 * we don't transfer the new state to <link_state> just yet;
968 	 * instead we mark the <link_state> as UNKNOWN, and our caller
969 	 * will resolve it once the status has stopped changing and
970 	 * been stable for several seconds.
971 	 */
972 	BGE_DEBUG(("bge_check_copper: link was %s speed %d duplex %d",
973 	    UPORDOWN(bgep->param_link_up),
974 	    bgep->param_link_speed,
975 	    bgep->param_link_duplex));
976 
977 	if (!linkup)
978 		mode = MII_AUX_STATUS_MODE_NONE;
979 	bgep->param_link_up = linkup;
980 	bgep->link_state = LINK_STATE_UNKNOWN;
981 	if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
982 		if (bgep->phy_aux_status & MII_AUX_STATUS_NEG_ENABLED_5906) {
983 			bgep->param_link_speed =
984 			    bge_copper_link_speed_5906[mode];
985 			bgep->param_link_duplex =
986 			    bge_copper_link_duplex_5906[mode];
987 		} else {
988 			bgep->param_link_speed = (bgep->phy_aux_status &
989 			    MII_AUX_STATUS_SPEED_IND_5906) ?  100 : 10;
990 			bgep->param_link_duplex = (bgep->phy_aux_status &
991 			    MII_AUX_STATUS_DUPLEX_IND_5906) ? LINK_DUPLEX_FULL :
992 			    LINK_DUPLEX_HALF;
993 		}
994 	} else {
995 		bgep->param_link_speed = bge_copper_link_speed[mode];
996 		bgep->param_link_duplex = bge_copper_link_duplex[mode];
997 	}
998 
999 	BGE_DEBUG(("bge_check_copper: link now %s speed %d duplex %d",
1000 	    UPORDOWN(bgep->param_link_up),
1001 	    bgep->param_link_speed,
1002 	    bgep->param_link_duplex));
1003 
1004 	return (B_TRUE);
1005 }
1006 
1007 static const phys_ops_t copper_ops = {
1008 	bge_restart_copper,
1009 	bge_update_copper,
1010 	bge_check_copper
1011 };
1012 
1013 
1014 /*
1015  * ========== SerDes support ==========
1016  */
1017 
1018 #undef	BGE_DBG
1019 #define	BGE_DBG		BGE_DBG_SERDES	/* debug flag for this code	*/
1020 
1021 /*
1022  * Reinitialise the SerDes interface.  Note that it normally powers
1023  * up in the disabled state, so we need to explicitly activate it.
1024  */
1025 static int
1026 bge_restart_serdes(bge_t *bgep, boolean_t powerdown)
1027 {
1028 	uint32_t macmode;
1029 
1030 	BGE_TRACE(("bge_restart_serdes($%p, %d)", (void *)bgep, powerdown));
1031 
1032 	ASSERT(mutex_owned(bgep->genlock));
1033 
1034 	/*
1035 	 * Ensure that the main Ethernet MAC mode register is programmed
1036 	 * appropriately for the SerDes interface ...
1037 	 */
1038 	macmode = bge_reg_get32(bgep, ETHERNET_MAC_MODE_REG);
1039 	if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
1040 		macmode |= ETHERNET_MODE_LINK_POLARITY;
1041 		macmode &= ~ETHERNET_MODE_PORTMODE_MASK;
1042 		macmode |= ETHERNET_MODE_PORTMODE_GMII;
1043 	} else {
1044 		macmode &= ~ETHERNET_MODE_LINK_POLARITY;
1045 		macmode &= ~ETHERNET_MODE_PORTMODE_MASK;
1046 		macmode |= ETHERNET_MODE_PORTMODE_TBI;
1047 	}
1048 	bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG, macmode);
1049 
1050 	/*
1051 	 * Ensure that loopback is OFF and comma detection is enabled.  Then
1052 	 * disable the SerDes output (the first time through, it may/will
1053 	 * already be disabled).  If we're shutting down, leave it disabled.
1054 	 */
1055 	bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TBI_LOOPBACK);
1056 	bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_COMMA_DETECT);
1057 	bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE);
1058 	if (powerdown)
1059 		return (DDI_SUCCESS);
1060 
1061 	/*
1062 	 * Otherwise, pause, (re-)enable the SerDes output, and send
1063 	 * all-zero config words in order to force autoneg restart.
1064 	 * Invalidate the saved "link partners received configs", as
1065 	 * we're starting over ...
1066 	 */
1067 	drv_usecwait(10000);
1068 	bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE);
1069 	bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG, 0);
1070 	bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS);
1071 	drv_usecwait(10);
1072 	bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS);
1073 	bgep->serdes_lpadv = AUTONEG_CODE_FAULT_ANEG_ERR;
1074 	bgep->serdes_status = ~0U;
1075 	return (DDI_SUCCESS);
1076 }
1077 
1078 /*
1079  * Synchronise the SerDes speed/duplex/autonegotiation capabilities and
1080  * advertisements with the required settings as specified by the various
1081  * param_* variables that can be poked via the NDD interface.
1082  *
1083  * We always reinitalise the SerDes; this should cause the link to go down,
1084  * and then back up again once the link is stable and autonegotiation
1085  * (if enabled) is complete.  We should get a link state change interrupt
1086  * somewhere along the way ...
1087  *
1088  * NOTE: SerDes only supports 1000FDX/HDX (with or without pause) so the
1089  * param_* variables relating to lower speeds are ignored.
1090  *
1091  * NOTE: <genlock> must already be held by the caller
1092  */
1093 static int
1094 bge_update_serdes(bge_t *bgep)
1095 {
1096 	boolean_t adv_autoneg;
1097 	boolean_t adv_pause;
1098 	boolean_t adv_asym_pause;
1099 	boolean_t adv_1000fdx;
1100 	boolean_t adv_1000hdx;
1101 
1102 	uint32_t serdes;
1103 	uint32_t advert;
1104 
1105 	BGE_TRACE(("bge_update_serdes($%p)", (void *)bgep));
1106 
1107 	ASSERT(mutex_owned(bgep->genlock));
1108 
1109 	BGE_DEBUG(("bge_update_serdes: autoneg %d "
1110 	    "pause %d asym_pause %d "
1111 	    "1000fdx %d 1000hdx %d "
1112 	    "100fdx %d 100hdx %d "
1113 	    "10fdx %d 10hdx %d ",
1114 	    bgep->param_adv_autoneg,
1115 	    bgep->param_adv_pause, bgep->param_adv_asym_pause,
1116 	    bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
1117 	    bgep->param_adv_100fdx, bgep->param_adv_100hdx,
1118 	    bgep->param_adv_10fdx, bgep->param_adv_10hdx));
1119 
1120 	serdes = advert = 0;
1121 
1122 	/*
1123 	 * SerDes settings are normally based on the param_* variables,
1124 	 * but if any loopback mode is in effect, that takes precedence.
1125 	 *
1126 	 * BGE supports MAC-internal loopback, PHY-internal loopback,
1127 	 * and External loopback at a variety of speeds (with a special
1128 	 * cable).  In all cases, autoneg is turned OFF, full-duplex
1129 	 * is turned ON, and the speed/mastership is forced.
1130 	 *
1131 	 * Note: for the SerDes interface, "PHY" internal loopback is
1132 	 * interpreted as SerDes internal loopback, and all external
1133 	 * loopback modes are treated equivalently, as 1Gb/external.
1134 	 */
1135 	switch (bgep->param_loop_mode) {
1136 	case BGE_LOOP_NONE:
1137 	default:
1138 		adv_autoneg = bgep->param_adv_autoneg;
1139 		adv_pause = bgep->param_adv_pause;
1140 		adv_asym_pause = bgep->param_adv_asym_pause;
1141 		adv_1000fdx = bgep->param_adv_1000fdx;
1142 		adv_1000hdx = bgep->param_adv_1000hdx;
1143 		break;
1144 
1145 	case BGE_LOOP_INTERNAL_PHY:
1146 		serdes |= SERDES_CONTROL_TBI_LOOPBACK;
1147 		/* FALLTHRU */
1148 	case BGE_LOOP_INTERNAL_MAC:
1149 	case BGE_LOOP_EXTERNAL_1000:
1150 	case BGE_LOOP_EXTERNAL_100:
1151 	case BGE_LOOP_EXTERNAL_10:
1152 		adv_autoneg = adv_pause = adv_asym_pause = B_FALSE;
1153 		adv_1000fdx = B_TRUE;
1154 		adv_1000hdx = B_FALSE;
1155 		break;
1156 	}
1157 
1158 	BGE_DEBUG(("bge_update_serdes: autoneg %d "
1159 	    "pause %d asym_pause %d "
1160 	    "1000fdx %d 1000hdx %d ",
1161 	    adv_autoneg,
1162 	    adv_pause, adv_asym_pause,
1163 	    adv_1000fdx, adv_1000hdx));
1164 
1165 	/*
1166 	 * We should have at least one gigabit technology capability
1167 	 * set; if not, we select a default of 1000Mb/s full-duplex
1168 	 */
1169 	if (!adv_1000fdx && !adv_1000hdx)
1170 		adv_1000fdx = B_TRUE;
1171 
1172 	/*
1173 	 * Now transform the adv_* variables into the proper settings
1174 	 * of the SerDes registers ...
1175 	 *
1176 	 * If autonegotiation is (now) not enabled, pretend it's been
1177 	 * done and failed ...
1178 	 */
1179 	if (!adv_autoneg)
1180 		advert |= AUTONEG_CODE_FAULT_ANEG_ERR;
1181 
1182 	if (adv_1000fdx) {
1183 		advert |= AUTONEG_CODE_FULL_DUPLEX;
1184 		bgep->param_adv_1000fdx = adv_1000fdx;
1185 		bgep->param_link_duplex = LINK_DUPLEX_FULL;
1186 		bgep->param_link_speed = 1000;
1187 	}
1188 	if (adv_1000hdx) {
1189 		advert |= AUTONEG_CODE_HALF_DUPLEX;
1190 		bgep->param_adv_1000hdx = adv_1000hdx;
1191 		bgep->param_link_duplex = LINK_DUPLEX_HALF;
1192 		bgep->param_link_speed = 1000;
1193 	}
1194 
1195 	if (adv_pause)
1196 		advert |= AUTONEG_CODE_PAUSE;
1197 	if (adv_asym_pause)
1198 		advert |= AUTONEG_CODE_ASYM_PAUSE;
1199 
1200 	/*
1201 	 * Restart the SerDes and write the new values.  Note the
1202 	 * time, so that we can say whether subsequent link state
1203 	 * changes can be attributed to our reprogramming the SerDes
1204 	 */
1205 	bgep->serdes_advert = advert;
1206 	(void) bge_restart_serdes(bgep, B_FALSE);
1207 	bge_reg_set32(bgep, SERDES_CONTROL_REG, serdes);
1208 
1209 	BGE_DEBUG(("bge_update_serdes: serdes |= 0x%x, advert 0x%x",
1210 	    serdes, advert));
1211 	return (DDI_SUCCESS);
1212 }
1213 
1214 /*
1215  * Bare-minimum autoneg protocol
1216  *
1217  * This code is only called when the link is up and we're receiving config
1218  * words, which implies that the link partner wants to autonegotiate
1219  * (otherwise, we wouldn't see configs and wouldn't reach this code).
1220  */
1221 static void
1222 bge_autoneg_serdes(bge_t *bgep)
1223 {
1224 	boolean_t ack;
1225 
1226 	bgep->serdes_lpadv = bge_reg_get32(bgep, RX_1000BASEX_AUTONEG_REG);
1227 	ack = BIS(bgep->serdes_lpadv, AUTONEG_CODE_ACKNOWLEDGE);
1228 
1229 	if (!ack) {
1230 		/*
1231 		 * Phase 1: after SerDes reset, we send a few zero configs
1232 		 * but then stop.  Here the partner is sending configs, but
1233 		 * not ACKing ours; we assume that's 'cos we're not sending
1234 		 * any.  So here we send ours, with ACK already set.
1235 		 */
1236 		bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG,
1237 		    bgep->serdes_advert | AUTONEG_CODE_ACKNOWLEDGE);
1238 		bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG,
1239 		    ETHERNET_MODE_SEND_CFGS);
1240 	} else {
1241 		/*
1242 		 * Phase 2: partner has ACKed our configs, so now we can
1243 		 * stop sending; once our partner also stops sending, we
1244 		 * can resolve the Tx/Rx configs.
1245 		 */
1246 		bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG,
1247 		    ETHERNET_MODE_SEND_CFGS);
1248 	}
1249 
1250 	BGE_DEBUG(("bge_autoneg_serdes: Rx 0x%x %s Tx 0x%x",
1251 	    bgep->serdes_lpadv,
1252 	    ack ? "stop" : "send",
1253 	    bgep->serdes_advert));
1254 }
1255 
1256 static boolean_t
1257 bge_check_serdes(bge_t *bgep, boolean_t recheck)
1258 {
1259 	uint32_t emac_status;
1260 	uint32_t lpadv;
1261 	boolean_t linkup;
1262 	boolean_t linkup_old = bgep->param_link_up;
1263 
1264 	for (;;) {
1265 		/*
1266 		 * Step 10: BCM5714S, BCM5715S only
1267 		 * Don't call function bge_autoneg_serdes() as
1268 		 * RX_1000BASEX_AUTONEG_REG (0x0448) is not applicable
1269 		 * to BCM5705, BCM5788, BCM5721, BCM5751, BCM5752,
1270 		 * BCM5714, and BCM5715 devices.
1271 		 */
1272 		if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
1273 			emac_status =  bge_reg_get32(bgep, MI_STATUS_REG);
1274 			linkup = BIS(emac_status, MI_STATUS_LINK);
1275 			bgep->serdes_status = emac_status;
1276 			if ((linkup && linkup_old) ||
1277 			    (!linkup && !linkup_old)) {
1278 				emac_status &= ~ETHERNET_STATUS_LINK_CHANGED;
1279 				emac_status &= ~ETHERNET_STATUS_RECEIVING_CFG;
1280 				break;
1281 			}
1282 			emac_status |= ETHERNET_STATUS_LINK_CHANGED;
1283 			emac_status |= ETHERNET_STATUS_RECEIVING_CFG;
1284 			if (linkup)
1285 				linkup_old = B_TRUE;
1286 			else
1287 				linkup_old = B_FALSE;
1288 			recheck = B_TRUE;
1289 		} else {
1290 			/*
1291 			 * Step 10: others
1292 			 * read & clear the main (Ethernet) MAC status
1293 			 * (the relevant bits of this are write-one-to-clear).
1294 			 */
1295 			emac_status = bge_reg_get32(bgep,
1296 			    ETHERNET_MAC_STATUS_REG);
1297 			bge_reg_put32(bgep,
1298 			    ETHERNET_MAC_STATUS_REG, emac_status);
1299 
1300 			BGE_DEBUG(("bge_check_serdes: link %d/%s, "
1301 			    "MAC status 0x%x (was 0x%x)",
1302 			    bgep->link_state, UPORDOWN(bgep->param_link_up),
1303 			    emac_status, bgep->serdes_status));
1304 
1305 			/*
1306 			 * We will only consider the link UP if all the readings
1307 			 * are consistent and give meaningful results ...
1308 			 */
1309 			bgep->serdes_status = emac_status;
1310 			linkup = BIS(emac_status,
1311 			    ETHERNET_STATUS_SIGNAL_DETECT);
1312 			linkup &= BIS(emac_status, ETHERNET_STATUS_PCS_SYNCHED);
1313 
1314 			/*
1315 			 * Now some fiddling with the interpretation:
1316 			 *	if there's been an error at the PCS level, treat
1317 			 *	it as a link change (the h/w doesn't do this)
1318 			 *
1319 			 *	if there's been a change, but it's only a PCS
1320 			 *	sync change (not a config change), AND the link
1321 			 *	already was & is still UP, then ignore the
1322 			 *	change
1323 			 */
1324 			if (BIS(emac_status, ETHERNET_STATUS_PCS_ERROR))
1325 				emac_status |= ETHERNET_STATUS_LINK_CHANGED;
1326 			else if (BIC(emac_status, ETHERNET_STATUS_CFG_CHANGED))
1327 				if (bgep->param_link_up && linkup)
1328 					emac_status &=
1329 					    ~ETHERNET_STATUS_LINK_CHANGED;
1330 
1331 			BGE_DEBUG(("bge_check_serdes: status 0x%x => 0x%x %s",
1332 			    bgep->serdes_status, emac_status,
1333 			    UPORDOWN(linkup)));
1334 
1335 			/*
1336 			 * If we're receiving configs, run the autoneg protocol
1337 			 */
1338 			if (linkup && BIS(emac_status,
1339 			    ETHERNET_STATUS_RECEIVING_CFG))
1340 				bge_autoneg_serdes(bgep);
1341 
1342 			/*
1343 			 * If the SerDes status hasn't changed, we're done ...
1344 			 */
1345 			if (BIC(emac_status, ETHERNET_STATUS_LINK_CHANGED))
1346 				break;
1347 
1348 			/*
1349 			 * Go round again until we no longer see a change ...
1350 			 */
1351 			recheck = B_TRUE;
1352 		}
1353 	}
1354 
1355 	/*
1356 	 * If we're not forcing a recheck (i.e. the link state was already
1357 	 * known), and we didn't see the hardware flag a change, there's
1358 	 * no more to do (and we tell the caller nothing happened).
1359 	 */
1360 	if (!recheck)
1361 		return (B_FALSE);
1362 
1363 	/*
1364 	 * Don't resolve autoneg until we're no longer receiving configs
1365 	 */
1366 	if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG))
1367 		return (B_FALSE);
1368 
1369 	/*
1370 	 * Assume very little ...
1371 	 */
1372 	bgep->param_lp_autoneg = B_FALSE;
1373 	bgep->param_lp_1000fdx = B_FALSE;
1374 	bgep->param_lp_1000hdx = B_FALSE;
1375 	bgep->param_lp_100fdx = B_FALSE;
1376 	bgep->param_lp_100hdx = B_FALSE;
1377 	bgep->param_lp_10fdx = B_FALSE;
1378 	bgep->param_lp_10hdx = B_FALSE;
1379 	bgep->param_lp_pause = B_FALSE;
1380 	bgep->param_lp_asym_pause = B_FALSE;
1381 	bgep->param_link_autoneg = B_FALSE;
1382 	bgep->param_link_tx_pause = B_FALSE;
1383 	if (bgep->param_adv_autoneg)
1384 		bgep->param_link_rx_pause = B_FALSE;
1385 	else
1386 		bgep->param_link_rx_pause = bgep->param_adv_pause;
1387 
1388 	/*
1389 	 * Discover all the link partner's abilities.
1390 	 */
1391 	lpadv = bgep->serdes_lpadv;
1392 	if (lpadv != 0 && BIC(lpadv, AUTONEG_CODE_FAULT_MASK)) {
1393 		/*
1394 		 * No fault, so derive partner's capabilities
1395 		 */
1396 		bgep->param_lp_autoneg = B_TRUE;
1397 		bgep->param_lp_1000fdx = BIS(lpadv, AUTONEG_CODE_FULL_DUPLEX);
1398 		bgep->param_lp_1000hdx = BIS(lpadv, AUTONEG_CODE_HALF_DUPLEX);
1399 		bgep->param_lp_pause = BIS(lpadv, AUTONEG_CODE_PAUSE);
1400 		bgep->param_lp_asym_pause = BIS(lpadv, AUTONEG_CODE_ASYM_PAUSE);
1401 
1402 		/*
1403 		 * Pause direction resolution
1404 		 */
1405 		bgep->param_link_autoneg = B_TRUE;
1406 		if (bgep->param_adv_pause &&
1407 		    bgep->param_lp_pause) {
1408 			bgep->param_link_tx_pause = B_TRUE;
1409 			bgep->param_link_rx_pause = B_TRUE;
1410 		}
1411 		if (bgep->param_adv_asym_pause &&
1412 		    bgep->param_lp_asym_pause) {
1413 			if (bgep->param_adv_pause)
1414 				bgep->param_link_rx_pause = B_TRUE;
1415 			if (bgep->param_lp_pause)
1416 				bgep->param_link_tx_pause = B_TRUE;
1417 		}
1418 	}
1419 
1420 	/*
1421 	 * Step 12: update ndd-visible state parameters, BUT!
1422 	 * we don't transfer the new state to <link_state> just yet;
1423 	 * instead we mark the <link_state> as UNKNOWN, and our caller
1424 	 * will resolve it once the status has stopped changing and
1425 	 * been stable for several seconds.
1426 	 */
1427 	BGE_DEBUG(("bge_check_serdes: link was %s speed %d duplex %d",
1428 	    UPORDOWN(bgep->param_link_up),
1429 	    bgep->param_link_speed,
1430 	    bgep->param_link_duplex));
1431 
1432 	if (linkup) {
1433 		bgep->param_link_up = B_TRUE;
1434 		bgep->param_link_speed = 1000;
1435 		if (bgep->param_adv_1000fdx)
1436 			bgep->param_link_duplex = LINK_DUPLEX_FULL;
1437 		else
1438 			bgep->param_link_duplex = LINK_DUPLEX_HALF;
1439 		if (bgep->param_lp_autoneg && !bgep->param_lp_1000fdx)
1440 			bgep->param_link_duplex = LINK_DUPLEX_HALF;
1441 	} else {
1442 		bgep->param_link_up = B_FALSE;
1443 		bgep->param_link_speed = 0;
1444 		bgep->param_link_duplex = LINK_DUPLEX_UNKNOWN;
1445 	}
1446 	bgep->link_state = LINK_STATE_UNKNOWN;
1447 
1448 	BGE_DEBUG(("bge_check_serdes: link now %s speed %d duplex %d",
1449 	    UPORDOWN(bgep->param_link_up),
1450 	    bgep->param_link_speed,
1451 	    bgep->param_link_duplex));
1452 
1453 	return (B_TRUE);
1454 }
1455 
1456 static const phys_ops_t serdes_ops = {
1457 	bge_restart_serdes,
1458 	bge_update_serdes,
1459 	bge_check_serdes
1460 };
1461 
1462 /*
1463  * ========== Exported physical layer control routines ==========
1464  */
1465 
1466 #undef	BGE_DBG
1467 #define	BGE_DBG		BGE_DBG_PHYS	/* debug flag for this code	*/
1468 
1469 /*
1470  * Here we have to determine which media we're using (copper or serdes).
1471  * Once that's done, we can initialise the physical layer appropriately.
1472  */
1473 int
1474 bge_phys_init(bge_t *bgep)
1475 {
1476 	BGE_TRACE(("bge_phys_init($%p)", (void *)bgep));
1477 
1478 	mutex_enter(bgep->genlock);
1479 
1480 	/*
1481 	 * Probe for the (internal) PHY.  If it's not there, we'll assume
1482 	 * that this is a 5703/4S, with a SerDes interface rather than
1483 	 * a PHY. BCM5714S/BCM5715S are not supported.It are based on
1484 	 * BCM800x PHY.
1485 	 */
1486 	bgep->phy_mii_addr = 1;
1487 	if (bge_phy_probe(bgep)) {
1488 		bgep->chipid.flags &= ~CHIP_FLAG_SERDES;
1489 		bgep->physops = &copper_ops;
1490 	} else {
1491 		bgep->chipid.flags |= CHIP_FLAG_SERDES;
1492 		bgep->physops = &serdes_ops;
1493 	}
1494 
1495 	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) {
1496 		mutex_exit(bgep->genlock);
1497 		return (EIO);
1498 	}
1499 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1500 		mutex_exit(bgep->genlock);
1501 		return (EIO);
1502 	}
1503 	mutex_exit(bgep->genlock);
1504 	return (0);
1505 }
1506 
1507 /*
1508  * Reset the physical layer
1509  */
1510 void
1511 bge_phys_reset(bge_t *bgep)
1512 {
1513 	BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep));
1514 
1515 	mutex_enter(bgep->genlock);
1516 	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS)
1517 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
1518 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
1519 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
1520 	mutex_exit(bgep->genlock);
1521 }
1522 
1523 /*
1524  * Reset and power off the physical layer.
1525  *
1526  * Another RESET should get it back to working, but it may take a few
1527  * seconds it may take a few moments to return to normal operation ...
1528  */
1529 int
1530 bge_phys_idle(bge_t *bgep)
1531 {
1532 	BGE_TRACE(("bge_phys_idle($%p)", (void *)bgep));
1533 
1534 	ASSERT(mutex_owned(bgep->genlock));
1535 	return ((*bgep->physops->phys_restart)(bgep, B_TRUE));
1536 }
1537 
1538 /*
1539  * Synchronise the PHYSICAL layer's speed/duplex/autonegotiation capabilities
1540  * and advertisements with the required settings as specified by the various
1541  * param_* variables that can be poked via the NDD interface.
1542  *
1543  * We always reset the PHYSICAL layer and reprogram *all* relevant registers.
1544  * This is expected to cause the link to go down, and then back up again once
1545  * the link is stable and autonegotiation (if enabled) is complete.  We should
1546  * get a link state change interrupt somewhere along the way ...
1547  *
1548  * NOTE: <genlock> must already be held by the caller
1549  */
1550 int
1551 bge_phys_update(bge_t *bgep)
1552 {
1553 	BGE_TRACE(("bge_phys_update($%p)", (void *)bgep));
1554 
1555 	ASSERT(mutex_owned(bgep->genlock));
1556 	return ((*bgep->physops->phys_update)(bgep));
1557 }
1558 
1559 #undef	BGE_DBG
1560 #define	BGE_DBG		BGE_DBG_LINK	/* debug flag for this code	*/
1561 
1562 /*
1563  * Read the link status and determine whether anything's changed ...
1564  *
1565  * This routine should be called whenever the chip flags a change
1566  * in the hardware link state.
1567  *
1568  * This routine returns B_FALSE if the link state has not changed,
1569  * returns B_TRUE when the change to the new state should be accepted.
1570  * In such a case, the param_* variables give the new hardware state,
1571  * which the caller should use to update link_state etc.
1572  *
1573  * The caller must already hold <genlock>
1574  */
1575 boolean_t
1576 bge_phys_check(bge_t *bgep)
1577 {
1578 	int32_t orig_state;
1579 	boolean_t recheck;
1580 
1581 	BGE_TRACE(("bge_phys_check($%p)", (void *)bgep));
1582 
1583 	ASSERT(mutex_owned(bgep->genlock));
1584 
1585 	orig_state = bgep->link_state;
1586 	recheck = orig_state == LINK_STATE_UNKNOWN;
1587 	recheck = (*bgep->physops->phys_check)(bgep, recheck);
1588 	if (!recheck)
1589 		return (B_FALSE);
1590 
1591 	return (B_TRUE);
1592 }
1593