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