Date: Sun, 25 Mar 2012 03:14:31 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r233453 - head/sys/dev/ath Message-ID: <201203250314.q2P3EVYt061493@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Sun Mar 25 03:14:31 2012 New Revision: 233453 URL: http://svn.freebsd.org/changeset/base/233453 Log: Add the new channel width change field to the ath(4) driver. This is not entirely correct as it simply resets the channel, flushing whatever is in the TX/RX queue. This can and will break aggregation BAW tracking. But the alternative (HT40 frames being sent with the hardware in HT20 mode) is even worse. There's still a small window between the htinfo being received (and the ni_chw field being updated) which could cause problems. I'll look at fleshing this out in follow-up commits. PR: kern/166286 Modified: head/sys/dev/ath/if_ath.c Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sun Mar 25 03:11:57 2012 (r233452) +++ head/sys/dev/ath/if_ath.c Sun Mar 25 03:14:31 2012 (r233453) @@ -199,6 +199,7 @@ static void ath_chan_change(struct ath_s static void ath_scan_start(struct ieee80211com *); static void ath_scan_end(struct ieee80211com *); static void ath_set_channel(struct ieee80211com *); +static void ath_update_chw(struct ieee80211com *); static void ath_calibrate(void *); static int ath_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void ath_setup_stationkey(struct ieee80211_node *); @@ -794,6 +795,7 @@ ath_attach(u_int16_t devid, struct ath_s ic->ic_scan_start = ath_scan_start; ic->ic_scan_end = ath_scan_end; ic->ic_set_channel = ath_set_channel; + ic->ic_update_chw = ath_update_chw; /* 802.11n specific - but just override anyway */ sc->sc_addba_request = ic->ic_addba_request; @@ -5717,6 +5719,31 @@ ath_scan_end(struct ieee80211com *ic) sc->sc_curaid); } +/* + * For now, just do a channel change. + * + * Later, we'll go through the hard slog of suspending tx/rx, changing rate + * control state and resetting the hardware without dropping frames out + * of the queue. + * + * The unfortunate trouble here is making absolutely sure that the + * channel width change has propagated enough so the hardware + * absolutely isn't handed bogus frames for it's current operating + * mode. (Eg, 40MHz frames in 20MHz mode.) Since TX and RX can and + * does occur in parallel, we need to make certain we've blocked + * any further ongoing TX (and RX, that can cause raw TX) + * before we do this. + */ +static void +ath_update_chw(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; + + DPRINTF(sc, ATH_DEBUG_STATE, "%s: called\n", __func__); + ath_set_channel(ic); +} + static void ath_set_channel(struct ieee80211com *ic) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203250314.q2P3EVYt061493>