diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-10-02 22:21:21 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-10-02 22:21:21 +0000 |
commit | 1a3f19d0368bb8140f71240821abfd58398b8676 (patch) | |
tree | b1fd2f3d7081162b285d173f446d07355dadd5f6 /sys/pci | |
parent | 6ac4dc906e3f2d0f1d319ca4c32047c25194eaa6 (diff) | |
download | FreeBSD-src-1a3f19d0368bb8140f71240821abfd58398b8676.zip FreeBSD-src-1a3f19d0368bb8140f71240821abfd58398b8676.tar.gz |
Various fixes and improvements- some from the folks at Sitara Networks (thx)
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_wx.c | 46 | ||||
-rw-r--r-- | sys/pci/if_wxreg.h | 2 |
2 files changed, 34 insertions, 14 deletions
diff --git a/sys/pci/if_wx.c b/sys/pci/if_wx.c index d9ef678..e9aa808 100644 --- a/sys/pci/if_wx.c +++ b/sys/pci/if_wx.c @@ -37,6 +37,12 @@ */ /* + * Many bug fixes gratefully acknowledged from: + * + * The folks at Sitara Networks + */ + +/* * Options */ @@ -254,12 +260,15 @@ wx_attach(device_t dev) error = ENXIO; goto out; } + + /* + * Let the BIOS do it's job- but check for sanity. + */ val = pci_read_config(dev, PCIR_CACHELNSZ, 1); - if (val != 0x10) { - pci_write_config(dev, PCIR_CACHELNSZ, 0x10, 1); + if (val < 4 || val > 32) { + pci_write_config(dev, PCIR_CACHELNSZ, 8, 1); } - /* * Map control/status registers. */ @@ -702,12 +711,12 @@ static void wx_start(struct ifnet *ifp) { wx_softc_t *sc = SOFTC_IFP(ifp); - u_int16_t cidx, nactv; + u_int16_t widx = WX_MAX_TDESC, cidx, nactv; WX_LOCK(sc); DPRINTF(sc, ("%s: wx_start\n", sc->wx_name)); nactv = sc->tactive; - while (nactv < WX_MAX_TDESC) { + while (nactv < WX_MAX_TDESC - 1) { int ndesc; int gctried = 0; struct mbuf *m, *mb_head; @@ -827,13 +836,10 @@ wx_start(struct ifnet *ifp) sc->tnxtfree = cidx; sc->tactive = nactv; ifp->if_timer = 10; - if (IS_WISEMAN(sc)) { - WRITE_CSR(sc, WXREG_TDT, cidx); - } else { - WRITE_CSR(sc, WXREG_TDT_LIVENGOOD, cidx); - } if (ifp->if_bpf) bpf_mtap(WX_BPFTAP_ARG(ifp), mb_head); + /* defer xmit until we've got them all */ + widx = cidx; continue; } @@ -883,7 +889,15 @@ wx_start(struct ifnet *ifp) goto again; } - if (sc->tactive == WX_MAX_TDESC) { + if (widx < WX_MAX_TDESC) { + if (IS_WISEMAN(sc)) { + WRITE_CSR(sc, WXREG_TDT, widx); + } else { + WRITE_CSR(sc, WXREG_TDT_LIVENGOOD, widx); + } + } + + if (sc->tactive == WX_MAX_TDESC - 1) { sc->wx_xmitblocked++; ifp->if_flags |= IFF_OACTIVE; } @@ -918,6 +932,9 @@ wx_intr(void *arg) wx_handle_link_intr(sc); } wx_handle_rxint(sc); + if (sc->wx_icr & WXISR_TXQE) { + wx_gc(sc); + } if (sc->wx_if.if_snd.ifq_head != NULL) { wx_start(&sc->wx_if); } @@ -1285,7 +1302,7 @@ wx_gc(wx_softc_t *sc) sc->tbsyf = txpkt->next; txpkt = sc->tbsyf; } - if (sc->tactive < WX_MAX_TDESC) { + if (sc->tactive < WX_MAX_TDESC - 1) { ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; } @@ -1660,7 +1677,10 @@ wx_init(void *xsc) WRITE_CSR(sc, WXREG_RDH0, 0); WRITE_CSR(sc, WXREG_RDT0, (WX_MAX_RDESC - RXINCR)); } else { - WRITE_CSR(sc, WXREG_RDTR0_LIVENGOOD, WXRDTR_FPD); + /* + * The delay should yield ~10us receive interrupt delay + */ + WRITE_CSR(sc, WXREG_RDTR0_LIVENGOOD, WXRDTR_FPD | 0x40); WRITE_CSR(sc, WXREG_RDBA0_LO_LIVENGOOD, vtophys((vm_offset_t)&sc->rdescriptors[0])); WRITE_CSR(sc, WXREG_RDBA0_HI_LIVENGOOD, 0); diff --git a/sys/pci/if_wxreg.h b/sys/pci/if_wxreg.h index 2b7deaf..a23efba 100644 --- a/sys/pci/if_wxreg.h +++ b/sys/pci/if_wxreg.h @@ -303,7 +303,7 @@ typedef struct { #define WXISR_GPI_EN3 0x4000 #define WXIENABLE_DEFAULT \ - (WXISR_RXO | WXISR_RXT0 | WXISR_RXDMT0 | WXISR_RXSEQ | \ + (WXISR_RXO | WXISR_RXT0 | WXISR_RXDMT0 | WXISR_RXSEQ | WXISR_TXQE |\ WXISR_LSC | WXISR_PCIE | WXISR_GPI_EN1) #define WXDISABLE 0xffffffff |