summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authormbr <mbr@FreeBSD.org>2003-01-28 10:55:38 +0000
committermbr <mbr@FreeBSD.org>2003-01-28 10:55:38 +0000
commitc4a07224346eda315a80ae43240cf06b18e5b322 (patch)
tree0a81e46d0887e54e69a0f27fe5bbe270b60d20dd /sys/pci
parent70310f135bf7194be508783d9d066eae00995119 (diff)
downloadFreeBSD-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.c101
-rw-r--r--sys/pci/if_sisreg.h4
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
OpenPOWER on IntegriCloud