rgephy.c (164827) | rgephy.c (164830) |
---|---|
1/*- 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 164827 2006-12-02 15:32:34Z marius $"); | 34__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 164830 2006-12-02 19:36:25Z marius $"); |
35 36/* 37 * Driver for the RealTek 8169S/8110S internal 10/100/1000 PHY. 38 */ 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/module.h> 44#include <sys/socket.h> 45#include <sys/bus.h> 46 | 35 36/* 37 * Driver for the RealTek 8169S/8110S internal 10/100/1000 PHY. 38 */ 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/module.h> 44#include <sys/socket.h> 45#include <sys/bus.h> 46 |
47 | |
48#include <net/if.h> 49#include <net/if_arp.h> 50#include <net/if_media.h> 51 52#include <dev/mii/mii.h> 53#include <dev/mii/miivar.h> 54#include "miidevs.h" 55 --- 27 unchanged lines hidden (view full) --- 83DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0); 84 85static int rgephy_service(struct mii_softc *, struct mii_data *, int); 86static void rgephy_status(struct mii_softc *); 87static int rgephy_mii_phy_auto(struct mii_softc *); 88static void rgephy_reset(struct mii_softc *); 89static void rgephy_loop(struct mii_softc *); 90static void rgephy_load_dspcode(struct mii_softc *); | 47#include <net/if.h> 48#include <net/if_arp.h> 49#include <net/if_media.h> 50 51#include <dev/mii/mii.h> 52#include <dev/mii/miivar.h> 53#include "miidevs.h" 54 --- 27 unchanged lines hidden (view full) --- 82DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0); 83 84static int rgephy_service(struct mii_softc *, struct mii_data *, int); 85static void rgephy_status(struct mii_softc *); 86static int rgephy_mii_phy_auto(struct mii_softc *); 87static void rgephy_reset(struct mii_softc *); 88static void rgephy_loop(struct mii_softc *); 89static void rgephy_load_dspcode(struct mii_softc *); |
91static int rgephy_mii_model; | |
92 93static const struct mii_phydesc rgephys[] = { 94 MII_PHY_DESC(xxREALTEK, RTL8169S), 95 MII_PHY_END 96}; 97 98static int 99rgephy_probe(device_t dev) --- 29 unchanged lines hidden (view full) --- 129 130 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 131 BMCR_ISO); 132#if 0 133 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), 134 BMCR_LOOP|BMCR_S100); 135#endif 136 | 90 91static const struct mii_phydesc rgephys[] = { 92 MII_PHY_DESC(xxREALTEK, RTL8169S), 93 MII_PHY_END 94}; 95 96static int 97rgephy_probe(device_t dev) --- 29 unchanged lines hidden (view full) --- 127 128 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 129 BMCR_ISO); 130#if 0 131 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), 132 BMCR_LOOP|BMCR_S100); 133#endif 134 |
137 rgephy_mii_model = MII_MODEL(ma->mii_id2); 138 | |
139 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 140 sc->mii_capabilities &= ~BMSR_ANEG; 141 142 device_printf(dev, " "); 143 mii_add_media(sc); 144 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), 145 RGEPHY_BMCR_FDX); 146 PRINT(", 1000baseTX"); 147 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0); 148 PRINT("1000baseTX-FDX"); 149 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); 150 PRINT("auto"); 151 152 printf("\n"); 153#undef ADD 154#undef PRINT 155 156 rgephy_reset(sc); 157 MIIBUS_MEDIAINIT(sc->mii_dev); | 135 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 136 sc->mii_capabilities &= ~BMSR_ANEG; 137 138 device_printf(dev, " "); 139 mii_add_media(sc); 140 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), 141 RGEPHY_BMCR_FDX); 142 PRINT(", 1000baseTX"); 143 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0); 144 PRINT("1000baseTX-FDX"); 145 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); 146 PRINT("auto"); 147 148 printf("\n"); 149#undef ADD 150#undef PRINT 151 152 rgephy_reset(sc); 153 MIIBUS_MEDIAINIT(sc->mii_dev); |
158 return(0); | 154 return (0); |
159} 160 161static int 162rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 163{ 164 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 165 int reg, speed, gig, anar; 166 --- 66 unchanged lines hidden (view full) --- 233 PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0); 234 PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); 235 PHY_WRITE(sc, RGEPHY_MII_BMCR, speed | 236 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); 237 break; 238 } 239 240 /* | 155} 156 157static int 158rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 159{ 160 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 161 int reg, speed, gig, anar; 162 --- 66 unchanged lines hidden (view full) --- 229 PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0); 230 PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); 231 PHY_WRITE(sc, RGEPHY_MII_BMCR, speed | 232 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); 233 break; 234 } 235 236 /* |
241 * When settning the link manually, one side must | 237 * When setting the link manually, one side must |
242 * be the master and the other the slave. However 243 * ifmedia doesn't give us a good way to specify 244 * this, so we fake it by using one of the LINK 245 * flags. If LINK0 is set, we program the PHY to 246 * be a master, otherwise it's a slave. 247 */ 248 if ((mii->mii_ifp->if_flags & IFF_LINK0)) { 249 PHY_WRITE(sc, RGEPHY_MII_1000CTL, --- 42 unchanged lines hidden (view full) --- 292 */ 293 reg = PHY_READ(sc, RL_GMEDIASTAT); 294 if (reg & RL_GMEDIASTAT_LINK) 295 break; 296 297 /* 298 * Only retry autonegotiation every 5 seconds. 299 */ | 238 * be the master and the other the slave. However 239 * ifmedia doesn't give us a good way to specify 240 * this, so we fake it by using one of the LINK 241 * flags. If LINK0 is set, we program the PHY to 242 * be a master, otherwise it's a slave. 243 */ 244 if ((mii->mii_ifp->if_flags & IFF_LINK0)) { 245 PHY_WRITE(sc, RGEPHY_MII_1000CTL, --- 42 unchanged lines hidden (view full) --- 288 */ 289 reg = PHY_READ(sc, RL_GMEDIASTAT); 290 if (reg & RL_GMEDIASTAT_LINK) 291 break; 292 293 /* 294 * Only retry autonegotiation every 5 seconds. 295 */ |
300 if (++sc->mii_ticks <= 5/*10*/) | 296 if (++sc->mii_ticks <= MII_ANEGTICKS) |
301 break; | 297 break; |
302 | 298 |
303 sc->mii_ticks = 0; 304 rgephy_mii_phy_auto(sc); 305 return (0); 306 } 307 308 /* Update the media status. */ 309 rgephy_status(sc); 310 311 /* 312 * Callback if something changed. Note that we need to poke 313 * the DSP on the RealTek PHYs if the media changes. 314 * 315 */ | 299 sc->mii_ticks = 0; 300 rgephy_mii_phy_auto(sc); 301 return (0); 302 } 303 304 /* Update the media status. */ 305 rgephy_status(sc); 306 307 /* 308 * Callback if something changed. Note that we need to poke 309 * the DSP on the RealTek PHYs if the media changes. 310 * 311 */ |
316 if (sc->mii_media_active != mii->mii_media_active || | 312 if (sc->mii_media_active != mii->mii_media_active || |
317 sc->mii_media_status != mii->mii_media_status || 318 cmd == MII_MEDIACHG) { 319 rgephy_load_dspcode(sc); 320 } 321 mii_phy_update(sc, cmd); 322 return (0); 323} 324 --- 31 unchanged lines hidden (view full) --- 356 else if (bmsr & RL_GMEDIASTAT_100MBPS) 357 mii->mii_media_active |= IFM_100_TX; 358 else if (bmsr & RL_GMEDIASTAT_10MBPS) 359 mii->mii_media_active |= IFM_10_T; 360 else 361 mii->mii_media_active |= IFM_NONE; 362 if (bmsr & RL_GMEDIASTAT_FDX) 363 mii->mii_media_active |= IFM_FDX; | 313 sc->mii_media_status != mii->mii_media_status || 314 cmd == MII_MEDIACHG) { 315 rgephy_load_dspcode(sc); 316 } 317 mii_phy_update(sc, cmd); 318 return (0); 319} 320 --- 31 unchanged lines hidden (view full) --- 352 else if (bmsr & RL_GMEDIASTAT_100MBPS) 353 mii->mii_media_active |= IFM_100_TX; 354 else if (bmsr & RL_GMEDIASTAT_10MBPS) 355 mii->mii_media_active |= IFM_10_T; 356 else 357 mii->mii_media_active |= IFM_NONE; 358 if (bmsr & RL_GMEDIASTAT_FDX) 359 mii->mii_media_active |= IFM_FDX; |
364 365 return; | |
366} 367 | 360} 361 |
368 | |
369static int 370rgephy_mii_phy_auto(struct mii_softc *mii) 371{ | 362static int 363rgephy_mii_phy_auto(struct mii_softc *mii) 364{ |
365 |
|
372 rgephy_loop(mii); 373 rgephy_reset(mii); 374 375 PHY_WRITE(mii, RGEPHY_MII_ANAR, 376 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); 377 DELAY(1000); 378 PHY_WRITE(mii, RGEPHY_MII_1000CTL, 379 RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD); 380 DELAY(1000); 381 PHY_WRITE(mii, RGEPHY_MII_BMCR, 382 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); 383 DELAY(100); 384 385 return (EJUSTRETURN); 386} 387 388static void 389rgephy_loop(struct mii_softc *sc) 390{ | 366 rgephy_loop(mii); 367 rgephy_reset(mii); 368 369 PHY_WRITE(mii, RGEPHY_MII_ANAR, 370 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); 371 DELAY(1000); 372 PHY_WRITE(mii, RGEPHY_MII_1000CTL, 373 RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD); 374 DELAY(1000); 375 PHY_WRITE(mii, RGEPHY_MII_BMCR, 376 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); 377 DELAY(100); 378 379 return (EJUSTRETURN); 380} 381 382static void 383rgephy_loop(struct mii_softc *sc) 384{ |
391 u_int32_t bmsr; | |
392 int i; 393 394 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); 395 DELAY(1000); 396 397 for (i = 0; i < 15000; i++) { | 385 int i; 386 387 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); 388 DELAY(1000); 389 390 for (i = 0; i < 15000; i++) { |
398 bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); 399 if (!(bmsr & RGEPHY_BMSR_LINK)) { | 391 if (!(PHY_READ(sc, RGEPHY_MII_BMSR) & RGEPHY_BMSR_LINK)) { |
400#if 0 401 device_printf(sc->mii_dev, "looped %d\n", i); 402#endif 403 break; 404 } 405 DELAY(10); 406 } 407} --- 55 unchanged lines hidden (view full) --- 463 PHY_WRITE(sc, 4, val); 464 PHY_WRITE(sc, 3, 0xDF01); 465 PHY_WRITE(sc, 2, 0xDF20); 466 PHY_WRITE(sc, 1, 0xFF95); 467 PHY_WRITE(sc, 0, 0xBF00); 468 PHY_SETBIT(sc, 4, 0x0800); 469 PHY_CLRBIT(sc, 4, 0x0800); 470 PHY_WRITE(sc, 31, 0x0000); | 392#if 0 393 device_printf(sc->mii_dev, "looped %d\n", i); 394#endif 395 break; 396 } 397 DELAY(10); 398 } 399} --- 55 unchanged lines hidden (view full) --- 455 PHY_WRITE(sc, 4, val); 456 PHY_WRITE(sc, 3, 0xDF01); 457 PHY_WRITE(sc, 2, 0xDF20); 458 PHY_WRITE(sc, 1, 0xFF95); 459 PHY_WRITE(sc, 0, 0xBF00); 460 PHY_SETBIT(sc, 4, 0x0800); 461 PHY_CLRBIT(sc, 4, 0x0800); 462 PHY_WRITE(sc, 31, 0x0000); |
471 | 463 |
472 DELAY(40); 473} 474 475static void 476rgephy_reset(struct mii_softc *sc) 477{ | 464 DELAY(40); 465} 466 467static void 468rgephy_reset(struct mii_softc *sc) 469{ |
470 |
|
478 mii_phy_reset(sc); 479 DELAY(1000); 480 rgephy_load_dspcode(sc); | 471 mii_phy_reset(sc); 472 DELAY(1000); 473 rgephy_load_dspcode(sc); |
481 482 return; | |
483} | 474} |