diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 86 |
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) | |||
792 | static void ap_sta_ps_end(struct sta_info *sta) | 792 | static 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 | ||
824 | static ieee80211_rx_result debug_noinline | 816 | static 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) | |||
1094 | static ieee80211_rx_result debug_noinline | 1086 | static ieee80211_rx_result debug_noinline |
1095 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 1087 | ieee80211_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. */ |