Add new PCI revision numbers and add some special cases for them. Readd the enhanced PHY access register method again for older chipsets, they do not seem to work with all old chips. --- sys/pci/if_sisreg.h.orig Fri Jan 10 09:16:03 2003 +++ sys/pci/if_sisreg.h Sun Jan 26 13:31:12 2003 @@ -114,6 +114,8 @@ #define SIS_CFG_OUTOFWIN_TIMER 0x00000020 #define SIS_CFG_SINGLE_BACKOFF 0x00000040 #define SIS_CFG_PCIREQ_ALG 0x00000080 +#define SIS_CFG_FAIR_BACKOFF 0x00000200 /* 635 & 900B Specific */ +#define SIS_CFG_RND_CNT 0x00000400 /* 635 & 900B Specific */ #define SIS_CFG_EDB_MASTER_EN 0x00002000 #define SIS_EECTL_DIN 0x00000001 @@ -395,6 +397,8 @@ /* * SiS 900 PCI revision codes. */ +#define SIS_REV_900B 0x0003 +#define SIS_REV_630A 0x0080 #define SIS_REV_630E 0x0081 #define SIS_REV_630S 0x0082 #define SIS_REV_630EA1 0x0083 --- sys/pci/if_sis.c.orig Sun Jan 26 14:05:55 2003 +++ sys/pci/if_sis.c Sun Jan 26 14:40:30 2003 @@ -731,17 +731,48 @@ return CSR_READ_4(sc, NS_BMCR + (reg * 4)); } + /* + * Chipsets < SIS_635 seem not to be able to read/write + * through mdio. Use the enhanced PHY access register + * again for them. + */ if (sc->sis_type == SIS_TYPE_900 && - sc->sis_rev < SIS_REV_635 && phy != 0) - return(0); + sc->sis_rev < SIS_REV_635) { + int i, val = 0; + + if (phy != 0) + return(0); + + CSR_WRITE_4(sc, SIS_PHYCTL, + (phy << 11) | (reg << 6) | SIS_PHYOP_READ); + SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS); + + for (i = 0; i < SIS_TIMEOUT; i++) { + if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS)) + break; + } - bzero((char *)&frame, sizeof(frame)); + if (i == SIS_TIMEOUT) { + printf("sis%d: PHY failed to come ready\n", + sc->sis_unit); + return(0); + } + + val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF; + + if (val == 0xFFFF) + return(0); + + return(val); + } else { + bzero((char *)&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - sis_mii_readreg(sc, &frame); + frame.mii_phyaddr = phy; + frame.mii_regaddr = reg; + sis_mii_readreg(sc, &frame); - return(frame.mii_data); + return(frame.mii_data); + } } static int @@ -761,17 +792,38 @@ return(0); } - if (sc->sis_type == SIS_TYPE_900 && phy != 0) - return(0); + /* + * Chipsets < SIS_635 seem not to be able to read/write + * through mdio. Use the enhanced PHY access register + * again for them. + */ + if (sc->sis_type == SIS_TYPE_900 && + sc->sis_rev < SIS_REV_635) { + int i; - bzero((char *)&frame, sizeof(frame)); + if (phy != 0) + return(0); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; + CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (phy << 11) | + (reg << 6) | SIS_PHYOP_WRITE); + SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS); + + for (i = 0; i < SIS_TIMEOUT; i++) { + if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS)) + break; + } - sis_mii_writereg(sc, &frame); + if (i == SIS_TIMEOUT) + printf("sis%d: PHY failed to come ready\n", + sc->sis_unit); + } else { + bzero((char *)&frame, sizeof(frame)); + frame.mii_phyaddr = phy; + frame.mii_regaddr = reg; + frame.mii_data = data; + sis_mii_writereg(sc, &frame); + } return(0); } @@ -818,11 +870,11 @@ */ if (sc->sis_type == SIS_TYPE_83815) return (crc >> 23); - - if (sc->sis_rev >= SIS_REV_635) + else if (sc->sis_rev >= SIS_REV_635 || + sc->sis_rev == SIS_REV_900B) return (crc >> 24); - - return (crc >> 25); + else + return (crc >> 25); } static void @@ -886,7 +938,11 @@ ifp = &sc->arpcom.ac_if; /* hash table size */ - n = sc->sis_rev >= SIS_REV_635 ? 16 : 8; + if (sc->sis_rev >= SIS_REV_635 || + sc->sis_rev == SIS_REV_900B) + n = 16; + else + n = 8; ctl = CSR_READ_4(sc, SIS_RXFILT_CTL) & SIS_RXFILTCTL_ENABLE; @@ -1094,6 +1150,13 @@ /* Reset the adapter. */ sis_reset(sc); + + if (sc->sis_type == SIS_TYPE_900 && + (sc->sis_rev == SIS_REV_635 || + sc->sis_rev == SIS_REV_900B)) { + SIO_SET(SIS_CFG_RND_CNT); + SIO_SET(SIS_CFG_PERR_DETECT); + } /* * Get station address from the EEPROM.