Skip to content

Commit

Permalink
ath10k: drain tx before restarting hw
Browse files Browse the repository at this point in the history
This makes sure no further tx requests are
submitted to HTT before driver teardown.

This should prevent invalid pointer/NULL
dereference on htt tx pool in ath10k_htt_tx() in
some cases of heavy traffic.

kvalo: remove the WARN_ON() if conf_mutex is held

Reported-By: Ben Greear <greearb@candelatech.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
  • Loading branch information
Michal Kazior authored and Kalle Valo committed May 27, 2014
1 parent c5058f5 commit bca7baf
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions drivers/net/wireless/ath/ath10k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -2289,9 +2289,19 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ath10k_tx_htt(ar, skb);
}

/*
* Initialize various parameters with default vaules.
*/
/* Must not be called with conf_mutex held as workers can use that also. */
static void ath10k_drain_tx(struct ath10k *ar)
{
/* make sure rcu-protected mac80211 tx path itself is drained */
synchronize_net();

ath10k_offchan_tx_purge(ar);
ath10k_mgmt_over_wmi_tx_purge(ar);

cancel_work_sync(&ar->offchan_tx_work);
cancel_work_sync(&ar->wmi_mgmt_tx_work);
}

void ath10k_halt(struct ath10k *ar)
{
struct ath10k_vif *arvif;
Expand All @@ -2307,8 +2317,6 @@ void ath10k_halt(struct ath10k *ar)

del_timer_sync(&ar->scan.timeout);
ath10k_reset_scan((unsigned long)ar);
ath10k_offchan_tx_purge(ar);
ath10k_mgmt_over_wmi_tx_purge(ar);
ath10k_peer_cleanup_all(ar);
ath10k_core_stop(ar);
ath10k_hif_power_down(ar);
Expand Down Expand Up @@ -2394,6 +2402,13 @@ static int ath10k_start(struct ieee80211_hw *hw)
struct ath10k *ar = hw->priv;
int ret = 0;

/*
* This makes sense only when restarting hw. It is harmless to call
* uncoditionally. This is necessary to make sure no HTT/WMI tx
* commands will be submitted while restarting.
*/
ath10k_drain_tx(ar);

mutex_lock(&ar->conf_mutex);

switch (ar->state) {
Expand Down Expand Up @@ -2481,17 +2496,15 @@ static void ath10k_stop(struct ieee80211_hw *hw)
{
struct ath10k *ar = hw->priv;

ath10k_drain_tx(ar);

mutex_lock(&ar->conf_mutex);
if (ar->state != ATH10K_STATE_OFF) {
ath10k_halt(ar);
ar->state = ATH10K_STATE_OFF;
}
mutex_unlock(&ar->conf_mutex);

ath10k_mgmt_over_wmi_tx_purge(ar);

cancel_work_sync(&ar->offchan_tx_work);
cancel_work_sync(&ar->wmi_mgmt_tx_work);
cancel_work_sync(&ar->restart_work);
}

Expand Down

0 comments on commit bca7baf

Please sign in to comment.