Skip site navigation (1)Skip section navigation (2)
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>