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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * mii - MII/PHY support for MAC drivers
29 * Utility module to provide a consistent interface to a MAC driver accross
30 * different implementations of PHY devices
33 #include <sys/types.h>
34 #include <sys/debug.h>
35 #include <sys/errno.h>
36 #include <sys/param.h>
40 #include <sys/sunddi.h>
41 #include <sys/modctl.h>
42 #include <sys/cmn_err.h>
43 #include <sys/policy.h>
45 #include <sys/strsun.h>
46 #include <sys/miiregs.h>
47 #include <sys/mac_provider.h>
48 #include <sys/mac_ether.h>
52 #define MII_SECOND 1000000
54 /* indices into error array */
64 static const char * const mii_errors
[] = {
66 "Failure resetting PHY.",
67 "Failure starting PHY.",
68 "No Ethernet PHY found.",
69 "Failure reading PHY (removed?)",
70 "Failure setting loopback."
73 /* Indexed by XCVR_ type */
74 static const char * const mii_xcvr_types
[] = {
106 boolean_t m_suspending
;
107 boolean_t m_suspended
;
109 mii_tstate_t m_tstate
;
111 #define MII_FLAG_EXIT 0x1 /* exit the thread */
112 #define MII_FLAG_STOP 0x2 /* shutdown MII monitoring */
113 #define MII_FLAG_RESET 0x4 /* reset the MII */
114 #define MII_FLAG_PROBE 0x8 /* probe for PHYs */
115 #define MII_FLAG_NOTIFY 0x10 /* notify about a change */
116 #define MII_FLAG_SUSPEND 0x20 /* monitoring suspended */
117 #define MII_FLAG_MACRESET 0x40 /* send reset to MAC */
118 #define MII_FLAG_PHYSTART 0x80 /* start up the PHY */
120 /* device name for printing, e.g. "hme0" */
121 char m_name
[MODMAXNAMELEN
+ 16];
124 phy_handle_t m_phys
[32];
125 phy_handle_t m_bogus_phy
;
130 /* these start out undefined, but get values due to mac_prop_set */
141 boolean_t m_cap_pause
;
142 boolean_t m_cap_asmpause
;
146 static void _mii_task(void *);
147 static void _mii_probe_phy(phy_handle_t
*);
148 static void _mii_probe(mii_handle_t
);
149 static int _mii_reset(mii_handle_t
);
150 static int _mii_loopback(mii_handle_t
);
151 static void _mii_notify(mii_handle_t
);
152 static int _mii_check(mii_handle_t
);
153 static int _mii_start(mii_handle_t
);
156 * Loadable module structures/entrypoints
159 extern struct mod_ops mod_misc_ops
;
161 static struct modlmisc modlmisc
= {
166 static struct modlinkage modlinkage
= {
167 MODREV_1
, &modlmisc
, NULL
173 return (mod_install(&modlinkage
));
179 return (mod_remove(&modlinkage
));
183 _info(struct modinfo
*modinfop
)
185 return (mod_info(&modlinkage
, modinfop
));
189 _mii_error(mii_handle_t mh
, int errno
)
192 * This dumps an error message, but it avoids filling the log with
193 * repeated error messages.
195 if (mh
->m_error
!= errno
) {
196 cmn_err(CE_WARN
, "%s: %s", mh
->m_name
, mii_errors
[errno
]);
202 * Known list of specific PHY probes.
204 typedef boolean_t (*phy_probe_t
)(phy_handle_t
*);
205 phy_probe_t _phy_probes
[] = {
217 * MII Interface functions
221 mii_alloc_instance(void *private, dev_info_t
*dip
, int inst
, mii_ops_t
*ops
)
226 if (ops
->mii_version
!= MII_OPS_VERSION
) {
227 cmn_err(CE_WARN
, "%s: incompatible MII version (%d)",
228 ddi_driver_name(dip
), ops
->mii_version
);
231 mh
= kmem_zalloc(sizeof (*mh
), KM_SLEEP
);
233 (void) snprintf(mh
->m_name
, sizeof (mh
->m_name
), "%s%d",
234 ddi_driver_name(dip
), inst
);
236 /* DDI will prepend the driver name */
237 (void) snprintf(tqname
, sizeof (tqname
), "mii%d", inst
);
241 mh
->m_private
= private;
242 mh
->m_suspended
= B_FALSE
;
243 mh
->m_started
= B_FALSE
;
244 mh
->m_tstate
= MII_STATE_PROBE
;
245 mh
->m_link
= LINK_STATE_UNKNOWN
;
246 mh
->m_error
= MII_EOK
;
248 mutex_init(&mh
->m_lock
, NULL
, MUTEX_DRIVER
, NULL
);
249 cv_init(&mh
->m_cv
, NULL
, CV_DRIVER
, NULL
);
251 mh
->m_tq
= ddi_taskq_create(dip
, tqname
, 1, TASKQ_DEFAULTPRI
, 0);
252 if (mh
->m_tq
== NULL
) {
253 cmn_err(CE_WARN
, "%s: unable to create MII monitoring task",
254 ddi_driver_name(dip
));
255 cv_destroy(&mh
->m_cv
);
256 mutex_destroy(&mh
->m_lock
);
257 kmem_free(mh
, sizeof (*mh
));
262 * Initialize user prefs by loading properties. Ultimately,
263 * Brussels interfaces would be superior here.
265 #define GETPROP(name) ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, name, -1)
266 mh
->m_en_aneg
= GETPROP("adv_autoneg_cap");
267 mh
->m_en_10_hdx
= GETPROP("adv_10hdx_cap");
268 mh
->m_en_10_fdx
= GETPROP("adv_10fdx_cap");
269 mh
->m_en_100_hdx
= GETPROP("adv_100hdx_cap");
270 mh
->m_en_100_fdx
= GETPROP("adv_100fdx_cap");
271 mh
->m_en_100_t4
= GETPROP("adv_100T4_cap");
272 mh
->m_en_1000_hdx
= GETPROP("adv_1000hdx_cap");
273 mh
->m_en_1000_fdx
= GETPROP("adv_1000fdx_cap");
275 mh
->m_cap_pause
= B_FALSE
;
276 mh
->m_cap_asmpause
= B_FALSE
;
278 bzero(&mh
->m_bogus_phy
, sizeof (mh
->m_bogus_phy
));
279 mh
->m_bogus_phy
.phy_link
= LINK_STATE_UNKNOWN
;
280 mh
->m_bogus_phy
.phy_duplex
= LINK_DUPLEX_UNKNOWN
;
281 mh
->m_bogus_phy
.phy_addr
= 0xff;
282 mh
->m_bogus_phy
.phy_type
= XCVR_NONE
;
283 mh
->m_bogus_phy
.phy_id
= (uint32_t)-1;
284 mh
->m_bogus_phy
.phy_loopback
= PHY_LB_NONE
;
285 mh
->m_bogus_phy
.phy_flowctrl
= LINK_FLOWCTRL_NONE
;
286 mh
->m_phy
= &mh
->m_bogus_phy
;
288 for (int i
= 0; i
< 32; i
++) {
289 mh
->m_phys
[i
].phy_mii
= mh
;
291 mh
->m_bogus_phy
.phy_mii
= mh
;
297 mii_alloc(void *private, dev_info_t
*dip
, mii_ops_t
*ops
)
299 return (mii_alloc_instance(private, dip
, ddi_get_instance(dip
), ops
));
303 mii_set_pauseable(mii_handle_t mh
, boolean_t pauseable
, boolean_t asymetric
)
307 mutex_enter(&mh
->m_lock
);
309 ph
->phy_cap_pause
= mh
->m_cap_pause
= pauseable
;
310 ph
->phy_cap_asmpause
= mh
->m_cap_asmpause
= asymetric
;
312 mh
->m_en_flowctrl
= LINK_FLOWCTRL_BI
;
314 mh
->m_en_flowctrl
= LINK_FLOWCTRL_NONE
;
316 mutex_exit(&mh
->m_lock
);
320 mii_free(mii_handle_t mh
)
322 mutex_enter(&mh
->m_lock
);
323 mh
->m_started
= B_FALSE
;
324 cv_broadcast(&mh
->m_cv
);
325 mutex_exit(&mh
->m_lock
);
327 ddi_taskq_destroy(mh
->m_tq
);
328 mutex_destroy(&mh
->m_lock
);
329 cv_destroy(&mh
->m_cv
);
330 kmem_free(mh
, sizeof (*mh
));
334 mii_reset(mii_handle_t mh
)
336 mutex_enter(&mh
->m_lock
);
337 if (mh
->m_tstate
> MII_STATE_RESET
)
338 mh
->m_tstate
= MII_STATE_RESET
;
339 cv_broadcast(&mh
->m_cv
);
340 mutex_exit(&mh
->m_lock
);
344 mii_suspend(mii_handle_t mh
)
346 mutex_enter(&mh
->m_lock
);
347 while ((!mh
->m_suspended
) && (mh
->m_started
)) {
348 mh
->m_suspending
= B_TRUE
;
349 cv_broadcast(&mh
->m_cv
);
350 cv_wait(&mh
->m_cv
, &mh
->m_lock
);
352 mutex_exit(&mh
->m_lock
);
356 mii_resume(mii_handle_t mh
)
358 mutex_enter(&mh
->m_lock
);
360 switch (mh
->m_tstate
) {
361 case MII_STATE_PROBE
:
363 case MII_STATE_RESET
:
364 case MII_STATE_START
:
366 /* let monitor thread deal with this */
367 mh
->m_tstate
= MII_STATE_RESET
;
370 case MII_STATE_LOOPBACK
:
371 /* loopback is handled synchronously */
372 (void) _mii_loopback(mh
);
376 mh
->m_suspended
= B_FALSE
;
377 cv_broadcast(&mh
->m_cv
);
378 mutex_exit(&mh
->m_lock
);
382 mii_start(mii_handle_t mh
)
384 mutex_enter(&mh
->m_lock
);
385 if (!mh
->m_started
) {
386 mh
->m_tstate
= MII_STATE_PROBE
;
387 mh
->m_started
= B_TRUE
;
388 if (ddi_taskq_dispatch(mh
->m_tq
, _mii_task
, mh
, DDI_NOSLEEP
) !=
391 "%s: unable to start MII monitoring task",
393 mh
->m_started
= B_FALSE
;
396 cv_broadcast(&mh
->m_cv
);
397 mutex_exit(&mh
->m_lock
);
401 mii_stop(mii_handle_t mh
)
403 mutex_enter(&mh
->m_lock
);
404 mh
->m_started
= B_FALSE
;
406 * Reset link state to unknown defaults, since we're not
407 * monitoring it anymore. We'll reprobe all link state later.
409 mh
->m_link
= LINK_STATE_UNKNOWN
;
410 mh
->m_phy
= &mh
->m_bogus_phy
;
411 cv_broadcast(&mh
->m_cv
);
412 mutex_exit(&mh
->m_lock
);
414 * Notify the MAC driver. This will allow it to call back
415 * into the MAC framework to clear any previous link state.
421 mii_probe(mii_handle_t mh
)
423 mutex_enter(&mh
->m_lock
);
425 mutex_exit(&mh
->m_lock
);
429 mii_check(mii_handle_t mh
)
431 mutex_enter(&mh
->m_lock
);
432 cv_broadcast(&mh
->m_cv
);
433 mutex_exit(&mh
->m_lock
);
437 mii_get_speed(mii_handle_t mh
)
439 phy_handle_t
*ph
= mh
->m_phy
;
441 return (ph
->phy_speed
);
445 mii_get_duplex(mii_handle_t mh
)
447 phy_handle_t
*ph
= mh
->m_phy
;
449 return (ph
->phy_duplex
);
453 mii_get_state(mii_handle_t mh
)
455 phy_handle_t
*ph
= mh
->m_phy
;
457 return (ph
->phy_link
);
461 mii_get_flowctrl(mii_handle_t mh
)
463 phy_handle_t
*ph
= mh
->m_phy
;
465 return (ph
->phy_flowctrl
);
469 mii_get_loopmodes(mii_handle_t mh
, lb_property_t
*modes
)
471 phy_handle_t
*ph
= mh
->m_phy
;
473 lb_property_t lmodes
[MII_LOOPBACK_MAX
];
475 lmodes
[cnt
].lb_type
= normal
;
476 (void) strlcpy(lmodes
[cnt
].key
, "normal", sizeof (lmodes
[cnt
].key
));
477 lmodes
[cnt
].value
= PHY_LB_NONE
;
480 if (ph
->phy_cap_1000_fdx
||
481 ph
->phy_cap_100_fdx
||
482 ph
->phy_cap_10_fdx
) {
483 /* we only support full duplex internal phy testing */
484 lmodes
[cnt
].lb_type
= internal
;
485 (void) strlcpy(lmodes
[cnt
].key
, "PHY",
486 sizeof (lmodes
[cnt
].key
));
487 lmodes
[cnt
].value
= PHY_LB_INT_PHY
;
491 if (ph
->phy_cap_1000_fdx
) {
492 lmodes
[cnt
].lb_type
= external
;
493 (void) strlcpy(lmodes
[cnt
].key
, "1000Mbps",
494 sizeof (lmodes
[cnt
].key
));
495 lmodes
[cnt
].value
= PHY_LB_EXT_1000
;
499 if (ph
->phy_cap_100_fdx
) {
500 lmodes
[cnt
].lb_type
= external
;
501 (void) strlcpy(lmodes
[cnt
].key
, "100Mbps",
502 sizeof (lmodes
[cnt
].key
));
503 lmodes
[cnt
].value
= PHY_LB_EXT_100
;
507 if (ph
->phy_cap_10_fdx
) {
508 lmodes
[cnt
].lb_type
= external
;
509 (void) strlcpy(lmodes
[cnt
].key
, "10Mbps",
510 sizeof (lmodes
[cnt
].key
));
511 lmodes
[cnt
].value
= PHY_LB_EXT_10
;
516 bcopy(lmodes
, modes
, sizeof (lb_property_t
) * cnt
);
523 mii_get_loopback(mii_handle_t mh
)
525 phy_handle_t
*ph
= mh
->m_phy
;
527 return (ph
->phy_loopback
);
531 mii_set_loopback(mii_handle_t mh
, uint32_t loop
)
536 mutex_enter(&mh
->m_lock
);
539 if ((!mh
->m_started
) || (!ph
->phy_present
) ||
540 (loop
>= mii_get_loopmodes(mh
, NULL
))) {
544 ph
->phy_loopback
= loop
;
545 rv
= _mii_loopback(mh
);
546 if (rv
== DDI_SUCCESS
) {
547 mh
->m_tstate
= MII_STATE_LOOPBACK
;
549 cv_broadcast(&mh
->m_cv
);
550 mutex_exit(&mh
->m_lock
);
552 return (rv
== DDI_SUCCESS
? 0 : EIO
);
556 mii_get_id(mii_handle_t mh
)
558 phy_handle_t
*ph
= mh
->m_phy
;
564 mii_get_addr(mii_handle_t mh
)
572 mii_m_loop_ioctl(mii_handle_t mh
, queue_t
*wq
, mblk_t
*mp
)
577 lb_property_t modes
[MII_LOOPBACK_MAX
];
582 iocp
= (void *)mp
->b_rptr
;
587 case LB_GET_INFO_SIZE
:
596 if (mp
->b_cont
== NULL
) {
597 miocnak(wq
, mp
, 0, EINVAL
);
602 case LB_GET_INFO_SIZE
:
603 cnt
= mii_get_loopmodes(mh
, modes
);
604 if (iocp
->ioc_count
!= sizeof (sz
)) {
607 sz
= cnt
* sizeof (lb_property_t
);
608 bcopy(&sz
, mp
->b_cont
->b_rptr
, sizeof (sz
));
613 cnt
= mii_get_loopmodes(mh
, modes
);
614 if (iocp
->ioc_count
!= (cnt
* sizeof (lb_property_t
))) {
617 bcopy(modes
, mp
->b_cont
->b_rptr
, iocp
->ioc_count
);
622 if (iocp
->ioc_count
!= sizeof (mode
)) {
625 mode
= mii_get_loopback(mh
);
626 bcopy(&mode
, mp
->b_cont
->b_rptr
, sizeof (mode
));
631 rv
= secpolicy_net_config(iocp
->ioc_cr
, B_FALSE
);
634 if (iocp
->ioc_count
!= sizeof (mode
)) {
638 bcopy(mp
->b_cont
->b_rptr
, &mode
, sizeof (mode
));
639 rv
= mii_set_loopback(mh
, mode
);
644 miocack(wq
, mp
, iocp
->ioc_count
, 0);
646 miocnak(wq
, mp
, 0, rv
);
652 mii_m_getprop(mii_handle_t mh
, const char *name
, mac_prop_id_t num
,
653 uint_t sz
, void *val
)
658 _NOTE(ARGUNUSED(name
));
663 mutex_enter(&mh
->m_lock
);
667 #define CASE_PROP_ABILITY(PROP, VAR) \
668 case MAC_PROP_ADV_##PROP: \
669 *(uint8_t *)val = ph->phy_adv_##VAR; \
672 case MAC_PROP_EN_##PROP: \
673 *(uint8_t *)val = ph->phy_en_##VAR; \
677 case MAC_PROP_DUPLEX
:
678 ASSERT(sz
>= sizeof (link_duplex_t
));
679 bcopy(&ph
->phy_duplex
, val
, sizeof (link_duplex_t
));
682 case MAC_PROP_SPEED
: {
683 uint64_t speed
= ph
->phy_speed
* 1000000ull;
684 ASSERT(sz
>= sizeof (uint64_t));
685 bcopy(&speed
, val
, sizeof (speed
));
689 case MAC_PROP_AUTONEG
:
690 *(uint8_t *)val
= ph
->phy_adv_aneg
;
693 case MAC_PROP_FLOWCTRL
:
694 ASSERT(sz
>= sizeof (link_flowctrl_t
));
695 bcopy(&ph
->phy_flowctrl
, val
, sizeof (link_flowctrl_t
));
698 CASE_PROP_ABILITY(1000FDX_CAP
, 1000_fdx
)
699 CASE_PROP_ABILITY(1000HDX_CAP
, 1000_hdx
)
700 CASE_PROP_ABILITY(100T4_CAP
, 100_t4
)
701 CASE_PROP_ABILITY(100FDX_CAP
, 100_fdx
)
702 CASE_PROP_ABILITY(100HDX_CAP
, 100_hdx
)
703 CASE_PROP_ABILITY(10FDX_CAP
, 10_fdx
)
704 CASE_PROP_ABILITY(10HDX_CAP
, 10_hdx
)
711 mutex_exit(&mh
->m_lock
);
717 mii_m_propinfo(mii_handle_t mh
, const char *name
, mac_prop_id_t num
,
718 mac_prop_info_handle_t prh
)
722 _NOTE(ARGUNUSED(name
));
724 mutex_enter(&mh
->m_lock
);
729 case MAC_PROP_DUPLEX
:
731 mac_prop_info_set_perm(prh
, MAC_PROP_PERM_READ
);
734 case MAC_PROP_AUTONEG
:
735 mac_prop_info_set_default_uint8(prh
, ph
->phy_cap_aneg
);
738 #define CASE_PROP_PERM(PROP, VAR) \
739 case MAC_PROP_ADV_##PROP: \
740 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); \
741 mac_prop_info_set_default_uint8(prh, ph->phy_cap_##VAR); \
744 case MAC_PROP_EN_##PROP: \
745 if (!ph->phy_cap_##VAR) \
746 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); \
747 mac_prop_info_set_default_uint8(prh, ph->phy_cap_##VAR); \
750 CASE_PROP_PERM(1000FDX_CAP
, 1000_fdx
)
751 CASE_PROP_PERM(1000HDX_CAP
, 1000_hdx
)
752 CASE_PROP_PERM(100T4_CAP
, 100_t4
)
753 CASE_PROP_PERM(100FDX_CAP
, 100_fdx
)
754 CASE_PROP_PERM(100HDX_CAP
, 100_hdx
)
755 CASE_PROP_PERM(10FDX_CAP
, 10_fdx
)
756 CASE_PROP_PERM(10HDX_CAP
, 10_hdx
)
759 mutex_exit(&mh
->m_lock
);
763 mii_m_setprop(mii_handle_t mh
, const char *name
, mac_prop_id_t num
,
764 uint_t sz
, const void *valp
)
767 boolean_t
*advp
= NULL
;
768 boolean_t
*capp
= NULL
;
772 _NOTE(ARGUNUSED(name
));
777 mutex_enter(&mh
->m_lock
);
781 /* we don't support changing parameters while in loopback mode */
782 if (ph
->phy_loopback
!= PHY_LB_NONE
) {
784 case MAC_PROP_EN_1000FDX_CAP
:
785 case MAC_PROP_EN_1000HDX_CAP
:
786 case MAC_PROP_EN_100FDX_CAP
:
787 case MAC_PROP_EN_100HDX_CAP
:
788 case MAC_PROP_EN_100T4_CAP
:
789 case MAC_PROP_EN_10FDX_CAP
:
790 case MAC_PROP_EN_10HDX_CAP
:
791 case MAC_PROP_AUTONEG
:
792 case MAC_PROP_FLOWCTRL
:
798 case MAC_PROP_EN_1000FDX_CAP
:
799 capp
= &ph
->phy_cap_1000_fdx
;
800 advp
= &ph
->phy_en_1000_fdx
;
801 macpp
= &mh
->m_en_1000_fdx
;
803 case MAC_PROP_EN_1000HDX_CAP
:
804 capp
= &ph
->phy_cap_1000_hdx
;
805 advp
= &ph
->phy_en_1000_hdx
;
806 macpp
= &mh
->m_en_1000_hdx
;
808 case MAC_PROP_EN_100FDX_CAP
:
809 capp
= &ph
->phy_cap_100_fdx
;
810 advp
= &ph
->phy_en_100_fdx
;
811 macpp
= &mh
->m_en_100_fdx
;
813 case MAC_PROP_EN_100HDX_CAP
:
814 capp
= &ph
->phy_cap_100_hdx
;
815 advp
= &ph
->phy_en_100_hdx
;
816 macpp
= &mh
->m_en_100_hdx
;
818 case MAC_PROP_EN_100T4_CAP
:
819 capp
= &ph
->phy_cap_100_t4
;
820 advp
= &ph
->phy_en_100_t4
;
821 macpp
= &mh
->m_en_100_t4
;
823 case MAC_PROP_EN_10FDX_CAP
:
824 capp
= &ph
->phy_cap_10_fdx
;
825 advp
= &ph
->phy_en_10_fdx
;
826 macpp
= &mh
->m_en_10_fdx
;
828 case MAC_PROP_EN_10HDX_CAP
:
829 capp
= &ph
->phy_cap_10_hdx
;
830 advp
= &ph
->phy_en_10_hdx
;
831 macpp
= &mh
->m_en_10_hdx
;
833 case MAC_PROP_AUTONEG
:
834 capp
= &ph
->phy_cap_aneg
;
835 advp
= &ph
->phy_en_aneg
;
836 macpp
= &mh
->m_en_aneg
;
838 case MAC_PROP_FLOWCTRL
: {
842 ASSERT(sz
>= sizeof (link_flowctrl_t
));
843 bcopy(valp
, &fc
, sizeof (fc
));
845 chg
= fc
== ph
->phy_en_flowctrl
? B_FALSE
: B_TRUE
;
847 case LINK_FLOWCTRL_NONE
:
848 ph
->phy_en_pause
= B_FALSE
;
849 ph
->phy_en_asmpause
= B_FALSE
;
850 ph
->phy_en_flowctrl
= fc
;
853 * Note that while we don't have a way to advertise
854 * that we can RX pause (we just won't send pause
855 * frames), we advertise full support. The MAC driver
856 * will learn of the configuration via the saved value
859 case LINK_FLOWCTRL_BI
:
860 case LINK_FLOWCTRL_RX
:
861 if (ph
->phy_cap_pause
) {
862 ph
->phy_en_pause
= B_TRUE
;
863 ph
->phy_en_asmpause
= B_TRUE
;
864 ph
->phy_en_flowctrl
= fc
;
871 * Tell the other side that we can assert pause, but
874 case LINK_FLOWCTRL_TX
:
875 if (ph
->phy_cap_asmpause
) {
876 ph
->phy_en_pause
= B_FALSE
;
877 ph
->phy_en_flowctrl
= fc
;
878 ph
->phy_en_asmpause
= B_TRUE
;
887 if ((rv
== 0) && chg
) {
888 mh
->m_en_flowctrl
= fc
;
889 mh
->m_tstate
= MII_STATE_RESET
;
890 cv_broadcast(&mh
->m_cv
);
900 if (capp
&& advp
&& macpp
) {
901 if (sz
< sizeof (uint8_t)) {
905 if (*advp
!= *(uint8_t *)valp
) {
906 *advp
= *(uint8_t *)valp
;
907 *macpp
= *(uint8_t *)valp
;
908 mh
->m_tstate
= MII_STATE_RESET
;
909 cv_broadcast(&mh
->m_cv
);
915 mutex_exit(&mh
->m_lock
);
920 mii_m_getstat(mii_handle_t mh
, uint_t stat
, uint64_t *val
)
925 mutex_enter(&mh
->m_lock
);
930 case MAC_STAT_IFSPEED
:
931 *val
= ph
->phy_speed
* 1000000ull;
933 case ETHER_STAT_LINK_DUPLEX
:
934 *val
= ph
->phy_duplex
;
936 case ETHER_STAT_LINK_AUTONEG
:
937 *val
= !!(ph
->phy_adv_aneg
&& ph
->phy_lp_aneg
);
939 case ETHER_STAT_XCVR_ID
:
942 case ETHER_STAT_XCVR_INUSE
:
945 case ETHER_STAT_XCVR_ADDR
:
948 case ETHER_STAT_LINK_ASMPAUSE
:
949 *val
= ph
->phy_adv_asmpause
&& ph
->phy_lp_asmpause
&&
950 ph
->phy_adv_pause
!= ph
->phy_lp_pause
;
952 case ETHER_STAT_LINK_PAUSE
:
953 *val
= (ph
->phy_flowctrl
== LINK_FLOWCTRL_BI
) ||
954 (ph
->phy_flowctrl
== LINK_FLOWCTRL_RX
);
956 case ETHER_STAT_CAP_1000FDX
:
957 *val
= ph
->phy_cap_1000_fdx
;
959 case ETHER_STAT_CAP_1000HDX
:
960 *val
= ph
->phy_cap_1000_hdx
;
962 case ETHER_STAT_CAP_100FDX
:
963 *val
= ph
->phy_cap_100_fdx
;
965 case ETHER_STAT_CAP_100HDX
:
966 *val
= ph
->phy_cap_100_hdx
;
968 case ETHER_STAT_CAP_10FDX
:
969 *val
= ph
->phy_cap_10_fdx
;
971 case ETHER_STAT_CAP_10HDX
:
972 *val
= ph
->phy_cap_10_hdx
;
974 case ETHER_STAT_CAP_100T4
:
975 *val
= ph
->phy_cap_100_t4
;
977 case ETHER_STAT_CAP_AUTONEG
:
978 *val
= ph
->phy_cap_aneg
;
980 case ETHER_STAT_CAP_PAUSE
:
981 *val
= ph
->phy_cap_pause
;
983 case ETHER_STAT_CAP_ASMPAUSE
:
984 *val
= ph
->phy_cap_asmpause
;
987 case ETHER_STAT_LP_CAP_1000FDX
:
988 *val
= ph
->phy_lp_1000_fdx
;
990 case ETHER_STAT_LP_CAP_1000HDX
:
991 *val
= ph
->phy_lp_1000_hdx
;
993 case ETHER_STAT_LP_CAP_100FDX
:
994 *val
= ph
->phy_lp_100_fdx
;
996 case ETHER_STAT_LP_CAP_100HDX
:
997 *val
= ph
->phy_lp_100_hdx
;
999 case ETHER_STAT_LP_CAP_10FDX
:
1000 *val
= ph
->phy_lp_10_fdx
;
1002 case ETHER_STAT_LP_CAP_10HDX
:
1003 *val
= ph
->phy_lp_10_hdx
;
1005 case ETHER_STAT_LP_CAP_100T4
:
1006 *val
= ph
->phy_lp_100_t4
;
1008 case ETHER_STAT_LP_CAP_AUTONEG
:
1009 *val
= ph
->phy_lp_aneg
;
1011 case ETHER_STAT_LP_CAP_PAUSE
:
1012 *val
= ph
->phy_lp_pause
;
1014 case ETHER_STAT_LP_CAP_ASMPAUSE
:
1015 *val
= ph
->phy_lp_asmpause
;
1018 case ETHER_STAT_ADV_CAP_1000FDX
:
1019 *val
= ph
->phy_adv_1000_fdx
;
1021 case ETHER_STAT_ADV_CAP_1000HDX
:
1022 *val
= ph
->phy_adv_1000_hdx
;
1024 case ETHER_STAT_ADV_CAP_100FDX
:
1025 *val
= ph
->phy_adv_100_fdx
;
1027 case ETHER_STAT_ADV_CAP_100HDX
:
1028 *val
= ph
->phy_adv_100_hdx
;
1030 case ETHER_STAT_ADV_CAP_10FDX
:
1031 *val
= ph
->phy_adv_10_fdx
;
1033 case ETHER_STAT_ADV_CAP_10HDX
:
1034 *val
= ph
->phy_adv_10_hdx
;
1036 case ETHER_STAT_ADV_CAP_100T4
:
1037 *val
= ph
->phy_adv_100_t4
;
1039 case ETHER_STAT_ADV_CAP_AUTONEG
:
1040 *val
= ph
->phy_adv_aneg
;
1042 case ETHER_STAT_ADV_CAP_PAUSE
:
1043 *val
= ph
->phy_adv_pause
;
1045 case ETHER_STAT_ADV_CAP_ASMPAUSE
:
1046 *val
= ph
->phy_adv_asmpause
;
1053 mutex_exit(&mh
->m_lock
);
1059 * PHY support routines. Private to the MII module and the vendor
1060 * specific PHY implementation code.
1063 phy_read(phy_handle_t
*ph
, uint8_t reg
)
1065 mii_handle_t mh
= ph
->phy_mii
;
1067 return ((*mh
->m_ops
.mii_read
)(mh
->m_private
, ph
->phy_addr
, reg
));
1071 phy_write(phy_handle_t
*ph
, uint8_t reg
, uint16_t val
)
1073 mii_handle_t mh
= ph
->phy_mii
;
1075 (*mh
->m_ops
.mii_write
)(mh
->m_private
, ph
->phy_addr
, reg
, val
);
1079 phy_reset(phy_handle_t
*ph
)
1081 ASSERT(mutex_owned(&ph
->phy_mii
->m_lock
));
1084 * For our device, make sure its powered up and unisolated.
1086 PHY_CLR(ph
, MII_CONTROL
,
1087 MII_CONTROL_PWRDN
| MII_CONTROL_ISOLATE
);
1092 PHY_SET(ph
, MII_CONTROL
, MII_CONTROL_RESET
);
1095 * Apparently some devices (DP83840A) like to have a little
1096 * bit of a wait before we start accessing anything else on
1102 * Wait for reset to complete - probably very fast, but no
1103 * more than 0.5 sec according to spec. It would be nice if
1104 * we could use delay() here, but MAC drivers may call
1105 * functions which hold this lock in interrupt context, so
1106 * sleeping would be a definite no-no. The good news here is
1107 * that it seems to be the case that most devices come back
1108 * within only a few hundred usec.
1110 for (int i
= 500000; i
; i
-= 100) {
1111 if ((phy_read(ph
, MII_CONTROL
) & MII_CONTROL_RESET
) == 0) {
1112 /* reset completed */
1113 return (DDI_SUCCESS
);
1118 return (DDI_FAILURE
);
1122 phy_stop(phy_handle_t
*ph
)
1124 phy_write(ph
, MII_CONTROL
, MII_CONTROL_ISOLATE
);
1126 return (DDI_SUCCESS
);
1130 phy_loop(phy_handle_t
*ph
)
1132 uint16_t bmcr
, gtcr
;
1134 ASSERT(mutex_owned(&ph
->phy_mii
->m_lock
));
1137 * Disable everything to start... we'll add in modes as we go.
1139 ph
->phy_adv_aneg
= B_FALSE
;
1140 ph
->phy_adv_1000_fdx
= B_FALSE
;
1141 ph
->phy_adv_1000_hdx
= B_FALSE
;
1142 ph
->phy_adv_100_fdx
= B_FALSE
;
1143 ph
->phy_adv_100_t4
= B_FALSE
;
1144 ph
->phy_adv_100_hdx
= B_FALSE
;
1145 ph
->phy_adv_10_fdx
= B_FALSE
;
1146 ph
->phy_adv_10_hdx
= B_FALSE
;
1147 ph
->phy_adv_pause
= B_FALSE
;
1148 ph
->phy_adv_asmpause
= B_FALSE
;
1151 gtcr
= MII_MSCONTROL_MANUAL
| MII_MSCONTROL_MASTER
;
1153 switch (ph
->phy_loopback
) {
1155 /* We shouldn't be here */
1159 case PHY_LB_INT_PHY
:
1160 bmcr
|= MII_CONTROL_LOOPBACK
;
1161 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1162 if (ph
->phy_cap_1000_fdx
) {
1163 bmcr
|= MII_CONTROL_1GB
| MII_CONTROL_FDUPLEX
;
1164 ph
->phy_speed
= 1000;
1165 } else if (ph
->phy_cap_100_fdx
) {
1166 bmcr
|= MII_CONTROL_100MB
| MII_CONTROL_FDUPLEX
;
1167 ph
->phy_speed
= 100;
1168 } else if (ph
->phy_cap_10_fdx
) {
1169 bmcr
|= MII_CONTROL_FDUPLEX
;
1175 bmcr
= MII_CONTROL_FDUPLEX
;
1177 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1180 case PHY_LB_EXT_100
:
1181 bmcr
= MII_CONTROL_100MB
| MII_CONTROL_FDUPLEX
;
1182 ph
->phy_speed
= 100;
1183 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1186 case PHY_LB_EXT_1000
:
1187 bmcr
= MII_CONTROL_1GB
| MII_CONTROL_FDUPLEX
;
1188 ph
->phy_speed
= 1000;
1189 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1193 ph
->phy_link
= LINK_STATE_UP
; /* force up for loopback */
1194 ph
->phy_flowctrl
= LINK_FLOWCTRL_NONE
;
1196 switch (ph
->phy_type
) {
1200 phy_write(ph
, MII_MSCONTROL
, gtcr
);
1204 phy_write(ph
, MII_CONTROL
, bmcr
);
1206 return (DDI_SUCCESS
);
1210 phy_start(phy_handle_t
*ph
)
1212 uint16_t bmcr
, anar
, gtcr
;
1213 ASSERT(mutex_owned(&ph
->phy_mii
->m_lock
));
1215 ASSERT(ph
->phy_loopback
== PHY_LB_NONE
);
1218 * No loopback overrides, so try to advertise everything
1219 * that is administratively enabled.
1221 ph
->phy_adv_aneg
= ph
->phy_en_aneg
;
1222 ph
->phy_adv_1000_fdx
= ph
->phy_en_1000_fdx
;
1223 ph
->phy_adv_1000_hdx
= ph
->phy_en_1000_hdx
;
1224 ph
->phy_adv_100_fdx
= ph
->phy_en_100_fdx
;
1225 ph
->phy_adv_100_t4
= ph
->phy_en_100_t4
;
1226 ph
->phy_adv_100_hdx
= ph
->phy_en_100_hdx
;
1227 ph
->phy_adv_10_fdx
= ph
->phy_en_10_fdx
;
1228 ph
->phy_adv_10_hdx
= ph
->phy_en_10_hdx
;
1229 ph
->phy_adv_pause
= ph
->phy_en_pause
;
1230 ph
->phy_adv_asmpause
= ph
->phy_en_asmpause
;
1233 * Limit properties to what the hardware can actually support.
1235 #define FILTER_ADV(CAP) \
1236 if (!ph->phy_cap_##CAP) \
1237 ph->phy_adv_##CAP = 0
1240 FILTER_ADV(1000_fdx
);
1241 FILTER_ADV(1000_hdx
);
1242 FILTER_ADV(100_fdx
);
1244 FILTER_ADV(100_hdx
);
1248 FILTER_ADV(asmpause
);
1253 * We need at least one valid mode.
1255 if ((!ph
->phy_adv_1000_fdx
) &&
1256 (!ph
->phy_adv_1000_hdx
) &&
1257 (!ph
->phy_adv_100_t4
) &&
1258 (!ph
->phy_adv_100_fdx
) &&
1259 (!ph
->phy_adv_100_hdx
) &&
1260 (!ph
->phy_adv_10_fdx
) &&
1261 (!ph
->phy_adv_10_hdx
)) {
1264 "No valid link mode selected. Powering down PHY.");
1266 PHY_SET(ph
, MII_CONTROL
, MII_CONTROL_PWRDN
);
1268 ph
->phy_link
= LINK_STATE_DOWN
;
1269 return (DDI_SUCCESS
);
1275 if (ph
->phy_adv_aneg
) {
1276 bmcr
|= MII_CONTROL_ANE
| MII_CONTROL_RSAN
;
1279 if ((ph
->phy_adv_1000_fdx
) || (ph
->phy_adv_1000_hdx
)) {
1280 bmcr
|= MII_CONTROL_1GB
;
1282 } else if (ph
->phy_adv_100_fdx
|| ph
->phy_adv_100_hdx
||
1283 ph
->phy_adv_100_t4
) {
1284 bmcr
|= MII_CONTROL_100MB
;
1287 if (ph
->phy_adv_1000_fdx
|| ph
->phy_adv_100_fdx
|| ph
->phy_adv_10_fdx
) {
1288 bmcr
|= MII_CONTROL_FDUPLEX
;
1291 if (ph
->phy_type
== XCVR_1000X
) {
1292 /* 1000BASE-X (usually fiber) */
1294 if (ph
->phy_adv_1000_fdx
) {
1295 anar
|= MII_ABILITY_X_FD
;
1297 if (ph
->phy_adv_1000_hdx
) {
1298 anar
|= MII_ABILITY_X_HD
;
1300 if (ph
->phy_adv_pause
) {
1301 anar
|= MII_ABILITY_X_PAUSE
;
1303 if (ph
->phy_adv_asmpause
) {
1304 anar
|= MII_ABILITY_X_ASMPAUSE
;
1307 } else if (ph
->phy_type
== XCVR_100T2
) {
1310 if (ph
->phy_adv_100_fdx
) {
1311 anar
|= MII_ABILITY_T2_FD
;
1313 if (ph
->phy_adv_100_hdx
) {
1314 anar
|= MII_ABILITY_T2_HD
;
1318 anar
= MII_AN_SELECTOR_8023
;
1320 /* 1000BASE-T or 100BASE-X probably */
1321 if (ph
->phy_adv_1000_fdx
) {
1322 gtcr
|= MII_MSCONTROL_1000T_FD
;
1324 if (ph
->phy_adv_1000_hdx
) {
1325 gtcr
|= MII_MSCONTROL_1000T
;
1327 if (ph
->phy_adv_100_fdx
) {
1328 anar
|= MII_ABILITY_100BASE_TX_FD
;
1330 if (ph
->phy_adv_100_hdx
) {
1331 anar
|= MII_ABILITY_100BASE_TX
;
1333 if (ph
->phy_adv_100_t4
) {
1334 anar
|= MII_ABILITY_100BASE_T4
;
1336 if (ph
->phy_adv_10_fdx
) {
1337 anar
|= MII_ABILITY_10BASE_T_FD
;
1339 if (ph
->phy_adv_10_hdx
) {
1340 anar
|= MII_ABILITY_10BASE_T
;
1342 if (ph
->phy_adv_pause
) {
1343 anar
|= MII_ABILITY_PAUSE
;
1345 if (ph
->phy_adv_asmpause
) {
1346 anar
|= MII_ABILITY_ASMPAUSE
;
1350 ph
->phy_link
= LINK_STATE_DOWN
;
1351 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1354 phy_write(ph
, MII_AN_ADVERT
, anar
);
1355 phy_write(ph
, MII_CONTROL
, bmcr
& ~(MII_CONTROL_RSAN
));
1357 switch (ph
->phy_type
) {
1361 phy_write(ph
, MII_MSCONTROL
, gtcr
);
1365 * Finally, this will start up autoneg if it is enabled, or
1366 * force link settings otherwise.
1368 phy_write(ph
, MII_CONTROL
, bmcr
);
1370 return (DDI_SUCCESS
);
1375 phy_check(phy_handle_t
*ph
)
1377 uint16_t control
, status
, lpar
, msstat
, anexp
;
1378 int debounces
= 100;
1380 ASSERT(mutex_owned(&ph
->phy_mii
->m_lock
));
1383 status
= phy_read(ph
, MII_STATUS
);
1384 control
= phy_read(ph
, MII_CONTROL
);
1386 if (status
& MII_STATUS_EXTENDED
) {
1387 lpar
= phy_read(ph
, MII_AN_LPABLE
);
1388 anexp
= phy_read(ph
, MII_AN_EXPANSION
);
1395 * We reread to clear any latched bits. This also debounces
1396 * any state that might be in transition.
1399 if ((status
!= phy_read(ph
, MII_STATUS
)) && debounces
) {
1405 * Detect the situation where the PHY is removed or has died.
1406 * According to spec, at least one bit of status must be set,
1407 * and at least one bit must be clear.
1409 if ((status
== 0xffff) || (status
== 0)) {
1411 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1412 ph
->phy_link
= LINK_STATE_UNKNOWN
;
1413 ph
->phy_present
= B_FALSE
;
1414 return (DDI_FAILURE
);
1417 /* We only respect the link flag if we are not in loopback. */
1418 if ((ph
->phy_loopback
!= PHY_LB_INT_PHY
) &&
1419 ((status
& MII_STATUS_LINKUP
) == 0)) {
1421 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1422 ph
->phy_link
= LINK_STATE_DOWN
;
1423 return (DDI_SUCCESS
);
1426 ph
->phy_link
= LINK_STATE_UP
;
1428 if ((control
& MII_CONTROL_ANE
) == 0) {
1430 ph
->phy_lp_aneg
= B_FALSE
;
1431 ph
->phy_lp_10_hdx
= B_FALSE
;
1432 ph
->phy_lp_10_fdx
= B_FALSE
;
1433 ph
->phy_lp_100_t4
= B_FALSE
;
1434 ph
->phy_lp_100_hdx
= B_FALSE
;
1435 ph
->phy_lp_100_fdx
= B_FALSE
;
1436 ph
->phy_lp_1000_hdx
= B_FALSE
;
1437 ph
->phy_lp_1000_fdx
= B_FALSE
;
1440 * We have no idea what our link partner might or might
1441 * not be able to support, except that it appears to
1442 * support the same mode that we have forced.
1444 if (control
& MII_CONTROL_1GB
) {
1445 ph
->phy_speed
= 1000;
1446 } else if (control
& MII_CONTROL_100MB
) {
1447 ph
->phy_speed
= 100;
1451 ph
->phy_duplex
= control
& MII_CONTROL_FDUPLEX
?
1452 LINK_DUPLEX_FULL
: LINK_DUPLEX_HALF
;
1454 return (DDI_SUCCESS
);
1457 if (ph
->phy_type
== XCVR_1000X
) {
1459 ph
->phy_lp_10_hdx
= B_FALSE
;
1460 ph
->phy_lp_10_fdx
= B_FALSE
;
1461 ph
->phy_lp_100_t4
= B_FALSE
;
1462 ph
->phy_lp_100_hdx
= B_FALSE
;
1463 ph
->phy_lp_100_fdx
= B_FALSE
;
1465 /* 1000BASE-X requires autonegotiation */
1466 ph
->phy_lp_aneg
= B_TRUE
;
1467 ph
->phy_lp_1000_fdx
= !!(lpar
& MII_ABILITY_X_FD
);
1468 ph
->phy_lp_1000_hdx
= !!(lpar
& MII_ABILITY_X_HD
);
1469 ph
->phy_lp_pause
= !!(lpar
& MII_ABILITY_X_PAUSE
);
1470 ph
->phy_lp_asmpause
= !!(lpar
& MII_ABILITY_X_ASMPAUSE
);
1472 } else if (ph
->phy_type
== XCVR_100T2
) {
1473 ph
->phy_lp_10_hdx
= B_FALSE
;
1474 ph
->phy_lp_10_fdx
= B_FALSE
;
1475 ph
->phy_lp_100_t4
= B_FALSE
;
1476 ph
->phy_lp_1000_hdx
= B_FALSE
;
1477 ph
->phy_lp_1000_fdx
= B_FALSE
;
1478 ph
->phy_lp_pause
= B_FALSE
;
1479 ph
->phy_lp_asmpause
= B_FALSE
;
1481 /* 100BASE-T2 requires autonegotiation */
1482 ph
->phy_lp_aneg
= B_TRUE
;
1483 ph
->phy_lp_100_fdx
= !!(lpar
& MII_ABILITY_T2_FD
);
1484 ph
->phy_lp_100_hdx
= !!(lpar
& MII_ABILITY_T2_HD
);
1486 } else if (anexp
& MII_AN_EXP_PARFAULT
) {
1488 * Parallel detection fault! This happens when the
1489 * peer does not use autonegotiation, and the
1490 * detection logic reports more than one type of legal
1491 * link is available. Note that parallel detection
1492 * can only happen with half duplex 10, 100, and
1493 * 100TX4. We also should not have got here, because
1494 * the link state bit should have failed.
1497 phy_warn(ph
, "Parallel detection fault!");
1499 ph
->phy_lp_10_hdx
= B_FALSE
;
1500 ph
->phy_lp_10_fdx
= B_FALSE
;
1501 ph
->phy_lp_100_t4
= B_FALSE
;
1502 ph
->phy_lp_100_hdx
= B_FALSE
;
1503 ph
->phy_lp_100_fdx
= B_FALSE
;
1504 ph
->phy_lp_1000_hdx
= B_FALSE
;
1505 ph
->phy_lp_1000_fdx
= B_FALSE
;
1506 ph
->phy_lp_pause
= B_FALSE
;
1507 ph
->phy_lp_asmpause
= B_FALSE
;
1509 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1510 return (DDI_SUCCESS
);
1513 ph
->phy_lp_aneg
= !!(anexp
& MII_AN_EXP_LPCANAN
);
1516 * Note: If the peer doesn't support autonegotiation, then
1517 * according to clause 28.5.4.5, the link partner ability
1518 * register will still have the right bits set. However,
1519 * gigabit modes cannot use legacy parallel detection.
1522 if ((ph
->phy_type
== XCVR_1000T
) &
1523 (anexp
& MII_AN_EXP_LPCANAN
)) {
1525 /* check for gige */
1526 msstat
= phy_read(ph
, MII_MSSTATUS
);
1528 ph
->phy_lp_1000_hdx
=
1529 !!(msstat
& MII_MSSTATUS_LP1000T
);
1531 ph
->phy_lp_1000_fdx
=
1532 !!(msstat
& MII_MSSTATUS_LP1000T_FD
);
1535 ph
->phy_lp_100_fdx
= !!(lpar
& MII_ABILITY_100BASE_TX_FD
);
1536 ph
->phy_lp_100_hdx
= !!(lpar
& MII_ABILITY_100BASE_TX
);
1537 ph
->phy_lp_100_t4
= !!(lpar
& MII_ABILITY_100BASE_T4
);
1538 ph
->phy_lp_10_fdx
= !!(lpar
& MII_ABILITY_10BASE_T_FD
);
1539 ph
->phy_lp_10_hdx
= !!(lpar
& MII_ABILITY_10BASE_T
);
1540 ph
->phy_lp_pause
= !!(lpar
& MII_ABILITY_PAUSE
);
1541 ph
->phy_lp_asmpause
= !!(lpar
& MII_ABILITY_ASMPAUSE
);
1544 /* resolve link pause */
1545 if ((ph
->phy_en_flowctrl
== LINK_FLOWCTRL_BI
) &&
1546 (ph
->phy_lp_pause
)) {
1547 ph
->phy_flowctrl
= LINK_FLOWCTRL_BI
;
1548 } else if ((ph
->phy_en_flowctrl
== LINK_FLOWCTRL_RX
) &&
1549 (ph
->phy_lp_pause
|| ph
->phy_lp_asmpause
)) {
1550 ph
->phy_flowctrl
= LINK_FLOWCTRL_RX
;
1551 } else if ((ph
->phy_en_flowctrl
== LINK_FLOWCTRL_TX
) &&
1552 (ph
->phy_lp_pause
)) {
1553 ph
->phy_flowctrl
= LINK_FLOWCTRL_TX
;
1555 ph
->phy_flowctrl
= LINK_FLOWCTRL_NONE
;
1558 if (ph
->phy_adv_1000_fdx
&& ph
->phy_lp_1000_fdx
) {
1559 ph
->phy_speed
= 1000;
1560 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1562 } else if (ph
->phy_adv_1000_hdx
&& ph
->phy_lp_1000_hdx
) {
1563 ph
->phy_speed
= 1000;
1564 ph
->phy_duplex
= LINK_DUPLEX_HALF
;
1566 } else if (ph
->phy_adv_100_fdx
&& ph
->phy_lp_100_fdx
) {
1567 ph
->phy_speed
= 100;
1568 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1570 } else if (ph
->phy_adv_100_t4
&& ph
->phy_lp_100_t4
) {
1571 ph
->phy_speed
= 100;
1572 ph
->phy_duplex
= LINK_DUPLEX_HALF
;
1574 } else if (ph
->phy_adv_100_hdx
&& ph
->phy_lp_100_hdx
) {
1575 ph
->phy_speed
= 100;
1576 ph
->phy_duplex
= LINK_DUPLEX_HALF
;
1578 } else if (ph
->phy_adv_10_fdx
&& ph
->phy_lp_10_fdx
) {
1580 ph
->phy_duplex
= LINK_DUPLEX_FULL
;
1582 } else if (ph
->phy_adv_10_hdx
&& ph
->phy_lp_10_hdx
) {
1584 ph
->phy_duplex
= LINK_DUPLEX_HALF
;
1588 phy_warn(ph
, "No common abilities.");
1591 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1594 return (DDI_SUCCESS
);
1598 phy_get_prop(phy_handle_t
*ph
, char *prop
, int dflt
)
1600 mii_handle_t mh
= ph
->phy_mii
;
1602 return (ddi_prop_get_int(DDI_DEV_T_ANY
, mh
->m_dip
, 0, prop
, dflt
));
1606 phy_get_name(phy_handle_t
*ph
)
1608 mii_handle_t mh
= ph
->phy_mii
;
1610 return (mh
->m_name
);
1614 phy_get_driver(phy_handle_t
*ph
)
1616 mii_handle_t mh
= ph
->phy_mii
;
1618 return (ddi_driver_name(mh
->m_dip
));
1622 phy_warn(phy_handle_t
*ph
, const char *fmt
, ...)
1627 (void) snprintf(buf
, sizeof (buf
), "%s: %s", phy_get_name(ph
), fmt
);
1630 vcmn_err(CE_WARN
, buf
, va
);
1635 * Internal support routines.
1639 _mii_notify(mii_handle_t mh
)
1641 if (mh
->m_ops
.mii_notify
!= NULL
) {
1642 mh
->m_ops
.mii_notify(mh
->m_private
, mh
->m_link
);
1647 _mii_probe_phy(phy_handle_t
*ph
)
1651 mii_handle_t mh
= ph
->phy_mii
;
1655 * Apparently, PHY 0 is less likely to be physically
1656 * connected, and should always be the last one tried. Most
1657 * single solution NICs use PHY1 for their built-in
1658 * transceiver. NICs with an external MII will often place
1659 * the external PHY at address 1, and use address 0 for the
1664 ph
->phy_model
= "PHY";
1665 ph
->phy_vendor
= "Unknown Vendor";
1667 /* done twice to clear any latched bits */
1668 bmsr
= phy_read(ph
, MII_STATUS
);
1669 bmsr
= phy_read(ph
, MII_STATUS
);
1670 if ((bmsr
== 0) || (bmsr
== 0xffff)) {
1671 ph
->phy_present
= B_FALSE
;
1675 if (bmsr
& MII_STATUS_EXTSTAT
) {
1676 extsr
= phy_read(ph
, MII_EXTSTATUS
);
1681 ph
->phy_present
= B_TRUE
;
1682 ph
->phy_id
= ((uint32_t)phy_read(ph
, MII_PHYIDH
) << 16) |
1683 phy_read(ph
, MII_PHYIDL
);
1685 /* setup default handlers */
1686 ph
->phy_reset
= phy_reset
;
1687 ph
->phy_start
= phy_start
;
1688 ph
->phy_stop
= phy_stop
;
1689 ph
->phy_check
= phy_check
;
1690 ph
->phy_loop
= phy_loop
;
1693 * We ignore the non-existent 100baseT2 stuff -- no
1694 * known products for it exist.
1696 ph
->phy_cap_aneg
= !!(bmsr
& MII_STATUS_CANAUTONEG
);
1697 ph
->phy_cap_100_t4
= !!(bmsr
& MII_STATUS_100_BASE_T4
);
1698 ph
->phy_cap_100_fdx
= !!(bmsr
& MII_STATUS_100_BASEX_FD
);
1699 ph
->phy_cap_100_hdx
= !!(bmsr
& MII_STATUS_100_BASEX
);
1700 ph
->phy_cap_10_fdx
= !!(bmsr
& MII_STATUS_10_FD
);
1701 ph
->phy_cap_10_hdx
= !!(bmsr
& MII_STATUS_10
);
1702 ph
->phy_cap_1000_fdx
=
1703 !!(extsr
& (MII_EXTSTATUS_1000X_FD
|MII_EXTSTATUS_1000T_FD
));
1704 ph
->phy_cap_1000_hdx
=
1705 !!(extsr
& (MII_EXTSTATUS_1000X
| MII_EXTSTATUS_1000T
));
1706 ph
->phy_cap_pause
= mh
->m_cap_pause
;
1707 ph
->phy_cap_asmpause
= mh
->m_cap_asmpause
;
1709 if (bmsr
& MII_STATUS_10
) {
1710 ph
->phy_cap_10_hdx
= B_TRUE
;
1711 ph
->phy_type
= XCVR_10
;
1713 if (bmsr
& MII_STATUS_10_FD
) {
1714 ph
->phy_cap_10_fdx
= B_TRUE
;
1715 ph
->phy_type
= XCVR_10
;
1717 if (bmsr
& MII_STATUS_100T2
) {
1718 ph
->phy_cap_100_hdx
= B_TRUE
;
1719 ph
->phy_type
= XCVR_100T2
;
1721 if (bmsr
& MII_STATUS_100T2_FD
) {
1722 ph
->phy_cap_100_fdx
= B_TRUE
;
1723 ph
->phy_type
= XCVR_100T2
;
1725 if (bmsr
& MII_STATUS_100_BASE_T4
) {
1726 ph
->phy_cap_100_hdx
= B_TRUE
;
1727 ph
->phy_type
= XCVR_100T4
;
1729 if (bmsr
& MII_STATUS_100_BASEX
) {
1730 ph
->phy_cap_100_hdx
= B_TRUE
;
1731 ph
->phy_type
= XCVR_100X
;
1733 if (bmsr
& MII_STATUS_100_BASEX_FD
) {
1734 ph
->phy_cap_100_fdx
= B_TRUE
;
1735 ph
->phy_type
= XCVR_100X
;
1737 if (extsr
& MII_EXTSTATUS_1000X
) {
1738 ph
->phy_cap_1000_hdx
= B_TRUE
;
1739 ph
->phy_type
= XCVR_1000X
;
1741 if (extsr
& MII_EXTSTATUS_1000X_FD
) {
1742 ph
->phy_cap_1000_fdx
= B_TRUE
;
1743 ph
->phy_type
= XCVR_1000X
;
1745 if (extsr
& MII_EXTSTATUS_1000T
) {
1746 ph
->phy_cap_1000_hdx
= B_TRUE
;
1747 ph
->phy_type
= XCVR_1000T
;
1749 if (extsr
& MII_EXTSTATUS_1000T_FD
) {
1750 ph
->phy_cap_1000_fdx
= B_TRUE
;
1751 ph
->phy_type
= XCVR_1000T
;
1754 for (int j
= 0; _phy_probes
[j
] != NULL
; j
++) {
1755 if ((*_phy_probes
[j
])(ph
)) {
1760 #define INIT_ENABLE(CAP) \
1761 ph->phy_en_##CAP = (mh->m_en_##CAP > 0) ? \
1762 mh->m_en_##CAP : ph->phy_cap_##CAP
1765 INIT_ENABLE(1000_fdx
);
1766 INIT_ENABLE(1000_hdx
);
1767 INIT_ENABLE(100_fdx
);
1768 INIT_ENABLE(100_t4
);
1769 INIT_ENABLE(100_hdx
);
1770 INIT_ENABLE(10_fdx
);
1771 INIT_ENABLE(10_hdx
);
1774 ph
->phy_en_flowctrl
= mh
->m_en_flowctrl
;
1775 switch (ph
->phy_en_flowctrl
) {
1776 case LINK_FLOWCTRL_BI
:
1777 case LINK_FLOWCTRL_RX
:
1778 ph
->phy_en_pause
= B_TRUE
;
1779 ph
->phy_en_asmpause
= B_TRUE
;
1781 case LINK_FLOWCTRL_TX
:
1782 ph
->phy_en_pause
= B_FALSE
;
1783 ph
->phy_en_asmpause
= B_TRUE
;
1786 ph
->phy_en_pause
= B_FALSE
;
1787 ph
->phy_en_asmpause
= B_FALSE
;
1793 _mii_probe(mii_handle_t mh
)
1803 user_addr
= ddi_prop_get_int(DDI_DEV_T_ANY
, mh
->m_dip
, 0,
1805 old_addr
= mh
->m_addr
;
1809 * Apparently, PHY 0 is less likely to be physically
1810 * connected, and should always be the last one tried. Most
1811 * single solution NICs use PHY1 for their built-in
1812 * transceiver. NICs with an external MII will often place
1813 * the external PHY at address 1, and use address 0 for the
1816 * Some devices have a different preference however. They can
1817 * override the default starting point of the search by
1818 * exporting a "first-phy" property.
1821 first
= ddi_prop_get_int(DDI_DEV_T_ANY
, mh
->m_dip
, 0, "first-phy", 1);
1822 if ((first
< 0) || (first
> 31)) {
1825 for (int i
= first
; i
< (first
+ 32); i
++) {
1828 * This is tricky: it lets us start searching at an
1829 * arbitrary address instead of 0, dealing with the
1830 * wrap-around at address 31 properly.
1834 ph
= &mh
->m_phys
[curr_addr
];
1836 bzero(ph
, sizeof (*ph
));
1837 ph
->phy_addr
= curr_addr
;
1842 if (!ph
->phy_present
)
1845 if (curr_addr
== user_addr
) {
1847 * We always try to honor the user configured phy.
1849 new_addr
= curr_addr
;
1854 /* two reads to clear latched bits */
1855 if ((phy_read(ph
, MII_STATUS
) & MII_STATUS_LINKUP
) &&
1856 (phy_read(ph
, MII_STATUS
) & MII_STATUS_LINKUP
) &&
1859 * Link present is good. We prefer this over
1860 * a possibly disconnected link.
1862 new_addr
= curr_addr
;
1865 if ((curr_addr
== old_addr
) && (pri
< 2)) {
1867 * All else being equal, minimize change.
1869 new_addr
= curr_addr
;
1875 * But make sure we at least select a present PHY.
1877 new_addr
= curr_addr
;
1882 if (new_addr
== 0xff) {
1884 mh
->m_phy
= &mh
->m_bogus_phy
;
1885 _mii_error(mh
, MII_ENOPHY
);
1887 mh
->m_addr
= new_addr
;
1888 mh
->m_phy
= &mh
->m_phys
[new_addr
];
1889 mh
->m_tstate
= MII_STATE_RESET
;
1890 if (new_addr
!= old_addr
) {
1892 "?%s: Using %s Ethernet PHY at %d: %s %s\n",
1893 mh
->m_name
, mii_xcvr_types
[mh
->m_phy
->phy_type
],
1894 mh
->m_addr
, mh
->m_phy
->phy_vendor
,
1895 mh
->m_phy
->phy_model
);
1896 mh
->m_link
= LINK_STATE_UNKNOWN
;
1902 _mii_reset(mii_handle_t mh
)
1907 ASSERT(mutex_owned(&mh
->m_lock
));
1910 * Reset logic. We want to isolate all the other
1911 * phys that are not in use.
1913 for (int i
= 0; i
< 32; i
++) {
1914 ph
= &mh
->m_phys
[i
];
1916 if (!ph
->phy_present
)
1919 /* Don't touch our own phy, yet. */
1920 if (ph
== mh
->m_phy
)
1928 ASSERT(ph
->phy_present
);
1930 /* If we're resetting the PHY, then we want to notify loss of link */
1931 notify
= (mh
->m_link
!= LINK_STATE_DOWN
);
1932 mh
->m_link
= LINK_STATE_DOWN
;
1933 ph
->phy_link
= LINK_STATE_DOWN
;
1935 ph
->phy_duplex
= LINK_DUPLEX_UNKNOWN
;
1937 if (ph
->phy_reset(ph
) != DDI_SUCCESS
) {
1938 _mii_error(mh
, MII_ERESET
);
1939 return (DDI_FAILURE
);
1942 /* Perform optional mac layer reset. */
1943 if (mh
->m_ops
.mii_reset
!= NULL
) {
1944 mh
->m_ops
.mii_reset(mh
->m_private
);
1947 /* Perform optional mac layer notification. */
1951 return (DDI_SUCCESS
);
1955 _mii_loopback(mii_handle_t mh
)
1959 ASSERT(mutex_owned(&mh
->m_lock
));
1963 if (_mii_reset(mh
) != DDI_SUCCESS
) {
1964 return (DDI_FAILURE
);
1966 if (ph
->phy_loopback
== PHY_LB_NONE
) {
1967 mh
->m_tstate
= MII_STATE_START
;
1968 return (DDI_SUCCESS
);
1970 if (ph
->phy_loop(ph
) != DDI_SUCCESS
) {
1971 _mii_error(mh
, MII_ELOOP
);
1972 return (DDI_FAILURE
);
1975 /* Just force loopback to link up. */
1976 mh
->m_link
= ph
->phy_link
= LINK_STATE_UP
;
1979 return (DDI_SUCCESS
);
1983 _mii_start(mii_handle_t mh
)
1989 ASSERT(mutex_owned(&mh
->m_lock
));
1990 ASSERT(ph
->phy_present
);
1991 ASSERT(ph
->phy_loopback
== PHY_LB_NONE
);
1993 if (ph
->phy_start(ph
) != DDI_SUCCESS
) {
1994 _mii_error(mh
, MII_ESTART
);
1995 return (DDI_FAILURE
);
1997 /* clear the error state since we got a good startup! */
1998 mh
->m_error
= MII_EOK
;
1999 return (DDI_SUCCESS
);
2003 _mii_check(mii_handle_t mh
)
2007 link_duplex_t oduplex
;
2008 link_flowctrl_t ofctrl
;
2014 ospeed
= ph
->phy_speed
;
2015 oduplex
= ph
->phy_duplex
;
2016 ofctrl
= ph
->phy_flowctrl
;
2018 ASSERT(ph
->phy_present
);
2020 if (ph
->phy_check(ph
) == DDI_FAILURE
) {
2021 _mii_error(mh
, MII_ECHECK
);
2022 mh
->m_link
= LINK_STATE_UNKNOWN
;
2024 return (DDI_FAILURE
);
2027 mh
->m_link
= ph
->phy_link
;
2029 /* if anything changed, notify! */
2030 if ((mh
->m_link
!= olink
) ||
2031 (ph
->phy_speed
!= ospeed
) ||
2032 (ph
->phy_duplex
!= oduplex
) ||
2033 (ph
->phy_flowctrl
!= ofctrl
)) {
2037 return (DDI_SUCCESS
);
2041 _mii_task(void *_mh
)
2043 mii_handle_t mh
= _mh
;
2048 mutex_enter(&mh
->m_lock
);
2052 /* If detaching, exit the thread. */
2053 if (!mh
->m_started
) {
2060 * If we're suspended or otherwise not supposed to be
2061 * monitoring the link, just go back to sleep.
2063 * Theoretically we could power down the PHY, but we
2064 * don't bother. (The link might be used for
2065 * wake-on-lan!) Another option would be to reduce
2066 * power on the PHY if both it and the link partner
2067 * support 10 Mbps mode.
2069 if (mh
->m_suspending
) {
2070 mh
->m_suspended
= B_TRUE
;
2071 cv_broadcast(&mh
->m_cv
);
2073 if (mh
->m_suspended
) {
2074 mh
->m_suspending
= B_FALSE
;
2075 cv_wait(&mh
->m_cv
, &mh
->m_lock
);
2079 switch (mh
->m_tstate
) {
2080 case MII_STATE_PROBE
:
2083 if (!ph
->phy_present
) {
2085 * If no PHY is found, wait a bit before
2086 * trying the probe again. 10 seconds ought
2089 wait
= 10 * MII_SECOND
;
2095 case MII_STATE_RESET
:
2096 if (_mii_reset(mh
) == DDI_SUCCESS
) {
2097 mh
->m_tstate
= MII_STATE_START
;
2101 * If an error occurred, wait a bit and
2104 wait
= 10 * MII_SECOND
;
2108 case MII_STATE_START
:
2110 * If an error occurs, we're going to go back to
2111 * probe or reset state. Otherwise we go to run
2112 * state. In all cases we want to wait 1 second
2113 * before doing anything else - either for link to
2114 * settle, or to give other code a chance to run
2117 if (_mii_start(mh
) == DDI_SUCCESS
) {
2118 /* reset watchdog to latest */
2119 downtime
= ddi_get_lbolt();
2120 mh
->m_tstate
= MII_STATE_RUN
;
2122 mh
->m_tstate
= MII_STATE_PROBE
;
2127 case MII_STATE_LOOPBACK
:
2129 * In loopback mode we don't check anything,
2130 * and just wait for some condition to change.
2137 if (_mii_check(mh
) == DDI_FAILURE
) {
2139 * On error (PHY removed?), wait a
2140 * short bit before reprobing or
2144 mh
->m_tstate
= MII_STATE_PROBE
;
2146 } else if (mh
->m_link
== LINK_STATE_UP
) {
2147 /* got goood link, so reset the watchdog */
2148 downtime
= ddi_get_lbolt();
2149 /* rescan again in a second */
2152 } else if ((ddi_get_lbolt() - downtime
) >
2153 (drv_usectohz(MII_SECOND
* 10))) {
2156 * If we were down for 10 seconds,
2157 * hard reset the PHY.
2159 mh
->m_tstate
= MII_STATE_RESET
;
2164 * Otherwise, if we are still down,
2165 * rescan the link much more
2166 * frequently. We might be trying to
2169 wait
= MII_SECOND
/ 4;
2179 cv_wait(&mh
->m_cv
, &mh
->m_lock
);
2183 (void) cv_reltimedwait(&mh
->m_cv
, &mh
->m_lock
,
2184 drv_usectohz(wait
), TR_CLOCK_TICK
);
2188 mutex_exit(&mh
->m_lock
);