Date: Sat, 15 Mar 2008 21:00:15 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 137801 for review Message-ID: <200803152100.m2FL0Fr5079611@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137801 Change 137801 by sam@sam_ebb on 2008/03/15 20:59:48 checkpoint temporary hack to split post state change work into a callback; going to explore a better solution next Affected files ... .. //depot/projects/vap/sys/dev/usb/if_rum.c#10 edit .. //depot/projects/vap/sys/dev/usb/if_ural.c#12 edit .. //depot/projects/vap/sys/dev/usb/if_zyd.c#11 edit .. //depot/projects/vap/sys/dev/wpi/if_wpi.c#11 edit .. //depot/projects/vap/sys/net80211/ieee80211_proto.c#24 edit .. //depot/projects/vap/sys/net80211/ieee80211_var.h#32 edit Differences ... ==== //depot/projects/vap/sys/dev/usb/if_rum.c#10 (text+ko) ==== @@ -801,13 +801,10 @@ RUM_UNLOCK(sc); - IEEE80211_LOCK(ic); /*XXX*/ + IEEE80211_LOCK(ic); rvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (sc->sc_state == IEEE80211_S_RUN) { - /* XXX compensate for deferred handling of newstate */ - vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_start(vap->iv_ifp); - } + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); IEEE80211_UNLOCK(ic); } @@ -825,11 +822,13 @@ sc->sc_arg = arg; usb_rem_task(sc->sc_udev, &sc->sc_task); - if (nstate == IEEE80211_S_INIT) + if (nstate == IEEE80211_S_INIT) { rvp->newstate(vap, nstate, arg); - else + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return 0; + return EINPROGRESS; + } } /* quickly determine if a given rate is CCK or OFDM */ ==== //depot/projects/vap/sys/dev/usb/if_ural.c#12 (text+ko) ==== @@ -808,13 +808,10 @@ RAL_UNLOCK(sc); - IEEE80211_LOCK(ic); /*XXX*/ + IEEE80211_LOCK(ic); uvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (sc->sc_state == IEEE80211_S_RUN) { - /* XXX compensate for deferred handling of newstate */ - vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_start(vap->iv_ifp); - } + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); IEEE80211_UNLOCK(ic); } @@ -857,11 +854,13 @@ sc->sc_arg = arg; usb_rem_task(sc->sc_udev, &sc->sc_task); - if (nstate == IEEE80211_S_INIT) + if (nstate == IEEE80211_S_INIT) { uvp->newstate(vap, nstate, arg); - else + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return 0; + return EINPROGRESS; + } } /* quickly determine if a given rate is CCK or OFDM */ ==== //depot/projects/vap/sys/dev/usb/if_zyd.c#11 (text+ko) ==== @@ -708,9 +708,6 @@ struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct zyd_vap *zvp = ZYD_VAP(vap); - enum ieee80211_state ostate; - - ostate = vap->iv_state; switch (sc->sc_state) { case IEEE80211_S_RUN: @@ -740,13 +737,10 @@ break; } - IEEE80211_LOCK(ic); /*XXX*/ + IEEE80211_LOCK(ic); zvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (sc->sc_state == IEEE80211_S_RUN) { - /* XXX compensate for deferred handling of newstate */ - vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_start(vap->iv_ifp); - } + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); IEEE80211_UNLOCK(ic); } @@ -763,12 +757,13 @@ sc->sc_state = nstate; sc->sc_arg = arg; - if (nstate == IEEE80211_S_INIT) + if (nstate == IEEE80211_S_INIT) { zvp->newstate(vap, nstate, arg); - else + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - - return 0; + return EINPROGRESS; + } } static int ==== //depot/projects/vap/sys/dev/wpi/if_wpi.c#11 (text+ko) ==== @@ -1256,6 +1256,7 @@ struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct wpi_softc *sc = ifp->if_softc; + int error; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, ieee80211_state_name[vap->iv_state], @@ -1265,11 +1266,13 @@ if (nstate == IEEE80211_S_AUTH) { /* Delay the auth transition until we can update the firmware */ - return wpi_queue_cmd(sc, WPI_AUTH, arg, WPI_QUEUE_NORMAL); + error = wpi_queue_cmd(sc, WPI_AUTH, arg, WPI_QUEUE_NORMAL); + return (error != 0 ? error : EINPROGRESS); } if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) { /* set the association id first */ - return wpi_queue_cmd(sc, WPI_RUN, arg, WPI_QUEUE_NORMAL); + error = wpi_queue_cmd(sc, WPI_RUN, arg, WPI_QUEUE_NORMAL); + return (error != 0 ? error : EINPROGRESS); } if (nstate == IEEE80211_S_RUN) { /* RUN -> RUN transition; just restart the timers */ @@ -3580,28 +3583,35 @@ case WPI_AUTH: /* The node must be registered in the firmware before auth */ error = wpi_auth(sc, vap); + WPI_UNLOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: could not move to auth state, error %d\n", __func__, error); - WPI_UNLOCK(sc); return; } - /* Send the auth frame now */ + IEEE80211_LOCK(ic); WPI_VAP(vap)->newstate(vap, IEEE80211_S_AUTH, arg); - break; + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, IEEE80211_S_AUTH, arg); + IEEE80211_UNLOCK(ic); + goto again; case WPI_RUN: error = wpi_run(sc, vap); + WPI_UNLOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: could not move to run state, error %d\n", __func__, error); - WPI_UNLOCK(sc); return; } + IEEE80211_LOCK(ic); WPI_VAP(vap)->newstate(vap, IEEE80211_S_RUN, arg); - break; + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, IEEE80211_S_RUN, arg); + IEEE80211_UNLOCK(ic); + goto again; } WPI_UNLOCK(sc); ==== //depot/projects/vap/sys/net80211/ieee80211_proto.c#24 (text+ko) ==== @@ -1473,6 +1473,53 @@ } /* + * Handle post state change work common to all operating modes. + */ +static void +ieee80211_newstate_cb(struct ieee80211vap *vap, + enum ieee80211_state nstate, int arg) +{ + struct ieee80211com *ic = vap->iv_ic; + + IEEE80211_LOCK_ASSERT(ic); + + IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, + "%s: %s arg %d\n", __func__, ieee80211_state_name[nstate], arg); + + if (nstate == IEEE80211_S_RUN) { + /* + * OACTIVE may be set on the vap if the upper layer + * tried to transmit (e.g. IPv6 NDP) before we reach + * RUN state. Clear it and restart xmit. + * + * Note this can also happen as a result of SLEEP->RUN + * (i.e. coming out of power save mode). + */ + vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if_start(vap->iv_ifp); + + /* bring up any vaps waiting on us */ + wakeupwaiting(vap); + } else if (nstate == IEEE80211_S_INIT) { + /* + * Flush the scan cache if we did the last scan (XXX?) + * and flush any frames on send queues from this vap. + * Note the mgt q is used only for legacy drivers and + * will go away shortly. + */ + ieee80211_scan_flush(vap); + + /* XXX can skip this if not using ic_mgtq */ + /* flush any frames for this vap in the shared q's */ + ieee80211_flush_ifq(&ic->ic_mgtq, vap); + /* XXX NB: cast for altq */ + ieee80211_flush_ifq((struct ifqueue *) + &ic->ic_ifp->if_snd, vap); + } + vap->iv_newstate_cb = NULL; +} + +/* * Public interface for initiating a state machine change. * This routine single-threads the request and coordinates * the scheduling of multiple vaps for the purpose of selecting @@ -1624,29 +1671,18 @@ default: break; } - rc = vap->iv_newstate(vap, nstate, arg); /* XXX on transition RUN->CAC do we need to set nstate = iv_state? */ if (ostate != nstate) { /* - * Handle work common to all operating modes. + * Arrange for work to happen after state change completes. + * If this happens asynchronously the caller must arrange + * for the com lock to be held. */ - if (nstate == IEEE80211_S_RUN) { - vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_start(vap->iv_ifp); - - /* bring up any vaps waiting on us */ - wakeupwaiting(vap); - } else if (nstate == IEEE80211_S_INIT) { - ieee80211_scan_flush(vap); - - /* XXX can skip this if not using ic_mgtq */ - /* flush any frames for this vap in the shared q's */ - ieee80211_flush_ifq(&ic->ic_mgtq, vap); - /* XXX NB: cast for altq */ - ieee80211_flush_ifq((struct ifqueue *) - &ic->ic_ifp->if_snd, vap); - } + vap->iv_newstate_cb = ieee80211_newstate_cb; } + rc = vap->iv_newstate(vap, nstate, arg); + if (rc == 0) + vap->iv_newstate_cb(vap, nstate, arg); done: return rc; } ==== //depot/projects/vap/sys/net80211/ieee80211_var.h#32 (text+ko) ==== @@ -293,6 +293,8 @@ uint32_t iv_htcaps; /* HT capabilities */ enum ieee80211_opmode iv_opmode; /* operation mode */ enum ieee80211_state iv_state; /* state machine state */ + void (*iv_newstate_cb)(struct ieee80211vap *, + enum ieee80211_state, int); struct callout iv_mgtsend; /* mgmt frame response timer */ /* inactivity timer settings */ int iv_inact_init; /* setting for new station */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803152100.m2FL0Fr5079611>