summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2018-02-02 06:02:10 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-02-02 06:02:09 -0800
commit55bc67e27acb84fac9036558dfba5c6a32d4656b (patch)
treeb9abdc2a3863f84ecf67da8fcd7a0a64dfd52a68 /drivers/net
parent768bfad12fa6763e34d0a587337e1617a4b99e22 (diff)
parentf6a04016327f28f509d33e915c4f71336cbb5c0f (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.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.c63
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.h2
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;
};