diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-16 14:15:28 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-16 14:15:28 -0400 |
commit | 75e58071c0c64f331ccc4c0037990a1e50099f7f (patch) | |
tree | 3074ad8e4be3762cae1e1f5d11d103ce8c216329 | |
parent | 5f407acbb7d6a92841c455b37a6ad4833757740e (diff) | |
parent | d9bc4b9b693d52dc14dc1de5dfec760634067d8c (diff) |
Merge branch 'for-linville' of git://github.com/kvalo/ath
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/pci.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 2 |
4 files changed, 39 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 6abde37fb339..75b3dfbd6509 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -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); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 0ac5437492fd..7026f021ccbb 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -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; } diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index bf1083d52e61..66b1f3017f2b 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -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; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index fe4d5f1c672f..72cc4f20d102 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -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; } |