Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Apr 2016 00:58:38 +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: r297729 - head/sys/dev/ath
Message-ID:  <201604090058.u390wcZZ038053@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat Apr  9 00:58:38 2016
New Revision: 297729
URL: https://svnweb.freebsd.org/changeset/base/297729

Log:
  [ath] Only process beacon frames for the IBSS/BSSID if appropriate.
  
  * Don't use arbitrary frames for the average RX RSSI - only frames
    from the current BSSID
  
  * Don't log / do the syncbeacon logic for another BSSID and definitely
    don't do the syncbeacon call if we miss beacons outside of STA mode.
  
  * Don't do the IBSS merge bits if the current node plainly won't ever
    match our current BSS (ie, the IBSS doesn't have to match, but all
    the same bits that we check in ieee80211_ibss_merge() have to match.)
  
  Tested:
  
  * ath(4), AR9380, IBSS mode, surrounded by a lot of IBSS 11ac networks.
  
  Sponsored by:	Eva Automation, Inc.

Modified:
  head/sys/dev/ath/if_ath_rx.c

Modified: head/sys/dev/ath/if_ath_rx.c
==============================================================================
--- head/sys/dev/ath/if_ath_rx.c	Sat Apr  9 00:55:55 2016	(r297728)
+++ head/sys/dev/ath/if_ath_rx.c	Sat Apr  9 00:58:38 2016	(r297729)
@@ -361,85 +361,102 @@ ath_recv_mgmt(struct ieee80211_node *ni,
 	ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
 	switch (subtype) {
 	case IEEE80211_FC0_SUBTYPE_BEACON:
-		/* update rssi statistics for use by the hal */
-		/* XXX unlocked check against vap->iv_bss? */
-		ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
 
-		tsf_beacon = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
-		tsf_beacon |= LE_READ_4(ni->ni_tstamp.data);
+		/*
+		 * Only do the following processing if it's for
+		 * the current BSS.
+		 *
+		 * In scan and IBSS mode we receive all beacons,
+		 * which means we need to filter out stuff
+		 * that isn't for us or we'll end up constantly
+		 * trying to sync / merge to BSSes that aren't
+		 * actually us.
+		 */
+		if (IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
+			/* update rssi statistics for use by the hal */
+			/* XXX unlocked check against vap->iv_bss? */
+			ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
 
-		nexttbtt = ath_hal_getnexttbtt(sc->sc_ah);
 
-		/*
-		 * Let's calculate the delta and remainder, so we can see
-		 * if the beacon timer from the AP is varying by more than
-		 * a few TU.  (Which would be a huge, huge problem.)
-		 */
-		tsf_delta = (long long) tsf_beacon - (long long) tsf_beacon_old;
+			tsf_beacon = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
+			tsf_beacon |= LE_READ_4(ni->ni_tstamp.data);
 
-		tsf_delta_bmiss = tsf_delta / tsf_intval;
+			nexttbtt = ath_hal_getnexttbtt(sc->sc_ah);
 
-		/*
-		 * If our delta is greater than half the beacon interval,
-		 * let's round the bmiss value up to the next beacon
-		 * interval.  Ie, we're running really, really early
-		 * on the next beacon.
-		 */
-		if (tsf_delta % tsf_intval > (tsf_intval / 2))
-			tsf_delta_bmiss ++;
+			/*
+			 * Let's calculate the delta and remainder, so we can see
+			 * if the beacon timer from the AP is varying by more than
+			 * a few TU.  (Which would be a huge, huge problem.)
+			 */
+			tsf_delta = (long long) tsf_beacon - (long long) tsf_beacon_old;
 
-		tsf_beacon_target = tsf_beacon_old +
-		    (((unsigned long long) tsf_delta_bmiss) * (long long) tsf_intval);
+			tsf_delta_bmiss = tsf_delta / tsf_intval;
 
-		/*
-		 * The remainder using '%' is between 0 .. intval-1.
-		 * If we're actually running too fast, then the remainder
-		 * will be some large number just under intval-1.
-		 * So we need to look at whether we're running
-		 * before or after the target beacon interval
-		 * and if we are, modify how we do the remainder
-		 * calculation.
-		 */
-		if (tsf_beacon < tsf_beacon_target) {
-			tsf_remainder =
-			    -(tsf_intval - ((tsf_beacon - tsf_beacon_old) % tsf_intval));
-		} else {
-			tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
-		}
+			/*
+			 * If our delta is greater than half the beacon interval,
+			 * let's round the bmiss value up to the next beacon
+			 * interval.  Ie, we're running really, really early
+			 * on the next beacon.
+			 */
+			if (tsf_delta % tsf_intval > (tsf_intval / 2))
+				tsf_delta_bmiss ++;
 
-		DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu, new_tsf=%llu, target_tsf=%llu, delta=%lld, bmiss=%d, remainder=%d\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon_old,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) tsf_beacon_target,
-		    (long long) tsf_delta,
-		    tsf_delta_bmiss,
-		    tsf_remainder);
+			tsf_beacon_target = tsf_beacon_old +
+			    (((unsigned long long) tsf_delta_bmiss) * (long long) tsf_intval);
 
-		DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu, nexttbtt=%llu, delta=%d\n",
-		    __func__,
-		    (unsigned long long) tsf_beacon,
-		    (unsigned long long) nexttbtt,
-		    (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
-
-		if (sc->sc_syncbeacon &&
-		    ni == vap->iv_bss &&
-		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
-			DPRINTF(sc, ATH_DEBUG_BEACON,
-			    "%s: syncbeacon=1; syncing\n",
-			    __func__);
 			/*
-			 * Resync beacon timers using the tsf of the beacon
-			 * frame we just received.
+			 * The remainder using '%' is between 0 .. intval-1.
+			 * If we're actually running too fast, then the remainder
+			 * will be some large number just under intval-1.
+			 * So we need to look at whether we're running
+			 * before or after the target beacon interval
+			 * and if we are, modify how we do the remainder
+			 * calculation.
 			 */
-			ath_beacon_config(sc, vap);
-			sc->sc_syncbeacon = 0;
+			if (tsf_beacon < tsf_beacon_target) {
+				tsf_remainder =
+				    -(tsf_intval - ((tsf_beacon - tsf_beacon_old) % tsf_intval));
+			} else {
+				tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
+			}
+
+			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu, new_tsf=%llu, target_tsf=%llu, delta=%lld, bmiss=%d, remainder=%d\n",
+			    __func__,
+			    (unsigned long long) tsf_beacon_old,
+			    (unsigned long long) tsf_beacon,
+			    (unsigned long long) tsf_beacon_target,
+			    (long long) tsf_delta,
+			    tsf_delta_bmiss,
+			    tsf_remainder);
+
+			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu, nexttbtt=%llu, delta=%d\n",
+			    __func__,
+			    (unsigned long long) tsf_beacon,
+			    (unsigned long long) nexttbtt,
+			    (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
+
+			/* We only do syncbeacon on STA VAPs; not on IBSS */
+			if (vap->iv_opmode == IEEE80211_M_STA &&
+			    sc->sc_syncbeacon &&
+			    ni == vap->iv_bss &&
+			    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
+				DPRINTF(sc, ATH_DEBUG_BEACON,
+				    "%s: syncbeacon=1; syncing\n",
+				    __func__);
+				/*
+				 * Resync beacon timers using the tsf of the beacon
+				 * frame we just received.
+				 */
+				ath_beacon_config(sc, vap);
+				sc->sc_syncbeacon = 0;
+			}
 		}
 
 		/* fall thru... */
 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 		if (vap->iv_opmode == IEEE80211_M_IBSS &&
-		    vap->iv_state == IEEE80211_S_RUN) {
+		    vap->iv_state == IEEE80211_S_RUN &&
+		    ieee80211_ibss_merge_check(ni)) {
 			uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
 			uint64_t tsf = ath_extend_tsf(sc, rstamp,
 				ath_hal_gettsf64(sc->sc_ah));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604090058.u390wcZZ038053>