]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/ath/ath9k/htc_drv_main.c
ath9k_htc: fix race conditions when stop device
[mv-sheeva.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
index f4d576bc3ccdbce3bef81d4702a756e9b900a34d..6bb59958f71e471c58466bb8d1f3c43b8bc0d0d7 100644 (file)
@@ -1025,12 +1025,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
        int ret = 0;
        u8 cmd_rsp;
 
-       /* Cancel all the running timers/work .. */
-       cancel_work_sync(&priv->fatal_work);
-       cancel_work_sync(&priv->ps_work);
-       cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
-       ath9k_led_stop_brightness(priv);
-
        mutex_lock(&priv->mutex);
 
        if (priv->op_flags & OP_INVALID) {
@@ -1044,8 +1038,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
        WMI_CMD(WMI_DISABLE_INTR_CMDID);
        WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
        WMI_CMD(WMI_STOP_RECV_CMDID);
+
+       tasklet_kill(&priv->swba_tasklet);
+       tasklet_kill(&priv->rx_tasklet);
+       tasklet_kill(&priv->tx_tasklet);
+
        skb_queue_purge(&priv->tx_queue);
 
+       mutex_unlock(&priv->mutex);
+
+       /* Cancel all the running timers/work .. */
+       cancel_work_sync(&priv->fatal_work);
+       cancel_work_sync(&priv->ps_work);
+       cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+       ath9k_led_stop_brightness(priv);
+
+       mutex_lock(&priv->mutex);
+
        /* Remove monitor interface here */
        if (ah->opmode == NL80211_IFTYPE_MONITOR) {
                if (ath9k_htc_remove_monitor_interface(priv))