diff options
author | Linux Build Service Account <lnxbuild@quicinc.com> | 2018-02-02 06:02:10 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-02-02 06:02:09 -0800 |
commit | 55bc67e27acb84fac9036558dfba5c6a32d4656b (patch) | |
tree | b9abdc2a3863f84ecf67da8fcd7a0a64dfd52a68 /drivers/net | |
parent | 768bfad12fa6763e34d0a587337e1617a4b99e22 (diff) | |
parent | f6a04016327f28f509d33e915c4f71336cbb5c0f (diff) |
Merge "ath10k: fix the race condition in wow suspend-resume cycle"
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wow.c | 63 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wow.h | 2 |
3 files changed, 55 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index d9365245da0a..d506702908cd 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4215,6 +4215,7 @@ void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb) return; } + ar->wow.wakeup_reason = ev.wake_reason; ath10k_dbg(ar, ATH10K_DBG_WMI, "wow wakeup host reason %s\n", wow_reason(ev.wake_reason)); } diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c index d9fbabef52df..74a9206c9f12 100644 --- a/drivers/net/wireless/ath/ath10k/wow.c +++ b/drivers/net/wireless/ath/ath10k/wow.c @@ -84,6 +84,7 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, int ret, i; unsigned long wow_mask = 0; struct ath10k *ar = arvif->ar; + struct ieee80211_bss_conf *bss = &arvif->vif->bss_conf; const struct cfg80211_pkt_pattern *patterns = wowlan->patterns; int pattern_id = 0; @@ -102,18 +103,19 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, __set_bit(WOW_RA_MATCH_EVENT, &wow_mask); break; case WMI_VDEV_TYPE_STA: - if (wowlan->disconnect) { - __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask); - __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask); - __set_bit(WOW_BMISS_EVENT, &wow_mask); - __set_bit(WOW_CSA_IE_EVENT, &wow_mask); + if (arvif->is_up && bss->assoc) { + if (wowlan->disconnect) { + __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask); + __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask); + __set_bit(WOW_BMISS_EVENT, &wow_mask); + __set_bit(WOW_CSA_IE_EVENT, &wow_mask); + } + + if (wowlan->magic_pkt) + __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); + if (wowlan->gtk_rekey_failure) + __set_bit(WOW_GTK_ERR_EVENT, &wow_mask); } - - if (wowlan->magic_pkt) - __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); - - if (wowlan->gtk_rekey_failure) - __set_bit(WOW_GTK_ERR_EVENT, &wow_mask); break; default: break; @@ -464,6 +466,44 @@ void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) mutex_unlock(&ar->conf_mutex); } +static void ath10k_wow_op_report_wakeup_reason(struct ath10k *ar) +{ + struct cfg80211_wowlan_wakeup *wakeup = &ar->wow.wakeup; + struct ath10k_vif *arvif; + + switch (ar->wow.wakeup_reason) { + case WOW_REASON_UNSPECIFIED: + wakeup = NULL; + break; + case WOW_REASON_RECV_MAGIC_PATTERN: + wakeup->magic_pkt = true; + break; + case WOW_REASON_DEAUTH_RECVD: + case WOW_REASON_DISASSOC_RECVD: + case WOW_REASON_AP_ASSOC_LOST: + case WOW_REASON_CSA_EVENT: + wakeup->disconnect = true; + break; + case WOW_REASON_GTK_HS_ERR: + wakeup->gtk_rekey_failure = true; + break; + } + + if (wakeup) { + wakeup->pattern_idx = -1; + list_for_each_entry(arvif, &ar->arvifs, list) { + ieee80211_report_wowlan_wakeup(arvif->vif, + wakeup, GFP_KERNEL); + if (wakeup->disconnect) + ieee80211_resume_disconnect(arvif->vif); + } + } else { + list_for_each_entry(arvif, &ar->arvifs, list) + ieee80211_report_wowlan_wakeup(arvif->vif, + NULL, GFP_KERNEL); + } +} + int ath10k_wow_op_resume(struct ieee80211_hw *hw) { struct ath10k *ar = hw->priv; @@ -518,6 +558,7 @@ exit: } } + ath10k_wow_op_report_wakeup_reason(ar); mutex_unlock(&ar->conf_mutex); return ret; } diff --git a/drivers/net/wireless/ath/ath10k/wow.h b/drivers/net/wireless/ath/ath10k/wow.h index ce79908cce19..b53211584052 100644 --- a/drivers/net/wireless/ath/ath10k/wow.h +++ b/drivers/net/wireless/ath/ath10k/wow.h @@ -17,8 +17,10 @@ #define _WOW_H_ struct ath10k_wow { + u32 wakeup_reason; u32 max_num_patterns; struct completion wakeup_completed; + struct cfg80211_wowlan_wakeup wakeup; struct wiphy_wowlan_support wowlan_support; }; |