diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-03-12 05:51:19 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-03-12 05:51:19 +0000 |
commit | 2f3d1f036f328f61450d7c3126a91ea2eeac0a6c (patch) | |
tree | 54f93408b046a14acbaf508f6888409269b67c31 /sys | |
parent | ae5b9c617251f0bbde3b4bc036c9c4fa6ac03be0 (diff) |
Add support for reading the MAC address from the APC CMOS RAM in the
integrated Ethernet controller on the SiS630E-based chipsets; from FreeBSD,
this patch mostly by jason@. With these changes, my SiS900 card still works
fine, but the new functionality is actually untested.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_sis.c | 59 | ||||
-rw-r--r-- | sys/dev/pci/if_sisreg.h | 10 |
2 files changed, 65 insertions, 4 deletions
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c index c86e4d561a8..8c4d5749eaa 100644 --- a/sys/dev/pci/if_sis.c +++ b/sys/dev/pci/if_sis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sis.c,v 1.10 2001/02/20 19:39:45 mickey Exp $ */ +/* $OpenBSD: if_sis.c,v 1.11 2001/03/12 05:51:18 aaron Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. @@ -129,6 +129,9 @@ void sis_delay __P((struct sis_softc *)); void sis_eeprom_idle __P((struct sis_softc *)); void sis_eeprom_putbyte __P((struct sis_softc *, int)); void sis_eeprom_getword __P((struct sis_softc *, int, u_int16_t *)); +#ifdef __i386__ +void sis_read_cmos __P((struct sis_softc *, struct pci_attach_args *, caddr_t, int, int)); +#endif void sis_read_eeprom __P((struct sis_softc *, caddr_t, int, int, int)); int sis_miibus_readreg __P((struct device *, int, int)); @@ -310,6 +313,31 @@ void sis_read_eeprom(sc, dest, off, cnt, swap) return; } +#ifdef __i386__ +void sis_read_cmos(sc, pa, dest, off, cnt) + struct sis_softc *sc; + struct pci_attach_args *pa; + caddr_t dest; + int off, cnt; +{ + bus_space_tag_t btag; + u_int32_t reg; + int i; + + reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x48); + pci_conf_write(pa->pa_pc, pa->pa_tag, 0x48, reg | 0x40); + + btag = I386_BUS_SPACE_IO; + + for (i = 0; i < cnt; i++) { + bus_space_write_1(btag, 0x0, 0x70, i + off); + *(dest + i) = bus_space_read_1(btag, 0x0, 0x71); + } + + pci_conf_write(pa->pa_pc, pa->pa_tag, 0x48, reg & ~0x40); +} +#endif + int sis_miibus_readreg(self, phy, reg) struct device *self; int phy, reg; @@ -739,8 +767,33 @@ void sis_attach(parent, self, aux) break; case PCI_VENDOR_SIS: default: - sis_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, - SIS_EE_NODEADDR, 3, 0); +#ifdef __i386__ + /* + * If this is a SiS 630E chipset with an embedded + * SiS 900 controller, we have to read the MAC address + * from the APC CMOS RAM. Our method for doing this + * is very ugly since we have to reach out and grab + * ahold of hardware for which we cannot properly + * allocate resources. This code is only compiled on + * the i386 architecture since the SiS 630E chipset + * is for x86 motherboards only. Note that there are + * a lot of magic numbers in this hack. These are + * taken from SiS's Linux driver. I'd like to replace + * them with proper symbolic definitions, but that + * requires some datasheets that I don't have access + * to at the moment. + */ + command = pci_conf_read(pc, pa->pa_tag, + PCI_CLASS_REG) & 0x000000ff; + if (command == SIS_REV_630S || + command == SIS_REV_630E || + command == SIS_REV_630EA1) + sis_read_cmos(sc, pa, (caddr_t)&sc->arpcom.ac_enaddr, + 0x9, 6); + else +#endif + sis_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, + SIS_EE_NODEADDR, 3, 0); break; } diff --git a/sys/dev/pci/if_sisreg.h b/sys/dev/pci/if_sisreg.h index 8232cc858d4..348ebce8699 100644 --- a/sys/dev/pci/if_sisreg.h +++ b/sys/dev/pci/if_sisreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sisreg.h,v 1.4 2000/12/06 15:48:28 mickey Exp $ */ +/* $OpenBSD: if_sisreg.h,v 1.5 2001/03/12 05:51:18 aaron Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -356,6 +356,14 @@ struct sis_ring_data { #define SIS_DEVICEID_900 0x0900 #define SIS_DEVICEID_7016 0x7016 + +/* + * SiS 900 PCI revision codes. + */ +#define SIS_REV_630E 0x0081 +#define SIS_REV_630S 0x0082 +#define SIS_REV_630EA1 0x0083 + struct sis_type { u_int16_t sis_vid; u_int16_t sis_did; |