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