Home | History | Annotate | Download | only in bge
      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 2009 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 (bge_phy_probe(bgep)) {
   1507 		bgep->chipid.flags &= ~CHIP_FLAG_SERDES;
   1508 		bgep->physops = &copper_ops;
   1509 	} else {
   1510 		bgep->chipid.flags |= CHIP_FLAG_SERDES;
   1511 		bgep->physops = &serdes_ops;
   1512 	}
   1513 
   1514 	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) {
   1515 		mutex_exit(bgep->genlock);
   1516 		return (EIO);
   1517 	}
   1518 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
   1519 		mutex_exit(bgep->genlock);
   1520 		return (EIO);
   1521 	}
   1522 	mutex_exit(bgep->genlock);
   1523 	return (0);
   1524 }
   1525 
   1526 /*
   1527  * Reset the physical layer
   1528  */
   1529 void
   1530 bge_phys_reset(bge_t *bgep)
   1531 {
   1532 	BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep));
   1533 
   1534 	mutex_enter(bgep->genlock);
   1535 	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS)
   1536 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
   1537 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
   1538 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
   1539 	mutex_exit(bgep->genlock);
   1540 }
   1541 
   1542 /*
   1543  * Reset and power off the physical layer.
   1544  *
   1545  * Another RESET should get it back to working, but it may take a few
   1546  * seconds it may take a few moments to return to normal operation ...
   1547  */
   1548 int
   1549 bge_phys_idle(bge_t *bgep)
   1550 {
   1551 	BGE_TRACE(("bge_phys_idle($%p)", (void *)bgep));
   1552 
   1553 	ASSERT(mutex_owned(bgep->genlock));
   1554 	return ((*bgep->physops->phys_restart)(bgep, B_TRUE));
   1555 }
   1556 
   1557 /*
   1558  * Synchronise the PHYSICAL layer's speed/duplex/autonegotiation capabilities
   1559  * and advertisements with the required settings as specified by the various
   1560  * param_* variables that can be poked via the NDD interface.
   1561  *
   1562  * We always reset the PHYSICAL layer and reprogram *all* relevant registers.
   1563  * This is expected to cause the link to go down, and then back up again once
   1564  * the link is stable and autonegotiation (if enabled) is complete.  We should
   1565  * get a link state change interrupt somewhere along the way ...
   1566  *
   1567  * NOTE: <genlock> must already be held by the caller
   1568  */
   1569 int
   1570 bge_phys_update(bge_t *bgep)
   1571 {
   1572 	BGE_TRACE(("bge_phys_update($%p)", (void *)bgep));
   1573 
   1574 	ASSERT(mutex_owned(bgep->genlock));
   1575 	return ((*bgep->physops->phys_update)(bgep));
   1576 }
   1577 
   1578 #undef	BGE_DBG
   1579 #define	BGE_DBG		BGE_DBG_LINK	/* debug flag for this code	*/
   1580 
   1581 /*
   1582  * Read the link status and determine whether anything's changed ...
   1583  *
   1584  * This routine should be called whenever the chip flags a change
   1585  * in the hardware link state.
   1586  *
   1587  * This routine returns B_FALSE if the link state has not changed,
   1588  * returns B_TRUE when the change to the new state should be accepted.
   1589  * In such a case, the param_* variables give the new hardware state,
   1590  * which the caller should use to update link_state etc.
   1591  *
   1592  * The caller must already hold <genlock>
   1593  */
   1594 boolean_t
   1595 bge_phys_check(bge_t *bgep)
   1596 {
   1597 	int32_t orig_state;
   1598 	boolean_t recheck;
   1599 
   1600 	BGE_TRACE(("bge_phys_check($%p)", (void *)bgep));
   1601 
   1602 	ASSERT(mutex_owned(bgep->genlock));
   1603 
   1604 	orig_state = bgep->link_state;
   1605 	recheck = orig_state == LINK_STATE_UNKNOWN;
   1606 	recheck = (*bgep->physops->phys_check)(bgep, recheck);
   1607 	if (!recheck)
   1608 		return (B_FALSE);
   1609 
   1610 	return (B_TRUE);
   1611 }
   1612