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