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:
parent
e6dea8f633
commit
131fe3293a
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user