diff options
author | mbr <mbr@FreeBSD.org> | 2003-01-28 10:55:38 +0000 |
---|---|---|
committer | mbr <mbr@FreeBSD.org> | 2003-01-28 10:55:38 +0000 |
commit | c4a07224346eda315a80ae43240cf06b18e5b322 (patch) | |
tree | 0a81e46d0887e54e69a0f27fe5bbe270b60d20dd /sys/pci | |
parent | 70310f135bf7194be508783d9d066eae00995119 (diff) | |
download | FreeBSD-src-c4a07224346eda315a80ae43240cf06b18e5b322.zip FreeBSD-src-c4a07224346eda315a80ae43240cf06b18e5b322.tar.gz |
Add PCI revision number for 630A and 900B. Enable parity error detection
on 900B and 635(A).
Re-add the enhanced PHY access register method again for older chipsets,
they do not seem to work with all old chips.
Reviewed by: phk
MFC after: 7 days
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_sis.c | 101 | ||||
-rw-r--r-- | sys/pci/if_sisreg.h | 4 |
2 files changed, 86 insertions, 19 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index 4f4cce0..3be4b3c 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -731,17 +731,48 @@ sis_miibus_readreg(dev, phy, reg) 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); + } - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - sis_mii_readreg(sc, &frame); + val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF; + + if (val == 0xFFFF) + return(0); - return(frame.mii_data); + return(val); + } else { + bzero((char *)&frame, sizeof(frame)); + + frame.mii_phyaddr = phy; + frame.mii_regaddr = reg; + sis_mii_readreg(sc, &frame); + + return(frame.mii_data); + } } static int @@ -761,17 +792,38 @@ sis_miibus_writereg(dev, phy, reg, data) 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); + + CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (phy << 11) | + (reg << 6) | SIS_PHYOP_WRITE); + SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; + 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 @@ sis_crc(sc, addr) */ 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 @@ sis_setmulti_sis(sc) 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; @@ -1095,6 +1151,13 @@ sis_attach(dev) /* 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. */ diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h index 6ec34ce..4e7627e 100644 --- a/sys/pci/if_sisreg.h +++ b/sys/pci/if_sisreg.h @@ -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 @@ struct sis_ring_data { /* * 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 |