summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1999-11-17 03:23:53 +0000
committerJason Wright <jason@cvs.openbsd.org>1999-11-17 03:23:53 +0000
commitbad7fa2a6ad2d84ee9916aac71a2ef49aa5804aa (patch)
tree7f1d4924999803e27f07b0c74e8f4436bb5d8611 /sys
parent326cf5dab2796d71d20df6608e0b56899c34354d (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.c156
-rw-r--r--sys/dev/pci/if_rlreg.h165
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
*/