]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'wireless-next/master' into ath-next
authorKalle Valo <kvalo@qca.qualcomm.com>
Wed, 14 May 2014 13:20:08 +0000 (16:20 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 14 May 2014 13:20:08 +0000 (16:20 +0300)
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/wmi.c

index 6abde37fb339c981f2c772af9ef908f5a32a66be..75b3dfbd6509ff21448edf10897a4d7397c1bd2c 100644 (file)
@@ -680,8 +680,8 @@ static void ath10k_core_restart(struct work_struct *work)
 
        switch (ar->state) {
        case ATH10K_STATE_ON:
-               ath10k_halt(ar);
                ar->state = ATH10K_STATE_RESTARTING;
+               ath10k_halt(ar);
                ieee80211_restart_hw(ar->hw);
                break;
        case ATH10K_STATE_OFF:
@@ -908,7 +908,9 @@ void ath10k_core_stop(struct ath10k *ar)
        lockdep_assert_held(&ar->conf_mutex);
 
        /* try to suspend target */
-       ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
+       if (ar->state != ATH10K_STATE_RESTARTING)
+               ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
+
        ath10k_debug_stop(ar);
        ath10k_htc_stop(&ar->htc);
        ath10k_htt_detach(&ar->htt);
index 0ac5437492fd5c100b95f7f576491d2d6d5d0025..7026f021ccbb00240aab98d91a59f4b8fe4bea78 100644 (file)
@@ -2291,6 +2291,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
  */
 void ath10k_halt(struct ath10k *ar)
 {
+       struct ath10k_vif *arvif;
+
        lockdep_assert_held(&ar->conf_mutex);
 
        if (ath10k_monitor_is_enabled(ar)) {
@@ -2313,6 +2315,17 @@ void ath10k_halt(struct ath10k *ar)
                ar->scan.in_progress = false;
                ieee80211_scan_completed(ar->hw, true);
        }
+
+       list_for_each_entry(arvif, &ar->arvifs, list) {
+               if (!arvif->beacon)
+                       continue;
+
+               dma_unmap_single(arvif->ar->dev,
+                                ATH10K_SKB_CB(arvif->beacon)->paddr,
+                                arvif->beacon->len, DMA_TO_DEVICE);
+               dev_kfree_skb_any(arvif->beacon);
+               arvif->beacon = NULL;
+       }
        spin_unlock_bh(&ar->data_lock);
 }
 
@@ -2771,6 +2784,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
 
        spin_lock_bh(&ar->data_lock);
        if (arvif->beacon) {
+               dma_unmap_single(arvif->ar->dev,
+                                ATH10K_SKB_CB(arvif->beacon)->paddr,
+                                arvif->beacon->len, DMA_TO_DEVICE);
                dev_kfree_skb_any(arvif->beacon);
                arvif->beacon = NULL;
        }
index bf1083d52e61d5f4c29bc6e649f357bf74c7ad51..66b1f3017f2b4a616da98cf61010987b9a7beb72 100644 (file)
@@ -2452,6 +2452,10 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
                if (val == 0xffffffff)
                        continue;
 
+               /* the device has crashed so don't bother trying anymore */
+               if (val & FW_IND_EVENT_PENDING)
+                       break;
+
                if (val & FW_IND_INITIALIZED)
                        break;
 
@@ -2464,7 +2468,19 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
                mdelay(10);
        } while (time_before(jiffies, timeout));
 
-       if (val == 0xffffffff || !(val & FW_IND_INITIALIZED)) {
+       if (val == 0xffffffff) {
+               ath10k_err("failed to read device register, device is gone\n");
+               ret = -EIO;
+               goto out;
+       }
+
+       if (val & FW_IND_EVENT_PENDING) {
+               ath10k_warn("device has crashed during init\n");
+               ret = -ECOMM;
+               goto out;
+       }
+
+       if (!(val & FW_IND_INITIALIZED)) {
                ath10k_err("failed to receive initialized event from target: %08x\n",
                           val);
                ret = -ETIMEDOUT;
index fe4d5f1c672f56b621db21370fa79a70214584bb..72cc4f20d102c39bfc7d7c750b4aeb62465cc981 100644 (file)
@@ -1431,6 +1431,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
                                         ATH10K_SKB_CB(arvif->beacon)->paddr,
                                         arvif->beacon->len, DMA_TO_DEVICE);
                        dev_kfree_skb_any(arvif->beacon);
+                       arvif->beacon = NULL;
                }
 
                ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
@@ -1440,6 +1441,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
                                        ATH10K_SKB_CB(bcn)->paddr);
                if (ret) {
                        ath10k_warn("failed to map beacon: %d\n", ret);
+                       dev_kfree_skb_any(bcn);
                        goto skip;
                }