aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h32
-rw-r--r--net/mac80211/debugfs_sta.c5
-rw-r--r--net/mac80211/main.c8
-rw-r--r--net/mac80211/rx.c86
-rw-r--r--net/mac80211/sta_info.c118
-rw-r--r--net/mac80211/sta_info.h23
-rw-r--r--net/mac80211/tx.c13
7 files changed, 200 insertions, 85 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7f035d779db9..2c10eac637d8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2137,6 +2137,38 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
2137 const u8 *addr); 2137 const u8 *addr);
2138 2138
2139/** 2139/**
2140 * ieee80211_sta_block_awake - block station from waking up
2141 * @hw: the hardware
2142 * @pubsta: the station
2143 * @block: whether to block or unblock
2144 *
2145 * Some devices require that all frames that are on the queues
2146 * for a specific station that went to sleep are flushed before
2147 * a poll response or frames after the station woke up can be
2148 * delivered to that it. Note that such frames must be rejected
2149 * by the driver as filtered, with the appropriate status flag.
2150 *
2151 * This function allows implementing this mode in a race-free
2152 * manner.
2153 *
2154 * To do this, a driver must keep track of the number of frames
2155 * still enqueued for a specific station. If this number is not
2156 * zero when the station goes to sleep, the driver must call
2157 * this function to force mac80211 to consider the station to
2158 * be asleep regardless of the station's actual state. Once the
2159 * number of outstanding frames reaches zero, the driver must
2160 * call this function again to unblock the station. That will
2161 * cause mac80211 to be able to send ps-poll responses, and if
2162 * the station queried in the meantime then frames will also
2163 * be sent out as a result of this. Additionally, the driver
2164 * will be notified that the station woke up some time after
2165 * it is unblocked, regardless of whether the station actually
2166 * woke up while blocked or not.
2167 */
2168void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
2169 struct ieee80211_sta *pubsta, bool block);
2170
2171/**
2140 * ieee80211_beacon_loss - inform hardware does not receive beacons 2172 * ieee80211_beacon_loss - inform hardware does not receive beacons
2141 * 2173 *
2142 * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. 2174 * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 4425b613552c..f043c29070d7 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -66,10 +66,11 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
66 char buf[100]; 66 char buf[100];
67 struct sta_info *sta = file->private_data; 67 struct sta_info *sta = file->private_data;
68 u32 staflags = get_sta_flags(sta); 68 u32 staflags = get_sta_flags(sta);
69 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s", 69 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
70 staflags & WLAN_STA_AUTH ? "AUTH\n" : "", 70 staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
71 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", 71 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
72 staflags & WLAN_STA_PS ? "PS\n" : "", 72 staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
73 staflags & WLAN_STA_PS_DRIVER ? "PS (driver)\n" : "",
73 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", 74 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
74 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", 75 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
75 staflags & WLAN_STA_WME ? "WME\n" : "", 76 staflags & WLAN_STA_WME ? "WME\n" : "",
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 9e6703ff7fbb..beb8718d905e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -385,13 +385,13 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
385 * can be unknown, for example with different interrupt status 385 * can be unknown, for example with different interrupt status
386 * bits. 386 * bits.
387 */ 387 */
388 if (test_sta_flags(sta, WLAN_STA_PS) && 388 if (test_sta_flags(sta, WLAN_STA_PS_STA) &&
389 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { 389 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
390 skb_queue_tail(&sta->tx_filtered, skb); 390 skb_queue_tail(&sta->tx_filtered, skb);
391 return; 391 return;
392 } 392 }
393 393
394 if (!test_sta_flags(sta, WLAN_STA_PS) && 394 if (!test_sta_flags(sta, WLAN_STA_PS_STA) &&
395 !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { 395 !(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
396 /* Software retry the packet once */ 396 /* Software retry the packet once */
397 info->flags |= IEEE80211_TX_INTFL_RETRIED; 397 info->flags |= IEEE80211_TX_INTFL_RETRIED;
@@ -406,7 +406,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
406 "queue_len=%d PS=%d @%lu\n", 406 "queue_len=%d PS=%d @%lu\n",
407 wiphy_name(local->hw.wiphy), 407 wiphy_name(local->hw.wiphy),
408 skb_queue_len(&sta->tx_filtered), 408 skb_queue_len(&sta->tx_filtered),
409 !!test_sta_flags(sta, WLAN_STA_PS), jiffies); 409 !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies);
410#endif 410#endif
411 dev_kfree_skb(skb); 411 dev_kfree_skb(skb);
412} 412}
@@ -446,7 +446,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
446 446
447 if (sta) { 447 if (sta) {
448 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 448 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
449 test_sta_flags(sta, WLAN_STA_PS)) { 449 test_sta_flags(sta, WLAN_STA_PS_STA)) {
450 /* 450 /*
451 * The STA is in power save mode, so assume 451 * The STA is in power save mode, so assume
452 * that this TX packet failed because of that. 452 * that this TX packet failed because of that.
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c06496f0b76d..28316b2a585f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -781,7 +781,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
781 struct ieee80211_local *local = sdata->local; 781 struct ieee80211_local *local = sdata->local;
782 782
783 atomic_inc(&sdata->bss->num_sta_ps); 783 atomic_inc(&sdata->bss->num_sta_ps);
784 set_sta_flags(sta, WLAN_STA_PS); 784 set_sta_flags(sta, WLAN_STA_PS_STA);
785 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); 785 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
786#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 786#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
787 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 787 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
@@ -792,33 +792,25 @@ static void ap_sta_ps_start(struct sta_info *sta)
792static void ap_sta_ps_end(struct sta_info *sta) 792static void ap_sta_ps_end(struct sta_info *sta)
793{ 793{
794 struct ieee80211_sub_if_data *sdata = sta->sdata; 794 struct ieee80211_sub_if_data *sdata = sta->sdata;
795 struct ieee80211_local *local = sdata->local;
796 int sent, buffered;
797 795
798 atomic_dec(&sdata->bss->num_sta_ps); 796 atomic_dec(&sdata->bss->num_sta_ps);
799 797
800 clear_sta_flags(sta, WLAN_STA_PS); 798 clear_sta_flags(sta, WLAN_STA_PS_STA);
801 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
802
803 if (!skb_queue_empty(&sta->ps_tx_buf))
804 sta_info_clear_tim_bit(sta);
805 799
806#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 800#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
807 printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", 801 printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
808 sdata->dev->name, sta->sta.addr, sta->sta.aid); 802 sdata->dev->name, sta->sta.addr, sta->sta.aid);
809#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 803#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
810 804
811 /* Send all buffered frames to the station */ 805 if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) {
812 sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
813 buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
814 sent += buffered;
815 local->total_ps_buffered -= buffered;
816
817#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 806#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
818 printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " 807 printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
819 "since STA not sleeping anymore\n", sdata->dev->name, 808 sdata->dev->name, sta->sta.addr, sta->sta.aid);
820 sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
821#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 809#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
810 return;
811 }
812
813 ieee80211_sta_ps_deliver_wakeup(sta);
822} 814}
823 815
824static ieee80211_rx_result debug_noinline 816static ieee80211_rx_result debug_noinline
@@ -866,7 +858,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
866 if (!ieee80211_has_morefrags(hdr->frame_control) && 858 if (!ieee80211_has_morefrags(hdr->frame_control) &&
867 (rx->sdata->vif.type == NL80211_IFTYPE_AP || 859 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
868 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { 860 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
869 if (test_sta_flags(sta, WLAN_STA_PS)) { 861 if (test_sta_flags(sta, WLAN_STA_PS_STA)) {
870 /* 862 /*
871 * Ignore doze->wake transitions that are 863 * Ignore doze->wake transitions that are
872 * indicated by non-data frames, the standard 864 * indicated by non-data frames, the standard
@@ -1094,9 +1086,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1094static ieee80211_rx_result debug_noinline 1086static ieee80211_rx_result debug_noinline
1095ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) 1087ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1096{ 1088{
1097 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 1089 struct ieee80211_sub_if_data *sdata = rx->sdata;
1098 struct sk_buff *skb;
1099 int no_pending_pkts;
1100 __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; 1090 __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
1101 1091
1102 if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || 1092 if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
@@ -1107,56 +1097,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1107 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) 1097 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
1108 return RX_DROP_UNUSABLE; 1098 return RX_DROP_UNUSABLE;
1109 1099
1110 skb = skb_dequeue(&rx->sta->tx_filtered); 1100 if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
1111 if (!skb) { 1101 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1112 skb = skb_dequeue(&rx->sta->ps_tx_buf); 1102 else
1113 if (skb) 1103 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
1114 rx->local->total_ps_buffered--;
1115 }
1116 no_pending_pkts = skb_queue_empty(&rx->sta->tx_filtered) &&
1117 skb_queue_empty(&rx->sta->ps_tx_buf);
1118
1119 if (skb) {
1120 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1121 struct ieee80211_hdr *hdr =
1122 (struct ieee80211_hdr *) skb->data;
1123
1124 /*
1125 * Tell TX path to send this frame even though the STA may
1126 * still remain is PS mode after this frame exchange.
1127 */
1128 info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
1129
1130#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1131 printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
1132 rx->sta->sta.addr, rx->sta->sta.aid,
1133 skb_queue_len(&rx->sta->ps_tx_buf));
1134#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1135
1136 /* Use MoreData flag to indicate whether there are more
1137 * buffered frames for this STA */
1138 if (no_pending_pkts)
1139 hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1140 else
1141 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1142
1143 ieee80211_add_pending_skb(rx->local, skb);
1144
1145 if (no_pending_pkts)
1146 sta_info_clear_tim_bit(rx->sta);
1147#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1148 } else {
1149 /*
1150 * FIXME: This can be the result of a race condition between
1151 * us expiring a frame and the station polling for it.
1152 * Should we send it a null-func frame indicating we
1153 * have nothing buffered for it?
1154 */
1155 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
1156 "though there are no buffered frames for it\n",
1157 rx->dev->name, rx->sta->sta.addr);
1158#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1159 }
1160 1104
1161 /* Free PS Poll skb here instead of returning RX_DROP that would 1105 /* Free PS Poll skb here instead of returning RX_DROP that would
1162 * count as an dropped frame. */ 1106 * count as an dropped frame. */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index cde2da7a74df..be59456e8a42 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -171,6 +171,8 @@ void sta_info_destroy(struct sta_info *sta)
171 171
172 local = sta->local; 172 local = sta->local;
173 173
174 cancel_work_sync(&sta->drv_unblock_wk);
175
174 rate_control_remove_sta_debugfs(sta); 176 rate_control_remove_sta_debugfs(sta);
175 ieee80211_sta_debugfs_remove(sta); 177 ieee80211_sta_debugfs_remove(sta);
176 178
@@ -259,6 +261,21 @@ static void sta_info_hash_add(struct ieee80211_local *local,
259 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); 261 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
260} 262}
261 263
264static void sta_unblock(struct work_struct *wk)
265{
266 struct sta_info *sta;
267
268 sta = container_of(wk, struct sta_info, drv_unblock_wk);
269
270 if (sta->dead)
271 return;
272
273 if (!test_sta_flags(sta, WLAN_STA_PS_STA))
274 ieee80211_sta_ps_deliver_wakeup(sta);
275 else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL))
276 ieee80211_sta_ps_deliver_poll_response(sta);
277}
278
262struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 279struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
263 u8 *addr, gfp_t gfp) 280 u8 *addr, gfp_t gfp)
264{ 281{
@@ -272,6 +289,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
272 289
273 spin_lock_init(&sta->lock); 290 spin_lock_init(&sta->lock);
274 spin_lock_init(&sta->flaglock); 291 spin_lock_init(&sta->flaglock);
292 INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
275 293
276 memcpy(sta->sta.addr, addr, ETH_ALEN); 294 memcpy(sta->sta.addr, addr, ETH_ALEN);
277 sta->local = local; 295 sta->local = local;
@@ -478,8 +496,10 @@ static void __sta_info_unlink(struct sta_info **sta)
478 } 496 }
479 497
480 list_del(&(*sta)->list); 498 list_del(&(*sta)->list);
499 (*sta)->dead = true;
481 500
482 if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { 501 if (test_and_clear_sta_flags(*sta,
502 WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) {
483 BUG_ON(!sdata->bss); 503 BUG_ON(!sdata->bss);
484 504
485 atomic_dec(&sdata->bss->num_sta_ps); 505 atomic_dec(&sdata->bss->num_sta_ps);
@@ -825,3 +845,99 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
825 return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); 845 return ieee80211_find_sta_by_hw(&sdata->local->hw, addr);
826} 846}
827EXPORT_SYMBOL(ieee80211_find_sta); 847EXPORT_SYMBOL(ieee80211_find_sta);
848
849/* powersave support code */
850void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
851{
852 struct ieee80211_sub_if_data *sdata = sta->sdata;
853 struct ieee80211_local *local = sdata->local;
854 int sent, buffered;
855
856 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
857
858 if (!skb_queue_empty(&sta->ps_tx_buf))
859 sta_info_clear_tim_bit(sta);
860
861 /* Send all buffered frames to the station */
862 sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
863 buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
864 sent += buffered;
865 local->total_ps_buffered -= buffered;
866
867#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
868 printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
869 "since STA not sleeping anymore\n", sdata->dev->name,
870 sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
871#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
872}
873
874void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
875{
876 struct ieee80211_sub_if_data *sdata = sta->sdata;
877 struct ieee80211_local *local = sdata->local;
878 struct sk_buff *skb;
879 int no_pending_pkts;
880
881 skb = skb_dequeue(&sta->tx_filtered);
882 if (!skb) {
883 skb = skb_dequeue(&sta->ps_tx_buf);
884 if (skb)
885 local->total_ps_buffered--;
886 }
887 no_pending_pkts = skb_queue_empty(&sta->tx_filtered) &&
888 skb_queue_empty(&sta->ps_tx_buf);
889
890 if (skb) {
891 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
892 struct ieee80211_hdr *hdr =
893 (struct ieee80211_hdr *) skb->data;
894
895 /*
896 * Tell TX path to send this frame even though the STA may
897 * still remain is PS mode after this frame exchange.
898 */
899 info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
900
901#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
902 printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
903 sta->sta.addr, sta->sta.aid,
904 skb_queue_len(&sta->ps_tx_buf));
905#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
906
907 /* Use MoreData flag to indicate whether there are more
908 * buffered frames for this STA */
909 if (no_pending_pkts)
910 hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
911 else
912 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
913
914 ieee80211_add_pending_skb(local, skb);
915
916 if (no_pending_pkts)
917 sta_info_clear_tim_bit(sta);
918#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
919 } else {
920 /*
921 * FIXME: This can be the result of a race condition between
922 * us expiring a frame and the station polling for it.
923 * Should we send it a null-func frame indicating we
924 * have nothing buffered for it?
925 */
926 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
927 "though there are no buffered frames for it\n",
928 sdata->dev->name, sta->sta.addr);
929#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
930 }
931}
932
933void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
934 struct ieee80211_sta *pubsta, bool block)
935{
936 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
937
938 if (block)
939 set_sta_flags(sta, WLAN_STA_PS_DRIVER);
940 else
941 ieee80211_queue_work(hw, &sta->drv_unblock_wk);
942}
943EXPORT_SYMBOL(ieee80211_sta_block_awake);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 703f5492ee65..4673454176ed 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -12,6 +12,7 @@
12#include <linux/list.h> 12#include <linux/list.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/if_ether.h> 14#include <linux/if_ether.h>
15#include <linux/workqueue.h>
15#include "key.h" 16#include "key.h"
16 17
17/** 18/**
@@ -21,7 +22,7 @@
21 * 22 *
22 * @WLAN_STA_AUTH: Station is authenticated. 23 * @WLAN_STA_AUTH: Station is authenticated.
23 * @WLAN_STA_ASSOC: Station is associated. 24 * @WLAN_STA_ASSOC: Station is associated.
24 * @WLAN_STA_PS: Station is in power-save mode 25 * @WLAN_STA_PS_STA: Station is in power-save mode
25 * @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic. 26 * @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic.
26 * This bit is always checked so needs to be enabled for all stations 27 * This bit is always checked so needs to be enabled for all stations
27 * when virtual port control is not in use. 28 * when virtual port control is not in use.
@@ -36,11 +37,16 @@
36 * @WLAN_STA_MFP: Management frame protection is used with this STA. 37 * @WLAN_STA_MFP: Management frame protection is used with this STA.
37 * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle. 38 * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle.
38 * Used to deny ADDBA requests (both TX and RX). 39 * Used to deny ADDBA requests (both TX and RX).
40 * @WLAN_STA_PS_DRIVER: driver requires keeping this station in
41 * power-save mode logically to flush frames that might still
42 * be in the queues
43 * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
44 * station in power-save mode, reply when the driver unblocks.
39 */ 45 */
40enum ieee80211_sta_info_flags { 46enum ieee80211_sta_info_flags {
41 WLAN_STA_AUTH = 1<<0, 47 WLAN_STA_AUTH = 1<<0,
42 WLAN_STA_ASSOC = 1<<1, 48 WLAN_STA_ASSOC = 1<<1,
43 WLAN_STA_PS = 1<<2, 49 WLAN_STA_PS_STA = 1<<2,
44 WLAN_STA_AUTHORIZED = 1<<3, 50 WLAN_STA_AUTHORIZED = 1<<3,
45 WLAN_STA_SHORT_PREAMBLE = 1<<4, 51 WLAN_STA_SHORT_PREAMBLE = 1<<4,
46 WLAN_STA_ASSOC_AP = 1<<5, 52 WLAN_STA_ASSOC_AP = 1<<5,
@@ -48,7 +54,9 @@ enum ieee80211_sta_info_flags {
48 WLAN_STA_WDS = 1<<7, 54 WLAN_STA_WDS = 1<<7,
49 WLAN_STA_CLEAR_PS_FILT = 1<<9, 55 WLAN_STA_CLEAR_PS_FILT = 1<<9,
50 WLAN_STA_MFP = 1<<10, 56 WLAN_STA_MFP = 1<<10,
51 WLAN_STA_SUSPEND = 1<<11 57 WLAN_STA_SUSPEND = 1<<11,
58 WLAN_STA_PS_DRIVER = 1<<12,
59 WLAN_STA_PSPOLL = 1<<13,
52}; 60};
53 61
54#define STA_TID_NUM 16 62#define STA_TID_NUM 16
@@ -216,6 +224,8 @@ struct sta_ampdu_mlme {
216 * @plink_timer_was_running: used by suspend/resume to restore timers 224 * @plink_timer_was_running: used by suspend/resume to restore timers
217 * @debugfs: debug filesystem info 225 * @debugfs: debug filesystem info
218 * @sta: station information we share with the driver 226 * @sta: station information we share with the driver
227 * @dead: set to true when sta is unlinked
228 * @drv_unblock_wk used for driver PS unblocking
219 */ 229 */
220struct sta_info { 230struct sta_info {
221 /* General information, mostly static */ 231 /* General information, mostly static */
@@ -229,8 +239,12 @@ struct sta_info {
229 spinlock_t lock; 239 spinlock_t lock;
230 spinlock_t flaglock; 240 spinlock_t flaglock;
231 241
242 struct work_struct drv_unblock_wk;
243
232 u16 listen_interval; 244 u16 listen_interval;
233 245
246 bool dead;
247
234 /* 248 /*
235 * for use by the internal lifetime management, 249 * for use by the internal lifetime management,
236 * see __sta_info_unlink 250 * see __sta_info_unlink
@@ -430,4 +444,7 @@ int sta_info_flush(struct ieee80211_local *local,
430void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 444void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
431 unsigned long exp_time); 445 unsigned long exp_time);
432 446
447void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
448void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
449
433#endif /* STA_INFO_H */ 450#endif /* STA_INFO_H */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c7dc8ccff5b2..bfaa43e096d2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -374,7 +374,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
374 374
375 staflags = get_sta_flags(sta); 375 staflags = get_sta_flags(sta);
376 376
377 if (unlikely((staflags & WLAN_STA_PS) && 377 if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) &&
378 !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { 378 !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) {
379#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 379#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
380 printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " 380 printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries "
@@ -397,8 +397,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
397 } else 397 } else
398 tx->local->total_ps_buffered++; 398 tx->local->total_ps_buffered++;
399 399
400 /* Queue frame to be sent after STA sends an PS Poll frame */ 400 /*
401 if (skb_queue_empty(&sta->ps_tx_buf)) 401 * Queue frame to be sent after STA wakes up/polls,
402 * but don't set the TIM bit if the driver is blocking
403 * wakeup or poll response transmissions anyway.
404 */
405 if (skb_queue_empty(&sta->ps_tx_buf) &&
406 !(staflags & WLAN_STA_PS_DRIVER))
402 sta_info_set_tim_bit(sta); 407 sta_info_set_tim_bit(sta);
403 408
404 info->control.jiffies = jiffies; 409 info->control.jiffies = jiffies;
@@ -408,7 +413,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
408 return TX_QUEUED; 413 return TX_QUEUED;
409 } 414 }
410#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 415#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
411 else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { 416 else if (unlikely(staflags & WLAN_STA_PS_STA)) {
412 printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " 417 printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll "
413 "set -> send frame\n", tx->dev->name, 418 "set -> send frame\n", tx->dev->name,
414 sta->sta.addr); 419 sta->sta.addr);