Add support for DEVICE_POLLING.

PR: kern/44772
Submitted by: Takashi Oono <takashi@yha.att.ne.jp>
MFC after: 1 week
This commit is contained in:
simokawa 2002-11-06 15:50:32 +00:00
parent e6dea8f633
commit 131fe3293a
2 changed files with 79 additions and 0 deletions

View File

@ -1340,6 +1340,14 @@ nge_rxeof(sc)
struct mbuf *m0 = NULL;
u_int32_t extsts;
#ifdef DEVICE_POLLING
if (ifp->if_ipending & IFF_POLLING) {
if (sc->rxcycles <= 0)
break;
sc->rxcycles--;
}
#endif /* DEVICE_POLLING */
cur_rx = &sc->nge_ldata->nge_rx_list[i];
rxstat = cur_rx->nge_rxstat;
extsts = cur_rx->nge_extsts;
@ -1545,6 +1553,52 @@ nge_tick(xsc)
return;
}
#ifdef DEVICE_POLLING
static poll_handler_t nge_poll;
static void
nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct nge_softc *sc = ifp->if_softc;
if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
CSR_WRITE_4(sc, NGE_IER, 1);
return;
}
/*
* On the nge, reading the status register also clears it.
* So before returning to intr mode we must make sure that all
* possible pending sources of interrupts have been served.
* In practice this means run to completion the *eof routines,
* and then call the interrupt routine
*/
sc->rxcycles = count;
nge_rxeof(sc);
nge_txeof(sc);
if (ifp->if_snd.ifq_head != NULL)
nge_start(ifp);
if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
u_int32_t status;
/* Reading the ISR register clears all interrupts. */
status = CSR_READ_4(sc, NGE_ISR);
if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW))
nge_rxeof(sc);
if (status & (NGE_ISR_RX_IDLE))
NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
if (status & NGE_ISR_SYSERR) {
nge_reset(sc);
nge_init(sc);
}
}
}
#endif /* DEVICE_POLLING */
static void
nge_intr(arg)
void *arg;
@ -1556,6 +1610,16 @@ nge_intr(arg)
sc = arg;
ifp = &sc->arpcom.ac_if;
#ifdef DEVICE_POLLING
if (ifp->if_ipending & IFF_POLLING)
return;
if (ether_poll_register(nge_poll, ifp)) { /* ok, disable interrupts */
CSR_WRITE_4(sc, NGE_IER, 0);
nge_poll(ifp, 0, 1);
return;
}
#endif /* DEVICE_POLLING */
/* Supress unwanted interrupts */
if (!(ifp->if_flags & IFF_UP)) {
nge_stop(sc);
@ -1927,6 +1991,15 @@ nge_init(xsc)
* Enable interrupts.
*/
CSR_WRITE_4(sc, NGE_IMR, NGE_INTRS);
#ifdef DEVICE_POLLING
/*
* ... only enable interrupts if we are not polling, make sure
* they are off otherwise.
*/
if (ifp->if_ipending & IFF_POLLING)
CSR_WRITE_4(sc, NGE_IER, 0);
else
#endif /* DEVICE_POLLING */
CSR_WRITE_4(sc, NGE_IER, 1);
/* Enable receiver and transmitter. */
@ -2183,6 +2256,9 @@ nge_stop(sc)
}
untimeout(nge_tick, sc, sc->nge_stat_ch);
#ifdef DEVICE_POLLING
ether_poll_deregister(ifp);
#endif
CSR_WRITE_4(sc, NGE_IER, 0);
CSR_WRITE_4(sc, NGE_IMR, 0);
NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE);

View File

@ -659,6 +659,9 @@ struct nge_softc {
struct mtx nge_mtx;
u_int8_t nge_tbi;
struct ifmedia nge_ifmedia;
#ifdef DEVICE_POLLING
int rxcycles;
#endif
};
/*