diff options
author | Jason Wright <jason@cvs.openbsd.org> | 1999-11-17 03:23:53 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 1999-11-17 03:23:53 +0000 |
commit | bad7fa2a6ad2d84ee9916aac71a2ef49aa5804aa (patch) | |
tree | 7f1d4924999803e27f07b0c74e8f4436bb5d8611 /sys | |
parent | 326cf5dab2796d71d20df6608e0b56899c34354d (diff) |
mii fixups and merge with freebsd:
o fix tx recovery with call to rl_reset/rl_init
o automatic tuning of tx threshold
o make sure first mbuf contains the entire ether_header
o remove matching of SiS 900 chipset
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_rl.c | 156 | ||||
-rw-r--r-- | sys/dev/pci/if_rlreg.h | 165 |
2 files changed, 100 insertions, 221 deletions
diff --git a/sys/dev/pci/if_rl.c b/sys/dev/pci/if_rl.c index bf561273d65..da56159322c 100644 --- a/sys/dev/pci/if_rl.c +++ b/sys/dev/pci/if_rl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rl.c,v 1.17 1999/09/30 00:12:22 jason Exp $ */ +/* $OpenBSD: if_rl.c,v 1.18 1999/11/17 03:23:52 jason Exp $ */ /* * Copyright (c) 1997, 1998 @@ -31,7 +31,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: if_rl.c,v 1.17 1999/06/19 20:17:37 wpaul Exp $ + * $FreeBSD: src/sys/pci/if_rl.c,v 1.36 1999/11/16 15:34:52 wpaul Exp $ */ /* @@ -146,15 +146,9 @@ int rl_probe __P((struct device *, void *, void *)); void rl_attach __P((struct device *, struct device *, void *)); int rl_intr __P((void *)); +void rl_tick __P((void *)); void rl_shutdown __P((void *)); -/* - * MII glue - */ -int rl_mii_read __P((struct device *, int, int)); -void rl_mii_write __P((struct device *, int, int, int)); -void rl_mii_statchg __P((struct device *)); - int rl_encap __P((struct rl_softc *, struct mbuf * )); void rl_rxeof __P((struct rl_softc *)); @@ -176,6 +170,10 @@ void rl_mii_send __P((struct rl_softc *, u_int32_t, int)); int rl_mii_readreg __P((struct rl_softc *, struct rl_mii_frame *)); int rl_mii_writereg __P((struct rl_softc *, struct rl_mii_frame *)); +int rl_miibus_readreg __P((struct device *, int, int)); +void rl_miibus_writereg __P((struct device *, int, int, int)); +void rl_miibus_statchg __P((struct device *)); + u_int8_t rl_calchash __P((caddr_t)); void rl_setmulti __P((struct rl_softc *)); void rl_reset __P((struct rl_softc *)); @@ -681,19 +679,8 @@ void rl_rxeof(sc) if (!(rxstat & RL_RXSTAT_RXOK)) { ifp->if_ierrors++; - if (rxstat & (RL_RXSTAT_BADSYM|RL_RXSTAT_RUNT| - RL_RXSTAT_GIANT|RL_RXSTAT_CRCERR| - RL_RXSTAT_ALIGNERR)) { - CSR_WRITE_2(sc, RL_COMMAND, RL_CMD_TX_ENB); - CSR_WRITE_2(sc, RL_COMMAND, RL_CMD_TX_ENB| - RL_CMD_RX_ENB); - CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); - CSR_WRITE_4(sc, RL_RXADDR, - vtophys(sc->rl_cdata.rl_rx_buf)); - CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); - cur_rx = 0; - } - break; + rl_init(sc); + return; } /* No errors; receive the packet. */ @@ -733,6 +720,7 @@ void rl_rxeof(sc) m_adj(m, RL_ETHER_ALIGN); m_copyback(m, wrap, total_len - wrap, sc->rl_cdata.rl_rx_buf); + m = m_pullup(m, MHLEN - RL_ETHER_ALIGN); } cur_rx = (total_len - wrap + ETHER_CRC_LEN); } else { @@ -806,16 +794,27 @@ void rl_txeof(sc) if (txstat & RL_TXSTAT_TX_OK) ifp->if_opackets++; else { + int oldthresh; + ifp->if_oerrors++; if ((txstat & RL_TXSTAT_TXABRT) || (txstat & RL_TXSTAT_OUTOFWIN)) CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); + oldthresh = sc->rl_txthresh; + /* error recovery */ + rl_reset(sc); + rl_init(sc); + /* + * If there was a transmit underrun, + * bump the TX threshold. + */ + if (txstat & RL_TXSTAT_TX_UNDERRUN) + sc->rl_txthresh = oldthresh + 32; + return; } RL_INC(sc->rl_cdata.last_tx); ifp->if_flags &= ~IFF_OACTIVE; } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); - - return; } int rl_intr(arg) @@ -860,11 +859,10 @@ int rl_intr(arg) /* Re-enable interrupts. */ CSR_WRITE_2(sc, RL_IMR, RL_INTRS); - if (ifp->if_snd.ifq_head != NULL) { + if (ifp->if_snd.ifq_head != NULL) rl_start(ifp); - } - return claimed; + return (claimed); } /* @@ -894,8 +892,7 @@ int rl_encap(sc, m_head) return(1); } } - m_copydata(m_head, 0, m_head->m_pkthdr.len, - mtod(m_new, caddr_t)); + m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t)); m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; m_freem(m_head); m_head = m_new; @@ -903,7 +900,7 @@ int rl_encap(sc, m_head) /* Pad frames to at least 60 bytes. */ if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { m_head->m_pkthdr.len += - (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); + (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); m_head->m_len = m_head->m_pkthdr.len; } @@ -946,7 +943,8 @@ void rl_start(ifp) CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), vtophys(mtod(RL_CUR_TXMBUF(sc), caddr_t))); CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), - RL_TX_EARLYTHRESH | RL_CUR_TXMBUF(sc)->m_pkthdr.len); + RL_TXTHRESH(sc->rl_txthresh) | + RL_CUR_TXMBUF(sc)->m_pkthdr.len); RL_INC(sc->rl_cdata.cur_tx); } @@ -1038,24 +1036,26 @@ void rl_init(xsc) */ CSR_WRITE_2(sc, RL_IMR, RL_INTRS); + /* Set initial TX threshold */ + sc->rl_txthresh = RL_TX_THRESH_INIT; + /* Start RX/TX process. */ CSR_WRITE_4(sc, RL_MISSEDPKT, 0); /* Enable receiver and transmitter. */ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); - CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); - - /* - * Set current media. - */ mii_mediachg(&sc->sc_mii); + CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); + ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; (void)splx(s); + timeout(rl_tick, sc, hz); + return; } @@ -1065,8 +1065,9 @@ void rl_init(xsc) int rl_ifmedia_upd(ifp) struct ifnet *ifp; { - if (ifp->if_flags & IFF_UP) - rl_init(ifp->if_softc); + struct rl_softc *sc = (struct rl_softc *)ifp->if_softc; + + mii_mediachg(&sc->sc_mii); return (0); } @@ -1173,6 +1174,8 @@ void rl_stop(sc) ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; + untimeout(rl_tick, sc); + CSR_WRITE_1(sc, RL_COMMAND, 0x00); CSR_WRITE_2(sc, RL_IMR, 0x0000); @@ -1220,10 +1223,6 @@ rl_probe(parent, match, aux) } } - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_900) - return (1); - return 0; } @@ -1310,8 +1309,7 @@ rl_attach(parent, self, aux) rl_read_eeprom(sc, (caddr_t)&rl_did, RL_EE_PCI_DID, 1, 0); if (rl_did == RT_DEVICEID_8139 || rl_did == ACCTON_DEVICEID_5030 || - rl_did == DELTA_DEVICEID_8139 || rl_did == ADDTRON_DEVICEID_8139 || - rl_did == SIS_DEVICEID_8139) + rl_did == DELTA_DEVICEID_8139 || rl_did == ADDTRON_DEVICEID_8139) sc->rl_type = RL_8139; else if (rl_did == RT_DEVICEID_8129) sc->rl_type = RL_8129; @@ -1350,9 +1348,9 @@ rl_attach(parent, self, aux) * Initialize our media structures and probe the MII. */ sc->sc_mii.mii_ifp = ifp; - sc->sc_mii.mii_readreg = rl_mii_read; - sc->sc_mii.mii_writereg = rl_mii_write; - sc->sc_mii.mii_statchg = rl_mii_statchg; + sc->sc_mii.mii_readreg = rl_miibus_readreg; + sc->sc_mii.mii_writereg = rl_miibus_writereg; + sc->sc_mii.mii_statchg = rl_miibus_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, rl_ifmedia_upd, rl_ifmedia_sts); mii_phy_probe(self, &sc->sc_mii, 0xffffffff); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { @@ -1384,12 +1382,13 @@ void rl_shutdown(arg) } int -rl_mii_read(self, phy, reg) +rl_miibus_readreg(self, phy, reg) struct device *self; int phy, reg; { struct rl_softc *sc = (struct rl_softc *)self; struct rl_mii_frame frame; + u_int16_t rl8139_reg; if (sc->rl_type == RL_8139) { /* @@ -1399,20 +1398,28 @@ rl_mii_read(self, phy, reg) if (phy != 0) return(0); - DELAY(100); switch (reg) { case MII_BMCR: - return CSR_READ_2(sc, RL_BMCR); + rl8139_reg = RL_BMCR; + break; case MII_BMSR: - return CSR_READ_2(sc, RL_BMSR); + rl8139_reg = RL_BMSR; + break; case MII_ANAR: - return CSR_READ_2(sc, RL_ANAR); - case MII_ANLPAR: - return CSR_READ_2(sc, RL_LPAR); + rl8139_reg = RL_ANAR; + break; case MII_ANER: - return CSR_READ_2(sc, RL_ANER); + rl8139_reg = RL_ANER; + break; + case MII_ANLPAR: + rl8139_reg = RL_LPAR; + break; + case MII_PHYIDR1: + case MII_PHYIDR2: + return (0); + break; } - return (0); + return (CSR_READ_2(sc, rl8139_reg)); } bzero((char *)&frame, sizeof(frame)); @@ -1425,34 +1432,39 @@ rl_mii_read(self, phy, reg) } void -rl_mii_write(self, phy, reg, val) +rl_miibus_writereg(self, phy, reg, val) struct device *self; int phy, reg, val; { struct rl_softc *sc = (struct rl_softc *)self; struct rl_mii_frame frame; + u_int16_t rl8139_reg = 0; if (sc->rl_type == RL_8139) { - if (phy != 0) + if (phy) return; switch (reg) { case MII_BMCR: - CSR_WRITE_2(sc, RL_BMCR, val); + rl8139_reg = RL_BMCR; break; case MII_BMSR: - CSR_WRITE_2(sc, RL_BMSR, val); + rl8139_reg = RL_BMSR; break; case MII_ANAR: - CSR_WRITE_2(sc, RL_ANAR, val); - break; - case MII_ANLPAR: - CSR_WRITE_2(sc, RL_LPAR, val); + rl8139_reg = RL_ANAR; break; case MII_ANER: - CSR_WRITE_2(sc, RL_ANER, val); + rl8139_reg = RL_ANER; break; + case MII_ANLPAR: + rl8139_reg = RL_LPAR; + break; + case MII_PHYIDR1: + case MII_PHYIDR2: + return; } + CSR_WRITE_2(sc, rl8139_reg, val); return; } @@ -1464,10 +1476,20 @@ rl_mii_write(self, phy, reg, val) } void -rl_mii_statchg(self) +rl_miibus_statchg(self) struct device *self; { - /* Nothing to do */ + return; +} + +void +rl_tick(v) + void *v; +{ + struct rl_softc *sc = v; + + mii_tick(&sc->sc_mii); + timeout(rl_tick, sc, hz); } struct cfattach rl_ca = { diff --git a/sys/dev/pci/if_rlreg.h b/sys/dev/pci/if_rlreg.h index 0f2835373ae..b58aaf19ad9 100644 --- a/sys/dev/pci/if_rlreg.h +++ b/sys/dev/pci/if_rlreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rlreg.h,v 1.8 1999/06/29 06:02:37 jason Exp $ */ +/* $OpenBSD: if_rlreg.h,v 1.9 1999/11/17 03:23:52 jason Exp $ */ /* * Copyright (c) 1997, 1998 @@ -31,7 +31,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: if_rlreg.h,v 1.9 1999/06/20 18:56:09 wpaul Exp $ + * $FreeBSD: src/sys/pci/if_rlreg.h,v 1.14 1999/10/21 19:42:03 wpaul Exp $ */ /* @@ -301,10 +301,11 @@ #define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13)) #define RL_TX_LIST_CNT 4 #define RL_MIN_FRAMELEN 60 -#define RL_TX_EARLYTHRESH (256 << 11) +#define RL_TXTHRESH(x) ((x) << 11) +#define RL_TX_THRESH_INIT 96 #define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES -#define RL_RX_MAXDMA RL_RXDMA_256BYTES -#define RL_TX_MAXDMA RL_TXDMA_256BYTES +#define RL_RX_MAXDMA RL_RXDMA_UNLIMITED +#define RL_TX_MAXDMA RL_TXDMA_2048BYTES #define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_MAXDMA|RL_RX_BUF_SZ) #define RL_TXCFG_CONFIG (RL_TXCFG_IFG|RL_TX_MAXDMA) @@ -352,10 +353,6 @@ struct rl_mii_frame { #define RL_MII_WRITEOP 0x01 #define RL_MII_TURNAROUND 0x02 -#define RL_FLAG_FORCEDELAY 1 -#define RL_FLAG_SCHEDDELAY 2 -#define RL_FLAG_DELAYTIMEO 3 - #define RL_8129 1 #define RL_8139 2 @@ -372,6 +369,7 @@ struct rl_softc { struct arpcom arpcom; /* interface info */ struct mii_data sc_mii; /* MII information */ u_int8_t rl_type; + int rl_txthresh; struct rl_chain_data rl_cdata; }; @@ -438,48 +436,6 @@ struct rl_softc { #define ADDTRON_DEVICEID_8139 0x1360 /* - * SiS vendor ID. - */ -#define SIS_VENDORID 0x1039 - -/* - * SiS device IDs. - */ -#define SIS_DEVICEID_8139 0x0900 - -/* - * Texas Instruments PHY identifiers - */ -#define TI_PHY_VENDORID 0x4000 -#define TI_PHY_10BT 0x501F -#define TI_PHY_100VGPMI 0x502F - -/* - * These ID values are for the NS DP83840A 10/100 PHY - */ -#define NS_PHY_VENDORID 0x2000 -#define NS_PHY_83840A 0x5C0F - -/* - * Level 1 10/100 PHY - */ -#define LEVEL1_PHY_VENDORID 0x7810 -#define LEVEL1_PHY_LXT970 0x000F - -/* - * Intel 82555 10/100 PHY - */ -#define INTEL_PHY_VENDORID 0x0A28 -#define INTEL_PHY_82555 0x015F - -/* - * SEEQ 80220 10/100 PHY - */ -#define SEEQ_PHY_VENDORID 0x0016 -#define SEEQ_PHY_80220 0xF83F - - -/* * PCI low memory base and low I/O base register, and * other PCI registers. Note: some are only available on * the 3c905B, in particular those that related to power management. @@ -502,10 +458,10 @@ struct rl_softc { #define RL_PCI_RESETOPT 0x48 #define RL_PCI_EEPROM_DATA 0x4C -#define RL_PCI_CAPID 0xDC /* 8 bits */ -#define RL_PCI_NEXTPTR 0xDD /* 8 bits */ -#define RL_PCI_PWRMGMTCAP 0xDE /* 16 bits */ -#define RL_PCI_PWRMGMTCTRL 0xE0 /* 16 bits */ +#define RL_PCI_CAPID 0x50 /* 8 bits */ +#define RL_PCI_NEXTPTR 0x51 /* 8 bits */ +#define RL_PCI_PWRMGMTCAP 0x52 /* 16 bits */ +#define RL_PCI_PWRMGMTCTRL 0x54 /* 16 bits */ #define RL_PSTATE_MASK 0x0003 #define RL_PSTATE_D0 0x0000 @@ -515,105 +471,6 @@ struct rl_softc { #define RL_PME_EN 0x0010 #define RL_PME_STATUS 0x8000 -#define PHY_UNKNOWN 6 - -#define RL_PHYADDR_MIN 0x00 -#define RL_PHYADDR_MAX 0x1F - -#define PHY_BMCR 0x00 -#define PHY_BMSR 0x01 -#define PHY_VENID 0x02 -#define PHY_DEVID 0x03 -#define PHY_ANAR 0x04 -#define PHY_LPAR 0x05 -#define PHY_ANEXP 0x06 - -#define PHY_ANAR_NEXTPAGE 0x8000 -#define PHY_ANAR_RSVD0 0x4000 -#define PHY_ANAR_TLRFLT 0x2000 -#define PHY_ANAR_RSVD1 0x1000 -#define PHY_ANAR_RSVD2 0x0800 -#define PHY_ANAR_RSVD3 0x0400 -#define PHY_ANAR_100BT4 0x0200 -#define PHY_ANAR_100BTXFULL 0x0100 -#define PHY_ANAR_100BTXHALF 0x0080 -#define PHY_ANAR_10BTFULL 0x0040 -#define PHY_ANAR_10BTHALF 0x0020 -#define PHY_ANAR_PROTO4 0x0010 -#define PHY_ANAR_PROTO3 0x0008 -#define PHY_ANAR_PROTO2 0x0004 -#define PHY_ANAR_PROTO1 0x0002 -#define PHY_ANAR_PROTO0 0x0001 - -/* - * These are the register definitions for the PHY (physical layer - * interface chip). - */ -/* - * PHY BMCR Basic Mode Control Register - */ -#define PHY_BMCR_RESET 0x8000 -#define PHY_BMCR_LOOPBK 0x4000 -#define PHY_BMCR_SPEEDSEL 0x2000 -#define PHY_BMCR_AUTONEGENBL 0x1000 -#define PHY_BMCR_RSVD0 0x0800 /* write as zero */ -#define PHY_BMCR_ISOLATE 0x0400 -#define PHY_BMCR_AUTONEGRSTR 0x0200 -#define PHY_BMCR_DUPLEX 0x0100 -#define PHY_BMCR_COLLTEST 0x0080 -#define PHY_BMCR_RSVD1 0x0040 /* write as zero, don't care */ -#define PHY_BMCR_RSVD2 0x0020 /* write as zero, don't care */ -#define PHY_BMCR_RSVD3 0x0010 /* write as zero, don't care */ -#define PHY_BMCR_RSVD4 0x0008 /* write as zero, don't care */ -#define PHY_BMCR_RSVD5 0x0004 /* write as zero, don't care */ -#define PHY_BMCR_RSVD6 0x0002 /* write as zero, don't care */ -#define PHY_BMCR_RSVD7 0x0001 /* write as zero, don't care */ -/* - * RESET: 1 == software reset, 0 == normal operation - * Resets status and control registers to default values. - * Relatches all hardware config values. - * - * LOOPBK: 1 == loopback operation enabled, 0 == normal operation - * - * SPEEDSEL: 1 == 100Mb/s, 0 == 10Mb/s - * Link speed is selected byt his bit or if auto-negotiation if bit - * 12 (AUTONEGENBL) is set (in which case the value of this register - * is ignored). - * - * AUTONEGENBL: 1 == Autonegotiation enabled, 0 == Autonegotiation disabled - * Bits 8 and 13 are ignored when autoneg is set, otherwise bits 8 and 13 - * determine speed and mode. Should be cleared and then set if PHY configured - * for no autoneg on startup. - * - * ISOLATE: 1 == isolate PHY from MII, 0 == normal operation - * - * AUTONEGRSTR: 1 == restart autonegotiation, 0 = normal operation - * - * DUPLEX: 1 == full duplex mode, 0 == half duplex mode - * - * COLLTEST: 1 == collision test enabled, 0 == normal operation - */ - -/* - * PHY, BMSR Basic Mode Status Register - */ -#define PHY_BMSR_100BT4 0x8000 -#define PHY_BMSR_100BTXFULL 0x4000 -#define PHY_BMSR_100BTXHALF 0x2000 -#define PHY_BMSR_10BTFULL 0x1000 -#define PHY_BMSR_10BTHALF 0x0800 -#define PHY_BMSR_RSVD1 0x0400 /* write as zero, don't care */ -#define PHY_BMSR_RSVD2 0x0200 /* write as zero, don't care */ -#define PHY_BMSR_RSVD3 0x0100 /* write as zero, don't care */ -#define PHY_BMSR_RSVD4 0x0080 /* write as zero, don't care */ -#define PHY_BMSR_MFPRESUP 0x0040 -#define PHY_BMSR_AUTONEGCOMP 0x0020 -#define PHY_BMSR_REMFAULT 0x0010 -#define PHY_BMSR_CANAUTONEG 0x0008 -#define PHY_BMSR_LINKSTAT 0x0004 -#define PHY_BMSR_JABBER 0x0002 -#define PHY_BMSR_EXTENDED 0x0001 - /* * FreeBSDism */ |