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