diff options
author | wpaul <wpaul@FreeBSD.org> | 2002-01-12 21:12:17 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2002-01-12 21:12:17 +0000 |
commit | 180b97fbde453178c2bb489a5179810bad7758d3 (patch) | |
tree | f87c377d356e404e6d43137f6a6cc8afa3b81ba8 /sys/pci/if_sis.c | |
parent | c6e526cffc373bd730b48c61cb3e36af675ee7ae (diff) | |
download | FreeBSD-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/pci/if_sis.c')
-rw-r--r-- | sys/pci/if_sis.c | 51 |
1 files changed, 46 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); |