diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c index 552fbc3..ff08180 100644 --- a/sys/dev/pci/if_de.c +++ b/sys/dev/pci/if_de.c @@ -205,10 +205,11 @@ void tulip_intr_handler(tulip_softc_t * const sc, int *progress_p); int tulip_intr_shared(void *arg); int tulip_intr_normal(void *arg); struct mbuf *tulip_mbuf_compress(struct mbuf *m); -struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int); +struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m); void tulip_txput_setup(tulip_softc_t * const sc); int tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data); void tulip_ifstart(struct ifnet *ifp); +void tulip_ifstart_one(struct ifnet *ifp); void tulip_ifwatchdog(struct ifnet *ifp); int tulip_busdma_allocmem(tulip_softc_t * const sc, size_t size, bus_dmamap_t *map_p, tulip_desc_t **desc_p); @@ -284,7 +285,7 @@ tulip_txprobe(tulip_softc_t * const sc) sc->tulip_flags |= TULIP_TXPROBE_ACTIVE; TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); - if ((m = tulip_txput(sc, m, 1)) != NULL) + if ((m = tulip_txput(sc, m)) != NULL) m_freem(m); sc->tulip_probe.probe_txprobes++; return (1); @@ -3808,7 +3809,7 @@ tulip_mbuf_compress(struct mbuf *m) } struct mbuf * -tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue) +tulip_txput(tulip_softc_t * const sc, struct mbuf *m) { TULIP_PERFSTART(txput) tulip_ringinfo_t * const ri = &sc->tulip_txinfo; @@ -3817,11 +3818,6 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue) u_int32_t d_status; bus_dmamap_t map; int error; - struct ifnet *ifp = &sc->tulip_if; -#ifdef DIAGNOSTIC - struct mbuf *ombuf = m; -#endif - int compressed = 0; #if defined(TULIP_DEBUG) if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { @@ -3882,19 +3878,6 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue) * entries that we can use for one packet, so we have * to recopy it into one mbuf and then try again. */ - struct mbuf *tmp; - if (!notonqueue) { -#ifdef DIAGNOSTIC - if (IF_IS_EMPTY(&ifp->if_snd)) - panic("%s: if_snd queue empty", ifp->if_xname); -#endif - IFQ_DEQUEUE(&ifp->if_snd, tmp); -#ifdef DIAGNOSTIC - if (tmp != ombuf) - panic("tulip_txput: different mbuf dequeued!"); -#endif - } - compressed = 1; m = tulip_mbuf_compress(m); if (m == NULL) { #if defined(TULIP_DEBUG) @@ -3965,19 +3948,6 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue) * The descriptors have been filled in. Now get ready * to transmit. */ - if (!compressed && !notonqueue) { - /* remove the mbuf from the queue */ - struct mbuf *tmp; -#ifdef DIAGNOSTIC - if (IF_IS_EMPTY(&ifp->if_snd)) - panic("%s: if_snd queue empty", ifp->if_xname); -#endif - IFQ_DEQUEUE(&ifp->if_snd, tmp); -#ifdef DIAGNOSTIC - if (tmp != ombuf) - panic("tulip_txput: different mbuf dequeued!"); -#endif - } ml_enqueue(&sc->tulip_txq, m); m = NULL; @@ -4214,12 +4184,6 @@ tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data) } /* - * the original dequeueing policy is dequeue-and-prepend if something - * goes wrong. - * the modification becomes a bit complicated since tulip_txput() might - * copy and modify the mbuf passed. - */ -/* * These routines gets called at device spl (from ether_output). */ @@ -4234,24 +4198,41 @@ tulip_ifstart(struct ifnet * const ifp) if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) tulip_txput_setup(sc); - while (!IFQ_IS_EMPTY(&sc->tulip_if.if_snd)) { - struct mbuf *m, *m0; - IFQ_POLL(&sc->tulip_if.if_snd, m); + while (!IFQ_IS_EMPTY(&ifp->if_snd)) { + struct mbuf *m; + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; - if ((m0 = tulip_txput(sc, m, 0)) != NULL) { - if (m0 != m) - /* should not happen */ - printf("tulip_if_start: txput failed!\n"); + if ((m = tulip_txput(sc, m)) != NULL) { + IFQ_REQUEUE(&ifp->if_snd, m); break; } } + + if (IFQ_IS_EMPTY(&ifp->if_snd)) + ifp->if_start = tulip_ifstart_one; } TULIP_PERFEND(ifstart); } void +tulip_ifstart_one(struct ifnet * const ifp) +{ + TULIP_PERFSTART(ifstart_one) + tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); + struct mbuf *m; + + if (sc->tulip_if.if_flags & IFF_RUNNING) { + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m != NULL && (m = tulip_txput(sc, m)) != NULL) + IFQ_REQUEUE(&ifp->if_snd, m); + } + + TULIP_PERFEND(ifstart_one); +} + +void tulip_ifwatchdog(struct ifnet *ifp) { TULIP_PERFSTART(ifwatchdog) diff --git a/sys/dev/pci/if_devar.h b/sys/dev/pci/if_devar.h index 33bd9f9..13a6852 100644 --- a/sys/dev/pci/if_devar.h +++ b/sys/dev/pci/if_devar.h @@ -570,6 +570,7 @@ struct _tulip_softc_t { struct tulip_perfstats { u_quad_t perf_intr_cycles; u_quad_t perf_ifstart_cycles; + u_quad_t perf_ifstart_one_cycles; u_quad_t perf_ifioctl_cycles; u_quad_t perf_ifwatchdog_cycles; u_quad_t perf_timeout_cycles; @@ -579,6 +580,7 @@ struct _tulip_softc_t { u_quad_t perf_rxget_cycles; unsigned perf_intr; unsigned perf_ifstart; + unsigned perf_ifstart_one; unsigned perf_ifioctl; unsigned perf_ifwatchdog; unsigned perf_timeout;