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