static void ciphy_fixup(struct mii_softc *sc) { uint16_t model, status, speed; device_t parent; model = MII_MODEL(PHY_READ(sc, CIPHY_MII_PHYIDR2)); status = PHY_READ(sc, CIPHY_MII_AUXCSR); speed = status & CIPHY_AUXCSR_SPEED; parent = device_get_parent(sc->mii_dev); if (strncmp(device_get_name(parent), "nfe", 3) == 0) { /* Need to set for 2.5V RGMII for NVIDIA adapters */ PHY_SETBIT(sc, CIPHY_MII_ECTL1, CIPHY_INTSEL_RGMII); PHY_SETBIT(sc, CIPHY_MII_ECTL1, CIPHY_IOVOL_2500MV); } switch (model) { case MII_MODEL_CICADA_CS8201: /* MII_MODEL_xxCICADA_CS8201 */ /* Turn off "aux mode" (whatever that means) */ PHY_SETBIT(sc, CIPHY_MII_AUXCSR, CIPHY_AUXCSR_MDPPS); /* * Work around speed polling bug in VT3119/VT3216 * when using MII in full duplex mode. */ if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && (status & CIPHY_AUXCSR_FDX)) { PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } else { PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } /* Enable link/activity LED blink. */ PHY_SETBIT(sc, CIPHY_MII_LED, CIPHY_LED_LINKACTBLINK); break; case MII_MODEL_CICADA_CS8201A: /* MII_MODEL_xxCICADA_CS8201A */ case MII_MODEL_CICADA_CS8201B: /* MII_MODEL_xxCICADA_CS8201B */ /* * Work around speed polling bug in VT3119/VT3216 * when using MII in full duplex mode. */ if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && (status & CIPHY_AUXCSR_FDX)) { PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } else { PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } break; case MII_MODEL_VITESSE_VSC8601: break; default: device_printf(sc->mii_dev, "unknown CICADA PHY model %x\n", model); break; } }
/* * Initialize RealTek PHY per the datasheet. The DSP in the PHYs of * existing revisions of the 8169S/8110S chips need to be tuned in * order to reliably negotiate a 1000Mbps link. This is only needed * for rev 0 and rev 1 of the PHY. Later versions work without * any fixups. */ static void rgephy_load_dspcode(struct mii_softc *sc) { struct rgephy_softc *rsc; int val; rsc = (struct rgephy_softc *)sc; if (rsc->mii_revision >= 2) return; PHY_WRITE(sc, 31, 0x0001); PHY_WRITE(sc, 21, 0x1000); PHY_WRITE(sc, 24, 0x65C7); PHY_CLRBIT(sc, 4, 0x0800); val = PHY_READ(sc, 4) & 0xFFF; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0x00A1); PHY_WRITE(sc, 2, 0x0008); PHY_WRITE(sc, 1, 0x1020); PHY_WRITE(sc, 0, 0x1000); PHY_SETBIT(sc, 4, 0x0800); PHY_CLRBIT(sc, 4, 0x0800); val = (PHY_READ(sc, 4) & 0xFFF) | 0x7000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xFF41); PHY_WRITE(sc, 2, 0xDE60); PHY_WRITE(sc, 1, 0x0140); PHY_WRITE(sc, 0, 0x0077); val = (PHY_READ(sc, 4) & 0xFFF) | 0xA000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xDF01); PHY_WRITE(sc, 2, 0xDF20); PHY_WRITE(sc, 1, 0xFF95); PHY_WRITE(sc, 0, 0xFA00); val = (PHY_READ(sc, 4) & 0xFFF) | 0xB000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xFF41); PHY_WRITE(sc, 2, 0xDE20); PHY_WRITE(sc, 1, 0x0140); PHY_WRITE(sc, 0, 0x00BB); val = (PHY_READ(sc, 4) & 0xFFF) | 0xF000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xDF01); PHY_WRITE(sc, 2, 0xDF20); PHY_WRITE(sc, 1, 0xFF95); PHY_WRITE(sc, 0, 0xBF00); PHY_SETBIT(sc, 4, 0x0800); PHY_CLRBIT(sc, 4, 0x0800); PHY_WRITE(sc, 31, 0x0000); DELAY(40); }
/* * Initialize RealTek PHY per the datasheet. The DSP in the PHYs of * existing revisions of the 8169S/8110S chips need to be tuned in * order to reliably negotiate a 1000Mbps link. This is only needed * for rev 0 and rev 1 of the PHY. Later versions work without * any fixups. */ static void rgephy_load_dspcode(struct mii_softc *sc) { int val; if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 || sc->mii_mpd_rev >= 2) return; PHY_WRITE(sc, 31, 0x0001); PHY_WRITE(sc, 21, 0x1000); PHY_WRITE(sc, 24, 0x65C7); PHY_CLRBIT(sc, 4, 0x0800); val = PHY_READ(sc, 4) & 0xFFF; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0x00A1); PHY_WRITE(sc, 2, 0x0008); PHY_WRITE(sc, 1, 0x1020); PHY_WRITE(sc, 0, 0x1000); PHY_SETBIT(sc, 4, 0x0800); PHY_CLRBIT(sc, 4, 0x0800); val = (PHY_READ(sc, 4) & 0xFFF) | 0x7000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xFF41); PHY_WRITE(sc, 2, 0xDE60); PHY_WRITE(sc, 1, 0x0140); PHY_WRITE(sc, 0, 0x0077); val = (PHY_READ(sc, 4) & 0xFFF) | 0xA000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xDF01); PHY_WRITE(sc, 2, 0xDF20); PHY_WRITE(sc, 1, 0xFF95); PHY_WRITE(sc, 0, 0xFA00); val = (PHY_READ(sc, 4) & 0xFFF) | 0xB000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xFF41); PHY_WRITE(sc, 2, 0xDE20); PHY_WRITE(sc, 1, 0x0140); PHY_WRITE(sc, 0, 0x00BB); val = (PHY_READ(sc, 4) & 0xFFF) | 0xF000; PHY_WRITE(sc, 4, val); PHY_WRITE(sc, 3, 0xDF01); PHY_WRITE(sc, 2, 0xDF20); PHY_WRITE(sc, 1, 0xFF95); PHY_WRITE(sc, 0, 0xBF00); PHY_SETBIT(sc, 4, 0x0800); PHY_CLRBIT(sc, 4, 0x0800); PHY_WRITE(sc, 31, 0x0000); DELAY(40); }
static void ciphy_fixup(struct mii_softc *sc) { uint16_t model; uint16_t status, speed; uint16_t val; model = MII_MODEL(PHY_READ(sc, CIPHY_MII_PHYIDR2)); status = PHY_READ(sc, CIPHY_MII_AUXCSR); speed = status & CIPHY_AUXCSR_SPEED; if (strcmp(device_get_name(device_get_parent(sc->mii_dev)), "nfe") == 0) { /* need to set for 2.5V RGMII for NVIDIA adapters */ val = PHY_READ(sc, CIPHY_MII_ECTL1); val &= ~(CIPHY_ECTL1_IOVOL | CIPHY_ECTL1_INTSEL); val |= (CIPHY_IOVOL_2500MV | CIPHY_INTSEL_RGMII); PHY_WRITE(sc, CIPHY_MII_ECTL1, val); /* From Linux. */ val = PHY_READ(sc, CIPHY_MII_AUXCSR); val |= CIPHY_AUXCSR_MDPPS; PHY_WRITE(sc, CIPHY_MII_AUXCSR, val); val = PHY_READ(sc, CIPHY_MII_10BTCSR); val |= CIPHY_10BTCSR_ECHO; PHY_WRITE(sc, CIPHY_MII_10BTCSR, val); } switch (model) { case MII_MODEL_xxCICADA_CS8204: case MII_MODEL_xxCICADA_CS8201: /* Turn off "aux mode" (whatever that means) */ PHY_SETBIT(sc, CIPHY_MII_AUXCSR, CIPHY_AUXCSR_MDPPS); /* * Work around speed polling bug in VT3119/VT3216 * when using MII in full duplex mode. */ if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && (status & CIPHY_AUXCSR_FDX)) { PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } else { PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } /* Enable link/activity LED blink. */ PHY_SETBIT(sc, CIPHY_MII_LED, CIPHY_LED_LINKACTBLINK); break; case MII_MODEL_xxCICADA_CS8201A: case MII_MODEL_xxCICADA_CS8201B: /* * Work around speed polling bug in VT3119/VT3216 * when using MII in full duplex mode. */ if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && (status & CIPHY_AUXCSR_FDX)) { PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } else { PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); } break; case MII_MODEL_xxCICADA_VSC8211: case MII_MODEL_xxCICADA_VSC8221: case MII_MODEL_xxCICADA_CS8244: case MII_MODEL_xxVITESSE_VSC8601: case MII_MODEL_xxVITESSE_VSC8641: break; default: device_printf(sc->mii_dev, "unknown CICADA PHY model %x\n", model); break; } }