Search Linux Wireless

[RFC 3/3] ath9k: implement the sw scan wait constraints

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

 



When mac80211 sw scan is triggered this will inform mac80211
to take us to the home channel if we are aware of some
time constraints for scanning. This ensures ath9k will not
loose buffered broadcast and multicast frames when scanning.

Cc: Amod Bodas <amod.bodas@xxxxxxxxxxx>
Signed-off-by: Luis R. Rodriguez <lrodriguez@xxxxxxxxxxx>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    1 +
 drivers/net/wireless/ath/ath9k/main.c  |   69 ++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f0197a6..89bbcd0 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -588,6 +588,7 @@ struct ath_softc {
 	int led_off_cnt;
 
 	int beacon_interval;
+	u32 scan_wait_counter;
 
 #ifdef CONFIG_ATH9K_DEBUGFS
 	struct ath9k_debug debug;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1165f90..181edea 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2043,6 +2043,74 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 	mutex_unlock(&sc->mutex);
 }
 
+static void ath9k_ps_flags_dbg(struct ath_softc *sc)
+{
+#define ATH9K_WAIT_DBG(_reason) do { \
+	if (sc->ps_flags & _reason) \
+		ath_print(common, ATH_DBG_PS, \
+			  "  %s\n", #_reason); \
+	} while (0)
+
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+	ath_print(common, ATH_DBG_PS, "PS flags:\n");
+
+	ATH9K_WAIT_DBG(PS_WAIT_FOR_BEACON);
+	ATH9K_WAIT_DBG(PS_WAIT_FOR_CAB);
+	ATH9K_WAIT_DBG(PS_WAIT_FOR_PSPOLL_DATA);
+	ATH9K_WAIT_DBG(PS_WAIT_FOR_TX_ACK);
+	ATH9K_WAIT_DBG(PS_BEACON_SYNC);
+	ATH9K_WAIT_DBG(PS_NULLFUNC_COMPLETED);
+	ATH9K_WAIT_DBG(PS_ENABLED);
+
+#undef ATH9K_WAIT_DBG
+}
+
+/*
+ * We expect to be disassociated if the counter gets too high.
+ */
+static int ath9k_sw_scan_wait_constraints(struct ieee80211_hw *hw)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	int r = 0;
+	u32 wait_for;
+
+	mutex_lock(&sc->mutex);
+
+	wait_for = PS_WAIT_FOR_BEACON |
+		   PS_BEACON_SYNC |
+		   PS_WAIT_FOR_CAB |
+		   PS_WAIT_FOR_PSPOLL_DATA |
+		   PS_WAIT_FOR_TX_ACK |
+		   PS_NULLFUNC_COMPLETED;
+
+	if (sc->ps_flags & wait_for) {
+		sc->scan_wait_counter++;
+		ath_print(common, ATH_DBG_PS,
+			  "Holding on channel change due to a "
+			  "wait constraint, count: %d, ps_flags: 0x%04x\n",
+			  sc->scan_wait_counter,
+			  sc->ps_flags);
+		ath9k_ps_flags_dbg(sc);
+		if (sc->ps_flags & PS_NULLFUNC_COMPLETED)
+			r = -EAGAIN;
+		else
+			r = -EBUSY;
+		goto out;
+	}
+
+	sc->scan_wait_counter = 0;
+	ath_print(common, ATH_DBG_PS,
+		  "No scan wait contraints found, ps_flags: 0x%04x\n",
+		   sc->ps_flags);
+out:
+	mutex_unlock(&sc->mutex);
+
+	return r;
+}
+
 /*
  * XXX: this requires a revisit after the driver
  * scan_complete gets moved to another place/removed in mac80211.
@@ -2089,6 +2157,7 @@ struct ieee80211_ops ath9k_ops = {
 	.ampdu_action       = ath9k_ampdu_action,
 	.get_survey	    = ath9k_get_survey,
 	.sw_scan_start      = ath9k_sw_scan_start,
+	.sw_scan_wait_constraints = ath9k_sw_scan_wait_constraints,
 	.sw_scan_complete   = ath9k_sw_scan_complete,
 	.rfkill_poll        = ath9k_rfkill_poll_state,
 	.set_coverage_class = ath9k_set_coverage_class,
-- 
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