diff options
author | wpaul <wpaul@FreeBSD.org> | 2001-09-04 17:10:11 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2001-09-04 17:10:11 +0000 |
commit | 67ffe2e20325b02d34088606594673184dc10e50 (patch) | |
tree | 1175747ef3547f559191d4ddff6c302568b4b2b9 /sys | |
parent | 75cc8b4799fb6c83a8a316cecf18cbc2a47601f0 (diff) | |
download | FreeBSD-src-67ffe2e20325b02d34088606594673184dc10e50.zip FreeBSD-src-67ffe2e20325b02d34088606594673184dc10e50.tar.gz |
Add support for Conexant LANfinity miniPCI controllers. People who have
laptops with this chip should test this and report back as I don't have
access to this hardware myself. People with -stable systems should try
the patch at:
http://www.freebsd.org/~wpaul/conexant.patch.gz
Submitted by: Phil Kernick <Phil@Kernick.org>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/dc/if_dc.c | 30 | ||||
-rw-r--r-- | sys/dev/dc/if_dcreg.h | 22 | ||||
-rw-r--r-- | sys/pci/if_dc.c | 30 | ||||
-rw-r--r-- | sys/pci/if_dcreg.h | 22 |
4 files changed, 98 insertions, 6 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index 7bf23e1..8cf4276 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -47,6 +47,7 @@ * Accton EN1217 (www.accton.com) * Xircom X3201 (www.xircom.com) * Abocom FE2500 + * Conexant LANfinity (www.conexant.com) * * Datasheets for the 21143 are available at developer.intel.com. * Datasheets for the clone parts can be found at their respective sites. @@ -186,6 +187,8 @@ static struct dc_type dc_devs[] = { "Xircom X3201 10/100BaseTX" }, { DC_VENDORID_ABOCOM, DC_DEVICEID_FE2500, "Abocom FE2500 10/100BaseTX" }, + { DC_VENDORID_CONEXANT, DC_DEVICEID_RS7112, + "Conexant LANfinity MiniPCI 10/100BaseTX" }, { 0, 0, NULL } }; @@ -363,7 +366,7 @@ static void dc_eeprom_putbyte(sc, addr) * a 93C46. It uses a different bit sequence for * specifying the "read" opcode. */ - if (DC_IS_CENTAUR(sc)) + if (DC_IS_CENTAUR(sc) || DC_IS_CONEXANT(sc)) d = addr | (DC_EECMD_READ << 2); else d = addr | DC_EECMD_READ; @@ -719,6 +722,14 @@ static int dc_miibus_readreg(dev, phy, reg) if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR) return(0); + /* + * Note: the ukphy probes of the RS7112 report a PHY at + * MII address 0 (possibly HomePNA?) and 1 (ethernet) + * so we only respond to correct one. + */ + if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR) + return(0); + if (sc->dc_pmode != DC_PMODE_MII) { if (phy == (MII_NPHY - 1)) { switch(reg) { @@ -825,6 +836,9 @@ static int dc_miibus_writereg(dev, phy, reg, data) if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR) return(0); + if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR) + return(0); + if (DC_IS_PNIC(sc)) { CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE | (phy << 23) | (reg << 10) | data); @@ -1283,7 +1297,7 @@ static void dc_setfilt(sc) struct dc_softc *sc; { if (DC_IS_INTEL(sc) || DC_IS_MACRONIX(sc) || DC_IS_PNIC(sc) || - DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc)) + DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc) || DC_IS_CONEXANT(sc)) dc_setfilt_21143(sc); if (DC_IS_ASIX(sc)) @@ -1465,7 +1479,7 @@ static void dc_reset(sc) break; } - if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || + if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_CONEXANT(sc) || DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc)) { DELAY(10000); DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET); @@ -1928,6 +1942,13 @@ static int dc_attach(dev) * it to obtain a double word aligned buffer. */ break; + case DC_DEVICEID_RS7112: + sc->dc_type = DC_TYPE_CONEXANT; + sc->dc_flags |= DC_TX_INTR_ALWAYS; + sc->dc_flags |= DC_REDUCED_MII_POLL; + sc->dc_pmode = DC_PMODE_MII; + dc_read_eeprom(sc, (caddr_t)&sc->dc_srom, 0, 256, 0); + break; default: printf("dc%d: unknown device: %x\n", sc->dc_unit, sc->dc_info->dc_did); @@ -1992,6 +2013,9 @@ static int dc_attach(dev) case DC_TYPE_AN985: dc_read_eeprom(sc, (caddr_t)&eaddr, DC_AL_EE_NODEADDR, 3, 0); break; + case DC_TYPE_CONEXANT: + bcopy(sc->dc_srom + DC_CONEXANT_EE_NODEADDR, &eaddr, 6); + break; case DC_TYPE_XIRCOM: dc_read_eeprom(sc, (caddr_t)&eaddr, 3, 3, 0); break; diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h index 658b221..d949fca 100644 --- a/sys/dev/dc/if_dcreg.h +++ b/sys/dev/dc/if_dcreg.h @@ -77,6 +77,7 @@ #define DC_TYPE_PNICII 0x9 /* 82c115 PNIC II */ #define DC_TYPE_PNIC 0xA /* 82c168/82c169 PNIC I */ #define DC_TYPE_XIRCOM 0xB /* Xircom X3201 */ +#define DC_TYPE_CONEXANT 0xC /* Conexant LANfinity RS7112 */ #define DC_IS_MACRONIX(x) \ (x->dc_type == DC_TYPE_98713 || \ @@ -95,6 +96,7 @@ #define DC_IS_PNICII(x) (x->dc_type == DC_TYPE_PNICII) #define DC_IS_PNIC(x) (x->dc_type == DC_TYPE_PNIC) #define DC_IS_XIRCOM(x) (x->dc_type == DC_TYPE_XIRCOM) +#define DC_IS_CONEXANT(x) (x->dc_type == DC_TYPE_CONEXANT) /* MII/symbol mode port types */ #define DC_PMODE_MII 0x1 @@ -676,6 +678,16 @@ struct dc_mii_frame { /* End of PNIC specific registers */ +/* + * CONEXANT specific registers. + */ + +#define DC_CONEXANT_PHYADDR 0x1 +#define DC_CONEXANT_EE_NODEADDR 0x19A + +/* End of CONEXANT specific registers */ + + struct dc_softc { struct arpcom arpcom; /* interface info */ bus_space_handle_t dc_bhandle; /* bus space handle */ @@ -883,6 +895,16 @@ struct dc_softc { #define DC_DEVICEID_FE2500 0xAB02 /* + * Conexant vendor ID. + */ +#define DC_VENDORID_CONEXANT 0x14f1 + +/* + * Conexant device IDs. + */ +#define DC_DEVICEID_RS7112 0x1803 + +/* * PCI low memory base and low I/O base register, and * other PCI registers. */ diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index 7bf23e1..8cf4276 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -47,6 +47,7 @@ * Accton EN1217 (www.accton.com) * Xircom X3201 (www.xircom.com) * Abocom FE2500 + * Conexant LANfinity (www.conexant.com) * * Datasheets for the 21143 are available at developer.intel.com. * Datasheets for the clone parts can be found at their respective sites. @@ -186,6 +187,8 @@ static struct dc_type dc_devs[] = { "Xircom X3201 10/100BaseTX" }, { DC_VENDORID_ABOCOM, DC_DEVICEID_FE2500, "Abocom FE2500 10/100BaseTX" }, + { DC_VENDORID_CONEXANT, DC_DEVICEID_RS7112, + "Conexant LANfinity MiniPCI 10/100BaseTX" }, { 0, 0, NULL } }; @@ -363,7 +366,7 @@ static void dc_eeprom_putbyte(sc, addr) * a 93C46. It uses a different bit sequence for * specifying the "read" opcode. */ - if (DC_IS_CENTAUR(sc)) + if (DC_IS_CENTAUR(sc) || DC_IS_CONEXANT(sc)) d = addr | (DC_EECMD_READ << 2); else d = addr | DC_EECMD_READ; @@ -719,6 +722,14 @@ static int dc_miibus_readreg(dev, phy, reg) if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR) return(0); + /* + * Note: the ukphy probes of the RS7112 report a PHY at + * MII address 0 (possibly HomePNA?) and 1 (ethernet) + * so we only respond to correct one. + */ + if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR) + return(0); + if (sc->dc_pmode != DC_PMODE_MII) { if (phy == (MII_NPHY - 1)) { switch(reg) { @@ -825,6 +836,9 @@ static int dc_miibus_writereg(dev, phy, reg, data) if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR) return(0); + if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR) + return(0); + if (DC_IS_PNIC(sc)) { CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE | (phy << 23) | (reg << 10) | data); @@ -1283,7 +1297,7 @@ static void dc_setfilt(sc) struct dc_softc *sc; { if (DC_IS_INTEL(sc) || DC_IS_MACRONIX(sc) || DC_IS_PNIC(sc) || - DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc)) + DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc) || DC_IS_CONEXANT(sc)) dc_setfilt_21143(sc); if (DC_IS_ASIX(sc)) @@ -1465,7 +1479,7 @@ static void dc_reset(sc) break; } - if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || + if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_CONEXANT(sc) || DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc)) { DELAY(10000); DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET); @@ -1928,6 +1942,13 @@ static int dc_attach(dev) * it to obtain a double word aligned buffer. */ break; + case DC_DEVICEID_RS7112: + sc->dc_type = DC_TYPE_CONEXANT; + sc->dc_flags |= DC_TX_INTR_ALWAYS; + sc->dc_flags |= DC_REDUCED_MII_POLL; + sc->dc_pmode = DC_PMODE_MII; + dc_read_eeprom(sc, (caddr_t)&sc->dc_srom, 0, 256, 0); + break; default: printf("dc%d: unknown device: %x\n", sc->dc_unit, sc->dc_info->dc_did); @@ -1992,6 +2013,9 @@ static int dc_attach(dev) case DC_TYPE_AN985: dc_read_eeprom(sc, (caddr_t)&eaddr, DC_AL_EE_NODEADDR, 3, 0); break; + case DC_TYPE_CONEXANT: + bcopy(sc->dc_srom + DC_CONEXANT_EE_NODEADDR, &eaddr, 6); + break; case DC_TYPE_XIRCOM: dc_read_eeprom(sc, (caddr_t)&eaddr, 3, 3, 0); break; diff --git a/sys/pci/if_dcreg.h b/sys/pci/if_dcreg.h index 658b221..d949fca 100644 --- a/sys/pci/if_dcreg.h +++ b/sys/pci/if_dcreg.h @@ -77,6 +77,7 @@ #define DC_TYPE_PNICII 0x9 /* 82c115 PNIC II */ #define DC_TYPE_PNIC 0xA /* 82c168/82c169 PNIC I */ #define DC_TYPE_XIRCOM 0xB /* Xircom X3201 */ +#define DC_TYPE_CONEXANT 0xC /* Conexant LANfinity RS7112 */ #define DC_IS_MACRONIX(x) \ (x->dc_type == DC_TYPE_98713 || \ @@ -95,6 +96,7 @@ #define DC_IS_PNICII(x) (x->dc_type == DC_TYPE_PNICII) #define DC_IS_PNIC(x) (x->dc_type == DC_TYPE_PNIC) #define DC_IS_XIRCOM(x) (x->dc_type == DC_TYPE_XIRCOM) +#define DC_IS_CONEXANT(x) (x->dc_type == DC_TYPE_CONEXANT) /* MII/symbol mode port types */ #define DC_PMODE_MII 0x1 @@ -676,6 +678,16 @@ struct dc_mii_frame { /* End of PNIC specific registers */ +/* + * CONEXANT specific registers. + */ + +#define DC_CONEXANT_PHYADDR 0x1 +#define DC_CONEXANT_EE_NODEADDR 0x19A + +/* End of CONEXANT specific registers */ + + struct dc_softc { struct arpcom arpcom; /* interface info */ bus_space_handle_t dc_bhandle; /* bus space handle */ @@ -883,6 +895,16 @@ struct dc_softc { #define DC_DEVICEID_FE2500 0xAB02 /* + * Conexant vendor ID. + */ +#define DC_VENDORID_CONEXANT 0x14f1 + +/* + * Conexant device IDs. + */ +#define DC_DEVICEID_RS7112 0x1803 + +/* * PCI low memory base and low I/O base register, and * other PCI registers. */ |