ath9k: Cancel pending offchannel operations
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
@@ -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
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 interfacewpa_sissues 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.
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
@@ -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