1 /* $OpenBSD: nsgphy.c,v 1.3 2001/07/02 06:29:49 nate Exp $ */ 2 /* 3 * Copyright (c) 2001 Wind River Systems 4 * Copyright (c) 2001 5 * Bill Paul <wpaul@bsdi.com>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * $FreeBSD$ 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/device.h> 55 #include <sys/malloc.h> 56 #include <sys/socket.h> 57 58 #include <net/if.h> 59 #include <net/if_media.h> 60 61 #include <dev/mii/mii.h> 62 #include <dev/mii/miivar.h> 63 #include <dev/mii/miidevs.h> 64 65 #include <dev/mii/nsgphyreg.h> 66 67 int nsgphymatch __P((struct device*, void *, void *)); 68 void nsgphyattach __P((struct device *, struct device *, void *)); 69 70 struct cfattach nsgphy_ca = { 71 sizeof(struct mii_softc), nsgphymatch, nsgphyattach, mii_phy_detach, 72 mii_phy_activate 73 }; 74 75 struct cfdriver nsgphy_cd = { 76 NULL, "nsgphy", DV_DULL 77 }; 78 79 int nsgphy_service __P((struct mii_softc *, struct mii_data *, int)); 80 void nsgphy_status __P((struct mii_softc *)); 81 82 static int nsgphy_mii_phy_auto __P((struct mii_softc *, int)); 83 extern void mii_phy_auto_timeout __P((void *)); 84 85 int 86 87 nsgphymatch(parent, match, aux) 88 struct device *parent; 89 void *match; 90 void *aux; 91 { 92 struct mii_attach_args *ma = aux; 93 94 if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_NATSEMI && 95 (MII_MODEL(ma->mii_id2) == MII_MODEL_NATSEMI_DP83891 || 96 MII_MODEL(ma->mii_id2) == MII_MODEL_NATSEMI_DP83861)) 97 return (10); 98 99 return (0); 100 } 101 102 void 103 nsgphyattach(parent, self, aux) 104 struct device *parent; 105 struct device *self; 106 void *aux; 107 { 108 struct mii_softc *sc = (struct mii_softc *)self; 109 struct mii_attach_args *ma = aux; 110 struct mii_data *mii = ma->mii_data; 111 112 switch(MII_MODEL(ma->mii_id2)) { 113 case MII_MODEL_NATSEMI_DP83861: 114 printf(": %s, rev. %d\n", MII_STR_NATSEMI_DP83861, 115 MII_REV(ma->mii_id2)); 116 break; 117 118 case MII_MODEL_NATSEMI_DP83891: 119 printf(": %s, rev. %d\n", MII_STR_NATSEMI_DP83891, 120 MII_REV(ma->mii_id2)); 121 break; 122 } 123 124 sc->mii_inst = mii->mii_instance; 125 sc->mii_phy = ma->mii_phyno; 126 sc->mii_service = nsgphy_service; 127 sc->mii_status = nsgphy_status; 128 sc->mii_pdata = mii; 129 sc->mii_flags = mii->mii_flags; 130 131 mii_phy_reset(sc); 132 133 sc->mii_capabilities = 134 PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 135 if (sc->mii_capabilities & BMSR_EXTSTAT) 136 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); 137 if ((sc->mii_capabilities & BMSR_MEDIAMASK) || 138 (sc->mii_extcapabilities & EXTSR_MEDIAMASK)) 139 mii_phy_add_media(sc); 140 141 #if 0 142 strap = PHY_READ(sc, MII_GPHYTER_STRAP); 143 printf("%s: strapped to %s mode", sc->mii_dev.dv_xname, 144 (strap & STRAP_MS_VAL) ? "master" : "slave"); 145 if (strap & STRAP_NC_MODE) 146 printf(", pre-C5 BCM5400 compat enabled"); 147 printf("\n"); 148 #endif 149 150 #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) 151 152 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 153 BMCR_ISO); 154 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, 0, sc->mii_inst), 155 NSGPHY_S1000); 156 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, IFM_FDX, sc->mii_inst), 157 NSGPHY_S1000|NSGPHY_BMCR_FDX); 158 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, 159 sc->mii_inst), BMCR_LOOP|BMCR_S100); 160 161 #undef ADD 162 } 163 164 int 165 nsgphy_service(sc, mii, cmd) 166 struct mii_softc *sc; 167 struct mii_data *mii; 168 int cmd; 169 { 170 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 171 int reg; 172 173 if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) 174 return (ENXIO); 175 176 switch (cmd) { 177 case MII_POLLSTAT: 178 /* 179 * If we're not polling our PHY instance, just return. 180 */ 181 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 182 return (0); 183 break; 184 185 case MII_MEDIACHG: 186 /* 187 * If the media indicates a different PHY instance, 188 * isolate ourselves. 189 */ 190 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 191 reg = PHY_READ(sc, MII_BMCR); 192 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 193 return (0); 194 } 195 196 /* 197 * If the interface is not up, don't do anything. 198 */ 199 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 200 break; 201 202 switch (IFM_SUBTYPE(ife->ifm_media)) { 203 case IFM_AUTO: 204 (void) nsgphy_mii_phy_auto(sc, 0); 205 break; 206 case IFM_1000_TX: 207 if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { 208 PHY_WRITE(sc, NSGPHY_MII_BMCR, 209 NSGPHY_BMCR_FDX|NSGPHY_BMCR_SPD1); 210 } else { 211 PHY_WRITE(sc, NSGPHY_MII_BMCR, 212 NSGPHY_BMCR_SPD1); 213 } 214 PHY_WRITE(sc, NSGPHY_MII_ANAR, NSGPHY_SEL_TYPE); 215 216 /* 217 * When setting the link manually, one side must 218 * be the master and the other the slave. However 219 * ifmedia doesn't give us a good way to specify 220 * this, so we fake it by using one of the LINK 221 * flags. If LINK0 is set, we program the PHY to 222 * be a master, otherwise it's a slave. 223 */ 224 if ((mii->mii_ifp->if_flags & IFF_LINK0)) { 225 PHY_WRITE(sc, NSGPHY_MII_1000CTL, 226 NSGPHY_1000CTL_MSE|NSGPHY_1000CTL_MSC); 227 } else { 228 PHY_WRITE(sc, NSGPHY_MII_1000CTL, 229 NSGPHY_1000CTL_MSE); 230 } 231 break; 232 case IFM_100_T4: 233 /* 234 * XXX Not supported as a manual setting right now. 235 */ 236 return (EINVAL); 237 case IFM_NONE: 238 PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); 239 break; 240 default: 241 /* 242 * BMCR data is stored in the ifmedia entry. 243 */ 244 PHY_WRITE(sc, MII_ANAR, 245 mii_anar(ife->ifm_media)); 246 PHY_WRITE(sc, MII_BMCR, ife->ifm_data); 247 break; 248 } 249 break; 250 251 case MII_TICK: 252 /* 253 * If we're not currently selected, just return. 254 */ 255 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 256 return (0); 257 258 /* 259 * Only used for autonegotiation. 260 */ 261 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 262 return (0); 263 264 /* 265 * Is the interface even up? 266 */ 267 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 268 return (0); 269 270 /* 271 * Only retry autonegotiation every 5 seconds. 272 * Actually, for gigE PHYs, we should wait longer, since 273 * 5 seconds is the mimimum time the documentation 274 * says to wait for a 1000mbps link to be established. 275 */ 276 if (++sc->mii_ticks != 10) 277 return (0); 278 279 sc->mii_ticks = 0; 280 281 /* 282 * Check to see if we have link. 283 */ 284 reg = PHY_READ(sc, NSGPHY_MII_PHYSUP); 285 if (reg & NSGPHY_PHYSUP_LNKSTS) 286 break; 287 288 mii_phy_reset(sc); 289 if (nsgphy_mii_phy_auto(sc, 0) == EJUSTRETURN) 290 return(0); 291 break; 292 case MII_DOWN: 293 mii_phy_down(sc); 294 return (0); 295 } 296 297 /* Update the media status. */ 298 mii_phy_status(sc); 299 300 /* Callback if something changed. */ 301 mii_phy_update(sc, cmd); 302 return (0); 303 } 304 305 void 306 nsgphy_status(sc) 307 struct mii_softc *sc; 308 { 309 struct mii_data *mii = sc->mii_pdata; 310 int bmsr, bmcr, physup, anlpar, gstat; 311 312 mii->mii_media_status = IFM_AVALID; 313 mii->mii_media_active = IFM_ETHER; 314 315 bmsr = PHY_READ(sc, NSGPHY_MII_BMSR) | PHY_READ(sc, NSGPHY_MII_BMSR); 316 physup = PHY_READ(sc, NSGPHY_MII_PHYSUP); 317 if (physup & NSGPHY_PHYSUP_LNKSTS) 318 mii->mii_media_status |= IFM_ACTIVE; 319 320 bmcr = PHY_READ(sc, NSGPHY_MII_BMCR); 321 322 if (bmcr & NSGPHY_BMCR_LOOP) 323 mii->mii_media_active |= IFM_LOOP; 324 325 if (bmcr & NSGPHY_BMCR_AUTOEN) { 326 if ((bmsr & NSGPHY_BMSR_ACOMP) == 0) { 327 /* Erg, still trying, I guess... */ 328 mii->mii_media_active |= IFM_NONE; 329 return; 330 } 331 anlpar = PHY_READ(sc, NSGPHY_MII_ANLPAR); 332 gstat = PHY_READ(sc, NSGPHY_MII_1000STS); 333 if (gstat & NSGPHY_1000STS_LPFD) 334 mii->mii_media_active |= IFM_1000_TX|IFM_FDX; 335 else if (gstat & NSGPHY_1000STS_LPHD) 336 mii->mii_media_active |= IFM_1000_TX|IFM_HDX; 337 else if (anlpar & NSGPHY_ANLPAR_100T4) 338 mii->mii_media_active |= IFM_100_T4; 339 else if (anlpar & NSGPHY_ANLPAR_100FDX) 340 mii->mii_media_active |= IFM_100_TX|IFM_FDX; 341 else if (anlpar & NSGPHY_ANLPAR_100HDX) 342 mii->mii_media_active |= IFM_100_TX; 343 else if (anlpar & NSGPHY_ANLPAR_10FDX) 344 mii->mii_media_active |= IFM_10_T|IFM_FDX; 345 else if (anlpar & NSGPHY_ANLPAR_10HDX) 346 mii->mii_media_active |= IFM_10_T|IFM_HDX; 347 else 348 mii->mii_media_active |= IFM_NONE; 349 return; 350 } 351 352 switch(bmcr & (NSGPHY_BMCR_SPD1|NSGPHY_BMCR_SPD0)) { 353 case NSGPHY_S1000: 354 mii->mii_media_active |= IFM_1000_TX; 355 break; 356 case NSGPHY_S100: 357 mii->mii_media_active |= IFM_100_TX; 358 break; 359 case NSGPHY_S10: 360 mii->mii_media_active |= IFM_10_T; 361 break; 362 default: 363 break; 364 } 365 366 if (bmcr & NSGPHY_BMCR_FDX) 367 mii->mii_media_active |= IFM_FDX; 368 else 369 mii->mii_media_active |= IFM_HDX; 370 371 return; 372 } 373 374 375 static int 376 nsgphy_mii_phy_auto(mii, waitfor) 377 struct mii_softc *mii; 378 int waitfor; 379 { 380 int bmsr, ktcr = 0, i; 381 382 if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { 383 mii_phy_reset(mii); 384 PHY_WRITE(mii, NSGPHY_MII_BMCR, 0); 385 DELAY(1000); 386 ktcr = PHY_READ(mii, NSGPHY_MII_1000CTL); 387 PHY_WRITE(mii, NSGPHY_MII_1000CTL, ktcr | 388 (NSGPHY_1000CTL_AFD|NSGPHY_1000CTL_AHD)); 389 ktcr = PHY_READ(mii, NSGPHY_MII_1000CTL); 390 DELAY(1000); 391 PHY_WRITE(mii, NSGPHY_MII_ANAR, 392 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); 393 DELAY(1000); 394 PHY_WRITE(mii, NSGPHY_MII_BMCR, 395 NSGPHY_BMCR_AUTOEN | NSGPHY_BMCR_STARTNEG); 396 } 397 398 if (waitfor) { 399 /* Wait 500ms for it to complete. */ 400 for (i = 0; i < 500; i++) { 401 if ((bmsr = PHY_READ(mii, NSGPHY_MII_BMSR)) & 402 NSGPHY_BMSR_ACOMP) 403 return (0); 404 DELAY(1000); 405 #if 0 406 if ((bmsr & BMSR_ACOMP) == 0) 407 printf("%s: autonegotiation failed to complete\n", 408 mii->mii_dev.dv_xname); 409 #endif 410 } 411 412 /* 413 * Don't need to worry about clearing MIIF_DOINGAUTO. 414 * If that's set, a timeout is pending, and it will 415 * clear the flag. 416 */ 417 return (EIO); 418 } 419 420 /* 421 * Just let it finish asynchronously. This is for the benefit of 422 * the tick handler driving autonegotiation. Don't want 500ms 423 * delays all the time while the system is running! 424 */ 425 if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { 426 mii->mii_flags |= MIIF_DOINGAUTO; 427 timeout(mii_phy_auto_timeout, mii, hz >> 1); 428 } 429 return (EJUSTRETURN); 430 } 431