|
Lines 87-92
static int rgephy_service(struct mii_softc *, stru
Link Here
|
| 87 |
static void rgephy_status(struct mii_softc *); |
87 |
static void rgephy_status(struct mii_softc *); |
| 88 |
static int rgephy_mii_phy_auto(struct mii_softc *, int); |
88 |
static int rgephy_mii_phy_auto(struct mii_softc *, int); |
| 89 |
static void rgephy_reset(struct mii_softc *); |
89 |
static void rgephy_reset(struct mii_softc *); |
|
|
90 |
static int rgephy_linkup(struct mii_softc *); |
| 90 |
static void rgephy_loop(struct mii_softc *); |
91 |
static void rgephy_loop(struct mii_softc *); |
| 91 |
static void rgephy_load_dspcode(struct mii_softc *); |
92 |
static void rgephy_load_dspcode(struct mii_softc *); |
| 92 |
|
93 |
|
|
Lines 147-153
static int
Link Here
|
| 147 |
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) |
148 |
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) |
| 148 |
{ |
149 |
{ |
| 149 |
struct ifmedia_entry *ife = mii->mii_media.ifm_cur; |
150 |
struct ifmedia_entry *ife = mii->mii_media.ifm_cur; |
| 150 |
int reg, speed, gig, anar; |
151 |
int speed, gig, anar; |
| 151 |
|
152 |
|
| 152 |
switch (cmd) { |
153 |
switch (cmd) { |
| 153 |
case MII_POLLSTAT: |
154 |
case MII_POLLSTAT: |
|
Lines 237-256
setit:
Link Here
|
| 237 |
* Check to see if we have link. If we do, we don't |
238 |
* Check to see if we have link. If we do, we don't |
| 238 |
* need to restart the autonegotiation process. |
239 |
* need to restart the autonegotiation process. |
| 239 |
*/ |
240 |
*/ |
| 240 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && |
241 |
if (rgephy_linkup(sc) != 0) { |
| 241 |
sc->mii_mpd_rev >= 2) { |
242 |
sc->mii_ticks = 0; |
| 242 |
/* RTL8211B(L) */ |
243 |
break; |
| 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 |
} |
| 254 |
} |
244 |
} |
| 255 |
|
245 |
|
| 256 |
/* Announce link loss right after it happens. */ |
246 |
/* Announce link loss right after it happens. */ |
|
Lines 283-288
setit:
Link Here
|
| 283 |
return (0); |
273 |
return (0); |
| 284 |
} |
274 |
} |
| 285 |
|
275 |
|
|
|
276 |
static int |
| 277 |
rgephy_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 |
|
| 286 |
static void |
303 |
static void |
| 287 |
rgephy_status(struct mii_softc *sc) |
304 |
rgephy_status(struct mii_softc *sc) |
| 288 |
{ |
305 |
{ |
|
Lines 293-310
rgephy_status(struct mii_softc *sc)
Link Here
|
| 293 |
mii->mii_media_status = IFM_AVALID; |
310 |
mii->mii_media_status = IFM_AVALID; |
| 294 |
mii->mii_media_active = IFM_ETHER; |
311 |
mii->mii_media_active = IFM_ETHER; |
| 295 |
|
312 |
|
| 296 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { |
313 |
if (rgephy_linkup(sc) != 0) |
| 297 |
ssr = PHY_READ(sc, RGEPHY_MII_SSR); |
314 |
mii->mii_media_status |= IFM_ACTIVE; |
| 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 |
} |
| 305 |
|
315 |
|
| 306 |
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); |
316 |
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); |
| 307 |
|
|
|
| 308 |
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); |
317 |
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); |
| 309 |
if (bmcr & RGEPHY_BMCR_ISO) { |
318 |
if (bmcr & RGEPHY_BMCR_ISO) { |
| 310 |
mii->mii_media_active |= IFM_NONE; |
319 |
mii->mii_media_active |= IFM_NONE; |
|
Lines 323-348
rgephy_status(struct mii_softc *sc)
Link Here
|
| 323 |
} |
332 |
} |
| 324 |
} |
333 |
} |
| 325 |
|
334 |
|
| 326 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { |
335 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && |
| 327 |
ssr = PHY_READ(sc, RGEPHY_MII_SSR); |
336 |
sc->mii_mpd_rev >= RGEPHY_8211B) { |
| 328 |
switch (ssr & RGEPHY_SSR_SPD_MASK) { |
337 |
if (sc->mii_mpd_rev == RGEPHY_8211F) { |
| 329 |
case RGEPHY_SSR_S1000: |
338 |
ssr = PHY_READ(sc, RGEPHY_F_MII_SSR); |
| 330 |
mii->mii_media_active |= IFM_1000_T; |
339 |
switch (ssr & RGEPHY_F_SSR_SPD_MASK) { |
| 331 |
break; |
340 |
case RGEPHY_F_SSR_S1000: |
| 332 |
case RGEPHY_SSR_S100: |
341 |
mii->mii_media_active |= IFM_1000_T; |
| 333 |
mii->mii_media_active |= IFM_100_TX; |
342 |
break; |
| 334 |
break; |
343 |
case RGEPHY_F_SSR_S100: |
| 335 |
case RGEPHY_SSR_S10: |
344 |
mii->mii_media_active |= IFM_100_TX; |
| 336 |
mii->mii_media_active |= IFM_10_T; |
345 |
break; |
| 337 |
break; |
346 |
case RGEPHY_F_SSR_S10: |
| 338 |
default: |
347 |
mii->mii_media_active |= IFM_10_T; |
| 339 |
mii->mii_media_active |= IFM_NONE; |
348 |
break; |
| 340 |
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 { |
379 |
} else { |
| 347 |
bmsr = PHY_READ(sc, RL_GMEDIASTAT); |
380 |
bmsr = PHY_READ(sc, RL_GMEDIASTAT); |
| 348 |
if (bmsr & RL_GMEDIASTAT_1000MBPS) |
381 |
if (bmsr & RL_GMEDIASTAT_1000MBPS) |
|
Lines 396-402
rgephy_loop(struct mii_softc *sc)
Link Here
|
| 396 |
int i; |
429 |
int i; |
| 397 |
|
430 |
|
| 398 |
if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 && |
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); |
433 |
PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); |
| 401 |
DELAY(1000); |
434 |
DELAY(1000); |
| 402 |
} |
435 |
} |
|
Lines 430-436
rgephy_load_dspcode(struct mii_softc *sc)
Link Here
|
| 430 |
int val; |
463 |
int val; |
| 431 |
|
464 |
|
| 432 |
if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 || |
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; |
467 |
return; |
| 435 |
|
468 |
|
| 436 |
PHY_WRITE(sc, 31, 0x0001); |
469 |
PHY_WRITE(sc, 31, 0x0001); |
|
Lines 481-502
rgephy_reset(struct mii_softc *sc)
Link Here
|
| 481 |
{ |
514 |
{ |
| 482 |
uint16_t pcr, ssr; |
515 |
uint16_t pcr, ssr; |
| 483 |
|
516 |
|
| 484 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) { |
517 |
switch (sc->mii_mpd_rev) { |
| 485 |
/* RTL8211C(L) */ |
518 |
case RGEPHY_8211F: |
| 486 |
ssr = PHY_READ(sc, RGEPHY_MII_SSR); |
519 |
pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1); |
| 487 |
if ((ssr & RGEPHY_SSR_ALDPS) != 0) { |
520 |
if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) { |
| 488 |
ssr &= ~RGEPHY_SSR_ALDPS; |
521 |
pcr &= ~RGEPHY_F_PCR1_MDI_MM; |
| 489 |
PHY_WRITE(sc, RGEPHY_MII_SSR, ssr); |
522 |
PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr); |
| 490 |
} |
523 |
} |
| 491 |
} |
524 |
break; |
| 492 |
|
525 |
case RGEPHY_8211C: |
| 493 |
if (sc->mii_mpd_rev >= 2) { |
526 |
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) { |
| 494 |
pcr = PHY_READ(sc, RGEPHY_MII_PCR); |
527 |
/* RTL8211C(L) */ |
| 495 |
if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) { |
528 |
ssr = PHY_READ(sc, RGEPHY_MII_SSR); |
| 496 |
pcr &= ~RGEPHY_PCR_MDI_MASK; |
529 |
if ((ssr & RGEPHY_SSR_ALDPS) != 0) { |
| 497 |
pcr |= RGEPHY_PCR_MDIX_AUTO; |
530 |
ssr &= ~RGEPHY_SSR_ALDPS; |
| 498 |
PHY_WRITE(sc, RGEPHY_MII_PCR, pcr); |
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 |
} |
545 |
} |
| 501 |
|
546 |
|
| 502 |
mii_phy_reset(sc); |
547 |
mii_phy_reset(sc); |