PERFORCE change 87637 for review
Sam Leffler
sam at FreeBSD.org
Fri Dec 2 05:49:37 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=87637
Change 87637 by sam at 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) {
More information about the p4-projects
mailing list