Skip to contentSkip to conversation

ath9k: Cancel pending offchannel operations

PATCH In review Sujith Manoharan 1 participant 3 messages Nov 1, 2014 – Nov 3, 2014 Qualcomm Atheros ATH9K wireless driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath9k: Cancel pending offchannel operations

From: Sujith Manoharan <[email protected]>

In mgd_prepare_tx(), any pending HW scan is cancelled, but pending RoC operations are not cancelled. This results in a RoC request that never completes. For example, in a GO/STA setup, if p2p-find is initiated on an active GO interface wpa_s issues a RoC on the listen channel at the end of each scan run.

Enabling the station interface will force the station context and the earlier RoC is not cleared. Fix this by clearing all pending offchannel operations in mgd_prepare_tx().

---
 drivers/net/wireless/ath/ath9k/main.c | 40 ++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 12 deletions(-)
drivers/net/wireless/ath/ath9k/main.c +28 -12
index a91ee92..cedc056 100644
@@ -2498,6 +2498,31 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
 	mutex_unlock(&sc->mutex);
 }
 
+static void ath9k_cancel_pending_offchannel(struct ieee80211_hw *hw)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+	if (sc->offchannel.roc_vif) {
+		ath_dbg(common, CHAN_CTX,
+			"%s: Aborting RoC\n", __func__);
+
+		del_timer_sync(&sc->offchannel.timer);
+		if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
+			ath_roc_complete(sc, true);
+	}
+
+	if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
+		ath_dbg(common, CHAN_CTX,
+			"%s: Aborting HW scan\n", __func__);
+
+		del_timer_sync(&sc->offchannel.timer);
+		ath_scan_complete(sc, true);
+	}
+
+	flush_work(&sc->chanctx_work);
+}
+
 static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
 				 struct ieee80211_vif *vif)
 {
@@ -2526,18 +2551,9 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
 	if (!changed)
 		goto out;
 
-	if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
-		ath_dbg(common, CHAN_CTX,
-			"%s: Aborting HW scan\n", __func__);
-
-		mutex_unlock(&sc->mutex);
-
-		del_timer_sync(&sc->offchannel.timer);
-		ath_scan_complete(sc, true);
-		flush_work(&sc->chanctx_work);
-
-		mutex_lock(&sc->mutex);
-	}
+	mutex_unlock(&sc->mutex);
+	ath9k_cancel_pending_offchannel(hw);
+	mutex_lock(&sc->mutex);
 
 	go_ctx = ath_is_go_chanctx_present(sc);
 
Signature · 1 line
2.1.3
#1 lore raw

Re: [PATCH] ath9k: Cancel pending offchannel operations [and 1 more messages]

Hi John,

Can you please hold off on these patches ?
I'll repost them after some more testing.

Sujith

Quoted 12 lines · Sujith Manoharan

From: Sujith Manoharan <[email protected]>

In mgd_prepare_tx(), any pending HW scan is cancelled, but pending RoC operations are not cancelled. This results in a RoC request that never completes. For example, in a GO/STA setup, if p2p-find is initiated on an active GO interface wpa_s issues a RoC on the listen channel at the end of each scan run.

Enabling the station interface will force the station context and the earlier RoC is not cleared. Fix this by clearing all pending offchannel operations in mgd_prepare_tx().

Quoted 9 lines · Sujith Manoharan

From: Sujith Manoharan <[email protected]>

When a pending roc or scan operation is cancelled, the offchannel operation is cleared, but the offchannel state in the main scheduler is not cleared. This causes problems since an active GO will try to process a stale offchannel request that was deferred earlier. Fix this by clearing the state when there is no pending offchannel (roc/scan) operation.

#2 lore raw

PATCH 1/1 ath9k: Clear offchannel state properly

From: Sujith Manoharan <[email protected]>

When a pending roc or scan operation is cancelled, the offchannel operation is cleared, but the offchannel state in the main scheduler is not cleared. This causes problems since an active GO will try to process a stale offchannel request that was deferred earlier. Fix this by clearing the state when there is no pending offchannel (roc/scan) operation.

---
 drivers/net/wireless/ath/ath9k/channel.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/wireless/ath/ath9k/channel.c +5 -0
index c7234d5..89ef61a 100644
@@ -900,6 +900,11 @@ void ath_offchannel_next(struct ath_softc *sc)
 		sc->offchannel.state = ATH_OFFCHANNEL_ROC_START;
 		ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan);
 	} else {
+		spin_lock_bh(&sc->chan_lock);
+		sc->sched.offchannel_pending = false;
+		sc->sched.wait_switch = false;
+		spin_unlock_bh(&sc->chan_lock);
+
 		ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),
 				   NULL);
 		sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
Signature · 1 line
2.1.3