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