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