diff options
| author | matt <matt@NetBSD.org> | 1998-09-15 02:39:03 +0000 |
|---|---|---|
| committer | matt <matt@NetBSD.org> | 1998-09-15 02:39:03 +0000 |
| commit | 2633c65da573fea5df9f41e923247bb95df9b460 (patch) | |
| tree | 9a5e3559ebf92b2ef9f1f9eeada53ea5b3fb8b2a /sys/dev | |
| parent | 765a4daca2b4bf26c7a5d53326363b4ba892d36a (diff) | |
This commit fixes two bugs in the de driver. The first is that the
descriptor count gets miscounted on txprobes. The second (and more
important) is that transmit stalls should now be fixed. The problem
was not due to lack of ring resources but dmamaps. When Jason changed
the driver to use pre-allocated maps (instead of the dynamic ones I
used), and when there were no more maps, the driver just gave up instead
of calling tx_intr to free any transmitted but unreclaimed dma maps.
Since there was nothing being transmitted, no transmit interrupts
would fire to restore things (and OACTIVE prevented other transmits
from happenning). So it stayed starved until another interrupt cause
(like a received packet) "woke" it up.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/if_de.c | 69 | ||||
| -rw-r--r-- | sys/dev/pci/if_devar.h | 3 |
2 files changed, 48 insertions, 24 deletions
diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c index 94dae246fab..41c79c29e36 100644 --- a/sys/dev/pci/if_de.c +++ b/sys/dev/pci/if_de.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_de.c,v 1.76 1998/08/28 20:58:37 drochner Exp $ */ +/* $NetBSD: if_de.c,v 1.77 1998/09/15 02:39:03 matt Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -3694,6 +3694,8 @@ tulip_tx_intr( if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER) break; + ri->ri_free++; + descs++; d_flag = ri->ri_nextin->d_flag; if (d_flag & TULIP_DFLAG_TxLASTSEG) { if (d_flag & TULIP_DFLAG_TxSETUPPKT) { @@ -3794,8 +3796,6 @@ tulip_tx_intr( if (++ri->ri_nextin == ri->ri_last) ri->ri_nextin = ri->ri_first; - ri->ri_free++; - descs++; if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) sc->tulip_if.if_flags &= ~IFF_OACTIVE; } @@ -4189,6 +4189,7 @@ tulip_txput( TULIP_PRINTF_ARGS, (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : ""); sc->tulip_flags |= TULIP_WANTTXSTART; + sc->tulip_dbg.dbg_txput_finishes[0]++; goto finish; } #endif @@ -4220,36 +4221,45 @@ tulip_txput( free = ri->ri_free; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) + /* + * Reclaim some dma maps from if we are out. + */ + if (sc->tulip_txmaps_free == 0) + free += tulip_tx_intr(sc); if (sc->tulip_txmaps_free > 0) { map = sc->tulip_txmaps[--sc->tulip_txmaps_free]; } else { sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[1]++; +#endif goto finish; } error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); - if (error == EFBIG) { - /* - * The packet exceeds the number of transmit buffer - * entries that we can use for one packet, so we have - * to recopy it into one mbuf and then try again. - */ - m = tulip_mbuf_compress(m); - if (m == NULL) - goto finish; - error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); - if (error) { + if (error != 0) { + if (error == EFBIG) { + /* + * The packet exceeds the number of transmit buffer + * entries that we can use for one packet, so we have + * to recopy it into one mbuf and then try again. + */ + m = tulip_mbuf_compress(m); + if (m == NULL) { +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[2]++; +#endif + goto finish; + } + error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); + } + if (error != 0) { printf(TULIP_PRINTF_FMT ": unable to load tx map, " "error = %d\n", TULIP_PRINTF_ARGS, error); +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[3]++; +#endif goto finish; } - } else if (error != 0) { - /* - * Some other error (possibly resource shortage?) has ocurred. - * Report it. - */ - printf(TULIP_PRINTF_FMT ": unable to load tx map, error = %d\n", - TULIP_PRINTF_ARGS, error); - goto finish; } if ((free -= (map->dm_nsegs + 1) / 2) <= 0 /* @@ -4263,6 +4273,9 @@ tulip_txput( * mbuf and return. */ sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[4]++; +#endif goto finish; } for (; map->dm_nsegs - segcnt > 1; segcnt += 2) { @@ -4332,6 +4345,9 @@ tulip_txput( * mbuf and return. */ sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[1]++; +#endif goto finish; } } @@ -4434,9 +4450,11 @@ tulip_txput( * switch back to the single queueing ifstart. */ sc->tulip_flags &= ~TULIP_WANTTXSTART; - sc->tulip_if.if_start = tulip_ifstart_one; if (sc->tulip_txtimer == 0) sc->tulip_txtimer = TULIP_TXTIMER; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[5]++; +#endif /* * If we want a txstart, there must be not enough space in the @@ -4448,6 +4466,9 @@ tulip_txput( * WANTTXSTART thereby causing TXINTR to be cleared. */ finish: +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[6]++; +#endif if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) { sc->tulip_if.if_flags |= IFF_OACTIVE; sc->tulip_if.if_start = tulip_ifstart; @@ -4758,6 +4779,8 @@ tulip_ifstart( break; } } + if (sc->tulip_if.if_snd.ifq_head == NULL) + sc->tulip_if.if_start = tulip_ifstart_one; } TULIP_PERFEND(ifstart); diff --git a/sys/dev/pci/if_devar.h b/sys/dev/pci/if_devar.h index 6e9fbc779c0..7c4b3cb13af 100644 --- a/sys/dev/pci/if_devar.h +++ b/sys/dev/pci/if_devar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_devar.h,v 1.28 1998/08/13 02:10:53 eeh Exp $ */ +/* $NetBSD: if_devar.h,v 1.29 1998/09/15 02:39:03 matt Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -630,6 +630,7 @@ struct _tulip_softc_t { u_int32_t dbg_rxintrs; u_int32_t dbg_last_rxintrs; u_int32_t dbg_high_rxintrs_hz; + u_int32_t dbg_txput_finishes[8]; u_int32_t dbg_txprobes_ok[TULIP_MEDIA_MAX]; u_int32_t dbg_txprobes_failed[TULIP_MEDIA_MAX]; u_int32_t dbg_events[TULIP_MEDIAPOLL_MAX]; |
