mirror of
https://github.com/opnsense/src.git
synced 2026-06-03 13:58:30 -04:00
Add DEVICE_POLLING support to the "rl" driver.
The diffs are very similar to the ones for the "sis" driver. MFC After: 5 days
This commit is contained in:
parent
700246cb79
commit
7632341a30
2 changed files with 73 additions and 6 deletions
|
|
@ -1183,6 +1183,13 @@ static void rl_rxeof(sc)
|
|||
max_bytes = limit - cur_rx;
|
||||
|
||||
while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) {
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifp->if_ipending & IFF_POLLING) {
|
||||
if (sc->rxcycles <= 0)
|
||||
break;
|
||||
sc->rxcycles--;
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx;
|
||||
rxstat = *(u_int32_t *)rxbufpos;
|
||||
|
||||
|
|
@ -1348,6 +1355,45 @@ static void rl_tick(xsc)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static void
|
||||
rl_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct rl_softc *sc = ifp->if_softc;
|
||||
|
||||
RL_LOCK(sc);
|
||||
if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
|
||||
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sc->rxcycles = count;
|
||||
rl_rxeof(sc);
|
||||
rl_txeof(sc);
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
rl_start(ifp);
|
||||
|
||||
if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
|
||||
u_int16_t status;
|
||||
|
||||
status = CSR_READ_2(sc, RL_ISR);
|
||||
if (status)
|
||||
CSR_WRITE_2(sc, RL_ISR, status);
|
||||
|
||||
/*
|
||||
* XXX check behaviour on receiver stalls.
|
||||
*/
|
||||
|
||||
if (status & RL_ISR_SYSTEM_ERR) {
|
||||
rl_reset(sc);
|
||||
rl_init(sc);
|
||||
}
|
||||
}
|
||||
done:
|
||||
RL_UNLOCK(sc);
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
static void rl_intr(arg)
|
||||
void *arg;
|
||||
{
|
||||
|
|
@ -1364,8 +1410,15 @@ static void rl_intr(arg)
|
|||
RL_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
/* Disable interrupts. */
|
||||
CSR_WRITE_2(sc, RL_IMR, 0x0000);
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifp->if_ipending & IFF_POLLING)
|
||||
goto done;
|
||||
if (ether_poll_register(rl_poll, ifp)) { /* ok, disable interrupts */
|
||||
CSR_WRITE_2(sc, RL_IMR, 0x0000);
|
||||
rl_poll(ifp, 0, 1);
|
||||
goto done;
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
for (;;) {
|
||||
|
||||
|
|
@ -1392,12 +1445,12 @@ static void rl_intr(arg)
|
|||
|
||||
}
|
||||
|
||||
/* Re-enable interrupts. */
|
||||
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
|
||||
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
rl_start(ifp);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
done:
|
||||
#endif
|
||||
RL_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
|
|
@ -1589,6 +1642,14 @@ static void rl_init(xsc)
|
|||
*/
|
||||
rl_setmulti(sc);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
/*
|
||||
* Disable interrupts if we are polling.
|
||||
*/
|
||||
if (ifp->if_ipending & IFF_POLLING)
|
||||
CSR_WRITE_2(sc, RL_IMR, 0);
|
||||
else /* otherwise ... */
|
||||
#endif /* DEVICE_POLLING */
|
||||
/*
|
||||
* Enable interrupts.
|
||||
*/
|
||||
|
|
@ -1732,6 +1793,10 @@ static void rl_stop(sc)
|
|||
ifp->if_timer = 0;
|
||||
|
||||
untimeout(rl_tick, sc, sc->rl_stat_ch);
|
||||
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
|
||||
#ifdef DEVICE_POLLING
|
||||
ether_poll_deregister(ifp);
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
CSR_WRITE_1(sc, RL_COMMAND, 0x00);
|
||||
CSR_WRITE_2(sc, RL_IMR, 0x0000);
|
||||
|
|
@ -1752,7 +1817,6 @@ static void rl_stop(sc)
|
|||
}
|
||||
}
|
||||
|
||||
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
|
||||
RL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,6 +378,9 @@ struct rl_softc {
|
|||
struct callout_handle rl_stat_ch;
|
||||
struct mtx rl_mtx;
|
||||
int suspended; /* 0 = normal 1 = suspended */
|
||||
#ifdef DEVICE_POLLING
|
||||
int rxcycles;
|
||||
#endif
|
||||
|
||||
u_int32_t saved_maps[5]; /* pci data */
|
||||
u_int32_t saved_biosaddr;
|
||||
|
|
|
|||
Loading…
Reference in a new issue