--- /dev/null
+From a754055a1296fcbe6f32de3a5eaca6efb2fd1865 Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Mon, 16 Sep 2013 11:12:07 +0300
+Subject: mac80211: correctly close cancelled scans
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit a754055a1296fcbe6f32de3a5eaca6efb2fd1865 upstream.
+
+__ieee80211_scan_completed is called from a worker. This
+means that the following flow is possible.
+
+ * driver calls ieee80211_scan_completed
+ * mac80211 cancels the scan (that is already complete)
+ * __ieee80211_scan_completed runs
+
+When scan_work will finally run, it will see that the scan
+hasn't been aborted and might even trigger another scan on
+another band. This leads to a situation where cfg80211's
+scan is not done and no further scan can be issued.
+
+Fix this by setting a new flag when a HW scan is being
+cancelled so that no other scan will be triggered.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/ieee80211_i.h | 3 +++
+ net/mac80211/scan.c | 19 +++++++++++++++++++
+ 2 files changed, 22 insertions(+)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -789,12 +789,15 @@ struct tpt_led_trigger {
+ * that the scan completed.
+ * @SCAN_ABORTED: Set for our scan work function when the driver reported
+ * a scan complete for an aborted scan.
++ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
++ * cancelled.
+ */
+ enum {
+ SCAN_SW_SCANNING,
+ SCAN_HW_SCANNING,
+ SCAN_COMPLETED,
+ SCAN_ABORTED,
++ SCAN_HW_CANCELLED,
+ };
+
+ /**
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -259,6 +259,9 @@ static bool ieee80211_prep_hw_scan(struc
+ enum ieee80211_band band;
+ int i, ielen, n_chans;
+
++ if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
++ return false;
++
+ do {
+ if (local->hw_scan_band == IEEE80211_NUM_BANDS)
+ return false;
+@@ -844,7 +847,23 @@ void ieee80211_scan_cancel(struct ieee80
+ if (!local->scan_req)
+ goto out;
+
++ /*
++ * We have a scan running and the driver already reported completion,
++ * but the worker hasn't run yet or is stuck on the mutex - mark it as
++ * cancelled.
++ */
++ if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
++ test_bit(SCAN_COMPLETED, &local->scanning)) {
++ set_bit(SCAN_HW_CANCELLED, &local->scanning);
++ goto out;
++ }
++
+ if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
++ /*
++ * Make sure that __ieee80211_scan_completed doesn't trigger a
++ * scan on another band.
++ */
++ set_bit(SCAN_HW_CANCELLED, &local->scanning);
+ if (local->ops->cancel_hw_scan)
+ drv_cancel_hw_scan(local, local->scan_sdata);
+ goto out;
--- /dev/null
+From 0c5b93290b2f3c7a376567c03ae8d385b0e99851 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 29 Sep 2013 21:39:34 +0200
+Subject: mac80211: update sta->last_rx on acked tx frames
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 0c5b93290b2f3c7a376567c03ae8d385b0e99851 upstream.
+
+When clients are idle for too long, hostapd sends nullfunc frames for
+probing. When those are acked by the client, the idle time needs to be
+updated.
+
+To make this work (and to avoid unnecessary probing), update sta->last_rx
+whenever an ACK was received for a tx packet. Only do this if the flag
+IEEE80211_HW_REPORTS_TX_ACK_STATUS is set.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/status.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -183,6 +183,9 @@ static void ieee80211_frame_acked(struct
+ struct ieee80211_local *local = sta->local;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+
++ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
++ sta->last_rx = jiffies;
++
+ if (ieee80211_is_data_qos(mgmt->frame_control)) {
+ struct ieee80211_hdr *hdr = (void *) skb->data;
+ u8 *qc = ieee80211_get_qos_ctl(hdr);