1 /* 2 * Copyright (c) 2001 Wind River Systems 3 * Copyright (c) 2001 4 * Bill Paul <wpaul@bsdi.com>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Bill Paul. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 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 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: src/sys/dev/mii/nsgphy.c,v 1.1.2.3 2002/11/08 21:53:49 semenu Exp $ 34 * $DragonFly: src/sys/dev/netif/mii_layer/nsgphy.c,v 1.7 2005/02/21 18:40:36 joerg Exp $ 35 */ 36 37 /* 38 * Driver for the National Semiconductor DP83891 and DP83861 39 * 10/100/1000 PHYs. 40 * Datasheet available at: http://www.national.com/ds/DP/DP83861.pdf 41 * 42 * The DP83891 is the older NatSemi gigE PHY which isn't being sold 43 * anymore. The DP83861 is its replacement, which is an 'enhanced' 44 * firmware driven component. The major difference between the 45 * two is that the 83891 can't generate interrupts, while the 46 * 83861 can. (I think it wasn't originally designed to do this, but 47 * it can now thanks to firmware updates.) The 83861 also allows 48 * access to its internal RAM via indirect register access. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/kernel.h> 54 #include <sys/socket.h> 55 #include <sys/bus.h> 56 57 #include <machine/clock.h> 58 59 #include <net/if.h> 60 #include <net/if_media.h> 61 62 #include "mii.h" 63 #include "miivar.h" 64 #include "miidevs.h" 65 66 #include "nsgphyreg.h" 67 68 #include "miibus_if.h" 69 70 static int nsgphy_probe (device_t); 71 static int nsgphy_attach (device_t); 72 static int nsgphy_detach (device_t); 73 74 static device_method_t nsgphy_methods[] = { 75 /* device interface */ 76 DEVMETHOD(device_probe, nsgphy_probe), 77 DEVMETHOD(device_attach, nsgphy_attach), 78 DEVMETHOD(device_detach, nsgphy_detach), 79 DEVMETHOD(device_shutdown, bus_generic_shutdown), 80 { 0, 0 } 81 }; 82 83 static devclass_t nsgphy_devclass; 84 85 static driver_t nsgphy_driver = { 86 "nsgphy", 87 nsgphy_methods, 88 sizeof(struct mii_softc) 89 }; 90 91 DRIVER_MODULE(nsgphy, miibus, nsgphy_driver, nsgphy_devclass, 0, 0); 92 93 int nsgphy_service (struct mii_softc *, struct mii_data *, int); 94 void nsgphy_status (struct mii_softc *); 95 96 static int nsgphy_mii_phy_auto (struct mii_softc *, int); 97 extern void mii_phy_auto_timeout (void *); 98 99 static int nsgphy_probe(dev) 100 device_t dev; 101 { 102 struct mii_attach_args *ma; 103 104 ma = device_get_ivars(dev); 105 106 if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_NATSEMI) { 107 if (MII_MODEL(ma->mii_id2) == MII_MODEL_NATSEMI_DP83891) { 108 device_set_desc(dev, MII_STR_NATSEMI_DP83891); 109 return(0); 110 } 111 if (MII_MODEL(ma->mii_id2) == MII_MODEL_NATSEMI_DP83861) { 112 device_set_desc(dev, MII_STR_NATSEMI_DP83861); 113 return(0); 114 } 115 } 116 117 return(ENXIO); 118 } 119 120 static int nsgphy_attach(dev) 121 device_t dev; 122 { 123 struct mii_softc *sc; 124 struct mii_attach_args *ma; 125 struct mii_data *mii; 126 const char *sep = ""; 127 128 sc = device_get_softc(dev); 129 ma = device_get_ivars(dev); 130 mii_softc_init(sc); 131 sc->mii_dev = device_get_parent(dev); 132 mii = device_get_softc(sc->mii_dev); 133 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 134 135 sc->mii_inst = mii->mii_instance; 136 sc->mii_phy = ma->mii_phyno; 137 sc->mii_service = nsgphy_service; 138 sc->mii_pdata = mii; 139 140 sc->mii_flags |= MIIF_NOISOLATE; 141 mii->mii_instance++; 142 143 #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) 144 #define PRINT(s) printf("%s%s", sep, s); sep = ", " 145 146 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 147 BMCR_ISO); 148 #if 0 149 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), 150 BMCR_LOOP|BMCR_S100); 151 #endif 152 153 mii_phy_reset(sc); 154 155 device_printf(dev, " "); 156 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 157 NSGPHY_S1000|NSGPHY_BMCR_FDX); 158 PRINT("1000baseTX-FDX"); 159 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), 160 NSGPHY_S1000); 161 PRINT("1000baseTX"); 162 sc->mii_capabilities = 163 (PHY_READ(sc, MII_BMSR) | 164 (BMSR_10TFDX|BMSR_10THDX)) & ma->mii_capmask; 165 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), 166 NSGPHY_S100|NSGPHY_BMCR_FDX); 167 PRINT("100baseTX-FDX"); 168 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), NSGPHY_S100); 169 PRINT("100baseTX"); 170 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), 171 NSGPHY_S10|NSGPHY_BMCR_FDX); 172 PRINT("10baseT-FDX"); 173 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), NSGPHY_S10); 174 PRINT("10baseT"); 175 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); 176 PRINT("auto"); 177 printf("\n"); 178 #undef ADD 179 #undef PRINT 180 181 MIIBUS_MEDIAINIT(sc->mii_dev); 182 return(0); 183 } 184 185 static int nsgphy_detach(dev) 186 device_t dev; 187 { 188 struct mii_softc *sc; 189 struct mii_data *mii; 190 191 sc = device_get_softc(dev); 192 mii = device_get_softc(device_get_parent(dev)); 193 if (sc->mii_flags & MIIF_DOINGAUTO) 194 callout_stop(&sc->mii_auto_ch); 195 sc->mii_dev = NULL; 196 LIST_REMOVE(sc, mii_list); 197 198 return(0); 199 } 200 int 201 nsgphy_service(sc, mii, cmd) 202 struct mii_softc *sc; 203 struct mii_data *mii; 204 int cmd; 205 { 206 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 207 int reg; 208 209 switch (cmd) { 210 case MII_POLLSTAT: 211 /* 212 * If we're not polling our PHY instance, just return. 213 */ 214 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 215 return (0); 216 break; 217 218 case MII_MEDIACHG: 219 /* 220 * If the media indicates a different PHY instance, 221 * isolate ourselves. 222 */ 223 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 224 reg = PHY_READ(sc, MII_BMCR); 225 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 226 return (0); 227 } 228 229 /* 230 * If the interface is not up, don't do anything. 231 */ 232 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 233 break; 234 235 236 switch (IFM_SUBTYPE(ife->ifm_media)) { 237 case IFM_AUTO: 238 #ifdef foo 239 /* 240 * If we're already in auto mode, just return. 241 */ 242 if (PHY_READ(sc, NSGPHY_MII_BMCR) & NSGPHY_BMCR_AUTOEN) 243 return (0); 244 #endif 245 (void) nsgphy_mii_phy_auto(sc, 0); 246 break; 247 case IFM_1000_T: 248 if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { 249 PHY_WRITE(sc, NSGPHY_MII_BMCR, 250 NSGPHY_BMCR_FDX|NSGPHY_BMCR_SPD1); 251 } else { 252 PHY_WRITE(sc, NSGPHY_MII_BMCR, 253 NSGPHY_BMCR_SPD1); 254 } 255 PHY_WRITE(sc, NSGPHY_MII_ANAR, NSGPHY_SEL_TYPE); 256 257 /* 258 * When setting the link manually, one side must 259 * be the master and the other the slave. However 260 * ifmedia doesn't give us a good way to specify 261 * this, so we fake it by using one of the LINK 262 * flags. If LINK0 is set, we program the PHY to 263 * be a master, otherwise it's a slave. 264 */ 265 if ((mii->mii_ifp->if_flags & IFF_LINK0)) { 266 PHY_WRITE(sc, NSGPHY_MII_1000CTL, 267 NSGPHY_1000CTL_MSE|NSGPHY_1000CTL_MSC); 268 } else { 269 PHY_WRITE(sc, NSGPHY_MII_1000CTL, 270 NSGPHY_1000CTL_MSE); 271 } 272 break; 273 case IFM_100_T4: 274 /* 275 * XXX Not supported as a manual setting right now. 276 */ 277 return (EINVAL); 278 case IFM_NONE: 279 PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); 280 break; 281 default: 282 /* 283 * BMCR data is stored in the ifmedia entry. 284 */ 285 PHY_WRITE(sc, MII_ANAR, 286 mii_anar(ife->ifm_media)); 287 PHY_WRITE(sc, MII_BMCR, ife->ifm_data); 288 break; 289 } 290 break; 291 292 case MII_TICK: 293 /* 294 * If we're not currently selected, just return. 295 */ 296 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 297 return (0); 298 299 /* 300 * Only used for autonegotiation. 301 */ 302 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 303 return (0); 304 305 /* 306 * Is the interface even up? 307 */ 308 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 309 return (0); 310 311 /* 312 * Only retry autonegotiation every 17 seconds. 313 * Actually, for gigE PHYs, we should wait longer, since 314 * 5 seconds is the mimimum time the documentation 315 * says to wait for a 1000mbps link to be established. 316 */ 317 if (++sc->mii_ticks != 17) 318 return (0); 319 320 sc->mii_ticks = 0; 321 322 /* 323 * Check to see if we have link. 324 */ 325 reg = PHY_READ(sc, NSGPHY_MII_PHYSUP); 326 if (reg & NSGPHY_PHYSUP_LNKSTS) 327 break; 328 329 mii_phy_reset(sc); 330 if (nsgphy_mii_phy_auto(sc, 0) == EJUSTRETURN) 331 return(0); 332 break; 333 } 334 335 /* Update the media status. */ 336 nsgphy_status(sc); 337 338 /* Callback if something changed. */ 339 if (sc->mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) { 340 MIIBUS_STATCHG(sc->mii_dev); 341 sc->mii_active = mii->mii_media_active; 342 } 343 return (0); 344 } 345 346 void 347 nsgphy_status(sc) 348 struct mii_softc *sc; 349 { 350 struct mii_data *mii = sc->mii_pdata; 351 int bmsr, bmcr, physup, anlpar, gstat; 352 353 mii->mii_media_status = IFM_AVALID; 354 mii->mii_media_active = IFM_ETHER; 355 356 bmsr = PHY_READ(sc, NSGPHY_MII_BMSR); 357 physup = PHY_READ(sc, NSGPHY_MII_PHYSUP); 358 if (physup & NSGPHY_PHYSUP_LNKSTS) 359 mii->mii_media_status |= IFM_ACTIVE; 360 361 bmcr = PHY_READ(sc, NSGPHY_MII_BMCR); 362 363 if (bmcr & NSGPHY_BMCR_LOOP) 364 mii->mii_media_active |= IFM_LOOP; 365 366 if (bmcr & NSGPHY_BMCR_AUTOEN) { 367 if ((bmsr & NSGPHY_BMSR_ACOMP) == 0) { 368 /* Erg, still trying, I guess... */ 369 mii->mii_media_active |= IFM_NONE; 370 return; 371 } 372 anlpar = PHY_READ(sc, NSGPHY_MII_ANLPAR); 373 gstat = PHY_READ(sc, NSGPHY_MII_1000STS); 374 if (gstat & NSGPHY_1000STS_LPFD) 375 mii->mii_media_active |= IFM_1000_T | IFM_FDX; 376 else if (gstat & NSGPHY_1000STS_LPHD) 377 mii->mii_media_active |= IFM_1000_T | IFM_HDX; 378 else if (anlpar & NSGPHY_ANLPAR_100T4) 379 mii->mii_media_active |= IFM_100_T4; 380 else if (anlpar & NSGPHY_ANLPAR_100FDX) 381 mii->mii_media_active |= IFM_100_TX|IFM_FDX; 382 else if (anlpar & NSGPHY_ANLPAR_100HDX) 383 mii->mii_media_active |= IFM_100_TX; 384 else if (anlpar & NSGPHY_ANLPAR_10FDX) 385 mii->mii_media_active |= IFM_10_T|IFM_FDX; 386 else if (anlpar & NSGPHY_ANLPAR_10HDX) 387 mii->mii_media_active |= IFM_10_T|IFM_HDX; 388 else 389 mii->mii_media_active |= IFM_NONE; 390 return; 391 } 392 393 switch(bmcr & (NSGPHY_BMCR_SPD1|NSGPHY_BMCR_SPD0)) { 394 case NSGPHY_S1000: 395 mii->mii_media_active |= IFM_1000_T; 396 break; 397 case NSGPHY_S100: 398 mii->mii_media_active |= IFM_100_TX; 399 break; 400 case NSGPHY_S10: 401 mii->mii_media_active |= IFM_10_T; 402 break; 403 default: 404 break; 405 } 406 407 if (bmcr & NSGPHY_BMCR_FDX) 408 mii->mii_media_active |= IFM_FDX; 409 else 410 mii->mii_media_active |= IFM_HDX; 411 412 return; 413 } 414 415 416 static int 417 nsgphy_mii_phy_auto(mii, waitfor) 418 struct mii_softc *mii; 419 int waitfor; 420 { 421 int bmsr, ktcr = 0, i; 422 423 if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { 424 mii_phy_reset(mii); 425 PHY_WRITE(mii, NSGPHY_MII_BMCR, 0); 426 DELAY(1000); 427 ktcr = PHY_READ(mii, NSGPHY_MII_1000CTL); 428 PHY_WRITE(mii, NSGPHY_MII_1000CTL, ktcr | 429 (NSGPHY_1000CTL_AFD|NSGPHY_1000CTL_AHD)); 430 ktcr = PHY_READ(mii, NSGPHY_MII_1000CTL); 431 DELAY(1000); 432 PHY_WRITE(mii, NSGPHY_MII_ANAR, 433 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); 434 DELAY(1000); 435 PHY_WRITE(mii, NSGPHY_MII_BMCR, 436 NSGPHY_BMCR_AUTOEN | NSGPHY_BMCR_STARTNEG); 437 } 438 439 if (waitfor) { 440 /* Wait 500ms for it to complete. */ 441 for (i = 0; i < 500; i++) { 442 if ((bmsr = PHY_READ(mii, NSGPHY_MII_BMSR)) & 443 NSGPHY_BMSR_ACOMP) 444 return (0); 445 DELAY(1000); 446 #if 0 447 if ((bmsr & BMSR_ACOMP) == 0) 448 printf("%s: autonegotiation failed to complete\n", 449 mii->mii_dev.dv_xname); 450 #endif 451 } 452 453 /* 454 * Don't need to worry about clearing MIIF_DOINGAUTO. 455 * If that's set, a timeout is pending, and it will 456 * clear the flag. 457 */ 458 return (EIO); 459 } 460 461 /* 462 * Just let it finish asynchronously. This is for the benefit of 463 * the tick handler driving autonegotiation. Don't want 500ms 464 * delays all the time while the system is running! 465 */ 466 if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { 467 mii->mii_flags |= MIIF_DOINGAUTO; 468 callout_reset(&mii->mii_auto_ch, hz >> 1, 469 mii_phy_auto_timeout, mii); 470 } 471 return (EJUSTRETURN); 472 } 473