diff options
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_sis.c | 29 | ||||
-rw-r--r-- | sys/pci/if_sisreg.h | 12 |
2 files changed, 38 insertions, 3 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index 5c78900..c25b4c2 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -107,7 +107,7 @@ MODULE_DEPEND(sis, miibus, 1, 1, 1); static struct sis_type sis_devs[] = { { SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" }, { SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" }, - { NS_VENDORID, NS_DEVICEID_DP83815, "NatSemi DP83815 10/100BaseTX" }, + { NS_VENDORID, NS_DEVICEID_DP83815, "NatSemi DP8381[56] 10/100BaseTX" }, { 0, 0, NULL } }; @@ -1052,6 +1052,8 @@ sis_attach(dev) sc = device_get_softc(dev); unit = device_get_unit(dev); + sc->sis_self = dev; + mtx_init(&sc->sis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); @@ -1131,6 +1133,18 @@ sis_attach(dev) */ switch (pci_get_vendor(dev)) { case NS_VENDORID: + sc->sis_srr = CSR_READ_4(sc, NS_SRR); + + /* We can't update the device description, so spew */ + if (sc->sis_srr == NS_SRR_15C) + device_printf(dev, "Silicon Revision: DP83815C\n"); + else if (sc->sis_srr == NS_SRR_15D) + device_printf(dev, "Silicon Revision: DP83815D\n"); + else if (sc->sis_srr == NS_SRR_16A) + device_printf(dev, "Silicon Revision: DP83816A\n"); + else + device_printf(dev, "Silicon Revision %x\n", sc->sis_srr); + /* * Reading the MAC address out of the EEPROM on * the NatSemi chip takes a bit more work than @@ -2031,6 +2045,16 @@ sis_init(xsc) */ sis_stop(sc); +#ifdef notyet + if (sc->sis_type == SIS_TYPE_83815 && sc->sis_srr >= NS_SRR_16A) { + /* + * Configure 400usec of interrupt holdoff. This is based + * on emperical tests on a Soekris 4801. + */ + CSR_WRITE_4(sc, NS_IHR, 0x100 | 4); + } +#endif + mii = device_get_softc(sc->sis_miibus); /* Set MAC address */ @@ -2146,7 +2170,7 @@ sis_init(xsc) SIS_CLRBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS); } - if (sc->sis_type == SIS_TYPE_83815 && + if (sc->sis_type == SIS_TYPE_83815 && sc->sis_srr < NS_SRR_16A && IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { uint32_t reg; @@ -2163,6 +2187,7 @@ sis_init(xsc) DELAY(100); reg = CSR_READ_4(sc, NS_PHY_TDATA); if ((reg & 0x0080) == 0 || (reg & 0xff) >= 0xd8) { + device_printf(sc->sis_self, "Applying short cable fix (reg=%x)\n", reg); CSR_WRITE_4(sc, NS_PHY_TDATA, 0x00e8); SIS_SETBIT(sc, NS_PHY_DSPCFG, 0x20); } diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h index 97c48f7..fa51a6f 100644 --- a/sys/pci/if_sisreg.h +++ b/sys/pci/if_sisreg.h @@ -74,8 +74,10 @@ #define SIS_TIMEUNIT 0xA4 #define SIS_GPIO 0xB8 -/* NS DP83815 registers */ +/* NS DP83815/6 registers */ +#define NS_IHR 0x1C #define NS_CLKRUN 0x3C +#define NS_SRR 0x58 #define NS_BMCR 0x80 #define NS_BMSR 0x84 #define NS_PHYIDR1 0x88 @@ -97,6 +99,11 @@ #define NS_CLKRUN_PMEENB 0x00000100 #define NS_CLNRUN_CLKRUN_ENB 0x00000001 +/* NS silicon revisions */ +#define NS_SRR_15C 0x302 +#define NS_SRR_15D 0x403 +#define NS_SRR_16A 0x505 + #define SIS_CSR_TX_ENABLE 0x00000001 #define SIS_CSR_TX_DISABLE 0x00000002 #define SIS_CSR_RX_ENABLE 0x00000004 @@ -442,6 +449,7 @@ struct sis_mii_frame { #define SIS_TYPE_900 1 #define SIS_TYPE_7016 2 #define SIS_TYPE_83815 3 +#define SIS_TYPE_83816 4 struct sis_softc { struct arpcom arpcom; /* interface info */ @@ -450,11 +458,13 @@ struct sis_softc { struct resource *sis_res; struct resource *sis_irq; void *sis_intrhand; + device_t sis_self; device_t sis_miibus; u_int8_t sis_unit; u_int8_t sis_type; u_int8_t sis_rev; u_int8_t sis_link; + u_int sis_srr; struct sis_list_data sis_ldata; bus_dma_tag_t sis_parent_tag; bus_dma_tag_t sis_tag; |