rgephy.c (51dd214c84efceda87c2ac10d34b7e3ee5b6c28f) | rgephy.c (72200a8ab5fcb903f8d9908c63a8c3dde456e906) |
---|---|
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 --- 73 unchanged lines hidden (view full) --- 82}; 83 84DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0); 85 86static int rgephy_service(struct mii_softc *, struct mii_data *, int); 87static void rgephy_status(struct mii_softc *); 88static int rgephy_mii_phy_auto(struct mii_softc *, int); 89static void rgephy_reset(struct mii_softc *); | 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 --- 73 unchanged lines hidden (view full) --- 82}; 83 84DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0); 85 86static int rgephy_service(struct mii_softc *, struct mii_data *, int); 87static void rgephy_status(struct mii_softc *); 88static int rgephy_mii_phy_auto(struct mii_softc *, int); 89static void rgephy_reset(struct mii_softc *); |
90static int rgephy_linkup(struct mii_softc *); |
|
90static void rgephy_loop(struct mii_softc *); 91static void rgephy_load_dspcode(struct mii_softc *); 92 93static const struct mii_phydesc rgephys[] = { 94 MII_PHY_DESC(REALTEK, RTL8169S), 95 MII_PHY_DESC(REALTEK, RTL8251), 96 MII_PHY_END 97}; --- 44 unchanged lines hidden (view full) --- 142 MIIBUS_MEDIAINIT(sc->mii_dev); 143 return (0); 144} 145 146static int 147rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 148{ 149 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; | 91static void rgephy_loop(struct mii_softc *); 92static void rgephy_load_dspcode(struct mii_softc *); 93 94static const struct mii_phydesc rgephys[] = { 95 MII_PHY_DESC(REALTEK, RTL8169S), 96 MII_PHY_DESC(REALTEK, RTL8251), 97 MII_PHY_END 98}; --- 44 unchanged lines hidden (view full) --- 143 MIIBUS_MEDIAINIT(sc->mii_dev); 144 return (0); 145} 146 147static int 148rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 149{ 150 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; |
150 int reg, speed, gig, anar; | 151 int speed, gig, anar; |
151 152 switch (cmd) { 153 case MII_POLLSTAT: 154 break; 155 156 case MII_MEDIACHG: 157 PHY_RESET(sc); /* XXX hardware bug work-around */ 158 --- 73 unchanged lines hidden (view full) --- 232 sc->mii_ticks = 0; 233 break; 234 } 235 236 /* 237 * Check to see if we have link. If we do, we don't 238 * need to restart the autonegotiation process. 239 */ | 152 153 switch (cmd) { 154 case MII_POLLSTAT: 155 break; 156 157 case MII_MEDIACHG: 158 PHY_RESET(sc); /* XXX hardware bug work-around */ 159 --- 73 unchanged lines hidden (view full) --- 233 sc->mii_ticks = 0; 234 break; 235 } 236 237 /* 238 * Check to see if we have link. If we do, we don't 239 * need to restart the autonegotiation process. 240 */ |
240 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && 241 sc->mii_mpd_rev >= 2) { 242 /* RTL8211B(L) */ 243 reg = PHY_READ(sc, RGEPHY_MII_SSR); 244 if (reg & RGEPHY_SSR_LINK) { 245 sc->mii_ticks = 0; 246 break; 247 } 248 } else { 249 reg = PHY_READ(sc, RL_GMEDIASTAT); 250 if (reg & RL_GMEDIASTAT_LINK) { 251 sc->mii_ticks = 0; 252 break; 253 } | 241 if (rgephy_linkup(sc) != 0) { 242 sc->mii_ticks = 0; 243 break; |
254 } 255 256 /* Announce link loss right after it happens. */ 257 if (sc->mii_ticks++ == 0) 258 break; 259 260 /* Only retry autonegotiation every mii_anegticks seconds. */ 261 if (sc->mii_ticks <= sc->mii_anegticks) --- 16 unchanged lines hidden (view full) --- 278 sc->mii_media_status != mii->mii_media_status || 279 cmd == MII_MEDIACHG) { 280 rgephy_load_dspcode(sc); 281 } 282 mii_phy_update(sc, cmd); 283 return (0); 284} 285 | 244 } 245 246 /* Announce link loss right after it happens. */ 247 if (sc->mii_ticks++ == 0) 248 break; 249 250 /* Only retry autonegotiation every mii_anegticks seconds. */ 251 if (sc->mii_ticks <= sc->mii_anegticks) --- 16 unchanged lines hidden (view full) --- 268 sc->mii_media_status != mii->mii_media_status || 269 cmd == MII_MEDIACHG) { 270 rgephy_load_dspcode(sc); 271 } 272 mii_phy_update(sc, cmd); 273 return (0); 274} 275 |
276static int 277rgephy_linkup(struct mii_softc *sc) 278{ 279 int linkup; 280 uint16_t reg; 281 282 linkup = 0; 283 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && 284 sc->mii_mpd_rev >= RGEPHY_8211B) { 285 if (sc->mii_mpd_rev == RGEPHY_8211F) { 286 reg = PHY_READ(sc, RGEPHY_F_MII_SSR); 287 if (reg & RGEPHY_F_SSR_LINK) 288 linkup++; 289 } else { 290 reg = PHY_READ(sc, RGEPHY_MII_SSR); 291 if (reg & RGEPHY_SSR_LINK) 292 linkup++; 293 } 294 } else { 295 reg = PHY_READ(sc, RL_GMEDIASTAT); 296 if (reg & RL_GMEDIASTAT_LINK) 297 linkup++; 298 } 299 300 return (linkup); 301} 302 |
|
286static void 287rgephy_status(struct mii_softc *sc) 288{ 289 struct mii_data *mii = sc->mii_pdata; 290 int bmsr, bmcr; 291 uint16_t ssr; 292 293 mii->mii_media_status = IFM_AVALID; 294 mii->mii_media_active = IFM_ETHER; 295 | 303static void 304rgephy_status(struct mii_softc *sc) 305{ 306 struct mii_data *mii = sc->mii_pdata; 307 int bmsr, bmcr; 308 uint16_t ssr; 309 310 mii->mii_media_status = IFM_AVALID; 311 mii->mii_media_active = IFM_ETHER; 312 |
296 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { 297 ssr = PHY_READ(sc, RGEPHY_MII_SSR); 298 if (ssr & RGEPHY_SSR_LINK) 299 mii->mii_media_status |= IFM_ACTIVE; 300 } else { 301 bmsr = PHY_READ(sc, RL_GMEDIASTAT); 302 if (bmsr & RL_GMEDIASTAT_LINK) 303 mii->mii_media_status |= IFM_ACTIVE; 304 } | 313 if (rgephy_linkup(sc) != 0) 314 mii->mii_media_status |= IFM_ACTIVE; |
305 306 bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); | 315 316 bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); |
307 | |
308 bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); 309 if (bmcr & RGEPHY_BMCR_ISO) { 310 mii->mii_media_active |= IFM_NONE; 311 mii->mii_media_status = 0; 312 return; 313 } 314 315 if (bmcr & RGEPHY_BMCR_LOOP) 316 mii->mii_media_active |= IFM_LOOP; 317 318 if (bmcr & RGEPHY_BMCR_AUTOEN) { 319 if ((bmsr & RGEPHY_BMSR_ACOMP) == 0) { 320 /* Erg, still trying, I guess... */ 321 mii->mii_media_active |= IFM_NONE; 322 return; 323 } 324 } 325 | 317 bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); 318 if (bmcr & RGEPHY_BMCR_ISO) { 319 mii->mii_media_active |= IFM_NONE; 320 mii->mii_media_status = 0; 321 return; 322 } 323 324 if (bmcr & RGEPHY_BMCR_LOOP) 325 mii->mii_media_active |= IFM_LOOP; 326 327 if (bmcr & RGEPHY_BMCR_AUTOEN) { 328 if ((bmsr & RGEPHY_BMSR_ACOMP) == 0) { 329 /* Erg, still trying, I guess... */ 330 mii->mii_media_active |= IFM_NONE; 331 return; 332 } 333 } 334 |
326 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { 327 ssr = PHY_READ(sc, RGEPHY_MII_SSR); 328 switch (ssr & RGEPHY_SSR_SPD_MASK) { 329 case RGEPHY_SSR_S1000: 330 mii->mii_media_active |= IFM_1000_T; 331 break; 332 case RGEPHY_SSR_S100: 333 mii->mii_media_active |= IFM_100_TX; 334 break; 335 case RGEPHY_SSR_S10: 336 mii->mii_media_active |= IFM_10_T; 337 break; 338 default: 339 mii->mii_media_active |= IFM_NONE; 340 break; | 335 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && 336 sc->mii_mpd_rev >= RGEPHY_8211B) { 337 if (sc->mii_mpd_rev == RGEPHY_8211F) { 338 ssr = PHY_READ(sc, RGEPHY_F_MII_SSR); 339 switch (ssr & RGEPHY_F_SSR_SPD_MASK) { 340 case RGEPHY_F_SSR_S1000: 341 mii->mii_media_active |= IFM_1000_T; 342 break; 343 case RGEPHY_F_SSR_S100: 344 mii->mii_media_active |= IFM_100_TX; 345 break; 346 case RGEPHY_F_SSR_S10: 347 mii->mii_media_active |= IFM_10_T; 348 break; 349 default: 350 mii->mii_media_active |= IFM_NONE; 351 break; 352 } 353 if (ssr & RGEPHY_F_SSR_FDX) 354 mii->mii_media_active |= IFM_FDX; 355 else 356 mii->mii_media_active |= IFM_HDX; 357 358 } else { 359 ssr = PHY_READ(sc, RGEPHY_MII_SSR); 360 switch (ssr & RGEPHY_SSR_SPD_MASK) { 361 case RGEPHY_SSR_S1000: 362 mii->mii_media_active |= IFM_1000_T; 363 break; 364 case RGEPHY_SSR_S100: 365 mii->mii_media_active |= IFM_100_TX; 366 break; 367 case RGEPHY_SSR_S10: 368 mii->mii_media_active |= IFM_10_T; 369 break; 370 default: 371 mii->mii_media_active |= IFM_NONE; 372 break; 373 } 374 if (ssr & RGEPHY_SSR_FDX) 375 mii->mii_media_active |= IFM_FDX; 376 else 377 mii->mii_media_active |= IFM_HDX; |
341 } | 378 } |
342 if (ssr & RGEPHY_SSR_FDX) 343 mii->mii_media_active |= IFM_FDX; 344 else 345 mii->mii_media_active |= IFM_HDX; | |
346 } else { 347 bmsr = PHY_READ(sc, RL_GMEDIASTAT); 348 if (bmsr & RL_GMEDIASTAT_1000MBPS) 349 mii->mii_media_active |= IFM_1000_T; 350 else if (bmsr & RL_GMEDIASTAT_100MBPS) 351 mii->mii_media_active |= IFM_100_TX; 352 else if (bmsr & RL_GMEDIASTAT_10MBPS) 353 mii->mii_media_active |= IFM_10_T; --- 37 unchanged lines hidden (view full) --- 391} 392 393static void 394rgephy_loop(struct mii_softc *sc) 395{ 396 int i; 397 398 if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 && | 379 } else { 380 bmsr = PHY_READ(sc, RL_GMEDIASTAT); 381 if (bmsr & RL_GMEDIASTAT_1000MBPS) 382 mii->mii_media_active |= IFM_1000_T; 383 else if (bmsr & RL_GMEDIASTAT_100MBPS) 384 mii->mii_media_active |= IFM_100_TX; 385 else if (bmsr & RL_GMEDIASTAT_10MBPS) 386 mii->mii_media_active |= IFM_10_T; --- 37 unchanged lines hidden (view full) --- 424} 425 426static void 427rgephy_loop(struct mii_softc *sc) 428{ 429 int i; 430 431 if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 && |
399 sc->mii_mpd_rev < 2) { | 432 sc->mii_mpd_rev < RGEPHY_8211B) { |
400 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); 401 DELAY(1000); 402 } 403 404 for (i = 0; i < 15000; i++) { 405 if (!(PHY_READ(sc, RGEPHY_MII_BMSR) & RGEPHY_BMSR_LINK)) { 406#if 0 407 device_printf(sc->mii_dev, "looped %d\n", i); --- 17 unchanged lines hidden (view full) --- 425 * any fixups. 426 */ 427static void 428rgephy_load_dspcode(struct mii_softc *sc) 429{ 430 int val; 431 432 if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 || | 433 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); 434 DELAY(1000); 435 } 436 437 for (i = 0; i < 15000; i++) { 438 if (!(PHY_READ(sc, RGEPHY_MII_BMSR) & RGEPHY_BMSR_LINK)) { 439#if 0 440 device_printf(sc->mii_dev, "looped %d\n", i); --- 17 unchanged lines hidden (view full) --- 458 * any fixups. 459 */ 460static void 461rgephy_load_dspcode(struct mii_softc *sc) 462{ 463 int val; 464 465 if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 || |
433 sc->mii_mpd_rev >= 2) | 466 sc->mii_mpd_rev >= RGEPHY_8211B) |
434 return; 435 436 PHY_WRITE(sc, 31, 0x0001); 437 PHY_WRITE(sc, 21, 0x1000); 438 PHY_WRITE(sc, 24, 0x65C7); 439 PHY_CLRBIT(sc, 4, 0x0800); 440 val = PHY_READ(sc, 4) & 0xFFF; 441 PHY_WRITE(sc, 4, val); --- 34 unchanged lines hidden (view full) --- 476 DELAY(40); 477} 478 479static void 480rgephy_reset(struct mii_softc *sc) 481{ 482 uint16_t pcr, ssr; 483 | 467 return; 468 469 PHY_WRITE(sc, 31, 0x0001); 470 PHY_WRITE(sc, 21, 0x1000); 471 PHY_WRITE(sc, 24, 0x65C7); 472 PHY_CLRBIT(sc, 4, 0x0800); 473 val = PHY_READ(sc, 4) & 0xFFF; 474 PHY_WRITE(sc, 4, val); --- 34 unchanged lines hidden (view full) --- 509 DELAY(40); 510} 511 512static void 513rgephy_reset(struct mii_softc *sc) 514{ 515 uint16_t pcr, ssr; 516 |
484 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) { 485 /* RTL8211C(L) */ 486 ssr = PHY_READ(sc, RGEPHY_MII_SSR); 487 if ((ssr & RGEPHY_SSR_ALDPS) != 0) { 488 ssr &= ~RGEPHY_SSR_ALDPS; 489 PHY_WRITE(sc, RGEPHY_MII_SSR, ssr); | 517 switch (sc->mii_mpd_rev) { 518 case RGEPHY_8211F: 519 pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1); 520 if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) { 521 pcr &= ~RGEPHY_F_PCR1_MDI_MM; 522 PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr); |
490 } | 523 } |
491 } 492 493 if (sc->mii_mpd_rev >= 2) { 494 pcr = PHY_READ(sc, RGEPHY_MII_PCR); 495 if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) { 496 pcr &= ~RGEPHY_PCR_MDI_MASK; 497 pcr |= RGEPHY_PCR_MDIX_AUTO; 498 PHY_WRITE(sc, RGEPHY_MII_PCR, pcr); | 524 break; 525 case RGEPHY_8211C: 526 if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) { 527 /* RTL8211C(L) */ 528 ssr = PHY_READ(sc, RGEPHY_MII_SSR); 529 if ((ssr & RGEPHY_SSR_ALDPS) != 0) { 530 ssr &= ~RGEPHY_SSR_ALDPS; 531 PHY_WRITE(sc, RGEPHY_MII_SSR, ssr); 532 } |
499 } | 533 } |
534 break; 535 default: 536 if (sc->mii_mpd_rev >= RGEPHY_8211B) { 537 pcr = PHY_READ(sc, RGEPHY_MII_PCR); 538 if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) { 539 pcr &= ~RGEPHY_PCR_MDI_MASK; 540 pcr |= RGEPHY_PCR_MDIX_AUTO; 541 PHY_WRITE(sc, RGEPHY_MII_PCR, pcr); 542 } 543 } 544 break; |
|
500 } 501 502 mii_phy_reset(sc); 503 DELAY(1000); 504 rgephy_load_dspcode(sc); 505} | 545 } 546 547 mii_phy_reset(sc); 548 DELAY(1000); 549 rgephy_load_dspcode(sc); 550} |