diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2001-08-10 15:02:06 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2001-08-10 15:02:06 +0000 |
commit | ad6a16906660b685acbdf0fa6dd42077fae77c8e (patch) | |
tree | db34752ecfa40395f960e0adee06a0f84efcd7bb | |
parent | e74d8b0e63cc105424cabde08fe5f128e82ff1ca (diff) |
- make transmit use linked lists not indexed arrays (more like it was when I started)
- also, only bus_dmamap_unload() loaded maps in fxp_stop()
-rw-r--r-- | sys/dev/ic/fxp.c | 65 | ||||
-rw-r--r-- | sys/dev/ic/fxpvar.h | 6 |
2 files changed, 31 insertions, 40 deletions
diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c index 3e4703a1493..0859bda0a01 100644 --- a/sys/dev/ic/fxp.c +++ b/sys/dev/ic/fxp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fxp.c,v 1.23 2001/08/09 21:12:51 jason Exp $ */ +/* $OpenBSD: fxp.c,v 1.24 2001/08/10 15:02:05 jason Exp $ */ /* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */ /* @@ -334,6 +334,7 @@ fxp_attach_common(sc, enaddr, intrstr) } sc->txs[i].tx_mbuf = NULL; sc->txs[i].tx_cb = sc->sc_ctrl->tx_cb + i; + sc->txs[i].tx_next = &sc->txs[(i + 1) & FXP_TXCB_MASK]; } bzero(sc->sc_ctrl, sizeof(struct fxp_ctrl)); @@ -631,25 +632,22 @@ fxp_start(ifp) struct ifnet *ifp; { struct fxp_softc *sc = ifp->if_softc; - struct fxp_txsw *txs; + struct fxp_txsw *txs = sc->sc_cbt_prod; struct fxp_cb_tx *txc; struct mbuf *m0, *m = NULL; - int prod, oprod, cnt, seg; + int cnt = sc->sc_cbt_cnt, seg; if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING) return; - prod = sc->tx_prod; - oprod = (prod == 0) ? oprod = FXP_NTXCB - 1 : prod - 1; - cnt = sc->tx_cnt; - txs = &sc->txs[prod]; - while (1) { if (cnt >= (FXP_NTXCB - 1)) { ifp->if_flags |= IFF_OACTIVE; break; } + txs = txs->tx_next; + IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; @@ -702,20 +700,17 @@ fxp_start(ifp) } ++cnt; - if (++prod == FXP_NTXCB) { - prod = 0; - txs = sc->txs; - } else - txs++; + sc->sc_cbt_prod = txs; } - if (cnt != sc->tx_cnt) { + if (cnt != sc->sc_cbt_cnt) { /* We enqueued at least one. */ ifp->if_timer = 5; - txc->cb_command |= FXP_CB_COMMAND_I | FXP_CB_COMMAND_S; - sc->txs[oprod].tx_cb->cb_command &= - ~(FXP_CB_COMMAND_S); + txs = sc->sc_cbt_prod; + txs->tx_cb->cb_command |= FXP_CB_COMMAND_I | FXP_CB_COMMAND_S; + sc->sc_cbt_prev->tx_cb->cb_command &= ~FXP_CB_COMMAND_S; + sc->sc_cbt_prev = txs; bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -723,8 +718,7 @@ fxp_start(ifp) fxp_scb_wait(sc); fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); - sc->tx_prod = prod; - sc->tx_cnt = cnt; + sc->sc_cbt_cnt = cnt; } } @@ -766,15 +760,14 @@ fxp_intr(arg) * Free any finished transmit mbuf chains. */ if (statack & (FXP_SCB_STATACK_CXTNO|FXP_SCB_STATACK_CNA)) { - int txcnt = sc->tx_cnt, txcons = sc->tx_cons; - struct fxp_txsw *txs = &sc->txs[txcons]; - struct fxp_cb_tx *txc = txs->tx_cb; + int txcnt = sc->sc_cbt_cnt; + struct fxp_txsw *txs = sc->sc_cbt_cons; bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); while ((txcnt > 0) && - (txc->cb_status & FXP_CB_STATUS_C)) { + (txs->tx_cb->cb_status & FXP_CB_STATUS_C)) { if (txs->tx_mbuf != NULL) { bus_dmamap_sync(sc->sc_dmat, txs->tx_map, BUS_DMASYNC_POSTREAD); @@ -784,15 +777,10 @@ fxp_intr(arg) txs->tx_mbuf = NULL; } --txcnt; - if (++txcons == FXP_NTXCB) { - txs = sc->txs; - txcons = 0; - } else - txs++; - txc = txs->tx_cb; + txs = txs->tx_next; } - sc->tx_cons = txcons; - sc->tx_cnt = txcnt; + sc->sc_cbt_cons = txs; + sc->sc_cbt_cnt = txcnt; ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; @@ -997,11 +985,13 @@ fxp_stop(sc, drain) * Release any xmit buffers. */ for (i = 0; i < FXP_NTXCB; i++) { - bus_dmamap_unload(sc->sc_dmat, sc->txs[i].tx_map); - m_freem(sc->txs[i].tx_mbuf); - sc->txs[i].tx_mbuf = NULL; + if (sc->txs[i].tx_mbuf != NULL) { + bus_dmamap_unload(sc->sc_dmat, sc->txs[i].tx_map); + m_freem(sc->txs[i].tx_mbuf); + sc->txs[i].tx_mbuf = NULL; + } } - sc->tx_prod = sc->tx_cons = sc->tx_cnt = 0; + sc->sc_cbt_cnt = 0; if (drain) { /* @@ -1208,9 +1198,8 @@ fxp_init(xsc) * Set the suspend flag on the first TxCB and start the control * unit. It will execute the NOP and then suspend. */ - sc->tx_cons = 0; - sc->tx_prod = 1; - sc->tx_cnt = 1; + sc->sc_cbt_prev = sc->sc_cbt_prod = sc->sc_cbt_cons = sc->txs; + sc->sc_cbt_cnt = 1; sc->sc_ctrl->tx_cb[0].cb_command = FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S | FXP_CB_COMMAND_I; bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, diff --git a/sys/dev/ic/fxpvar.h b/sys/dev/ic/fxpvar.h index d2fd387715e..ba8516e5a96 100644 --- a/sys/dev/ic/fxpvar.h +++ b/sys/dev/ic/fxpvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fxpvar.h,v 1.6 2001/08/09 21:12:51 jason Exp $ */ +/* $OpenBSD: fxpvar.h,v 1.7 2001/08/10 15:02:05 jason Exp $ */ /* $NetBSD: if_fxpvar.h,v 1.1 1997/06/05 02:01:58 thorpej Exp $ */ /* @@ -50,6 +50,7 @@ * for functional grouping. */ struct fxp_txsw { + struct fxp_txsw *tx_next; struct mbuf *tx_mbuf; bus_dmamap_t tx_map; struct fxp_cb_tx *tx_cb; @@ -90,7 +91,8 @@ struct fxp_softc { void *sc_sdhook; /* shutdownhook */ void *sc_powerhook; /* powerhook */ struct fxp_txsw txs[FXP_NTXCB]; - int tx_cons, tx_prod, tx_cnt; + struct fxp_txsw *sc_cbt_cons, *sc_cbt_prod, *sc_cbt_prev; + int sc_cbt_cnt; bus_dmamap_t tx_cb_map; bus_dma_segment_t sc_cb_seg; int sc_cb_nseg; |