summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2001-10-02 22:21:21 +0000
committermjacob <mjacob@FreeBSD.org>2001-10-02 22:21:21 +0000
commit1a3f19d0368bb8140f71240821abfd58398b8676 (patch)
treeb1fd2f3d7081162b285d173f446d07355dadd5f6 /sys/pci
parent6ac4dc906e3f2d0f1d319ca4c32047c25194eaa6 (diff)
downloadFreeBSD-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.c46
-rw-r--r--sys/pci/if_wxreg.h2
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
OpenPOWER on IntegriCloud