aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c86
1 files changed, 15 insertions, 71 deletions
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. */