xl(4) meets polling(4). Hardware for this work kindly provided by
Eric Masson. MFC after: 3 weeks
This commit is contained in:
parent
4a650cc291
commit
77d23c9bc3
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 14, 2004
|
||||
.Dd March 26, 2005
|
||||
.Dt POLLING 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -185,6 +185,7 @@ As of this writing, the
|
||||
.Xr fxp 4 ,
|
||||
.Xr ixgb 4 ,
|
||||
.Xr nge 4 ,
|
||||
.Xr polling 4 ,
|
||||
.Xr re 4 ,
|
||||
.Xr rl 4 ,
|
||||
.Xr sf 4 ,
|
||||
|
@ -240,6 +240,7 @@ the author considers it a manufacturing defect.
|
||||
.Xr netintro 4 ,
|
||||
.Xr ng_ether 4 ,
|
||||
.Xr pccard 4 ,
|
||||
.Xr polling 4 ,
|
||||
.Xr ifconfig 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
119
sys/pci/if_xl.c
119
sys/pci/if_xl.c
@ -245,6 +245,11 @@ static void xl_shutdown(device_t);
|
||||
static int xl_suspend(device_t);
|
||||
static int xl_resume(device_t);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
static void xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
static int xl_ifmedia_upd(struct ifnet *);
|
||||
static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
||||
|
||||
@ -1484,6 +1489,9 @@ xl_attach(device_t dev)
|
||||
ifp->if_capabilities |= IFCAP_HWCSUM;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEVICE_POLLING
|
||||
ifp->if_capabilities |= IFCAP_POLLING;
|
||||
#endif /* DEVICE_POLLING */
|
||||
ifp->if_start = xl_start;
|
||||
ifp->if_watchdog = xl_watchdog;
|
||||
ifp->if_init = xl_init;
|
||||
@ -1957,6 +1965,13 @@ xl_rxeof(struct xl_softc *sc)
|
||||
bus_dmamap_sync(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
while ((rxstat = le32toh(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))) {
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifp->if_flags & IFF_POLLING) {
|
||||
if (sc->rxcycles <= 0)
|
||||
break;
|
||||
sc->rxcycles--;
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
cur_rx = sc->xl_cdata.xl_rx_head;
|
||||
sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
|
||||
total_len = rxstat & XL_RXSTAT_LENMASK;
|
||||
@ -2241,6 +2256,26 @@ xl_intr(void *arg)
|
||||
|
||||
XL_LOCK(sc);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifp->if_flags & IFF_POLLING) {
|
||||
XL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_POLLING) &&
|
||||
ether_poll_register(xl_poll, ifp)) {
|
||||
/* Disable interrupts. */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG)
|
||||
bus_space_write_4(sc->xl_ftag, sc->xl_fhandle,
|
||||
4, 0x8000);
|
||||
xl_poll_locked(ifp, 0, 1);
|
||||
XL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
|
||||
status != 0xFFFF) {
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
@ -2291,6 +2326,81 @@ xl_intr(void *arg)
|
||||
XL_UNLOCK(sc);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static void
|
||||
xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
|
||||
XL_LOCK(sc);
|
||||
xl_poll_locked(ifp, cmd, count);
|
||||
XL_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
if (!(ifp->if_capenable & IFCAP_POLLING)) {
|
||||
ether_poll_deregister(ifp);
|
||||
cmd = POLL_DEREGISTER;
|
||||
}
|
||||
|
||||
if (cmd == POLL_DEREGISTER) {
|
||||
/* Final call; enable interrupts. */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG)
|
||||
bus_space_write_4(sc->xl_ftag, sc->xl_fhandle,
|
||||
4, 0x8000);
|
||||
return;
|
||||
}
|
||||
|
||||
sc->rxcycles = count;
|
||||
xl_rxeof(sc);
|
||||
if (sc->xl_type == XL_TYPE_905B)
|
||||
xl_txeof_90xB(sc);
|
||||
else
|
||||
xl_txeof(sc);
|
||||
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||
if (sc->xl_type == XL_TYPE_905B)
|
||||
xl_start_90xB_locked(ifp);
|
||||
else
|
||||
xl_start_locked(ifp);
|
||||
}
|
||||
|
||||
if (cmd == POLL_AND_CHECK_STATUS) {
|
||||
u_int16_t status;
|
||||
|
||||
status = CSR_READ_2(sc, XL_STATUS);
|
||||
if (status & XL_INTRS && status != 0xFFFF) {
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
XL_CMD_INTR_ACK|(status & XL_INTRS));
|
||||
|
||||
if (status & XL_STAT_TX_COMPLETE) {
|
||||
ifp->if_oerrors++;
|
||||
xl_txeoc(sc);
|
||||
}
|
||||
|
||||
if (status & XL_STAT_ADFAIL) {
|
||||
xl_reset(sc);
|
||||
xl_init_locked(sc);
|
||||
}
|
||||
|
||||
if (status & XL_STAT_STATSOFLOW) {
|
||||
sc->xl_stats_no_timeout = 1;
|
||||
xl_stats_update_locked(sc);
|
||||
sc->xl_stats_no_timeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
/*
|
||||
* XXX: This is an entry point for callout which needs to take the lock.
|
||||
*/
|
||||
@ -2860,6 +2970,12 @@ xl_init_locked(struct xl_softc *sc)
|
||||
*/
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
|
||||
#ifdef DEVICE_POLLING
|
||||
/* Disable interrupts if we are polling. */
|
||||
if (ifp->if_flags & IFF_POLLING)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
|
||||
else
|
||||
#endif /* DEVICE_POLLING */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG)
|
||||
bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
|
||||
@ -3134,6 +3250,9 @@ xl_stop(struct xl_softc *sc)
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
ifp->if_timer = 0;
|
||||
#ifdef DEVICE_POLLING
|
||||
ether_poll_deregister(ifp);
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
|
||||
|
@ -607,6 +607,9 @@ struct xl_softc {
|
||||
bus_space_handle_t xl_fhandle;
|
||||
bus_space_tag_t xl_ftag;
|
||||
struct mtx xl_mtx;
|
||||
#ifdef DEVICE_POLLING
|
||||
int rxcycles;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define XL_LOCK(_sc) mtx_lock(&(_sc)->xl_mtx)
|
||||
|
Loading…
Reference in New Issue
Block a user