summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2002-01-12 21:12:17 +0000
committerwpaul <wpaul@FreeBSD.org>2002-01-12 21:12:17 +0000
commit180b97fbde453178c2bb489a5179810bad7758d3 (patch)
treef87c377d356e404e6d43137f6a6cc8afa3b81ba8 /sys
parentc6e526cffc373bd730b48c61cb3e36af675ee7ae (diff)
downloadFreeBSD-src-180b97fbde453178c2bb489a5179810bad7758d3.zip
FreeBSD-src-180b97fbde453178c2bb489a5179810bad7758d3.tar.gz
Add support for newer integrated SiS 900 controllers on the 635 and 735
motherboard chipsets. We need to force the chip to reload its MAC address into the receive filter, and enable software access mode for the PHY. PR: kern/33294
Diffstat (limited to 'sys')
-rw-r--r--sys/pci/if_sis.c51
-rw-r--r--sys/pci/if_sisreg.h8
2 files changed, 54 insertions, 5 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index fb5435d..704df70 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -146,6 +146,7 @@ static void sis_read_eeprom __P((struct sis_softc *, caddr_t, int,
#ifdef __i386__
static void sis_read_cmos __P((struct sis_softc *, device_t, caddr_t,
int, int));
+static void sis_read_mac __P((struct sis_softc *, device_t, caddr_t));
static device_t sis_find_bridge __P((device_t));
#endif
@@ -486,6 +487,33 @@ static void sis_read_cmos(sc, dev, dest, off, cnt)
pci_write_config(bridge, 0x48, reg & ~0x40, 1);
return;
}
+
+static void sis_read_mac(sc, dev, dest)
+ struct sis_softc *sc;
+ device_t dev;
+ caddr_t dest;
+{
+ u_int32_t filtsave, csrsave;
+
+ filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
+ csrsave = CSR_READ_4(sc, SIS_CSR);
+
+ CSR_WRITE_4(sc, SIS_CSR, SIS_CSR_RELOAD | filtsave);
+ CSR_WRITE_4(sc, SIS_CSR, 0);
+
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave & ~SIS_RXFILTCTL_ENABLE);
+
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
+ ((u_int16_t *)dest)[0] = CSR_READ_2(sc, SIS_RXFILT_DATA);
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL,SIS_FILTADDR_PAR1);
+ ((u_int16_t *)dest)[1] = CSR_READ_2(sc, SIS_RXFILT_DATA);
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
+ ((u_int16_t *)dest)[2] = CSR_READ_2(sc, SIS_RXFILT_DATA);
+
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
+ CSR_WRITE_4(sc, SIS_CSR, csrsave);
+ return;
+}
#endif
static int sis_miibus_readreg(dev, phy, reg)
@@ -516,7 +544,8 @@ static int sis_miibus_readreg(dev, phy, reg)
return(val);
}
- if (sc->sis_type == SIS_TYPE_900 && phy != 0)
+ if (sc->sis_type == SIS_TYPE_900 &&
+ sc->sis_rev < SIS_REV_635 && phy != 0)
return(0);
CSR_WRITE_4(sc, SIS_PHYCTL, (phy << 11) | (reg << 6) | SIS_PHYOP_READ);
@@ -785,6 +814,8 @@ static int sis_attach(dev)
if (pci_get_vendor(dev) == NS_VENDORID)
sc->sis_type = SIS_TYPE_83815;
+ sc->sis_rev = pci_read_config(dev, PCIR_REVID, 1);
+
/*
* Handle power management nonsense.
*/
@@ -925,11 +956,14 @@ static int sis_attach(dev)
* requires some datasheets that I don't have access
* to at the moment.
*/
- command = pci_read_config(dev, PCIR_REVID, 1);
- if (command == SIS_REV_630S ||
- command == SIS_REV_630E ||
- command == SIS_REV_630EA1)
+ if (sc->sis_rev == SIS_REV_630S ||
+ sc->sis_rev == SIS_REV_630E ||
+ sc->sis_rev == SIS_REV_630EA1 ||
+ sc->sis_rev == SIS_REV_630ET)
sis_read_cmos(sc, dev, (caddr_t)&eaddr, 0x9, 6);
+
+ else if (command == SIS_REV_635)
+ sis_read_mac(sc, dev, (caddr_t)&eaddr);
else
#endif
sis_read_eeprom(sc, (caddr_t)&eaddr,
@@ -942,6 +976,13 @@ static int sis_attach(dev)
*/
printf("sis%d: Ethernet address: %6D\n", unit, eaddr, ":");
+ /*
+ * From the Linux driver:
+ * 630ET : set the mii access mode as software-mode
+ */
+ if (sc->sis_rev == SIS_REV_630ET)
+ SIS_SETBIT(sc, SIS_CSR, SIS_CSR_ACCESS_MODE);
+
sc->sis_unit = unit;
callout_handle_init(&sc->sis_stat_ch);
bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h
index 9ab779f..81e3e60 100644
--- a/sys/pci/if_sisreg.h
+++ b/sys/pci/if_sisreg.h
@@ -105,6 +105,8 @@
#define SIS_CSR_RX_RESET 0x00000020
#define SIS_CSR_SOFTINTR 0x00000080
#define SIS_CSR_RESET 0x00000100
+#define SIS_CSR_ACCESS_MODE 0x00000200
+#define SIS_CSR_RELOAD 0x00000400
#define SIS_CFG_BIGENDIAN 0x00000001
#define SIS_CFG_PERR_DETECT 0x00000008
@@ -381,6 +383,8 @@ struct sis_ring_data {
#define SIS_REV_630E 0x0081
#define SIS_REV_630S 0x0082
#define SIS_REV_630EA1 0x0083
+#define SIS_REV_630ET 0x0083
+#define SIS_REV_635 0x0090
/*
* NatSemi vendor ID
@@ -412,6 +416,7 @@ struct sis_softc {
device_t sis_miibus;
u_int8_t sis_unit;
u_int8_t sis_type;
+ u_int8_t sis_rev;
u_int8_t sis_link;
struct sis_list_data sis_ldata;
bus_dma_tag_t sis_parent_tag;
@@ -436,6 +441,9 @@ struct sis_softc {
#define CSR_READ_4(sc, reg) \
bus_space_read_4(sc->sis_btag, sc->sis_bhandle, reg)
+#define CSR_READ_2(sc, reg) \
+ bus_space_read_2(sc->sis_btag, sc->sis_bhandle, reg)
+
#define SIS_TIMEOUT 1000
#define ETHER_ALIGN 2
#define SIS_RXLEN 1536
OpenPOWER on IntegriCloud