Commit 828853ac authored by Wen Gong's avatar Wen Gong Committed by Kalle Valo

ath10k: add waiting htt tx complete before wow enable

If there are some tx packets pending in firmware, and then system
enters suspend, firmware will fail for wow enable. This will trigger
mac80211 to stop ath10k and download firmware again, then it is
non-wow suspend.

After add the waiting htt tx complete, then firmware will have some
time window to send or flush the pending tx packets.

Tested with QCA6174 PCI with firmware
WLAN.RM.4.4.1-00109-QCARMSWPZ-1, but this will also affect QCA9377 PCI.
It's not a regression with new firmware releases.
Signed-off-by: default avatarWen Gong <wgong@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 9d580466
...@@ -6769,23 +6769,17 @@ static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) ...@@ -6769,23 +6769,17 @@ static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void ath10k_mac_wait_tx_complete(struct ath10k *ar)
u32 queues, bool drop)
{ {
struct ath10k *ar = hw->priv;
bool skip; bool skip;
long time_left; long time_left;
/* mac80211 doesn't care if we really xmit queued frames or not /* mac80211 doesn't care if we really xmit queued frames or not
* we'll collect those frames either way if we stop/delete vdevs * we'll collect those frames either way if we stop/delete vdevs
*/ */
if (drop)
return;
mutex_lock(&ar->conf_mutex);
if (ar->state == ATH10K_STATE_WEDGED) if (ar->state == ATH10K_STATE_WEDGED)
goto skip; return;
time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({ time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
bool empty; bool empty;
...@@ -6804,8 +6798,18 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -6804,8 +6798,18 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (time_left == 0 || skip) if (time_left == 0 || skip)
ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n", ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
skip, ar->state, time_left); skip, ar->state, time_left);
}
skip: static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{
struct ath10k *ar = hw->priv;
if (drop)
return;
mutex_lock(&ar->conf_mutex);
ath10k_mac_wait_tx_complete(ar);
mutex_unlock(&ar->conf_mutex); mutex_unlock(&ar->conf_mutex);
} }
......
...@@ -82,6 +82,7 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar, ...@@ -82,6 +82,7 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
u16 peer_id, u16 peer_id,
u8 tid); u8 tid);
int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val); int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val);
void ath10k_mac_wait_tx_complete(struct ath10k *ar);
static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif, static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif,
struct sk_buff *skb) struct sk_buff *skb)
......
...@@ -374,6 +374,8 @@ int ath10k_wow_op_suspend(struct ieee80211_hw *hw, ...@@ -374,6 +374,8 @@ int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
goto cleanup; goto cleanup;
} }
ath10k_mac_wait_tx_complete(ar);
ret = ath10k_wow_enable(ar); ret = ath10k_wow_enable(ar);
if (ret) { if (ret) {
ath10k_warn(ar, "failed to start wow: %d\n", ret); ath10k_warn(ar, "failed to start wow: %d\n", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment