1 /*- 2 * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: src/sys/dev/mii/atphy.c,v 1.3 2008/10/25 06:39:17 yongari Exp $ 28 */ 29 30 /* 31 * Driver for the Attansic/Atheros F1 10/100/1000 PHY. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/kernel.h> 37 38 #include <net/if.h> 39 #include <net/if_media.h> 40 41 #include <dev/netif/mii_layer/mii.h> 42 #include <dev/netif/mii_layer/miivar.h> 43 #include <dev/netif/mii_layer/atphyreg.h> 44 45 #include "miibus_if.h" 46 #include "miidevs.h" 47 48 static int atphy_probe(device_t); 49 static int atphy_attach(device_t); 50 static int atphy_service(struct mii_softc *, struct mii_data *, int); 51 static void atphy_status(struct mii_softc *); 52 static void atphy_reset(struct mii_softc *); 53 static uint16_t atphy_anar(struct ifmedia_entry *); 54 static void atphy_auto(struct mii_softc *); 55 56 static device_method_t atphy_methods[] = { 57 /* Device interface. */ 58 DEVMETHOD(device_probe, atphy_probe), 59 DEVMETHOD(device_attach, atphy_attach), 60 DEVMETHOD(device_detach, ukphy_detach), 61 DEVMETHOD(device_shutdown, bus_generic_shutdown), 62 DEVMETHOD_END 63 }; 64 65 static const struct mii_phydesc atphys[] = { 66 MII_PHYDESC(ATHEROS, F1), 67 MII_PHYDESC(ATHEROS, F1_7), 68 MII_PHYDESC(ATHEROS, F2), 69 MII_PHYDESC_NULL 70 }; 71 72 static devclass_t atphy_devclass; 73 74 static driver_t atphy_driver = { 75 "atphy", 76 atphy_methods, 77 sizeof(struct mii_softc) 78 }; 79 80 DRIVER_MODULE(atphy, miibus, atphy_driver, atphy_devclass, NULL, NULL); 81 82 static int 83 atphy_probe(device_t dev) 84 { 85 struct mii_attach_args *ma = device_get_ivars(dev); 86 const struct mii_phydesc *mpd; 87 88 mpd = mii_phy_match(ma, atphys); 89 if (mpd != NULL) { 90 device_set_desc(dev, mpd->mpd_name); 91 return 0; 92 } 93 return ENXIO; 94 } 95 96 static int 97 atphy_attach(device_t dev) 98 { 99 struct mii_softc *sc; 100 struct mii_attach_args *ma; 101 struct mii_data *mii; 102 103 sc = device_get_softc(dev); 104 ma = device_get_ivars(dev); 105 106 mii_softc_init(sc, ma); 107 sc->mii_dev = device_get_parent(dev); 108 mii = device_get_softc(sc->mii_dev); 109 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 110 111 sc->mii_inst = mii->mii_instance; 112 sc->mii_service = atphy_service; 113 sc->mii_pdata = mii; 114 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 115 116 mii->mii_instance++; 117 118 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 119 if (sc->mii_capabilities & BMSR_EXTSTAT) 120 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); 121 122 device_printf(dev, " "); 123 if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 && 124 (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0) 125 kprintf("no media present"); 126 else 127 mii_phy_add_media(sc); 128 kprintf("\n"); 129 130 atphy_reset(sc); 131 132 MIIBUS_MEDIAINIT(sc->mii_dev); 133 return 0; 134 } 135 136 static int 137 atphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 138 { 139 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 140 uint16_t anar, bmcr, bmsr; 141 142 switch (cmd) { 143 case MII_POLLSTAT: 144 /* 145 * If we're not polling our PHY instance, just return. 146 */ 147 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 148 return 0; 149 break; 150 151 case MII_MEDIACHG: 152 /* 153 * If the media indicates a different PHY instance, 154 * isolate ourselves. 155 */ 156 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 157 bmcr = PHY_READ(sc, MII_BMCR); 158 PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO); 159 return 0; 160 } 161 162 /* 163 * If the interface is not up, don't do anything. 164 */ 165 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 166 break; 167 168 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO || 169 IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { 170 atphy_auto(sc); 171 break; 172 } 173 174 bmcr = 0; 175 switch (IFM_SUBTYPE(ife->ifm_media)) { 176 case IFM_100_TX: 177 bmcr = BMCR_S100; 178 break; 179 180 case IFM_10_T: 181 bmcr = BMCR_S10; 182 break; 183 184 case IFM_NONE: 185 bmcr = PHY_READ(sc, MII_BMCR); 186 /* 187 * XXX 188 * Due to an unknown reason powering down PHY resulted 189 * in unexpected results such as inaccessbility of 190 * hardware of freshly rebooted system. Disable 191 * powering down PHY until I got more information for 192 * Attansic/Atheros PHY hardwares. 193 */ 194 PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO); 195 goto done; 196 197 default: 198 return EINVAL; 199 } 200 201 anar = atphy_anar(ife); 202 if ((ife->ifm_media & IFM_GMASK) & IFM_FDX) { 203 bmcr |= BMCR_FDX; 204 /* Enable pause. */ 205 anar |= (3 << 10); 206 } 207 208 if (sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) 209 PHY_WRITE(sc, MII_100T2CR, 0); 210 PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA); 211 212 /* 213 * Reset the PHY so all changes take effect. 214 */ 215 PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_RESET | BMCR_AUTOEN | 216 BMCR_STARTNEG); 217 done: 218 break; 219 220 case MII_TICK: 221 /* 222 * If we're not currently selected, just return. 223 */ 224 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 225 return 0; 226 227 /* 228 * Is the interface even up? 229 */ 230 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 231 return 0; 232 233 /* 234 * Only used for autonegotiation. 235 */ 236 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { 237 sc->mii_ticks = 0; 238 break; 239 } 240 241 /* 242 * check for link. 243 * Read the status register twice; BMSR_LINK is latch-low. 244 */ 245 bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 246 if (bmsr & BMSR_LINK) { 247 sc->mii_ticks = 0; 248 break; 249 } 250 251 /* Announce link loss right after it happens. */ 252 if (sc->mii_ticks++ == 0) 253 break; 254 if (sc->mii_ticks <= sc->mii_anegticks) 255 return 0; 256 257 sc->mii_ticks = 0; 258 atphy_auto(sc); 259 break; 260 } 261 262 /* Update the media status. */ 263 atphy_status(sc); 264 265 /* Callback if something changed. */ 266 mii_phy_update(sc, cmd); 267 return 0; 268 } 269 270 static void 271 atphy_status(struct mii_softc *sc) 272 { 273 struct mii_data *mii = sc->mii_pdata; 274 uint32_t bmsr, bmcr, ssr; 275 276 mii->mii_media_status = IFM_AVALID; 277 mii->mii_media_active = IFM_ETHER; 278 279 bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 280 if (bmsr & BMSR_LINK) 281 mii->mii_media_status |= IFM_ACTIVE; 282 283 bmcr = PHY_READ(sc, MII_BMCR); 284 if (bmcr & BMCR_ISO) { 285 mii->mii_media_active |= IFM_NONE; 286 mii->mii_media_status = 0; 287 return; 288 } 289 290 if (bmcr & BMCR_LOOP) 291 mii->mii_media_active |= IFM_LOOP; 292 293 ssr = PHY_READ(sc, ATPHY_SSR); 294 if ((ssr & ATPHY_SSR_SPD_DPLX_RESOLVED) == 0) { 295 /* Erg, still trying, I guess... */ 296 mii->mii_media_active |= IFM_NONE; 297 return; 298 } 299 300 switch (ssr & ATPHY_SSR_SPEED_MASK) { 301 case ATPHY_SSR_1000MBS: 302 mii->mii_media_active |= IFM_1000_T; 303 /* 304 * atphy(4) got a valid link so reset mii_ticks. 305 * Resetting mii_ticks is needed in order to 306 * detect link loss after auto-negotiation. 307 */ 308 sc->mii_ticks = 0; 309 break; 310 311 case ATPHY_SSR_100MBS: 312 mii->mii_media_active |= IFM_100_TX; 313 sc->mii_ticks = 0; 314 break; 315 316 case ATPHY_SSR_10MBS: 317 mii->mii_media_active |= IFM_10_T; 318 sc->mii_ticks = 0; 319 break; 320 321 default: 322 mii->mii_media_active |= IFM_NONE; 323 return; 324 } 325 326 if (ssr & ATPHY_SSR_DUPLEX) 327 mii->mii_media_active |= IFM_FDX; 328 else 329 mii->mii_media_active |= IFM_HDX; 330 331 /* XXX Master/Slave, Flow-control */ 332 } 333 334 static void 335 atphy_reset(struct mii_softc *sc) 336 { 337 uint32_t reg; 338 int i; 339 340 /* Take PHY out of power down mode. */ 341 PHY_WRITE(sc, 29, 0x29); 342 PHY_WRITE(sc, 30, 0); 343 344 reg = PHY_READ(sc, ATPHY_SCR); 345 /* Enable automatic crossover. */ 346 reg |= ATPHY_SCR_AUTO_X_MODE; 347 /* Disable power down. */ 348 reg &= ~ATPHY_SCR_MAC_PDOWN; 349 /* Enable CRS on Tx. */ 350 reg |= ATPHY_SCR_ASSERT_CRS_ON_TX; 351 /* Auto correction for reversed cable polarity. */ 352 reg |= ATPHY_SCR_POLARITY_REVERSAL; 353 PHY_WRITE(sc, ATPHY_SCR, reg); 354 355 /* Workaround F1 bug to reset phy. */ 356 atphy_auto(sc); 357 358 for (i = 0; i < 1000; i++) { 359 DELAY(1); 360 if ((PHY_READ(sc, MII_BMCR) & BMCR_RESET) == 0) 361 break; 362 } 363 } 364 365 static uint16_t 366 atphy_anar(struct ifmedia_entry *ife) 367 { 368 uint16_t anar = 0; 369 370 switch (IFM_SUBTYPE(ife->ifm_media)) { 371 case IFM_AUTO: 372 anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; 373 return anar; 374 375 case IFM_1000_T: 376 return anar; 377 378 case IFM_100_TX: 379 anar |= ANAR_TX; 380 break; 381 382 case IFM_10_T: 383 anar |= ANAR_10; 384 break; 385 386 default: 387 return 0; 388 } 389 390 if ((ife->ifm_media & IFM_GMASK) & IFM_FDX) { 391 if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX) 392 anar |= ANAR_TX_FD; 393 else 394 anar |= ANAR_10_FD; 395 } 396 return anar; 397 } 398 399 static void 400 atphy_auto(struct mii_softc *sc) 401 { 402 uint16_t anar; 403 404 anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities); 405 PHY_WRITE(sc, MII_ANAR, anar | (3 << 10) | ANAR_CSMA); 406 407 if (sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) { 408 PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | 409 GTCR_ADV_1000THDX); 410 } else if (sc->mii_model == MII_MODEL_ATHEROS_F1) { 411 /* 412 * AR8132 has 10/100 PHY and the PHY uses the same 413 * model number of F1 gigabit PHY. The PHY has no 414 * ability to establish gigabit link so explicitly 415 * disable 1000baseT configuration for the PHY. 416 * Otherwise, there is a case that atphy(4) could 417 * not establish a link against gigabit link partner 418 * unless the link partner supports down-shifting. 419 */ 420 PHY_WRITE(sc, MII_100T2CR, 0); 421 } 422 PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); 423 } 424