summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2001-06-13 23:19:18 +0000
committerJason Wright <jason@cvs.openbsd.org>2001-06-13 23:19:18 +0000
commitf5c8be48ee0c293957d240b9e2e69689630d86ee (patch)
tree66125a75af892b77f48e4f9ea77bf6c67408bb4a /sys/dev
parent729720c4255908257e88572bd15738e3e890d1e5 (diff)
From NetBSD, 82562 requires a nop before a resume (tested by mickey)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/fxp.c78
-rw-r--r--sys/dev/ic/fxpvar.h6
-rw-r--r--sys/dev/pci/if_fxp_pci.c39
3 files changed, 78 insertions, 45 deletions
diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c
index 3428da957b4..81bd01421b2 100644
--- a/sys/dev/ic/fxp.c
+++ b/sys/dev/ic/fxp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fxp.c,v 1.17 2001/05/27 01:32:21 art Exp $ */
+/* $OpenBSD: fxp.c,v 1.18 2001/06/13 23:19:17 jason Exp $ */
/* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */
/*
@@ -182,6 +182,7 @@ void fxp_read_eeprom __P((struct fxp_softc *, u_int16_t *,
int, int));
void fxp_stats_update __P((void *));
void fxp_mc_setup __P((struct fxp_softc *));
+static __inline void fxp_scb_cmd __P((struct fxp_softc *, u_int8_t));
/*
* Set initial transmit threshold at 64 (512 bytes). This is
@@ -740,6 +741,8 @@ tbdinit:
}
}
+volatile int _fxp_debugit;
+
/*
* Process interface interrupts.
*/
@@ -750,7 +753,7 @@ fxp_intr(arg)
struct fxp_softc *sc = arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
u_int8_t statack;
- int claimed = 0;
+ int claimed = 0, rnr;
/*
* If the interface isn't running, don't try to
@@ -767,6 +770,8 @@ fxp_intr(arg)
while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
claimed = 1;
+ rnr = 0;
+
/*
* First ACK all the interrupts in this pass.
*/
@@ -782,7 +787,9 @@ fxp_intr(arg)
(txp->cb_status & FXP_CB_STATUS_C) != 0;
txp = txp->next) {
if (txp->mb_head != NULL) {
+ _fxp_debugit = 1;
m_freem(txp->mb_head);
+ _fxp_debugit = 0;
txp->mb_head = NULL;
}
sc->tx_queued--;
@@ -814,6 +821,11 @@ rcvloop:
if (*(u_int16_t *)(rfap +
offsetof(struct fxp_rfa, rfa_status)) &
FXP_RFA_STATUS_C) {
+ if (*(u_int16_t *)(rfap +
+ offsetof(struct fxp_rfa, rfa_status)) &
+ FXP_RFA_STATUS_RNR)
+ rnr = 1;
+
/*
* Remove first packet from the chain.
*/
@@ -835,7 +847,9 @@ rcvloop:
(MCLBYTES - 1);
if (total_len <
sizeof(struct ether_header)) {
+ _fxp_debugit = 2;
m_freem(m);
+ _fxp_debugit = 0;
goto rcvloop;
}
m->m_pkthdr.rcvif = ifp;
@@ -855,13 +869,12 @@ rcvloop:
}
goto rcvloop;
}
- if (statack & FXP_SCB_STATACK_RNR) {
+ if (rnr) {
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
vtophys(sc->rfa_headm->m_ext.ext_buf) +
RFA_ALIGNMENT_FUDGE);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND,
- FXP_SCB_COMMAND_RU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
}
}
}
@@ -933,8 +946,7 @@ fxp_stats_update(arg)
/*
* Start another stats dump.
*/
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND,
- FXP_SCB_COMMAND_CU_DUMPRESET);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
} else {
/*
* A previous command is still waiting to be accepted.
@@ -1044,6 +1056,22 @@ fxp_watchdog(ifp)
fxp_init(sc);
}
+/*
+ * Submit a command to the i82557.
+ */
+static __inline void
+fxp_scb_cmd(sc, cmd)
+ struct fxp_softc *sc;
+ u_int8_t cmd;
+{
+ if (cmd == FXP_SCB_COMMAND_CU_RESUME &&
+ (sc->sc_flags & FXPF_FIX_RESUME_BUG) != 0) {
+ CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_CB_COMMAND_NOP);
+ fxp_scb_wait(sc);
+ }
+ CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
+}
+
void
fxp_init(xsc)
void *xsc;
@@ -1068,17 +1096,17 @@ fxp_init(xsc)
* sets it up for regular linear addressing.
*/
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_BASE);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
fxp_scb_wait(sc);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_BASE);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
/*
* Initialize base of dump-stats buffer.
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(sc->fxp_stats));
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_DUMP_ADR);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
/*
* We temporarily use memory that contains the TxCB list to
@@ -1135,7 +1163,7 @@ fxp_init(xsc)
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
while (!(cbp->cb_status & FXP_CB_STATUS_C));
@@ -1154,7 +1182,7 @@ fxp_init(xsc)
* Start the IAS (Individual Address Setup) command/DMA.
*/
fxp_scb_wait(sc);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
while (!(cb_ias->cb_status & FXP_CB_STATUS_C));
@@ -1180,7 +1208,7 @@ fxp_init(xsc)
sc->tx_queued = 1;
fxp_scb_wait(sc);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/*
* Initialize receiver buffer area - RFA.
@@ -1188,7 +1216,7 @@ fxp_init(xsc)
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
vtophys(sc->rfa_headm->m_ext.ext_buf) + RFA_ALIGNMENT_FUDGE);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
/*
* Set current media.
@@ -1345,8 +1373,18 @@ void
fxp_statchg(self)
struct device *self;
{
+ struct fxp_softc *sc = (struct fxp_softc *)self;
- /* XXX Update ifp->if_baudrate */
+ /*
+ * Determine whether or not we have to work-around the
+ * Resume Bug.
+ */
+ if (sc->sc_flags & FXPF_HAS_RESUME_BUG) {
+ if (IFM_TYPE(sc->sc_mii.mii_media_active) == IFM_10_T)
+ sc->sc_flags |= FXPF_FIX_RESUME_BUG;
+ else
+ sc->sc_flags &= ~FXPF_FIX_RESUME_BUG;
+ }
}
void
@@ -1542,11 +1580,9 @@ fxp_mc_setup(sc)
* Issue a resume in case the CU has just suspended.
*/
fxp_scb_wait(sc);
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
- /*
- * Set a 5 second timer just in case we don't hear from the
- * card again.
- */
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
+
+ /* Set a 5 watchdog timer in case the chip flakes out. */
ifp->if_timer = 5;
return;
@@ -1601,7 +1637,7 @@ fxp_mc_setup(sc)
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&mcsp->cb_status));
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
ifp->if_timer = 2;
return;
diff --git a/sys/dev/ic/fxpvar.h b/sys/dev/ic/fxpvar.h
index f41abdc9755..d34e0a40268 100644
--- a/sys/dev/ic/fxpvar.h
+++ b/sys/dev/ic/fxpvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fxpvar.h,v 1.4 2000/09/17 17:08:16 aaron Exp $ */
+/* $OpenBSD: fxpvar.h,v 1.5 2001/06/13 23:19:17 jason Exp $ */
/* $NetBSD: if_fxpvar.h,v 1.1 1997/06/05 02:01:58 thorpej Exp $ */
/*
@@ -51,6 +51,10 @@ struct fxp_softc {
struct mbuf *rfa_headm; /* first mbuf in receive frame area */
struct mbuf *rfa_tailm; /* last mbuf in receive frame area */
struct fxp_cb_tx *cbl_first; /* first active TxCB in list */
+ int sc_flags; /* misc. flags */
+#define FXPF_HAS_RESUME_BUG 0x08 /* has the resume bug */
+#define FXPF_FIX_RESUME_BUG 0x10 /* currently need to work-around
+ the resume bug */
int tx_queued; /* # of active TxCB's */
int need_mcsetup; /* multicast filter needs programming */
struct fxp_cb_tx *cbl_last; /* last active TxCB in list */
diff --git a/sys/dev/pci/if_fxp_pci.c b/sys/dev/pci/if_fxp_pci.c
index 7c34c0792c7..68ad759e4c1 100644
--- a/sys/dev/pci/if_fxp_pci.c
+++ b/sys/dev/pci/if_fxp_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_fxp_pci.c,v 1.5 2000/12/29 14:03:01 art Exp $ */
+/* $OpenBSD: if_fxp_pci.c,v 1.6 2001/06/13 23:19:16 jason Exp $ */
/*
* Copyright (c) 1995, David Greenman
@@ -58,21 +58,6 @@
#include <netinet/ip.h>
#endif
-#ifdef IPX
-#include <netipx/ipx.h>
-#include <netipx/ipx_if.h>
-#endif
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#include <net/bpfdesc.h>
-#endif
-
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/device.h>
@@ -173,13 +158,21 @@ fxp_pci_attach(parent, self, aux)
return;
}
- /*
- * revisions
- * 2 = 82557
- * 4-6 = 82558
- * 8 = 82559
- */
- sc->not_82557 = (rev >= 4) ? 1 : 0;
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82562:
+ sc->sc_flags |= FXPF_HAS_RESUME_BUG;
+ sc->not_82557 = 1;
+ break;
+ default:
+ /*
+ * revisions
+ * 2 = 82557
+ * 4-6 = 82558
+ * 8 = 82559
+ */
+ sc->not_82557 = (rev >= 4) ? 1 : 0;
+ break;
+ }
/* Do generic parts of attach. */
if (fxp_attach_common(sc, enaddr, intrstr)) {