1 /* $OpenBSD: mii_physubr.c,v 1.46 2020/01/15 00:14:47 cheloha Exp $ */ 2 /* $NetBSD: mii_physubr.c,v 1.20 2001/04/13 23:30:09 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Subroutines common to all PHYs. 36 */ 37 38 #include <sys/param.h> 39 #include <sys/device.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/socket.h> 43 #include <sys/errno.h> 44 45 #include <net/if.h> 46 #include <net/if_var.h> 47 #include <net/if_media.h> 48 49 #include <dev/mii/mii.h> 50 #include <dev/mii/miivar.h> 51 52 /* 53 * Media to register setting conversion table. Order matters. 54 * XXX 802.3 doesn't specify ANAR or ANLPAR bits for 1000base. 55 */ 56 const struct mii_media mii_media_table[] = { 57 /* None */ 58 { BMCR_ISO, ANAR_CSMA, 0 }, 59 /* 10baseT */ 60 { BMCR_S10, ANAR_CSMA|ANAR_10, 0 }, 61 /* 10baseT-FDX */ 62 { BMCR_S10|BMCR_FDX, ANAR_CSMA|ANAR_10_FD, 0 }, 63 /* 100baseT4 */ 64 { BMCR_S100, ANAR_CSMA|ANAR_T4, 0 }, 65 /* 100baseTX */ 66 { BMCR_S100, ANAR_CSMA|ANAR_TX, 0 }, 67 /* 100baseTX-FDX */ 68 { BMCR_S100|BMCR_FDX, ANAR_CSMA|ANAR_TX_FD, 0 }, 69 /* 1000baseX */ 70 { BMCR_S1000, ANAR_CSMA, 0 }, 71 /* 1000baseX-FDX */ 72 { BMCR_S1000|BMCR_FDX, ANAR_CSMA, 0 }, 73 /* 1000baseT */ 74 { BMCR_S1000, ANAR_CSMA, GTCR_ADV_1000THDX }, 75 /* 1000baseT-FDX */ 76 { BMCR_S1000|BMCR_FDX, ANAR_CSMA, GTCR_ADV_1000TFDX }, 77 }; 78 79 void 80 mii_phy_setmedia(struct mii_softc *sc) 81 { 82 struct mii_data *mii = sc->mii_pdata; 83 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 84 int bmcr, anar, gtcr; 85 86 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 87 if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 || 88 (sc->mii_flags & MIIF_FORCEANEG)) 89 (void) mii_phy_auto(sc, 1); 90 return; 91 } 92 93 /* 94 * Table index is stored in the media entry. 95 */ 96 #ifdef DIAGNOSTIC 97 if (ife->ifm_data >= MII_NMEDIA) 98 panic("mii_phy_setmedia"); 99 #endif 100 101 anar = mii_media_table[ife->ifm_data].mm_anar; 102 bmcr = mii_media_table[ife->ifm_data].mm_bmcr; 103 gtcr = mii_media_table[ife->ifm_data].mm_gtcr; 104 105 if (mii->mii_media.ifm_media & IFM_ETH_MASTER) { 106 switch (IFM_SUBTYPE(ife->ifm_media)) { 107 case IFM_1000_T: 108 gtcr |= GTCR_MAN_MS|GTCR_ADV_MS; 109 break; 110 111 default: 112 panic("mii_phy_setmedia: MASTER on wrong media"); 113 } 114 } 115 116 if (ife->ifm_media & IFM_LOOP) 117 bmcr |= BMCR_LOOP; 118 119 PHY_WRITE(sc, MII_ANAR, anar); 120 PHY_WRITE(sc, MII_BMCR, bmcr); 121 if (sc->mii_flags & MIIF_HAVE_GTCR) 122 PHY_WRITE(sc, MII_100T2CR, gtcr); 123 } 124 125 int 126 mii_phy_auto(struct mii_softc *sc, int waitfor) 127 { 128 int bmsr, i; 129 130 if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { 131 /* 132 * Check for 1000BASE-X. Autonegotiation is a bit 133 * different on such devices. 134 */ 135 if (sc->mii_flags & MIIF_IS_1000X) { 136 uint16_t anar = 0; 137 138 if (sc->mii_extcapabilities & EXTSR_1000XFDX) 139 anar |= ANAR_X_FD; 140 if (sc->mii_extcapabilities & EXTSR_1000XHDX) 141 anar |= ANAR_X_HD; 142 143 if (sc->mii_flags & MIIF_DOPAUSE && 144 sc->mii_extcapabilities & EXTSR_1000XFDX) 145 anar |= ANAR_X_PAUSE_TOWARDS; 146 147 PHY_WRITE(sc, MII_ANAR, anar); 148 } else { 149 uint16_t anar; 150 151 anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | 152 ANAR_CSMA; 153 /* 154 * Most 100baseTX PHY's only support symmetric 155 * PAUSE, so we don't advertise asymmetric 156 * PAUSE unless we also have 1000baseT capability. 157 */ 158 if (sc->mii_flags & MIIF_DOPAUSE) { 159 if (sc->mii_capabilities & BMSR_100TXFDX) 160 anar |= ANAR_FC; 161 if (sc->mii_extcapabilities & EXTSR_1000TFDX) 162 anar |= ANAR_PAUSE_TOWARDS; 163 } 164 PHY_WRITE(sc, MII_ANAR, anar); 165 if (sc->mii_flags & MIIF_HAVE_GTCR) { 166 uint16_t gtcr = 0; 167 168 if (sc->mii_extcapabilities & EXTSR_1000TFDX) 169 gtcr |= GTCR_ADV_1000TFDX; 170 if (sc->mii_extcapabilities & EXTSR_1000THDX) 171 gtcr |= GTCR_ADV_1000THDX; 172 173 PHY_WRITE(sc, MII_100T2CR, gtcr); 174 } 175 } 176 PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); 177 } 178 179 if (waitfor) { 180 /* Wait 500ms for it to complete. */ 181 for (i = 0; i < 500; i++) { 182 if ((bmsr = PHY_READ(sc, MII_BMSR)) & BMSR_ACOMP) 183 return (0); 184 delay(1000); 185 } 186 187 /* 188 * Don't need to worry about clearing MIIF_DOINGAUTO. 189 * If that's set, a timeout is pending, and it will 190 * clear the flag. 191 */ 192 return (EIO); 193 } 194 195 /* 196 * Just let it finish asynchronously. This is for the benefit of 197 * the tick handler driving autonegotiation. Don't want 500ms 198 * delays all the time while the system is running! 199 */ 200 if (sc->mii_flags & MIIF_AUTOTSLEEP) { 201 sc->mii_flags |= MIIF_DOINGAUTO; 202 tsleep_nsec(&sc->mii_flags, PZERO, "miiaut", MSEC_TO_NSEC(500)); 203 mii_phy_auto_timeout(sc); 204 } else if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { 205 sc->mii_flags |= MIIF_DOINGAUTO; 206 timeout_set(&sc->mii_phy_timo, mii_phy_auto_timeout, sc); 207 timeout_add_msec(&sc->mii_phy_timo, 500); 208 } 209 return (EJUSTRETURN); 210 } 211 212 void 213 mii_phy_auto_timeout(void *arg) 214 { 215 struct mii_softc *sc = arg; 216 int s, bmsr; 217 218 if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) 219 return; 220 221 s = splnet(); 222 sc->mii_flags &= ~MIIF_DOINGAUTO; 223 bmsr = PHY_READ(sc, MII_BMSR); 224 225 /* Update the media status. */ 226 (void) PHY_SERVICE(sc, sc->mii_pdata, MII_POLLSTAT); 227 splx(s); 228 } 229 230 int 231 mii_phy_tick(struct mii_softc *sc) 232 { 233 struct mii_data *mii = sc->mii_pdata; 234 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 235 int reg; 236 237 /* Just bail now if the interface is down. */ 238 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 239 return (EJUSTRETURN); 240 241 /* 242 * If we're not doing autonegotiation, we don't need to do 243 * any extra work here. However, we need to check the link 244 * status so we can generate an announcement if the status 245 * changes. 246 */ 247 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 248 return (0); 249 250 /* Read the status register twice; BMSR_LINK is latch-low. */ 251 reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 252 if (reg & BMSR_LINK) { 253 /* 254 * See above. 255 */ 256 return (0); 257 } 258 259 /* 260 * Only retry autonegotiation every mii_anegticks seconds. 261 */ 262 if (!sc->mii_anegticks) 263 sc->mii_anegticks = MII_ANEGTICKS; 264 265 if (++sc->mii_ticks <= sc->mii_anegticks) 266 return (EJUSTRETURN); 267 268 sc->mii_ticks = 0; 269 PHY_RESET(sc); 270 271 if (mii_phy_auto(sc, 0) == EJUSTRETURN) 272 return (EJUSTRETURN); 273 274 /* 275 * Might need to generate a status message if autonegotiation 276 * failed. 277 */ 278 return (0); 279 } 280 281 void 282 mii_phy_reset(struct mii_softc *sc) 283 { 284 int reg, i; 285 286 if (sc->mii_flags & MIIF_NOISOLATE) 287 reg = BMCR_RESET; 288 else 289 reg = BMCR_RESET | BMCR_ISO; 290 PHY_WRITE(sc, MII_BMCR, reg); 291 292 /* 293 * It is best to allow a little time for the reset to settle 294 * in before we start polling the BMCR again. Notably, the 295 * DP83840A manual states that there should be a 500us delay 296 * between asserting software reset and attempting MII serial 297 * operations. Also, a DP83815 can get into a bad state on 298 * cable removal and reinsertion if we do not delay here. 299 */ 300 delay(500); 301 302 /* Wait another 100ms for it to complete. */ 303 for (i = 0; i < 100; i++) { 304 reg = PHY_READ(sc, MII_BMCR); 305 if ((reg & BMCR_RESET) == 0) 306 break; 307 delay(1000); 308 } 309 310 if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0)) 311 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 312 } 313 314 void 315 mii_phy_down(struct mii_softc *sc) 316 { 317 if (sc->mii_flags & MIIF_DOINGAUTO) { 318 sc->mii_flags &= ~MIIF_DOINGAUTO; 319 timeout_del(&sc->mii_phy_timo); 320 } 321 } 322 323 324 void 325 mii_phy_status(struct mii_softc *sc) 326 { 327 PHY_STATUS(sc); 328 } 329 330 void 331 mii_phy_update(struct mii_softc *sc, int cmd) 332 { 333 struct mii_data *mii = sc->mii_pdata; 334 struct ifnet *ifp = mii->mii_ifp; 335 int announce, s; 336 337 if (sc->mii_media_active != mii->mii_media_active || 338 sc->mii_media_status != mii->mii_media_status || 339 cmd == MII_MEDIACHG) { 340 announce = mii_phy_statusmsg(sc); 341 (*mii->mii_statchg)(sc->mii_dev.dv_parent); 342 sc->mii_media_active = mii->mii_media_active; 343 sc->mii_media_status = mii->mii_media_status; 344 345 if (announce) { 346 s = splnet(); 347 if_link_state_change(ifp); 348 splx(s); 349 } 350 } 351 } 352 353 int 354 mii_phy_statusmsg(struct mii_softc *sc) 355 { 356 struct mii_data *mii = sc->mii_pdata; 357 struct ifnet *ifp = mii->mii_ifp; 358 u_int64_t baudrate; 359 int link_state, announce = 0; 360 361 if (mii->mii_media_status & IFM_AVALID) { 362 if (mii->mii_media_status & IFM_ACTIVE) { 363 if (mii->mii_media_active & IFM_FDX) 364 link_state = LINK_STATE_FULL_DUPLEX; 365 else 366 link_state = LINK_STATE_HALF_DUPLEX; 367 } else 368 link_state = LINK_STATE_DOWN; 369 } else 370 link_state = LINK_STATE_UNKNOWN; 371 372 baudrate = ifmedia_baudrate(mii->mii_media_active); 373 374 if (link_state != ifp->if_link_state) { 375 ifp->if_link_state = link_state; 376 /* 377 * XXX Right here we'd like to notify protocols 378 * XXX that the link status has changed, so that 379 * XXX e.g. Duplicate Address Detection can restart. 380 */ 381 announce = 1; 382 } 383 384 if (baudrate != ifp->if_baudrate) { 385 ifp->if_baudrate = baudrate; 386 announce = 1; 387 } 388 389 return (announce); 390 } 391 392 /* 393 * Initialize generic PHY media based on BMSR, called when a PHY is 394 * attached. 395 */ 396 void 397 mii_phy_add_media(struct mii_softc *sc) 398 { 399 struct mii_data *mii = sc->mii_pdata; 400 401 #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) 402 403 if ((sc->mii_flags & MIIF_NOISOLATE) == 0) 404 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 405 MII_MEDIA_NONE); 406 407 if (sc->mii_capabilities & BMSR_10THDX) { 408 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), 409 MII_MEDIA_10_T); 410 } 411 if (sc->mii_capabilities & BMSR_10TFDX) { 412 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), 413 MII_MEDIA_10_T_FDX); 414 } 415 if (sc->mii_capabilities & BMSR_100TXHDX) { 416 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), 417 MII_MEDIA_100_TX); 418 } 419 if (sc->mii_capabilities & BMSR_100TXFDX) { 420 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), 421 MII_MEDIA_100_TX_FDX); 422 } 423 if (sc->mii_capabilities & BMSR_100T4) { 424 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst), 425 MII_MEDIA_100_T4); 426 } 427 if (sc->mii_extcapabilities & EXTSR_MEDIAMASK) { 428 /* 429 * XXX Right now only handle 1000SX and 1000TX. Need 430 * XXX to handle 1000LX and 1000CX some how. 431 */ 432 if (sc->mii_extcapabilities & EXTSR_1000XHDX) { 433 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 434 sc->mii_flags |= MIIF_IS_1000X; 435 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, 436 sc->mii_inst), MII_MEDIA_1000_X); 437 } 438 if (sc->mii_extcapabilities & EXTSR_1000XFDX) { 439 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 440 sc->mii_flags |= MIIF_IS_1000X; 441 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, 442 sc->mii_inst), MII_MEDIA_1000_X_FDX); 443 } 444 445 /* 446 * 1000baseT media needs to be able to manipulate 447 * master/slave mode. We set IFM_ETH_MASTER in 448 * the "don't care mask" and filter it out when 449 * the media is set. 450 * 451 * All 1000baseT PHYs have a 1000baseT control register. 452 */ 453 if (sc->mii_extcapabilities & EXTSR_1000THDX) { 454 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 455 sc->mii_flags |= MIIF_HAVE_GTCR; 456 mii->mii_media.ifm_mask |= IFM_ETH_MASTER; 457 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, 458 sc->mii_inst), MII_MEDIA_1000_T); 459 } 460 if (sc->mii_extcapabilities & EXTSR_1000TFDX) { 461 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 462 sc->mii_flags |= MIIF_HAVE_GTCR; 463 mii->mii_media.ifm_mask |= IFM_ETH_MASTER; 464 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, 465 sc->mii_inst), MII_MEDIA_1000_T_FDX); 466 } 467 } 468 469 if (sc->mii_capabilities & BMSR_ANEG) { 470 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 471 MII_NMEDIA); /* intentionally invalid index */ 472 } 473 #undef ADD 474 } 475 476 void 477 mii_phy_delete_media(struct mii_softc *sc) 478 { 479 struct mii_data *mii = sc->mii_pdata; 480 481 ifmedia_delete_instance(&mii->mii_media, sc->mii_inst); 482 } 483 484 int 485 mii_phy_detach(struct device *self, int flags) 486 { 487 struct mii_softc *sc = (void *) self; 488 489 if (sc->mii_flags & MIIF_DOINGAUTO) 490 timeout_del(&sc->mii_phy_timo); 491 492 mii_phy_delete_media(sc); 493 494 return (0); 495 } 496 497 const struct mii_phydesc * 498 mii_phy_match(const struct mii_attach_args *ma, const struct mii_phydesc *mpd) 499 { 500 501 for (; mpd->mpd_name != NULL; mpd++) { 502 if (MII_OUI(ma->mii_id1, ma->mii_id2) == mpd->mpd_oui && 503 MII_MODEL(ma->mii_id2) == mpd->mpd_model) 504 return (mpd); 505 } 506 return (NULL); 507 } 508 509 /* 510 * Return the flow control status flag from MII_ANAR & MII_ANLPAR. 511 */ 512 uint64_t 513 mii_phy_flowstatus(struct mii_softc *sc) 514 { 515 int anar, anlpar; 516 517 if ((sc->mii_flags & MIIF_DOPAUSE) == 0) 518 return (0); 519 520 anar = PHY_READ(sc, MII_ANAR); 521 anlpar = PHY_READ(sc, MII_ANLPAR); 522 523 /* For 1000baseX, the bits are in a different location. */ 524 if (sc->mii_flags & MIIF_IS_1000X) { 525 anar <<= 3; 526 anlpar <<= 3; 527 } 528 529 if ((anar & ANAR_PAUSE_SYM) & (anlpar & ANLPAR_PAUSE_SYM)) 530 return (IFM_FLOW|IFM_ETH_TXPAUSE|IFM_ETH_RXPAUSE); 531 532 if ((anar & ANAR_PAUSE_SYM) == 0) { 533 if ((anar & ANAR_PAUSE_ASYM) && 534 ((anlpar & ANLPAR_PAUSE_TOWARDS) == ANLPAR_PAUSE_TOWARDS)) 535 return (IFM_FLOW|IFM_ETH_TXPAUSE); 536 else 537 return (0); 538 } 539 540 if ((anar & ANAR_PAUSE_ASYM) == 0) { 541 if (anlpar & ANLPAR_PAUSE_SYM) 542 return (IFM_FLOW|IFM_ETH_TXPAUSE|IFM_ETH_RXPAUSE); 543 else 544 return (0); 545 } 546 547 switch ((anlpar & ANLPAR_PAUSE_TOWARDS)) { 548 case ANLPAR_PAUSE_NONE: 549 return (0); 550 551 case ANLPAR_PAUSE_ASYM: 552 return (IFM_FLOW|IFM_ETH_RXPAUSE); 553 554 default: 555 return (IFM_FLOW|IFM_ETH_RXPAUSE|IFM_ETH_TXPAUSE); 556 } 557 /* NOTREACHED */ 558 } 559 560 /* 561 * Given an ifmedia word, return the corresponding ANAR value. 562 */ 563 int 564 mii_anar(uint64_t media) 565 { 566 int rv; 567 568 switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) { 569 case IFM_ETHER|IFM_10_T: 570 rv = ANAR_10|ANAR_CSMA; 571 break; 572 case IFM_ETHER|IFM_10_T|IFM_FDX: 573 rv = ANAR_10_FD|ANAR_CSMA; 574 break; 575 case IFM_ETHER|IFM_100_TX: 576 rv = ANAR_TX|ANAR_CSMA; 577 break; 578 case IFM_ETHER|IFM_100_TX|IFM_FDX: 579 rv = ANAR_TX_FD|ANAR_CSMA; 580 break; 581 case IFM_ETHER|IFM_100_T4: 582 rv = ANAR_T4|ANAR_CSMA; 583 break; 584 default: 585 rv = 0; 586 break; 587 } 588 589 return (rv); 590 } 591