Search Linux Wireless

[PATCH] ath9k: fix drop of multicast / broadcast data during scan

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



mac80211's scan implementation puts the burden of processing the DTIM
count on drivers to accurately disallow scanning during certain wait
constraints. ath9k was allowing to change channel while a few of these
wait constraints were still in effect causing some drop of buffered
broadcast and multicast traffic. Fix this by checking for the wait
constraints prior to switching channels.

This is tested against a Cisco E3000 AP configued with a DTIM Interval of 2
and beacon interval of 1000. Then setup ath9k to receive multicast
traffic:

  user@ath9k-RX-box $ iperf -s -u -B 224.0.55.55 -i 1

On the transmit multicast box connected to the same AP:

  user@ath9k-TX-box $ while true ; do iperf -c 224.0.55.55 \
	-u -T 32 -t 3 -i 1 -b 10M -t 1000; sleep 2 ; done

Without this patch we would otherwise loose that data. You can verify we run into
this by enabling the ATH_DBG_PS (0x800) when loading ath9k.

Cc: stable@xxxxxxxxxx
Cc: Amod Bodas <Amod.Bodas@xxxxxxxxxxx>
Signed-off-by: Luis R. Rodriguez <lrodriguez@xxxxxxxxxxx>
---

With other types of tests my AP just ends up dying so this is as
far as I could test it. For example setting the DTIM interval to a
max 255 beacon interval to a max of 65535 I poo out my AP in no time
when sending broadcast / multicast traffic. In fact even Ethernet
dies out immediately.

 drivers/net/wireless/ath/ath9k/main.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1165f90..3b0cd19 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1511,6 +1511,22 @@ void ath9k_enable_ps(struct ath_softc *sc)
 	}
 }
 
+static bool ath9k_can_change_channel(struct ath_softc *sc)
+{
+	u32 wait_for = PS_WAIT_FOR_BEACON |
+		       PS_WAIT_FOR_CAB |
+		       PS_WAIT_FOR_PSPOLL_DATA |
+		       PS_WAIT_FOR_TX_ACK;
+
+	if (sc->ps_flags & wait_for) {
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_PS,
+			  "Cannot change channel due to a wait constraint\n");
+		return false;
+	}
+
+	return true;
+}
+
 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -1605,6 +1621,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 		struct ieee80211_channel *curchan = hw->conf.channel;
 		int pos = curchan->hw_value;
 
+		if (!ath9k_can_change_channel(sc))
+			goto skip_chan_change;
+
 		aphy->chan_idx = pos;
 		aphy->chan_is_ht = conf_is_ht(conf);
 		if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux