Date: Fri, 2 Dec 2005 05:49:35 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87637 for review Message-ID: <200512020549.jB25nZoj021512@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87637 Change 87637 by sam@sam_ebb on 2005/12/02 05:49:19 device polling Affected files ... .. //depot/projects/wifi/sys/dev/ath/if_ath.c#118 edit Differences ... ==== //depot/projects/wifi/sys/dev/ath/if_ath.c#118 (text+ko) ==== @@ -44,6 +44,9 @@ * is greatly appreciated. */ +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#endif #include "opt_inet.h" #include <sys/param.h> @@ -490,6 +493,7 @@ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); + ifp->if_capabilities |= IFCAP_POLLING; ic->ic_ifp = ifp; ic->ic_reset = ath_reset; @@ -634,6 +638,10 @@ DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", __func__, ifp->if_flags); +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif ath_stop(ifp); bpfdetach(ifp); /* @@ -705,34 +713,25 @@ } /* - * Interrupt handler. Most of the actual processing is deferred. + * Set/enable interrupts. We actually enable + * interrupts only if we are not polling. */ -void -ath_intr(void *arg) +static __inline void +ath_intrset(struct ath_softc *sc, u_int32_t mask) +{ + struct ath_hal *ah = sc->sc_ah; + + if (sc->sc_ifp->if_capenable & IFCAP_POLLING) + mask &= ~HAL_INT_GLOBAL; + ath_hal_intrset(ah, mask); +} + +static void +ath_intr_body(struct ath_softc *sc, int count) { - struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; HAL_INT status; - if (sc->sc_invalid) { - /* - * The hardware is not ready/present, don't touch anything. - * Note this can happen early on if the IRQ is shared. - */ - DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid; ignored\n", __func__); - return; - } - if (!ath_hal_intrpend(ah)) /* shared irq, not for us */ - return; - if (!((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & - IFF_DRV_RUNNING))) { - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - ath_hal_getisr(ah, &status); /* clear ISR */ - ath_hal_intrset(ah, 0); /* disable further intr's */ - return; - } /* * Figure out the reason(s) for the interrupt. Note * that the hal returns a pseudo-ISR that may include @@ -800,11 +799,58 @@ * clear whatever condition caused the interrupt. */ ath_hal_mibevent(ah, &sc->sc_halstats); - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); } } } +/* + * Interrupt handler. Most of the actual processing is deferred. + */ +void +ath_intr(void *arg) +{ + struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ath_hal *ah = sc->sc_ah; + + if (ifp->if_capenable & IFCAP_POLLING) + return; + if (sc->sc_invalid) { + /* + * The hardware is not ready/present, don't touch anything. + * Note this can happen early on if the IRQ is shared. + */ + DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid; ignored\n", __func__); + return; + } + if (!ath_hal_intrpend(ah)) /* shared irq, not for us */ + return; + if ((ifp->if_flags & IFF_UP) == 0 || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + HAL_INT status; + + DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n", + __func__, ifp->if_flags); + ath_hal_getisr(ah, &status); /* clear ISR */ + ath_hal_intrset(ah, 0); /* disable further intr's */ + return; + } + ath_intr_body(sc, 1); +} + +/* + * Polling callback. + */ +static void +ath_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct ath_softc *sc = ifp->if_softc; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ath_intr_body(sc, count); +} + static void ath_fatal_proc(void *arg, int pending) { @@ -951,7 +997,7 @@ */ if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA) sc->sc_imask |= HAL_INT_MIB; - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); ifp->if_drv_flags |= IFF_DRV_RUNNING; ic->ic_state = IEEE80211_S_INIT; @@ -1093,7 +1139,7 @@ ath_chan_change(sc, c); if (ic->ic_state == IEEE80211_S_RUN) ath_beacon_config(sc); /* restart beacons */ - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); ath_start(ifp); /* restart xmit */ return 0; @@ -2686,7 +2732,7 @@ ath_hal_intrset(ah, 0); ath_hal_beacontimers(ah, &bs); sc->sc_imask |= HAL_INT_BMISS; - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); } else { ath_hal_intrset(ah, 0); if (nexttbtt == intval) @@ -2725,7 +2771,7 @@ } ath_hal_beaconinit(ah, nexttbtt, intval); sc->sc_bmisscount = 0; - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); /* * When using a self-linked beacon descriptor in * ibss mode load it once here. @@ -4705,7 +4751,7 @@ /* * Re-enable interrupts. */ - ath_hal_intrset(ah, sc->sc_imask); + ath_intrset(sc, sc->sc_imask); } return 0; } @@ -4852,7 +4898,7 @@ /* * NB: disable interrupts so we don't rx frames. */ - ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL); + ath_intrset(sc, sc->sc_imask &~ HAL_INT_GLOBAL); /* * Notify the rate control algorithm. */ @@ -4948,8 +4994,7 @@ sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; } else { - ath_hal_intrset(ah, - sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); + ath_intrset(sc, sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); } done: @@ -5470,6 +5515,22 @@ case SIOCGATHDIAG: error = ath_ioctl_diag(sc, (struct ath_diag *) ifr); break; + case SIOCSIFCAP: +#ifdef DEVICE_POLLING + if ((ifr->ifr_reqcap ^ ifp->if_capenable) & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { + error = ether_poll_register(ath_poll, ifp); + if (!error) + ifp->if_capenable |= IFCAP_POLLING; + } else { + error = ether_poll_deregister(ifp); + /* NB: enable interrupts even if error */ + ifp->if_capenable &= ~IFCAP_POLLING; + } + ath_intrset(sc, sc->sc_imask); + } +#endif + break; default: error = ieee80211_ioctl(ic, cmd, data); if (error == ENETRESET) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200512020549.jB25nZoj021512>
