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