diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2001-06-13 23:19:18 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2001-06-13 23:19:18 +0000 |
commit | f5c8be48ee0c293957d240b9e2e69689630d86ee (patch) | |
tree | 66125a75af892b77f48e4f9ea77bf6c67408bb4a /sys/dev | |
parent | 729720c4255908257e88572bd15738e3e890d1e5 (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.c | 78 | ||||
-rw-r--r-- | sys/dev/ic/fxpvar.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/if_fxp_pci.c | 39 |
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)) { |