xref: /titanic_50/usr/src/uts/common/io/mii/mii.c (revision b2b3ca14272ffe2a6fc37bab2ab65b8f6702d750)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * mii - MII/PHY support for MAC drivers
28  *
29  * Utility module to provide a consistent interface to a MAC driver accross
30  * different implementations of PHY devices
31  */
32 
33 #include <sys/types.h>
34 #include <sys/debug.h>
35 #include <sys/errno.h>
36 #include <sys/param.h>
37 #include <sys/kmem.h>
38 #include <sys/conf.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/modctl.h>
42 #include <sys/cmn_err.h>
43 #include <sys/policy.h>
44 #include <sys/note.h>
45 #include <sys/strsun.h>
46 #include <sys/miiregs.h>
47 #include <sys/mac_provider.h>
48 #include <sys/mac_ether.h>
49 #include <sys/mii.h>
50 #include "miipriv.h"
51 
52 #define	MII_SECOND	1000000
53 
54 /* indices into error array */
55 enum {
56 	MII_EOK = 0,
57 	MII_ERESET,
58 	MII_ESTART,
59 	MII_ENOPHY,
60 	MII_ECHECK,
61 };
62 
63 static const char *mii_errors[] = {
64 	"",
65 	"Failure resetting PHY.",
66 	"Failure starting PHY.",
67 	"No Ethernet PHY found.",
68 	"Failure reading PHY (removed?)"
69 };
70 
71 /* Indexed by XCVR_ type */
72 static const const char *mii_xcvr_types[] = {
73 	"Undefined",
74 	"Unknown",
75 	"10 Mbps",
76 	"100BASE-T4",
77 	"100BASE-X",
78 	"100BASE-T2",
79 	"1000BASE-X",
80 	"1000BASE-T"
81 };
82 
83 static lb_property_t mii_loopmodes[] = {
84 	{ normal,	"normal",	PHY_LB_NONE },
85 	{ internal,	"PHY",		PHY_LB_INT_PHY },
86 	{ external,	"10Mbps",	PHY_LB_EXT_10 },
87 	{ external,	"100Mbps",	PHY_LB_EXT_100 },
88 	{ external,	"1000Mbps",	PHY_LB_EXT_1000 },
89 };
90 
91 /* state machine */
92 typedef enum {
93 	MII_STATE_PROBE = 0,
94 	MII_STATE_RESET,
95 	MII_STATE_START,
96 	MII_STATE_RUN,
97 } mii_tstate_t;
98 
99 struct mii_handle {
100 	dev_info_t	*m_dip;
101 	void		*m_private;
102 	mii_ops_t	m_ops;
103 
104 	kt_did_t	m_tq_id;
105 	kmutex_t	m_lock;
106 	kcondvar_t	m_cv;
107 	ddi_taskq_t	*m_tq;
108 	int		m_flags;
109 
110 	boolean_t	m_started;
111 	boolean_t	m_suspending;
112 	boolean_t	m_suspended;
113 	boolean_t	m_notify;
114 	int		m_error;
115 	mii_tstate_t	m_tstate;
116 
117 #define	MII_FLAG_EXIT		0x1	/* exit the thread */
118 #define	MII_FLAG_STOP		0x2	/* shutdown MII monitoring */
119 #define	MII_FLAG_RESET		0x4	/* reset the MII */
120 #define	MII_FLAG_PROBE		0x8	/* probe for PHYs */
121 #define	MII_FLAG_NOTIFY		0x10	/* notify about a change */
122 #define	MII_FLAG_SUSPEND	0x20	/* monitoring suspended */
123 #define	MII_FLAG_MACRESET	0x40	/* send reset to MAC */
124 #define	MII_FLAG_PHYSTART	0x80	/* start up the PHY */
125 
126 	/* device name for printing, e.g. "hme0" */
127 	char		m_name[MODMAXNAMELEN + 16];
128 
129 	int		m_addr;
130 	phy_handle_t	m_phys[32];
131 	phy_handle_t	m_bogus_phy;
132 	phy_handle_t	*m_phy;
133 
134 	link_state_t	m_link;
135 
136 	/* these start out undefined, but get values due to mac_prop_set */
137 	int		m_en_aneg;
138 	int		m_en_10_hdx;
139 	int		m_en_10_fdx;
140 	int		m_en_100_t4;
141 	int		m_en_100_hdx;
142 	int		m_en_100_fdx;
143 	int		m_en_1000_hdx;
144 	int		m_en_1000_fdx;
145 	int		m_en_flowctrl;
146 
147 	boolean_t	m_cap_pause;
148 	boolean_t	m_cap_asmpause;
149 };
150 
151 
152 static void _mii_task(void *);
153 static void _mii_probe_task(mii_handle_t);
154 
155 /*
156  * Loadable module structures/entrypoints
157  */
158 
159 extern struct mod_ops mod_misc_ops;
160 
161 static struct modlmisc modlmisc = {
162 	&mod_miscops,
163 	"802.3 MII support",
164 };
165 
166 static struct modlinkage modlinkage = {
167 	MODREV_1, &modlmisc, NULL
168 };
169 
170 int
171 _init(void)
172 {
173 	return (mod_install(&modlinkage));
174 }
175 
176 int
177 _fini(void)
178 {
179 	return (mod_remove(&modlinkage));
180 }
181 
182 int
183 _info(struct modinfo *modinfop)
184 {
185 	return (mod_info(&modlinkage, modinfop));
186 }
187 
188 void
189 _mii_error(mii_handle_t mh, int errno)
190 {
191 	/*
192 	 * This dumps an error message, but it avoids filling the log with
193 	 * repeated error messages.
194 	 */
195 	if (mh->m_error != errno) {
196 		cmn_err(CE_WARN, "%s: %s", mh->m_name, mii_errors[errno]);
197 		mh->m_error = errno;
198 	}
199 }
200 
201 /*
202  * Known list of specific PHY probes.
203  */
204 typedef boolean_t (*phy_probe_t)(phy_handle_t *);
205 phy_probe_t _phy_probes[] = {
206 	phy_natsemi_probe,
207 	phy_intel_probe,
208 	phy_qualsemi_probe,
209 	phy_cicada_probe,
210 	phy_other_probe,
211 	NULL
212 };
213 
214 /*
215  * MII Interface functions
216  */
217 
218 mii_handle_t
219 mii_alloc_instance(void *private, dev_info_t *dip, int inst, mii_ops_t *ops)
220 {
221 	mii_handle_t	mh;
222 	char		tqname[16];
223 
224 	if (ops->mii_version != MII_OPS_VERSION) {
225 		cmn_err(CE_WARN, "%s: incompatible MII version (%d)",
226 		    ddi_driver_name(dip), ops->mii_version);
227 		return (NULL);
228 	}
229 	mh = kmem_zalloc(sizeof (*mh), KM_SLEEP);
230 
231 	(void) snprintf(mh->m_name, sizeof (mh->m_name), "%s%d",
232 	    ddi_driver_name(dip), inst);
233 
234 	/* DDI will prepend the driver name */
235 	(void) snprintf(tqname, sizeof (tqname), "mii%d", inst);
236 
237 	mh->m_dip = dip;
238 	mh->m_ops = *ops;
239 	mh->m_private = private;
240 	mh->m_suspended = B_FALSE;
241 	mh->m_started = B_FALSE;
242 	mh->m_notify = B_FALSE;
243 	mh->m_tstate = MII_STATE_PROBE;
244 	mh->m_error = MII_EOK;
245 	mutex_init(&mh->m_lock, NULL, MUTEX_DRIVER, NULL);
246 	cv_init(&mh->m_cv, NULL, CV_DRIVER, NULL);
247 
248 	mh->m_tq = ddi_taskq_create(dip, tqname, 1, TASKQ_DEFAULTPRI, 0);
249 	if (mh->m_tq == NULL) {
250 		cmn_err(CE_WARN, "%s: unable to create MII monitoring task",
251 		    ddi_driver_name(dip));
252 		cv_destroy(&mh->m_cv);
253 		mutex_destroy(&mh->m_lock);
254 		kmem_free(mh, sizeof (*mh));
255 		return (NULL);
256 	}
257 
258 	/*
259 	 * Initialize user prefs by loading properties.  Ultimately,
260 	 * Brussels interfaces would be superior here.
261 	 */
262 #define	GETPROP(name)	ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, name, -1)
263 	mh->m_en_aneg = GETPROP("adv_autoneg_cap");
264 	mh->m_en_10_hdx = GETPROP("adv_10hdx_cap");
265 	mh->m_en_10_fdx = GETPROP("adv_10fdx_cap");
266 	mh->m_en_100_hdx = GETPROP("adv_100hdx_cap");
267 	mh->m_en_100_fdx = GETPROP("adv_100fdx_cap");
268 	mh->m_en_100_t4 = GETPROP("adv_100T4_cap");
269 	mh->m_en_1000_hdx = GETPROP("adv_1000hdx_cap");
270 	mh->m_en_1000_fdx = GETPROP("adv_1000fdx_cap");
271 
272 	mh->m_cap_pause = B_FALSE;
273 	mh->m_cap_asmpause = B_FALSE;
274 
275 	bzero(&mh->m_bogus_phy, sizeof (mh->m_bogus_phy));
276 	mh->m_bogus_phy.phy_link = LINK_STATE_UNKNOWN;
277 	mh->m_bogus_phy.phy_duplex = LINK_DUPLEX_UNKNOWN;
278 	mh->m_bogus_phy.phy_addr = 0xff;
279 	mh->m_bogus_phy.phy_type = XCVR_NONE;
280 	mh->m_bogus_phy.phy_id = (uint32_t)-1;
281 	mh->m_bogus_phy.phy_loopback = PHY_LB_NONE;
282 	mh->m_bogus_phy.phy_flowctrl = LINK_FLOWCTRL_NONE;
283 	mh->m_phy = &mh->m_bogus_phy;
284 
285 	for (int i = 0; i < 32; i++) {
286 		mh->m_phys[i].phy_mii = mh;
287 	}
288 	mh->m_bogus_phy.phy_mii = mh;
289 
290 	return (mh);
291 }
292 
293 mii_handle_t
294 mii_alloc(void *private, dev_info_t *dip, mii_ops_t *ops)
295 {
296 	return (mii_alloc_instance(private, dip, ddi_get_instance(dip), ops));
297 }
298 
299 void
300 mii_set_pauseable(mii_handle_t mh, boolean_t pauseable, boolean_t asymetric)
301 {
302 	phy_handle_t	*ph;
303 
304 	mutex_enter(&mh->m_lock);
305 	ph = mh->m_phy;
306 	ph->phy_cap_pause = mh->m_cap_pause = pauseable;
307 	ph->phy_cap_asmpause = mh->m_cap_asmpause = asymetric;
308 	if (pauseable) {
309 		mh->m_en_flowctrl = LINK_FLOWCTRL_BI;
310 	} else {
311 		mh->m_en_flowctrl = LINK_FLOWCTRL_NONE;
312 	}
313 	mutex_exit(&mh->m_lock);
314 }
315 
316 void
317 mii_free(mii_handle_t mh)
318 {
319 	mutex_enter(&mh->m_lock);
320 	mh->m_started = B_FALSE;
321 	cv_broadcast(&mh->m_cv);
322 	mutex_exit(&mh->m_lock);
323 
324 	ddi_taskq_destroy(mh->m_tq);
325 	mutex_destroy(&mh->m_lock);
326 	cv_destroy(&mh->m_cv);
327 	kmem_free(mh, sizeof (*mh));
328 }
329 
330 void
331 mii_reset(mii_handle_t mh)
332 {
333 	mutex_enter(&mh->m_lock);
334 	if (mh->m_tstate > MII_STATE_RESET)
335 		mh->m_tstate = MII_STATE_RESET;
336 	cv_broadcast(&mh->m_cv);
337 	mutex_exit(&mh->m_lock);
338 }
339 
340 void
341 mii_suspend(mii_handle_t mh)
342 {
343 	mutex_enter(&mh->m_lock);
344 	while ((!mh->m_suspended) && (mh->m_started)) {
345 		mh->m_suspending = B_TRUE;
346 		cv_broadcast(&mh->m_cv);
347 		cv_wait(&mh->m_cv, &mh->m_lock);
348 	}
349 	mutex_exit(&mh->m_lock);
350 }
351 
352 void
353 mii_resume(mii_handle_t mh)
354 {
355 	mutex_enter(&mh->m_lock);
356 	/* resume implicity causes a PHY reset */
357 	if (mh->m_tstate > MII_STATE_RESET) {
358 		mh->m_tstate = MII_STATE_RESET;
359 	}
360 	mh->m_suspended = B_FALSE;
361 	cv_broadcast(&mh->m_cv);
362 	mutex_exit(&mh->m_lock);
363 }
364 
365 void
366 mii_start(mii_handle_t mh)
367 {
368 	mutex_enter(&mh->m_lock);
369 	if (!mh->m_started) {
370 		mh->m_started = B_TRUE;
371 		if (ddi_taskq_dispatch(mh->m_tq, _mii_task, mh, DDI_NOSLEEP) !=
372 		    DDI_SUCCESS) {
373 			cmn_err(CE_WARN,
374 			    "%s: unable to start MII monitoring task",
375 			    mh->m_name);
376 			mh->m_started = B_FALSE;
377 		}
378 	}
379 	cv_broadcast(&mh->m_cv);
380 	mutex_exit(&mh->m_lock);
381 }
382 
383 void
384 mii_stop(mii_handle_t mh)
385 {
386 	phy_handle_t	*ph;
387 
388 	mutex_enter(&mh->m_lock);
389 	mh->m_started = B_FALSE;
390 	ph = mh->m_phy;
391 	if (ph->phy_present) {
392 		ph->phy_stop(ph);
393 	}
394 	cv_broadcast(&mh->m_cv);
395 	mutex_exit(&mh->m_lock);
396 }
397 
398 void
399 mii_probe(mii_handle_t mh)
400 {
401 	mutex_enter(&mh->m_lock);
402 	_mii_probe_task(mh);
403 	mutex_exit(&mh->m_lock);
404 }
405 
406 void
407 mii_check(mii_handle_t mh)
408 {
409 	mutex_enter(&mh->m_lock);
410 	cv_broadcast(&mh->m_cv);
411 	mutex_exit(&mh->m_lock);
412 }
413 
414 int
415 mii_get_speed(mii_handle_t mh)
416 {
417 	phy_handle_t	*ph = mh->m_phy;
418 
419 	return (ph->phy_speed);
420 }
421 
422 link_duplex_t
423 mii_get_duplex(mii_handle_t mh)
424 {
425 	phy_handle_t	*ph = mh->m_phy;
426 
427 	return (ph->phy_duplex);
428 }
429 
430 link_state_t
431 mii_get_state(mii_handle_t mh)
432 {
433 	phy_handle_t	*ph = mh->m_phy;
434 
435 	return (ph->phy_link);
436 }
437 
438 link_flowctrl_t
439 mii_get_flowctrl(mii_handle_t mh)
440 {
441 	phy_handle_t	*ph = mh->m_phy;
442 
443 	return (ph->phy_flowctrl);
444 }
445 
446 int
447 mii_get_loopmodes(mii_handle_t mh, lb_property_t *modes)
448 {
449 	phy_handle_t	*ph = mh->m_phy;
450 	int		cnt;
451 
452 	/*
453 	 * There's a pretty big assumption in here.  The assumption is
454 	 * that for 1000BASE-T and 100BASE-TX modes that we can
455 	 * support all of the lower speeds and full duplex uniformly.
456 	 */
457 	switch (ph->phy_type) {
458 	case XCVR_1000T:
459 		cnt = 5;	/* 1000 BASE-T should support all modes */
460 		break;
461 	case XCVR_100X:
462 		/*
463 		 * This might be 100BASE-FX.  If so, it won't support the
464 		 * 10Mbps modes.
465 		 */
466 		if (ph->phy_cap_10_fdx) {
467 			cnt = 4;	/* 100BASE-TX probably */
468 		} else {
469 			cnt = 2;	/* 100BASE-FX? */
470 		}
471 		break;
472 	case XCVR_10:
473 		/* Some 10Mbs PHYs don't do full duplex */
474 		if (ph->phy_cap_10_fdx) {
475 			cnt = 3;
476 		} else {
477 			cnt = 2;
478 		}
479 		break;
480 	case XCVR_NONE:
481 		cnt = 1;	/* No XCVR, all we can do is leave it off */
482 		break;
483 	case XCVR_1000X:
484 	case XCVR_100T4:
485 	case XCVR_100T2:
486 	default:
487 		/*
488 		 * Anything else we just allow for internal PHY loopback.
489 		 * Note that many of these will probably be capable of
490 		 * supporting additional external loopback modes, but we
491 		 * can't be sure of it, so we just leave it alone.
492 		 */
493 		cnt = 2;
494 		break;
495 	}
496 
497 	if (modes) {
498 		bcopy(mii_loopmodes, modes, sizeof (lb_property_t) * cnt);
499 	}
500 	return (cnt);
501 }
502 
503 uint32_t
504 mii_get_loopback(mii_handle_t mh)
505 {
506 	phy_handle_t	*ph = mh->m_phy;
507 
508 	return (ph->phy_loopback);
509 }
510 
511 int
512 mii_set_loopback(mii_handle_t mh, uint32_t loop)
513 {
514 	phy_handle_t	*ph;
515 
516 	mutex_enter(&mh->m_lock);
517 	ph = mh->m_phy;
518 
519 	if ((!mh->m_started) || (!ph->phy_present) ||
520 	    (loop >= mii_get_loopmodes(mh, NULL))) {
521 		return (EINVAL);
522 	}
523 
524 	ph->phy_loopback = loop;
525 	mh->m_tstate = MII_STATE_RESET;
526 	cv_broadcast(&mh->m_cv);
527 	mutex_exit(&mh->m_lock);
528 
529 	return (0);
530 }
531 
532 uint32_t
533 mii_get_id(mii_handle_t mh)
534 {
535 	phy_handle_t	*ph = mh->m_phy;
536 
537 	return (ph->phy_id);
538 }
539 
540 int
541 mii_get_addr(mii_handle_t mh)
542 {
543 	return (mh->m_addr);
544 }
545 
546 /* GLDv3 helpers */
547 
548 boolean_t
549 mii_m_loop_ioctl(mii_handle_t mh, queue_t *wq, mblk_t *mp)
550 {
551 	struct iocblk	*iocp;
552 	int		rv = 0;
553 	int		cnt;
554 	lb_property_t	modes[MII_LOOPBACK_MAX];
555 	lb_info_sz_t	sz;
556 	int		cmd;
557 	uint32_t	mode;
558 
559 	iocp = (void *)mp->b_rptr;
560 	cmd = iocp->ioc_cmd;
561 
562 	switch (cmd) {
563 	case LB_SET_MODE:
564 	case LB_GET_INFO_SIZE:
565 	case LB_GET_INFO:
566 	case LB_GET_MODE:
567 		break;
568 
569 	default:
570 		return (B_FALSE);
571 	}
572 
573 	if (mp->b_cont == NULL) {
574 		miocnak(wq, mp, 0, EINVAL);
575 		return (B_TRUE);
576 	}
577 
578 	switch (cmd) {
579 	case LB_GET_INFO_SIZE:
580 		cnt = mii_get_loopmodes(mh, modes);
581 		if (iocp->ioc_count != sizeof (sz)) {
582 			rv = EINVAL;
583 		} else {
584 			sz = cnt * sizeof (lb_property_t);
585 			bcopy(&sz, mp->b_cont->b_rptr, sizeof (sz));
586 		}
587 		break;
588 
589 	case LB_GET_INFO:
590 		cnt = mii_get_loopmodes(mh, modes);
591 		if (iocp->ioc_count != (cnt * sizeof (lb_property_t))) {
592 			rv = EINVAL;
593 		} else {
594 			bcopy(modes, mp->b_cont->b_rptr, iocp->ioc_count);
595 		}
596 		break;
597 
598 	case LB_GET_MODE:
599 		if (iocp->ioc_count != sizeof (mode)) {
600 			rv = EINVAL;
601 		} else {
602 			mode = mii_get_loopback(mh);
603 			bcopy(&mode, mp->b_cont->b_rptr, sizeof (mode));
604 		}
605 		break;
606 
607 	case LB_SET_MODE:
608 		rv = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
609 		if (rv != 0)
610 			break;
611 		if (iocp->ioc_count != sizeof (mode)) {
612 			rv = EINVAL;
613 			break;
614 		}
615 		bcopy(mp->b_cont->b_rptr, &mode, sizeof (mode));
616 		rv = mii_set_loopback(mh, mode);
617 		break;
618 	}
619 
620 	if (rv == 0) {
621 		miocack(wq, mp, iocp->ioc_count, 0);
622 	} else {
623 		miocnak(wq, mp, 0, rv);
624 	}
625 	return (B_TRUE);
626 }
627 
628 int
629 mii_m_getprop(mii_handle_t mh, const char *name, mac_prop_id_t num,
630     uint_t flags, uint_t sz, void *val, uint_t *permp)
631 {
632 	phy_handle_t	*ph;
633 	int		err = 0;
634 	uint_t		perm;
635 	boolean_t	dfl = flags & MAC_PROP_DEFAULT;
636 
637 	_NOTE(ARGUNUSED(name));
638 
639 	if (sz < 1)
640 		return (EINVAL);
641 
642 	mutex_enter(&mh->m_lock);
643 
644 	ph = mh->m_phy;
645 	perm = MAC_PROP_PERM_RW;
646 
647 #define	CASE_PROP_ABILITY(PROP, VAR)					\
648 	case MAC_PROP_ADV_##PROP:					\
649 		perm = MAC_PROP_PERM_READ;				\
650 		*(uint8_t *)val =					\
651 		    dfl ? ph->phy_cap_##VAR : ph->phy_adv_##VAR;	\
652 		break;							\
653 									\
654 	case MAC_PROP_EN_##PROP:					\
655 		if (!ph->phy_cap_##VAR)					\
656 			perm = MAC_PROP_PERM_READ;			\
657 		*(uint8_t *)val =					\
658 		    dfl ? ph->phy_cap_##VAR : ph->phy_en_##VAR;		\
659 		break;
660 
661 	switch (num) {
662 	case MAC_PROP_DUPLEX:
663 		perm = MAC_PROP_PERM_READ;
664 		if (sz >= sizeof (link_duplex_t)) {
665 			bcopy(&ph->phy_duplex, val, sizeof (link_duplex_t));
666 		} else {
667 			err = EINVAL;
668 		}
669 		break;
670 
671 	case MAC_PROP_SPEED:
672 		perm = MAC_PROP_PERM_READ;
673 		if (sz >= sizeof (uint64_t)) {
674 			uint64_t speed = ph->phy_speed * 1000000ull;
675 			bcopy(&speed, val, sizeof (speed));
676 		} else {
677 			err = EINVAL;
678 		}
679 		break;
680 
681 	case MAC_PROP_AUTONEG:
682 		*(uint8_t *)val =
683 		    dfl ? ph->phy_cap_aneg : ph->phy_adv_aneg;
684 		break;
685 
686 	case MAC_PROP_FLOWCTRL:
687 		if (sz >= sizeof (link_flowctrl_t)) {
688 			bcopy(&ph->phy_flowctrl, val,
689 			    sizeof (link_flowctrl_t));
690 		} else {
691 			err = EINVAL;
692 		}
693 		break;
694 
695 	CASE_PROP_ABILITY(1000FDX_CAP, 1000_fdx)
696 	CASE_PROP_ABILITY(1000HDX_CAP, 1000_hdx)
697 	CASE_PROP_ABILITY(100T4_CAP, 100_t4)
698 	CASE_PROP_ABILITY(100FDX_CAP, 100_fdx)
699 	CASE_PROP_ABILITY(100HDX_CAP, 100_hdx)
700 	CASE_PROP_ABILITY(10FDX_CAP, 10_fdx)
701 	CASE_PROP_ABILITY(10HDX_CAP, 10_hdx)
702 
703 	default:
704 		err = ENOTSUP;
705 		break;
706 	}
707 
708 	if (err == 0) {
709 		*permp = perm;
710 	}
711 
712 	mutex_exit(&mh->m_lock);
713 
714 	return (err);
715 }
716 
717 int
718 mii_m_setprop(mii_handle_t mh, const char *name, mac_prop_id_t num,
719     uint_t sz, const void *valp)
720 {
721 	phy_handle_t	*ph;
722 	boolean_t	*advp = NULL;
723 	boolean_t	*capp = NULL;
724 	int		*macpp = NULL;
725 	int		rv = ENOTSUP;
726 
727 	_NOTE(ARGUNUSED(name));
728 
729 	if (sz < 1)
730 		return (EINVAL);
731 
732 	mutex_enter(&mh->m_lock);
733 
734 	ph = mh->m_phy;
735 
736 	/* we don't support changing parameters while in loopback mode */
737 	if (ph->phy_loopback != PHY_LB_NONE) {
738 		switch (num) {
739 		case MAC_PROP_EN_1000FDX_CAP:
740 		case MAC_PROP_EN_1000HDX_CAP:
741 		case MAC_PROP_EN_100FDX_CAP:
742 		case MAC_PROP_EN_100HDX_CAP:
743 		case MAC_PROP_EN_100T4_CAP:
744 		case MAC_PROP_EN_10FDX_CAP:
745 		case MAC_PROP_EN_10HDX_CAP:
746 		case MAC_PROP_AUTONEG:
747 		case MAC_PROP_FLOWCTRL:
748 			return (EBUSY);
749 		}
750 	}
751 
752 	switch (num) {
753 	case MAC_PROP_EN_1000FDX_CAP:
754 		capp = &ph->phy_cap_1000_fdx;
755 		advp = &ph->phy_en_1000_fdx;
756 		macpp = &mh->m_en_1000_fdx;
757 		break;
758 	case MAC_PROP_EN_1000HDX_CAP:
759 		capp = &ph->phy_cap_1000_hdx;
760 		advp = &ph->phy_en_1000_hdx;
761 		macpp = &mh->m_en_1000_hdx;
762 		break;
763 	case MAC_PROP_EN_100FDX_CAP:
764 		capp = &ph->phy_cap_100_fdx;
765 		advp = &ph->phy_en_100_fdx;
766 		macpp = &mh->m_en_100_fdx;
767 		break;
768 	case MAC_PROP_EN_100HDX_CAP:
769 		capp = &ph->phy_cap_100_hdx;
770 		advp = &ph->phy_en_100_hdx;
771 		macpp = &mh->m_en_100_hdx;
772 		break;
773 	case MAC_PROP_EN_100T4_CAP:
774 		capp = &ph->phy_cap_100_t4;
775 		advp = &ph->phy_en_100_t4;
776 		macpp = &mh->m_en_100_t4;
777 		break;
778 	case MAC_PROP_EN_10FDX_CAP:
779 		capp = &ph->phy_cap_10_fdx;
780 		advp = &ph->phy_en_10_fdx;
781 		macpp = &mh->m_en_10_fdx;
782 		break;
783 	case MAC_PROP_EN_10HDX_CAP:
784 		capp = &ph->phy_cap_10_hdx;
785 		advp = &ph->phy_en_10_hdx;
786 		macpp = &mh->m_en_10_hdx;
787 		break;
788 	case MAC_PROP_AUTONEG:
789 		capp = &ph->phy_cap_aneg;
790 		advp = &ph->phy_en_aneg;
791 		macpp = &mh->m_en_aneg;
792 		break;
793 	case MAC_PROP_FLOWCTRL:
794 		if (sz < sizeof (link_flowctrl_t)) {
795 			rv = EINVAL;
796 		} else {
797 			link_flowctrl_t	fc;
798 			boolean_t chg;
799 
800 			bcopy(valp, &fc, sizeof (fc));
801 
802 			chg = fc == ph->phy_en_flowctrl ? B_FALSE : B_TRUE;
803 			switch (fc) {
804 			case LINK_FLOWCTRL_NONE:
805 				ph->phy_en_pause = B_FALSE;
806 				ph->phy_en_asmpause = B_FALSE;
807 				ph->phy_en_flowctrl = fc;
808 				break;
809 			/*
810 			 * Note that while we don't have a way to
811 			 * advertise that we can RX pause (we just
812 			 * won't send pause frames), we advertise full
813 			 * support.  The MAC driver will learn of the
814 			 * configuration via the saved value of the
815 			 * tunable.
816 			 */
817 			case LINK_FLOWCTRL_BI:
818 			case LINK_FLOWCTRL_RX:
819 				if (ph->phy_cap_pause) {
820 					ph->phy_en_pause = B_TRUE;
821 					ph->phy_en_asmpause = B_TRUE;
822 					ph->phy_en_flowctrl = fc;
823 				} else {
824 					rv = EINVAL;
825 				}
826 				break;
827 
828 			/*
829 			 * Tell the other side that we can assert
830 			 * pause, but we cannot resend.
831 			 */
832 			case LINK_FLOWCTRL_TX:
833 				if (ph->phy_cap_asmpause) {
834 					ph->phy_en_pause = B_FALSE;
835 					ph->phy_en_flowctrl = fc;
836 					ph->phy_en_asmpause = B_TRUE;
837 				} else {
838 					rv = EINVAL;
839 				}
840 				break;
841 			default:
842 				rv = EINVAL;
843 				break;
844 			}
845 			if ((rv == 0) && chg) {
846 				mh->m_en_flowctrl = fc;
847 				mh->m_tstate = MII_STATE_RESET;
848 				cv_broadcast(&mh->m_cv);
849 			}
850 		}
851 		break;
852 
853 	default:
854 		rv = ENOTSUP;
855 		break;
856 	}
857 
858 	if (capp && advp && macpp) {
859 		if (sz < sizeof (uint8_t)) {
860 			rv = EINVAL;
861 
862 		} else if (*capp) {
863 			if (*advp != *(uint8_t *)valp) {
864 				*advp = *(uint8_t *)valp;
865 				*macpp = *(uint8_t *)valp;
866 				mh->m_tstate = MII_STATE_RESET;
867 				cv_broadcast(&mh->m_cv);
868 			}
869 			rv = 0;
870 		}
871 	}
872 
873 	mutex_exit(&mh->m_lock);
874 	return (rv);
875 }
876 
877 int
878 mii_m_getstat(mii_handle_t mh, uint_t stat, uint64_t *val)
879 {
880 	phy_handle_t	*ph;
881 	int		rv = 0;
882 
883 	mutex_enter(&mh->m_lock);
884 
885 	ph = mh->m_phy;
886 
887 	switch (stat) {
888 	case MAC_STAT_IFSPEED:
889 		*val = ph->phy_speed * 1000000ull;
890 		break;
891 	case ETHER_STAT_LINK_DUPLEX:
892 		*val = ph->phy_duplex;
893 		break;
894 	case ETHER_STAT_LINK_AUTONEG:
895 		*val = !!(ph->phy_adv_aneg && ph->phy_lp_aneg);
896 		break;
897 	case ETHER_STAT_XCVR_ID:
898 		*val = ph->phy_id;
899 		break;
900 	case ETHER_STAT_XCVR_INUSE:
901 		*val = ph->phy_type;
902 		break;
903 	case ETHER_STAT_XCVR_ADDR:
904 		*val = ph->phy_addr;
905 		break;
906 	case ETHER_STAT_LINK_ASMPAUSE:
907 		*val = ph->phy_adv_asmpause && ph->phy_lp_asmpause &&
908 		    ph->phy_adv_pause != ph->phy_lp_pause;
909 		break;
910 	case ETHER_STAT_LINK_PAUSE:
911 		*val = (ph->phy_flowctrl == LINK_FLOWCTRL_BI) ||
912 		    (ph->phy_flowctrl == LINK_FLOWCTRL_RX);
913 		break;
914 	case ETHER_STAT_CAP_1000FDX:
915 		*val = ph->phy_cap_1000_fdx;
916 		break;
917 	case ETHER_STAT_CAP_1000HDX:
918 		*val = ph->phy_cap_1000_hdx;
919 		break;
920 	case ETHER_STAT_CAP_100FDX:
921 		*val = ph->phy_cap_100_fdx;
922 		break;
923 	case ETHER_STAT_CAP_100HDX:
924 		*val = ph->phy_cap_100_hdx;
925 		break;
926 	case ETHER_STAT_CAP_10FDX:
927 		*val = ph->phy_cap_10_fdx;
928 		break;
929 	case ETHER_STAT_CAP_10HDX:
930 		*val = ph->phy_cap_10_hdx;
931 		break;
932 	case ETHER_STAT_CAP_100T4:
933 		*val = ph->phy_cap_100_t4;
934 		break;
935 	case ETHER_STAT_CAP_AUTONEG:
936 		*val = ph->phy_cap_aneg;
937 		break;
938 	case ETHER_STAT_CAP_PAUSE:
939 		*val = ph->phy_cap_pause;
940 		break;
941 	case ETHER_STAT_CAP_ASMPAUSE:
942 		*val = ph->phy_cap_asmpause;
943 		break;
944 
945 	case ETHER_STAT_LP_CAP_1000FDX:
946 		*val = ph->phy_lp_1000_fdx;
947 		break;
948 	case ETHER_STAT_LP_CAP_1000HDX:
949 		*val = ph->phy_lp_1000_hdx;
950 		break;
951 	case ETHER_STAT_LP_CAP_100FDX:
952 		*val = ph->phy_lp_100_fdx;
953 		break;
954 	case ETHER_STAT_LP_CAP_100HDX:
955 		*val = ph->phy_lp_100_hdx;
956 		break;
957 	case ETHER_STAT_LP_CAP_10FDX:
958 		*val = ph->phy_lp_10_fdx;
959 		break;
960 	case ETHER_STAT_LP_CAP_10HDX:
961 		*val = ph->phy_lp_10_hdx;
962 		break;
963 	case ETHER_STAT_LP_CAP_100T4:
964 		*val = ph->phy_lp_100_t4;
965 		break;
966 	case ETHER_STAT_LP_CAP_AUTONEG:
967 		*val = ph->phy_lp_aneg;
968 		break;
969 	case ETHER_STAT_LP_CAP_PAUSE:
970 		*val = ph->phy_lp_pause;
971 		break;
972 	case ETHER_STAT_LP_CAP_ASMPAUSE:
973 		*val = ph->phy_lp_asmpause;
974 		break;
975 
976 	case ETHER_STAT_ADV_CAP_1000FDX:
977 		*val = ph->phy_adv_1000_fdx;
978 		break;
979 	case ETHER_STAT_ADV_CAP_1000HDX:
980 		*val = ph->phy_adv_1000_hdx;
981 		break;
982 	case ETHER_STAT_ADV_CAP_100FDX:
983 		*val = ph->phy_adv_100_fdx;
984 		break;
985 	case ETHER_STAT_ADV_CAP_100HDX:
986 		*val = ph->phy_adv_100_hdx;
987 		break;
988 	case ETHER_STAT_ADV_CAP_10FDX:
989 		*val = ph->phy_adv_10_fdx;
990 		break;
991 	case ETHER_STAT_ADV_CAP_10HDX:
992 		*val = ph->phy_adv_10_hdx;
993 		break;
994 	case ETHER_STAT_ADV_CAP_100T4:
995 		*val = ph->phy_adv_100_t4;
996 		break;
997 	case ETHER_STAT_ADV_CAP_AUTONEG:
998 		*val = ph->phy_adv_aneg;
999 		break;
1000 	case ETHER_STAT_ADV_CAP_PAUSE:
1001 		*val = ph->phy_adv_pause;
1002 		break;
1003 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
1004 		*val = ph->phy_adv_asmpause;
1005 		break;
1006 
1007 	default:
1008 		rv = ENOTSUP;
1009 		break;
1010 	}
1011 	mutex_exit(&mh->m_lock);
1012 
1013 	return (rv);
1014 }
1015 
1016 /*
1017  * PHY support routines.  Private to the MII module and the vendor
1018  * specific PHY implementation code.
1019  */
1020 uint16_t
1021 phy_read(phy_handle_t *ph, uint8_t reg)
1022 {
1023 	mii_handle_t	mh = ph->phy_mii;
1024 
1025 	return ((*mh->m_ops.mii_read)(mh->m_private, ph->phy_addr, reg));
1026 }
1027 
1028 void
1029 phy_write(phy_handle_t *ph, uint8_t reg, uint16_t val)
1030 {
1031 	mii_handle_t	mh = ph->phy_mii;
1032 
1033 	(*mh->m_ops.mii_write)(mh->m_private, ph->phy_addr, reg, val);
1034 }
1035 
1036 int
1037 phy_reset(phy_handle_t *ph)
1038 {
1039 	ASSERT(mutex_owned(&ph->phy_mii->m_lock));
1040 
1041 	/*
1042 	 * For our device, make sure its powered up, unisolated, and
1043 	 * not in loopback.
1044 	 */
1045 	PHY_CLR(ph, MII_CONTROL,
1046 	    MII_CONTROL_PWRDN | MII_CONTROL_LOOPBACK | MII_CONTROL_ISOLATE);
1047 
1048 	/*
1049 	 * Finally reset it.
1050 	 */
1051 	PHY_SET(ph, MII_CONTROL, MII_CONTROL_RESET);
1052 
1053 	/*
1054 	 * Apparently some devices (DP83840A) like to have a little
1055 	 * bit of a wait before we start accessing anything else on
1056 	 * the PHY.
1057 	 */
1058 	drv_usecwait(500);
1059 
1060 	/*
1061 	 * Wait for reset to complete - probably very fast, but no
1062 	 * more than 0.5 sec according to spec.  It would be nice if
1063 	 * we could use delay() here, but MAC drivers may call
1064 	 * functions which hold this lock in interrupt context, so
1065 	 * sleeping would be a definite no-no.  The good news here is
1066 	 * that it seems to be the case that most devices come back
1067 	 * within only a few hundred usec.
1068 	 */
1069 	for (int i = 500000; i; i -= 100) {
1070 		if ((phy_read(ph, MII_CONTROL) & MII_CONTROL_RESET) == 0) {
1071 			/* reset completed */
1072 			return (DDI_SUCCESS);
1073 		}
1074 		drv_usecwait(100);
1075 	}
1076 
1077 	return (DDI_FAILURE);
1078 }
1079 
1080 int
1081 phy_stop(phy_handle_t *ph)
1082 {
1083 	phy_write(ph, MII_CONTROL,
1084 	    MII_CONTROL_ISOLATE | MII_CONTROL_PWRDN |
1085 	    MII_CONTROL_LOOPBACK);
1086 	return (DDI_SUCCESS);
1087 }
1088 
1089 int
1090 phy_start(phy_handle_t *ph)
1091 {
1092 	uint16_t	bmcr, anar, gtcr;
1093 	ASSERT(mutex_owned(&ph->phy_mii->m_lock));
1094 
1095 	/*
1096 	 * Disable everything to start... we'll add in modes as we go.
1097 	 */
1098 	ph->phy_adv_aneg = B_FALSE;
1099 	ph->phy_adv_1000_fdx = B_FALSE;
1100 	ph->phy_adv_1000_hdx = B_FALSE;
1101 	ph->phy_adv_100_fdx = B_FALSE;
1102 	ph->phy_adv_100_t4 = B_FALSE;
1103 	ph->phy_adv_100_hdx = B_FALSE;
1104 	ph->phy_adv_10_fdx = B_FALSE;
1105 	ph->phy_adv_10_hdx = B_FALSE;
1106 	ph->phy_adv_pause = B_FALSE;
1107 	ph->phy_adv_asmpause = B_FALSE;
1108 
1109 	switch (ph->phy_loopback) {
1110 	case PHY_LB_NONE:
1111 		/*
1112 		 * No loopback overrides, so try to advertise everything
1113 		 * that is administratively enabled.
1114 		 */
1115 		ph->phy_adv_aneg = ph->phy_en_aneg;
1116 		ph->phy_adv_1000_fdx = ph->phy_en_1000_fdx;
1117 		ph->phy_adv_1000_hdx = ph->phy_en_1000_hdx;
1118 		ph->phy_adv_100_fdx = ph->phy_en_100_fdx;
1119 		ph->phy_adv_100_t4 = ph->phy_en_100_t4;
1120 		ph->phy_adv_100_hdx = ph->phy_en_100_hdx;
1121 		ph->phy_adv_10_fdx = ph->phy_en_10_fdx;
1122 		ph->phy_adv_10_hdx = ph->phy_en_10_hdx;
1123 		ph->phy_adv_pause = ph->phy_en_pause;
1124 		ph->phy_adv_asmpause = ph->phy_en_asmpause;
1125 		break;
1126 
1127 	case PHY_LB_INT_PHY:
1128 		if (ph->phy_cap_1000_fdx) {
1129 			ph->phy_adv_1000_fdx = B_TRUE;
1130 		} else if (ph->phy_cap_100_fdx) {
1131 			ph->phy_adv_100_fdx = B_TRUE;
1132 		} else if (ph->phy_cap_10_fdx) {
1133 			ph->phy_adv_10_fdx = B_TRUE;
1134 		}
1135 		break;
1136 
1137 	case PHY_LB_EXT_10:
1138 		ph->phy_adv_10_fdx = B_TRUE;
1139 		break;
1140 
1141 	case PHY_LB_EXT_100:
1142 		ph->phy_adv_100_fdx = B_TRUE;
1143 		break;
1144 
1145 	case PHY_LB_EXT_1000:
1146 		ph->phy_adv_1000_fdx = B_TRUE;
1147 		break;
1148 	}
1149 
1150 	/*
1151 	 * Limit properties to what the hardware can actually support.
1152 	 */
1153 #define	FILTER_ADV(CAP)		\
1154 	if (!ph->phy_cap_##CAP)	\
1155 	    ph->phy_adv_##CAP = 0
1156 
1157 	FILTER_ADV(aneg);
1158 	FILTER_ADV(1000_fdx);
1159 	FILTER_ADV(1000_hdx);
1160 	FILTER_ADV(100_fdx);
1161 	FILTER_ADV(100_t4);
1162 	FILTER_ADV(100_hdx);
1163 	FILTER_ADV(10_fdx);
1164 	FILTER_ADV(10_hdx);
1165 	FILTER_ADV(pause);
1166 	FILTER_ADV(asmpause);
1167 
1168 #undef	FILTER_ADV
1169 
1170 	/*
1171 	 * We need at least one valid mode.
1172 	 */
1173 	if ((!ph->phy_adv_1000_fdx) &&
1174 	    (!ph->phy_adv_1000_hdx) &&
1175 	    (!ph->phy_adv_100_t4) &&
1176 	    (!ph->phy_adv_100_fdx) &&
1177 	    (!ph->phy_adv_100_hdx) &&
1178 	    (!ph->phy_adv_10_fdx) &&
1179 	    (!ph->phy_adv_10_hdx)) {
1180 
1181 		phy_warn(ph,
1182 		    "No valid link mode selected.  Powering down PHY.");
1183 
1184 		PHY_SET(ph, MII_CONTROL, MII_CONTROL_PWRDN);
1185 
1186 		ph->phy_link = LINK_STATE_DOWN;
1187 		return (DDI_SUCCESS);
1188 	}
1189 
1190 	switch (ph->phy_loopback) {
1191 	case PHY_LB_INT_PHY:
1192 		bmcr = MII_CONTROL_LOOPBACK;
1193 		gtcr = 0;
1194 		break;
1195 	case PHY_LB_EXT_10:
1196 	case PHY_LB_EXT_100:
1197 	case PHY_LB_EXT_1000:
1198 		bmcr = 0;
1199 		gtcr = MII_MSCONTROL_MANUAL | MII_MSCONTROL_MASTER;
1200 		break;
1201 	case PHY_LB_NONE:
1202 	default:
1203 		bmcr = 0;
1204 		gtcr = 0;
1205 		break;
1206 	}
1207 
1208 	if (ph->phy_adv_aneg) {
1209 		bmcr |= MII_CONTROL_ANE | MII_CONTROL_RSAN;
1210 	}
1211 
1212 	if ((ph->phy_adv_1000_fdx) || (ph->phy_adv_1000_hdx)) {
1213 		bmcr |= MII_CONTROL_1GB;
1214 
1215 	} else if (ph->phy_adv_100_fdx || ph->phy_adv_100_hdx ||
1216 	    ph->phy_adv_100_t4) {
1217 		bmcr |= MII_CONTROL_100MB;
1218 	}
1219 
1220 	if (ph->phy_adv_1000_fdx || ph->phy_adv_100_fdx || ph->phy_adv_10_fdx) {
1221 		bmcr |= MII_CONTROL_FDUPLEX;
1222 	}
1223 
1224 	if (ph->phy_type == XCVR_1000X) {
1225 		/* 1000BASE-X (usually fiber) */
1226 		anar = 0;
1227 		if (ph->phy_adv_1000_fdx) {
1228 			anar |= MII_ABILITY_X_FD;
1229 		}
1230 		if (ph->phy_adv_1000_hdx) {
1231 			anar |= MII_ABILITY_X_HD;
1232 		}
1233 		if (ph->phy_adv_pause) {
1234 			anar |= MII_ABILITY_X_PAUSE;
1235 		}
1236 		if (ph->phy_adv_asmpause) {
1237 			anar |= MII_ABILITY_X_ASMPAUSE;
1238 		}
1239 
1240 	} else if (ph->phy_type == XCVR_100T2) {
1241 		/* 100BASE-T2 */
1242 		anar = 0;
1243 		if (ph->phy_adv_100_fdx) {
1244 			anar |= MII_ABILITY_T2_FD;
1245 		}
1246 		if (ph->phy_adv_100_hdx) {
1247 			anar |= MII_ABILITY_T2_HD;
1248 		}
1249 
1250 	} else {
1251 		anar = MII_AN_SELECTOR_8023;
1252 
1253 		/* 1000BASE-T or 100BASE-X probably  */
1254 		if (ph->phy_adv_1000_fdx) {
1255 			gtcr |= MII_MSCONTROL_1000T_FD;
1256 		}
1257 		if (ph->phy_adv_1000_hdx) {
1258 			gtcr |= MII_MSCONTROL_1000T;
1259 		}
1260 		if (ph->phy_adv_100_fdx) {
1261 			anar |= MII_ABILITY_100BASE_TX_FD;
1262 		}
1263 		if (ph->phy_adv_100_hdx) {
1264 			anar |= MII_ABILITY_100BASE_TX;
1265 		}
1266 		if (ph->phy_adv_100_t4) {
1267 			anar |= MII_ABILITY_100BASE_T4;
1268 		}
1269 		if (ph->phy_adv_10_fdx) {
1270 			anar |= MII_ABILITY_10BASE_T_FD;
1271 		}
1272 		if (ph->phy_adv_100_hdx) {
1273 			anar |= MII_ABILITY_10BASE_T;
1274 		}
1275 		if (ph->phy_adv_pause) {
1276 			anar |= MII_ABILITY_PAUSE;
1277 		}
1278 		if (ph->phy_adv_asmpause) {
1279 			anar |= MII_ABILITY_ASMPAUSE;
1280 		}
1281 	}
1282 
1283 	ph->phy_link = LINK_STATE_DOWN;
1284 	ph->phy_duplex = LINK_DUPLEX_UNKNOWN;
1285 	ph->phy_speed = 0;
1286 
1287 	phy_write(ph, MII_AN_ADVERT, anar);
1288 	phy_write(ph, MII_CONTROL,
1289 	    bmcr & ~(MII_CONTROL_ANE|MII_CONTROL_RSAN|MII_CONTROL_LOOPBACK));
1290 	switch (ph->phy_type) {
1291 	case XCVR_1000T:
1292 	case XCVR_1000X:
1293 	case XCVR_100T2:
1294 		phy_write(ph, MII_MSCONTROL, gtcr);
1295 	}
1296 
1297 	/*
1298 	 * Finally, this will start up autoneg if it is enabled, or
1299 	 * force link settings otherwise.
1300 	 */
1301 	phy_write(ph, MII_CONTROL, bmcr);
1302 
1303 	return (DDI_SUCCESS);
1304 }
1305 
1306 
1307 int
1308 phy_check(phy_handle_t *ph)
1309 {
1310 	uint16_t control, status, lpar, msstat, anexp;
1311 	int debounces = 100;
1312 
1313 	ASSERT(mutex_owned(&ph->phy_mii->m_lock));
1314 
1315 debounce:
1316 	status = phy_read(ph, MII_STATUS);
1317 	control = phy_read(ph, MII_CONTROL);
1318 
1319 	if (status & MII_STATUS_EXTENDED) {
1320 		lpar = phy_read(ph, MII_AN_LPABLE);
1321 		anexp = phy_read(ph, MII_AN_EXPANSION);
1322 	} else {
1323 		lpar = 0;
1324 		anexp = 0;
1325 	}
1326 
1327 	/*
1328 	 * We reread to clear any latched bits.  This also debounces
1329 	 * any state that might be in transition.
1330 	 */
1331 	drv_usecwait(10);
1332 	if ((status != phy_read(ph, MII_STATUS)) && debounces) {
1333 		debounces--;
1334 		goto debounce;
1335 	}
1336 
1337 	/*
1338 	 * Detect the situation where the PHY is removed or has died.
1339 	 * According to spec, at least one bit of status must be set,
1340 	 * and at least one bit must be clear.
1341 	 */
1342 	if ((status == 0xffff) || (status == 0)) {
1343 		ph->phy_speed = 0;
1344 		ph->phy_duplex = LINK_DUPLEX_UNKNOWN;
1345 		ph->phy_link = LINK_STATE_UNKNOWN;
1346 		ph->phy_present = B_FALSE;
1347 		return (DDI_FAILURE);
1348 	}
1349 
1350 	/* We only respect the link flag if we are not in loopback. */
1351 	if ((ph->phy_loopback != PHY_LB_INT_PHY) &&
1352 	    ((status & MII_STATUS_LINKUP) == 0)) {
1353 		ph->phy_speed = 0;
1354 		ph->phy_duplex = LINK_DUPLEX_UNKNOWN;
1355 		ph->phy_link = LINK_STATE_DOWN;
1356 		return (DDI_SUCCESS);
1357 	}
1358 
1359 	ph->phy_link = LINK_STATE_UP;
1360 
1361 	if ((control & MII_CONTROL_ANE) == 0) {
1362 
1363 		ph->phy_lp_aneg = B_FALSE;
1364 		ph->phy_lp_10_hdx = B_FALSE;
1365 		ph->phy_lp_10_fdx = B_FALSE;
1366 		ph->phy_lp_100_t4 = B_FALSE;
1367 		ph->phy_lp_100_hdx = B_FALSE;
1368 		ph->phy_lp_100_fdx = B_FALSE;
1369 		ph->phy_lp_1000_hdx = B_FALSE;
1370 		ph->phy_lp_1000_fdx = B_FALSE;
1371 
1372 		/*
1373 		 * We have no idea what our link partner might or might
1374 		 * not be able to support, except that it appears to
1375 		 * support the same mode that we have forced.
1376 		 */
1377 		if (control & MII_CONTROL_1GB) {
1378 			ph->phy_speed = 1000;
1379 		} else if (control & MII_CONTROL_100MB) {
1380 			ph->phy_speed = 100;
1381 		} else {
1382 			ph->phy_speed = 10;
1383 		}
1384 		ph->phy_duplex = control & MII_CONTROL_FDUPLEX ?
1385 		    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
1386 
1387 		return (DDI_SUCCESS);
1388 	}
1389 
1390 	if (ph->phy_type == XCVR_1000X) {
1391 
1392 		ph->phy_lp_10_hdx = B_FALSE;
1393 		ph->phy_lp_10_fdx = B_FALSE;
1394 		ph->phy_lp_100_t4 = B_FALSE;
1395 		ph->phy_lp_100_hdx = B_FALSE;
1396 		ph->phy_lp_100_fdx = B_FALSE;
1397 
1398 		/* 1000BASE-X requires autonegotiation */
1399 		ph->phy_lp_aneg = B_TRUE;
1400 		ph->phy_lp_1000_fdx = !!(lpar & MII_ABILITY_X_FD);
1401 		ph->phy_lp_1000_hdx = !!(lpar & MII_ABILITY_X_HD);
1402 		ph->phy_lp_pause = !!(lpar & MII_ABILITY_X_PAUSE);
1403 		ph->phy_lp_asmpause = !!(lpar & MII_ABILITY_X_ASMPAUSE);
1404 
1405 	} else if (ph->phy_type == XCVR_100T2) {
1406 		ph->phy_lp_10_hdx = B_FALSE;
1407 		ph->phy_lp_10_fdx = B_FALSE;
1408 		ph->phy_lp_100_t4 = B_FALSE;
1409 		ph->phy_lp_1000_hdx = B_FALSE;
1410 		ph->phy_lp_1000_fdx = B_FALSE;
1411 		ph->phy_lp_pause = B_FALSE;
1412 		ph->phy_lp_asmpause = B_FALSE;
1413 
1414 		/* 100BASE-T2 requires autonegotiation */
1415 		ph->phy_lp_aneg = B_TRUE;
1416 		ph->phy_lp_100_fdx = !!(lpar & MII_ABILITY_T2_FD);
1417 		ph->phy_lp_100_hdx = !!(lpar & MII_ABILITY_T2_HD);
1418 
1419 	} else if (anexp & MII_AN_EXP_PARFAULT) {
1420 		/*
1421 		 * Parallel detection fault!  This happens when the
1422 		 * peer does not use autonegotiation, and the
1423 		 * detection logic reports more than one type of legal
1424 		 * link is available.  Note that parallel detection
1425 		 * can only happen with half duplex 10, 100, and
1426 		 * 100TX4.  We also should not have got here, because
1427 		 * the link state bit should have failed.
1428 		 */
1429 #ifdef	DEBUG
1430 		phy_warn(ph, "Parallel detection fault!");
1431 #endif
1432 		ph->phy_lp_10_hdx = B_FALSE;
1433 		ph->phy_lp_10_fdx = B_FALSE;
1434 		ph->phy_lp_100_t4 = B_FALSE;
1435 		ph->phy_lp_100_hdx = B_FALSE;
1436 		ph->phy_lp_100_fdx = B_FALSE;
1437 		ph->phy_lp_1000_hdx = B_FALSE;
1438 		ph->phy_lp_1000_fdx = B_FALSE;
1439 		ph->phy_lp_pause = B_FALSE;
1440 		ph->phy_lp_asmpause = B_FALSE;
1441 		ph->phy_speed = 0;
1442 		ph->phy_duplex = LINK_DUPLEX_UNKNOWN;
1443 		return (DDI_SUCCESS);
1444 
1445 	} else {
1446 		ph->phy_lp_aneg = !!(anexp & MII_AN_EXP_LPCANAN);
1447 
1448 		/*
1449 		 * Note: If the peer doesn't support autonegotiation, then
1450 		 * according to clause 28.5.4.5, the link partner ability
1451 		 * register will still have the right bits set.  However,
1452 		 * gigabit modes cannot use legacy parallel detection.
1453 		 */
1454 
1455 		if ((ph->phy_type == XCVR_1000T) &
1456 		    (anexp & MII_AN_EXP_LPCANAN)) {
1457 
1458 			/* check for gige */
1459 			msstat = phy_read(ph, MII_MSSTATUS);
1460 
1461 			ph->phy_lp_1000_hdx =
1462 			    !!(msstat & MII_MSSTATUS_LP1000T);
1463 
1464 			ph->phy_lp_1000_fdx =
1465 			    !!(msstat & MII_MSSTATUS_LP1000T_FD);
1466 		}
1467 
1468 		ph->phy_lp_100_fdx = !!(lpar & MII_ABILITY_100BASE_TX_FD);
1469 		ph->phy_lp_100_hdx = !!(lpar & MII_ABILITY_100BASE_TX);
1470 		ph->phy_lp_100_t4 = !!(lpar & MII_ABILITY_100BASE_T4);
1471 		ph->phy_lp_10_fdx = !!(lpar & MII_ABILITY_10BASE_T_FD);
1472 		ph->phy_lp_10_hdx = !!(lpar & MII_ABILITY_10BASE_T);
1473 		ph->phy_lp_pause = !!(lpar & MII_ABILITY_PAUSE);
1474 		ph->phy_lp_asmpause = !!(lpar & MII_ABILITY_ASMPAUSE);
1475 	}
1476 
1477 	/* resolve link pause */
1478 	if ((ph->phy_en_flowctrl == LINK_FLOWCTRL_BI) &&
1479 	    (ph->phy_lp_pause)) {
1480 		ph->phy_flowctrl = LINK_FLOWCTRL_BI;
1481 	} else if ((ph->phy_en_flowctrl == LINK_FLOWCTRL_RX) &&
1482 	    (ph->phy_lp_pause || ph->phy_lp_asmpause)) {
1483 		ph->phy_flowctrl = LINK_FLOWCTRL_RX;
1484 	} else if ((ph->phy_en_flowctrl == LINK_FLOWCTRL_TX) &&
1485 	    (ph->phy_lp_pause)) {
1486 		ph->phy_flowctrl = LINK_FLOWCTRL_TX;
1487 	} else {
1488 		ph->phy_flowctrl = LINK_FLOWCTRL_NONE;
1489 	}
1490 
1491 	if (ph->phy_adv_1000_fdx && ph->phy_lp_1000_fdx) {
1492 		ph->phy_speed = 1000;
1493 		ph->phy_duplex = LINK_DUPLEX_FULL;
1494 
1495 	} else if (ph->phy_adv_1000_hdx && ph->phy_lp_1000_hdx) {
1496 		ph->phy_speed = 1000;
1497 		ph->phy_duplex = LINK_DUPLEX_HALF;
1498 
1499 	} else if (ph->phy_adv_100_fdx && ph->phy_lp_100_fdx) {
1500 		ph->phy_speed = 100;
1501 		ph->phy_duplex = LINK_DUPLEX_FULL;
1502 
1503 	} else if (ph->phy_adv_100_t4 && ph->phy_lp_100_t4) {
1504 		ph->phy_speed = 100;
1505 		ph->phy_duplex = LINK_DUPLEX_HALF;
1506 
1507 	} else if (ph->phy_adv_100_hdx && ph->phy_lp_100_hdx) {
1508 		ph->phy_speed = 100;
1509 		ph->phy_duplex = LINK_DUPLEX_HALF;
1510 
1511 	} else if (ph->phy_adv_10_fdx && ph->phy_lp_10_fdx) {
1512 		ph->phy_speed = 10;
1513 		ph->phy_duplex = LINK_DUPLEX_FULL;
1514 
1515 	} else if (ph->phy_adv_10_hdx && ph->phy_lp_10_hdx) {
1516 		ph->phy_speed = 10;
1517 		ph->phy_duplex = LINK_DUPLEX_HALF;
1518 
1519 	} else {
1520 #ifdef	DEBUG
1521 		phy_warn(ph, "No common abilities.");
1522 #endif
1523 		ph->phy_speed = 0;
1524 		ph->phy_duplex = LINK_DUPLEX_UNKNOWN;
1525 	}
1526 
1527 	return (DDI_SUCCESS);
1528 }
1529 
1530 int
1531 phy_get_prop(phy_handle_t *ph, char *prop, int dflt)
1532 {
1533 	mii_handle_t	mh = ph->phy_mii;
1534 
1535 	return (ddi_prop_get_int(DDI_DEV_T_ANY, mh->m_dip, 0, prop, dflt));
1536 }
1537 
1538 const char *
1539 phy_get_name(phy_handle_t *ph)
1540 {
1541 	mii_handle_t	mh = ph->phy_mii;
1542 
1543 	return (mh->m_name);
1544 }
1545 
1546 const char *
1547 phy_get_driver(phy_handle_t *ph)
1548 {
1549 	mii_handle_t	mh = ph->phy_mii;
1550 
1551 	return (ddi_driver_name(mh->m_dip));
1552 }
1553 
1554 void
1555 phy_warn(phy_handle_t *ph, const char *fmt, ...)
1556 {
1557 	va_list	va;
1558 	char buf[256];
1559 
1560 	(void) snprintf(buf, sizeof (buf), "%s: %s", phy_get_name(ph), fmt);
1561 
1562 	va_start(va, fmt);
1563 	vcmn_err(CE_WARN, buf, va);
1564 	va_end(va);
1565 }
1566 
1567 /*
1568  * Internal support routines.
1569  */
1570 
1571 void
1572 _mii_probe_phy(phy_handle_t *ph)
1573 {
1574 	uint16_t	bmsr;
1575 	uint16_t	extsr;
1576 	mii_handle_t	mh = ph->phy_mii;
1577 
1578 
1579 	/*
1580 	 * Apparently, PHY 0 is less likely to be physically
1581 	 * connected, and should always be the last one tried.  Most
1582 	 * single solution NICs use PHY1 for their built-in
1583 	 * transceiver.  NICs with an external MII will often place
1584 	 * the external PHY at address 1, and use address 0 for the
1585 	 * internal PHY.
1586 	 */
1587 
1588 	ph->phy_id = 0;
1589 	ph->phy_model = "PHY";
1590 	ph->phy_vendor = "Unknown Vendor";
1591 
1592 	/* done twice to clear any latched bits */
1593 	bmsr = phy_read(ph, MII_STATUS);
1594 	bmsr = phy_read(ph, MII_STATUS);
1595 	if ((bmsr == 0) || (bmsr == 0xffff)) {
1596 		ph->phy_present = B_FALSE;
1597 		return;
1598 	}
1599 
1600 	if (bmsr & MII_STATUS_EXTSTAT) {
1601 		extsr = phy_read(ph, MII_EXTSTATUS);
1602 	} else {
1603 		extsr = 0;
1604 	}
1605 
1606 	ph->phy_present = B_TRUE;
1607 	ph->phy_id = ((uint32_t)phy_read(ph, MII_PHYIDH) << 16) |
1608 	    phy_read(ph, MII_PHYIDL);
1609 
1610 	/* setup default handlers */
1611 	ph->phy_reset = phy_reset;
1612 	ph->phy_start = phy_start;
1613 	ph->phy_stop = phy_stop;
1614 	ph->phy_check = phy_check;
1615 
1616 	/*
1617 	 * We ignore the non-existent 100baseT2 stuff -- no
1618 	 * known products for it exist.
1619 	 */
1620 	ph->phy_cap_aneg =	!!(bmsr & MII_STATUS_CANAUTONEG);
1621 	ph->phy_cap_100_t4 =	!!(bmsr & MII_STATUS_100_BASE_T4);
1622 	ph->phy_cap_100_fdx =	!!(bmsr & MII_STATUS_100_BASEX_FD);
1623 	ph->phy_cap_100_hdx =	!!(bmsr & MII_STATUS_100_BASEX);
1624 	ph->phy_cap_10_fdx =	!!(bmsr & MII_STATUS_10_FD);
1625 	ph->phy_cap_10_hdx =	!!(bmsr & MII_STATUS_10);
1626 	ph->phy_cap_1000_fdx =
1627 	    !!(extsr & (MII_EXTSTATUS_1000X_FD|MII_EXTSTATUS_1000T_FD));
1628 	ph->phy_cap_1000_hdx =
1629 	    !!(extsr & (MII_EXTSTATUS_1000X | MII_EXTSTATUS_1000T));
1630 	ph->phy_cap_pause =	mh->m_cap_pause;
1631 	ph->phy_cap_asmpause =	mh->m_cap_asmpause;
1632 
1633 	if (bmsr & MII_STATUS_10) {
1634 		ph->phy_cap_10_hdx = B_TRUE;
1635 		ph->phy_type = XCVR_10;
1636 	}
1637 	if (bmsr & MII_STATUS_10_FD) {
1638 		ph->phy_cap_10_fdx = B_TRUE;
1639 		ph->phy_type = XCVR_10;
1640 	}
1641 	if (bmsr & MII_STATUS_100T2) {
1642 		ph->phy_cap_100_hdx = B_TRUE;
1643 		ph->phy_type = XCVR_100T2;
1644 	}
1645 	if (bmsr & MII_STATUS_100T2_FD) {
1646 		ph->phy_cap_100_fdx = B_TRUE;
1647 		ph->phy_type = XCVR_100T2;
1648 	}
1649 	if (bmsr & MII_STATUS_100_BASE_T4) {
1650 		ph->phy_cap_100_hdx = B_TRUE;
1651 		ph->phy_type = XCVR_100T4;
1652 	}
1653 	if (bmsr & MII_STATUS_100_BASEX) {
1654 		ph->phy_cap_100_hdx = B_TRUE;
1655 		ph->phy_type = XCVR_100X;
1656 	}
1657 	if (bmsr & MII_STATUS_100_BASEX_FD) {
1658 		ph->phy_cap_100_fdx = B_TRUE;
1659 		ph->phy_type = XCVR_100X;
1660 	}
1661 	if (extsr & MII_EXTSTATUS_1000X) {
1662 		ph->phy_cap_1000_hdx = B_TRUE;
1663 		ph->phy_type = XCVR_1000X;
1664 	}
1665 	if (extsr & MII_EXTSTATUS_1000X_FD) {
1666 		ph->phy_cap_1000_fdx = B_TRUE;
1667 		ph->phy_type = XCVR_1000X;
1668 	}
1669 	if (extsr & MII_EXTSTATUS_1000T) {
1670 		ph->phy_cap_1000_hdx = B_TRUE;
1671 		ph->phy_type = XCVR_1000T;
1672 	}
1673 	if (extsr & MII_EXTSTATUS_1000T_FD) {
1674 		ph->phy_cap_1000_fdx = B_TRUE;
1675 		ph->phy_type = XCVR_1000T;
1676 	}
1677 
1678 	for (int j = 0; _phy_probes[j] != NULL; j++) {
1679 		if ((*_phy_probes[j])(ph)) {
1680 			break;
1681 		}
1682 	}
1683 
1684 #define	INIT_ENABLE(CAP)	\
1685 	ph->phy_en_##CAP = (mh->m_en_##CAP > 0) ? \
1686 	    mh->m_en_##CAP : ph->phy_cap_##CAP
1687 
1688 	INIT_ENABLE(aneg);
1689 	INIT_ENABLE(1000_fdx);
1690 	INIT_ENABLE(1000_hdx);
1691 	INIT_ENABLE(100_fdx);
1692 	INIT_ENABLE(100_t4);
1693 	INIT_ENABLE(100_hdx);
1694 	INIT_ENABLE(10_fdx);
1695 	INIT_ENABLE(10_hdx);
1696 
1697 #undef	INIT_ENABLE
1698 	ph->phy_en_flowctrl = mh->m_en_flowctrl;
1699 	switch (ph->phy_en_flowctrl) {
1700 	case LINK_FLOWCTRL_BI:
1701 	case LINK_FLOWCTRL_RX:
1702 		ph->phy_en_pause = B_TRUE;
1703 		ph->phy_en_asmpause = B_TRUE;
1704 		break;
1705 	case LINK_FLOWCTRL_TX:
1706 		ph->phy_en_pause = B_FALSE;
1707 		ph->phy_en_asmpause = B_TRUE;
1708 		break;
1709 	default:
1710 		ph->phy_en_pause = B_FALSE;
1711 		ph->phy_en_asmpause = B_FALSE;
1712 		break;
1713 	}
1714 }
1715 
1716 void
1717 _mii_probe_task(mii_handle_t mh)
1718 {
1719 	uint8_t		new_addr;
1720 	uint8_t		old_addr;
1721 	uint8_t		user_addr;
1722 	uint8_t		curr_addr;
1723 	phy_handle_t	*ph;
1724 	int		pri = 0;
1725 
1726 	user_addr = ddi_prop_get_int(DDI_DEV_T_ANY, mh->m_dip, 0,
1727 	    "phy-addr", -1);
1728 	old_addr = mh->m_addr;
1729 	new_addr = 0xff;
1730 
1731 	/*
1732 	 * Apparently, PHY 0 is less likely to be physically
1733 	 * connected, and should always be the last one tried.  Most
1734 	 * single solution NICs use PHY1 for their built-in
1735 	 * transceiver.  NICs with an external MII will often place
1736 	 * the external PHY at address 1, and use address 0 for the
1737 	 * internal PHY.
1738 	 */
1739 
1740 	for (int i = 1; i < 33; i++) {
1741 
1742 		/*
1743 		 * This is tricky: it lets us try 0 last by starting
1744 		 * loop at 1 instead of 0.
1745 		 */
1746 		curr_addr = i % 32;
1747 
1748 		ph = &mh->m_phys[curr_addr];
1749 
1750 		bzero(ph, sizeof (*ph));
1751 		ph->phy_addr = curr_addr;
1752 		ph->phy_mii = mh;
1753 
1754 		_mii_probe_phy(ph);
1755 
1756 		if (!ph->phy_present)
1757 			continue;
1758 
1759 		if (curr_addr == user_addr) {
1760 			/*
1761 			 * We always try to honor the user configured phy.
1762 			 */
1763 			new_addr = curr_addr;
1764 			pri = 4;
1765 
1766 		}
1767 
1768 		/* two reads to clear latched bits */
1769 		if ((phy_read(ph, MII_STATUS) & MII_STATUS_LINKUP) &&
1770 		    (phy_read(ph, MII_STATUS) & MII_STATUS_LINKUP) &&
1771 		    (pri < 3)) {
1772 			/*
1773 			 * Link present is good.  We prefer this over
1774 			 * a possibly disconnected link.
1775 			 */
1776 			new_addr = curr_addr;
1777 			pri = 3;
1778 		}
1779 		if ((curr_addr == old_addr) && (pri < 2)) {
1780 			/*
1781 			 * All else being equal, minimize change.
1782 			 */
1783 			new_addr = curr_addr;
1784 			pri = 2;
1785 
1786 		}
1787 		if (pri < 1) {
1788 			/*
1789 			 * But make sure we at least select a present PHY.
1790 			 */
1791 			new_addr = curr_addr;
1792 			pri = 1;
1793 		}
1794 	}
1795 
1796 	if (new_addr == 0xff) {
1797 		mh->m_addr = -1;
1798 		mh->m_phy = &mh->m_bogus_phy;
1799 		_mii_error(mh, MII_ENOPHY);
1800 	} else {
1801 		mh->m_addr = new_addr;
1802 		mh->m_phy = &mh->m_phys[new_addr];
1803 		mh->m_tstate = MII_STATE_RESET;
1804 		cmn_err(CE_CONT, "?%s: Using %s Ethernet PHY at %d: %s %s\n",
1805 		    mh->m_name, mii_xcvr_types[mh->m_phy->phy_type],
1806 		    mh->m_addr, mh->m_phy->phy_vendor, mh->m_phy->phy_model);
1807 	}
1808 }
1809 
1810 static int
1811 _mii_reset_task(mii_handle_t mh)
1812 {
1813 	phy_handle_t	*ph;
1814 
1815 	ASSERT(mutex_owned(&mh->m_lock));
1816 
1817 	/*
1818 	 * Reset logic.  We want to isolate all the other
1819 	 * phys that are not in use.
1820 	 */
1821 	for (int i = 0; i < 32; i++) {
1822 		ph = &mh->m_phys[i];
1823 
1824 		if (!ph->phy_present)
1825 			continue;
1826 
1827 		/* don't touch our own phy, yet */
1828 		if (ph == mh->m_phy)
1829 			continue;
1830 
1831 		ph->phy_stop(ph);
1832 	}
1833 
1834 	ph = mh->m_phy;
1835 
1836 	ASSERT(ph->phy_present);
1837 
1838 	/* If we're resetting the PHY, then for sure we want to notify */
1839 	mh->m_notify = B_TRUE;
1840 
1841 	if (ph->phy_reset(ph) != DDI_SUCCESS) {
1842 		_mii_error(mh, MII_ERESET);
1843 		return (DDI_FAILURE);
1844 	}
1845 
1846 	mh->m_tstate = MII_STATE_START;
1847 	return (DDI_SUCCESS);
1848 }
1849 
1850 static void
1851 _mii_start_task(mii_handle_t mh)
1852 {
1853 	phy_handle_t		*ph;
1854 
1855 	ph = mh->m_phy;
1856 
1857 	ASSERT(mutex_owned(&mh->m_lock));
1858 	ASSERT(ph->phy_present);
1859 
1860 	if (phy_start(ph) != DDI_SUCCESS) {
1861 		_mii_error(mh, MII_ESTART);
1862 		mh->m_tstate = MII_STATE_RESET;
1863 		return;
1864 	}
1865 	/* clear the error state since we got a good startup! */
1866 	mh->m_error = MII_EOK;
1867 	mh->m_tstate = MII_STATE_RUN;
1868 }
1869 
1870 static int
1871 _mii_check_task(mii_handle_t mh)
1872 {
1873 	link_state_t	olink;
1874 	int		ospeed;
1875 	link_duplex_t	oduplex;
1876 	link_flowctrl_t	ofctrl;
1877 	phy_handle_t	*ph;
1878 
1879 	ph = mh->m_phy;
1880 
1881 	olink = mh->m_link;
1882 	ospeed = ph->phy_speed;
1883 	oduplex = ph->phy_duplex;
1884 	ofctrl = ph->phy_flowctrl;
1885 
1886 	ASSERT(ph->phy_present);
1887 
1888 	if (ph->phy_check(ph) == DDI_FAILURE) {
1889 		_mii_error(mh, MII_ECHECK);
1890 		mh->m_link = LINK_STATE_UNKNOWN;
1891 		mh->m_tstate = MII_STATE_PROBE;
1892 		mh->m_notify = B_TRUE;
1893 		return (DDI_FAILURE);
1894 	}
1895 
1896 	mh->m_link = ph->phy_link;
1897 
1898 	/* if anything changed, notify! */
1899 	if ((mh->m_link != olink) ||
1900 	    (ph->phy_speed != ospeed) ||
1901 	    (ph->phy_duplex != oduplex) ||
1902 	    (ph->phy_flowctrl != ofctrl)) {
1903 		mh->m_notify = B_TRUE;
1904 	}
1905 
1906 	return (DDI_SUCCESS);
1907 }
1908 
1909 static void
1910 _mii_task(void *_mh)
1911 {
1912 	mii_handle_t	mh = _mh;
1913 	phy_handle_t	*ph;
1914 	clock_t		wait;
1915 	clock_t		downtime;
1916 
1917 	mutex_enter(&mh->m_lock);
1918 
1919 	for (;;) {
1920 
1921 		/* If detaching, exit the thread. */
1922 		if (!mh->m_started) {
1923 			break;
1924 		}
1925 
1926 		ph = mh->m_phy;
1927 
1928 		/*
1929 		 * If we're suspended or otherwise not supposed to be
1930 		 * monitoring the link, just go back to sleep.
1931 		 *
1932 		 * Theoretically we could power down the PHY, but we
1933 		 * don't bother.  (The link might be used for
1934 		 * wake-on-lan!)  Another option would be to reduce
1935 		 * power on the PHY if both it and the link partner
1936 		 * support 10 Mbps mode.
1937 		 */
1938 		if (mh->m_suspending) {
1939 			mh->m_suspended = B_TRUE;
1940 			cv_broadcast(&mh->m_cv);
1941 		}
1942 		if (mh->m_suspended) {
1943 			mh->m_suspending = B_FALSE;
1944 			cv_wait(&mh->m_cv, &mh->m_lock);
1945 			continue;
1946 		}
1947 
1948 		switch (mh->m_tstate) {
1949 		case MII_STATE_PROBE:
1950 			_mii_probe_task(mh);
1951 			ph = mh->m_phy;
1952 			if (!ph->phy_present) {
1953 				/*
1954 				 * If no PHY is found, wait a bit before
1955 				 * trying the probe again.  10 seconds ought
1956 				 * to be enough.
1957 				 */
1958 				wait = 10 * MII_SECOND;
1959 			} else {
1960 				wait = 0;
1961 			}
1962 			break;
1963 
1964 		case MII_STATE_RESET:
1965 			if (_mii_reset_task(mh) == DDI_SUCCESS) {
1966 				ASSERT(mh->m_tstate == MII_STATE_START);
1967 
1968 				/*
1969 				 * We have to go back to the top of
1970 				 * the routine to check for changed
1971 				 * conditions while we drop the lock
1972 				 * to call into the mac layer.
1973 				 */
1974 				if (mh->m_ops.mii_reset != NULL) {
1975 					mutex_exit(&mh->m_lock);
1976 					mh->m_ops.mii_reset(mh->m_private);
1977 					mutex_enter(&mh->m_lock);
1978 					continue;
1979 				}
1980 				wait = 0;
1981 			} else {
1982 				/*
1983 				 * If an error occurred, wait a bit and
1984 				 * try again later.
1985 				 */
1986 				wait = 10 * MII_SECOND;
1987 			}
1988 			break;
1989 
1990 		case MII_STATE_START:
1991 			/*
1992 			 * If an error occurs, we're going to go back to
1993 			 * probe or reset state.  Otherwise we go to run
1994 			 * state.  In all cases we want to wait 1 second
1995 			 * before doing anything else - either for link to
1996 			 * settle, or to give other code a chance to run
1997 			 * while we reset.
1998 			 */
1999 			_mii_start_task(mh);
2000 			/* reset watchdog to latest */
2001 			downtime = ddi_get_lbolt();
2002 			wait = MII_SECOND;
2003 			break;
2004 
2005 		case MII_STATE_RUN:
2006 		default:
2007 			if (_mii_check_task(mh) == DDI_FAILURE) {
2008 				/*
2009 				 * On error (PHY removed?), wait a
2010 				 * short bit before reprobing or
2011 				 * resetting.
2012 				 */
2013 				wait = MII_SECOND;
2014 
2015 			} else if (mh->m_link == LINK_STATE_UP) {
2016 				/* got goood link, so reset the watchdog */
2017 				downtime = ddi_get_lbolt();
2018 				/* rescan again in a second */
2019 				wait = MII_SECOND;
2020 
2021 			} else if ((ddi_get_lbolt() - downtime) >
2022 			    (drv_usectohz(MII_SECOND * 10))) {
2023 
2024 				/*
2025 				 * If we were down for 10 seconds,
2026 				 * hard reset the PHY.
2027 				 */
2028 				mh->m_tstate = MII_STATE_RESET;
2029 				wait = 0;
2030 
2031 			} else {
2032 				/*
2033 				 * Otherwise, if we are still down,
2034 				 * rescan the link much more
2035 				 * frequently.  We might be trying to
2036 				 * autonegotiate.
2037 				 */
2038 				wait = MII_SECOND / 4;
2039 			}
2040 			break;
2041 		}
2042 
2043 		if (mh->m_notify) {
2044 			mh->m_notify = B_FALSE;
2045 
2046 			if (mh->m_ops.mii_notify != NULL) {
2047 				link_state_t state = mh->m_link;
2048 				mutex_exit(&mh->m_lock);
2049 				mh->m_ops.mii_notify(mh->m_private, state);
2050 				mutex_enter(&mh->m_lock);
2051 				continue;
2052 			}
2053 		}
2054 
2055 		if (wait)
2056 			(void) cv_timedwait(&mh->m_cv, &mh->m_lock,
2057 			    ddi_get_lbolt() + drv_usectohz(wait));
2058 	}
2059 
2060 	mutex_exit(&mh->m_lock);
2061 }
2062