In some cases, RX descriptors that are signalled to have been completed

by the hardware are still marked as owned. Handle this by installing a
timeout handler to collect this descriptor to avoid having received
packets remain unhandled until the next one arrives.
This commit is contained in:
Thomas Moestl 2002-03-23 19:43:15 +00:00
parent 038148d678
commit 0d80b9bd88
2 changed files with 26 additions and 3 deletions

View File

@ -90,6 +90,7 @@ static void gem_setladrf(struct gem_softc *);
struct mbuf *gem_get(struct gem_softc *, int, int);
static void gem_eint(struct gem_softc *, u_int);
static void gem_rint(struct gem_softc *);
static void gem_rint_timeout(void *);
static void gem_tint(struct gem_softc *);
#ifdef notyet
static void gem_power(int, void *);
@ -299,6 +300,7 @@ gem_attach(sc)
#endif
callout_init(&sc->sc_tick_ch, 0);
callout_init(&sc->sc_rx_ch, 0);
return (0);
/*
@ -1392,6 +1394,14 @@ gem_tint(sc)
gem_start(ifp);
}
static void
gem_rint_timeout(arg)
void *arg;
{
gem_rint((struct gem_softc *)arg);
}
/*
* Receive interrupt.
*/
@ -1408,6 +1418,7 @@ gem_rint(sc)
u_int64_t rxstat;
int i, len;
callout_stop(&sc->sc_rx_ch);
DPRINTF(sc, ("%s: gem_rint\n", device_get_name(sc->sc_dev)));
CTR1(KTR_GEM, "%s: gem_rint", device_get_name(sc->sc_dev));
/*
@ -1427,11 +1438,16 @@ gem_rint(sc)
rxstat = GEM_DMA_READ(sc, sc->sc_rxdescs[i].gd_flags);
if (rxstat & GEM_RD_OWN) {
printf("gem_rint: completed descriptor "
"still owned %d\n", i);
/*
* We have processed all of the receive buffers.
* The descriptor is still marked as owned, although
* it is supposed to have completed. This has been
* observed on some machines. Just exiting here
* might leave the packet sitting around until another
* one arrives to trigger a new interrupt, which is
* generally undesirable, so set up a timeout.
*/
callout_reset(&sc->sc_rx_ch, GEM_RXOWN_TICKS,
gem_rint_timeout, sc);
break;
}

View File

@ -59,6 +59,12 @@
#define GEM_NRXDESC_MASK (GEM_NRXDESC - 1)
#define GEM_NEXTRX(x) ((x + 1) & GEM_NRXDESC_MASK)
/*
* How many ticks to wait until to retry on a RX descriptor that is still owned
* by the hardware.
*/
#define GEM_RXOWN_TICKS (hz / 50)
/*
* Control structures are DMA'd to the GEM chip. We allocate them in
* a single clump that maps to a single DMA segment to make several things
@ -132,6 +138,7 @@ struct gem_softc {
struct mii_data *sc_mii; /* MII media control */
device_t sc_dev; /* generic device information */
struct callout sc_tick_ch; /* tick callout */
struct callout sc_rx_ch; /* delayed rx callout */
/* The following bus handles are to be provided by the bus front-end */
bus_space_tag_t sc_bustag; /* bus tag */