diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 204 |
1 files changed, 154 insertions, 50 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 8dabe66fc37f..4d85672f0b8f 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -309,8 +309,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
309 | */ | 309 | */ |
310 | sta->timer_to_tid[i] = i; | 310 | sta->timer_to_tid[i] = i; |
311 | } | 311 | } |
312 | skb_queue_head_init(&sta->ps_tx_buf); | 312 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
313 | skb_queue_head_init(&sta->tx_filtered); | 313 | skb_queue_head_init(&sta->ps_tx_buf[i]); |
314 | skb_queue_head_init(&sta->tx_filtered[i]); | ||
315 | } | ||
314 | 316 | ||
315 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 317 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
316 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 318 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
@@ -641,12 +643,32 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | |||
641 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | 643 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); |
642 | } | 644 | } |
643 | 645 | ||
646 | static unsigned long ieee80211_tids_for_ac(int ac) | ||
647 | { | ||
648 | /* If we ever support TIDs > 7, this obviously needs to be adjusted */ | ||
649 | switch (ac) { | ||
650 | case IEEE80211_AC_VO: | ||
651 | return BIT(6) | BIT(7); | ||
652 | case IEEE80211_AC_VI: | ||
653 | return BIT(4) | BIT(5); | ||
654 | case IEEE80211_AC_BE: | ||
655 | return BIT(0) | BIT(3); | ||
656 | case IEEE80211_AC_BK: | ||
657 | return BIT(1) | BIT(2); | ||
658 | default: | ||
659 | WARN_ON(1); | ||
660 | return 0; | ||
661 | } | ||
662 | } | ||
663 | |||
644 | void sta_info_recalc_tim(struct sta_info *sta) | 664 | void sta_info_recalc_tim(struct sta_info *sta) |
645 | { | 665 | { |
646 | struct ieee80211_local *local = sta->local; | 666 | struct ieee80211_local *local = sta->local; |
647 | struct ieee80211_if_ap *bss = sta->sdata->bss; | 667 | struct ieee80211_if_ap *bss = sta->sdata->bss; |
648 | unsigned long flags; | 668 | unsigned long flags; |
649 | bool have_data = false; | 669 | bool indicate_tim = false; |
670 | u8 ignore_for_tim = sta->sta.uapsd_queues; | ||
671 | int ac; | ||
650 | 672 | ||
651 | if (WARN_ON_ONCE(!sta->sdata->bss)) | 673 | if (WARN_ON_ONCE(!sta->sdata->bss)) |
652 | return; | 674 | return; |
@@ -658,21 +680,43 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
658 | if (sta->dead) | 680 | if (sta->dead) |
659 | goto done; | 681 | goto done; |
660 | 682 | ||
661 | have_data = test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF) || | 683 | /* |
662 | !skb_queue_empty(&sta->tx_filtered) || | 684 | * If all ACs are delivery-enabled then we should build |
663 | !skb_queue_empty(&sta->ps_tx_buf); | 685 | * the TIM bit for all ACs anyway; if only some are then |
686 | * we ignore those and build the TIM bit using only the | ||
687 | * non-enabled ones. | ||
688 | */ | ||
689 | if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1) | ||
690 | ignore_for_tim = 0; | ||
691 | |||
692 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
693 | unsigned long tids; | ||
694 | |||
695 | if (ignore_for_tim & BIT(ac)) | ||
696 | continue; | ||
697 | |||
698 | indicate_tim |= !skb_queue_empty(&sta->tx_filtered[ac]) || | ||
699 | !skb_queue_empty(&sta->ps_tx_buf[ac]); | ||
700 | if (indicate_tim) | ||
701 | break; | ||
702 | |||
703 | tids = ieee80211_tids_for_ac(ac); | ||
704 | |||
705 | indicate_tim |= | ||
706 | sta->driver_buffered_tids & tids; | ||
707 | } | ||
664 | 708 | ||
665 | done: | 709 | done: |
666 | spin_lock_irqsave(&local->sta_lock, flags); | 710 | spin_lock_irqsave(&local->sta_lock, flags); |
667 | 711 | ||
668 | if (have_data) | 712 | if (indicate_tim) |
669 | __bss_tim_set(bss, sta->sta.aid); | 713 | __bss_tim_set(bss, sta->sta.aid); |
670 | else | 714 | else |
671 | __bss_tim_clear(bss, sta->sta.aid); | 715 | __bss_tim_clear(bss, sta->sta.aid); |
672 | 716 | ||
673 | if (local->ops->set_tim) { | 717 | if (local->ops->set_tim) { |
674 | local->tim_in_locked_section = true; | 718 | local->tim_in_locked_section = true; |
675 | drv_set_tim(local, &sta->sta, have_data); | 719 | drv_set_tim(local, &sta->sta, indicate_tim); |
676 | local->tim_in_locked_section = false; | 720 | local->tim_in_locked_section = false; |
677 | } | 721 | } |
678 | 722 | ||
@@ -699,16 +743,12 @@ static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) | |||
699 | } | 743 | } |
700 | 744 | ||
701 | 745 | ||
702 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | 746 | static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, |
703 | struct sta_info *sta) | 747 | struct sta_info *sta, int ac) |
704 | { | 748 | { |
705 | unsigned long flags; | 749 | unsigned long flags; |
706 | struct sk_buff *skb; | 750 | struct sk_buff *skb; |
707 | 751 | ||
708 | /* This is only necessary for stations on BSS interfaces */ | ||
709 | if (!sta->sdata->bss) | ||
710 | return false; | ||
711 | |||
712 | /* | 752 | /* |
713 | * First check for frames that should expire on the filtered | 753 | * First check for frames that should expire on the filtered |
714 | * queue. Frames here were rejected by the driver and are on | 754 | * queue. Frames here were rejected by the driver and are on |
@@ -717,13 +757,13 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
717 | * total_ps_buffered counter. | 757 | * total_ps_buffered counter. |
718 | */ | 758 | */ |
719 | for (;;) { | 759 | for (;;) { |
720 | spin_lock_irqsave(&sta->tx_filtered.lock, flags); | 760 | spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); |
721 | skb = skb_peek(&sta->tx_filtered); | 761 | skb = skb_peek(&sta->tx_filtered[ac]); |
722 | if (sta_info_buffer_expired(sta, skb)) | 762 | if (sta_info_buffer_expired(sta, skb)) |
723 | skb = __skb_dequeue(&sta->tx_filtered); | 763 | skb = __skb_dequeue(&sta->tx_filtered[ac]); |
724 | else | 764 | else |
725 | skb = NULL; | 765 | skb = NULL; |
726 | spin_unlock_irqrestore(&sta->tx_filtered.lock, flags); | 766 | spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); |
727 | 767 | ||
728 | /* | 768 | /* |
729 | * Frames are queued in order, so if this one | 769 | * Frames are queued in order, so if this one |
@@ -743,13 +783,13 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
743 | * buffered frames. | 783 | * buffered frames. |
744 | */ | 784 | */ |
745 | for (;;) { | 785 | for (;;) { |
746 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 786 | spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); |
747 | skb = skb_peek(&sta->ps_tx_buf); | 787 | skb = skb_peek(&sta->ps_tx_buf[ac]); |
748 | if (sta_info_buffer_expired(sta, skb)) | 788 | if (sta_info_buffer_expired(sta, skb)) |
749 | skb = __skb_dequeue(&sta->ps_tx_buf); | 789 | skb = __skb_dequeue(&sta->ps_tx_buf[ac]); |
750 | else | 790 | else |
751 | skb = NULL; | 791 | skb = NULL; |
752 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); | 792 | spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); |
753 | 793 | ||
754 | /* | 794 | /* |
755 | * frames are queued in order, so if this one | 795 | * frames are queued in order, so if this one |
@@ -779,8 +819,25 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
779 | * used to check whether the cleanup timer still needs to run, | 819 | * used to check whether the cleanup timer still needs to run, |
780 | * if there are no frames we don't need to rearm the timer. | 820 | * if there are no frames we don't need to rearm the timer. |
781 | */ | 821 | */ |
782 | return !(skb_queue_empty(&sta->ps_tx_buf) && | 822 | return !(skb_queue_empty(&sta->ps_tx_buf[ac]) && |
783 | skb_queue_empty(&sta->tx_filtered)); | 823 | skb_queue_empty(&sta->tx_filtered[ac])); |
824 | } | ||
825 | |||
826 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | ||
827 | struct sta_info *sta) | ||
828 | { | ||
829 | bool have_buffered = false; | ||
830 | int ac; | ||
831 | |||
832 | /* This is only necessary for stations on BSS interfaces */ | ||
833 | if (!sta->sdata->bss) | ||
834 | return false; | ||
835 | |||
836 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
837 | have_buffered |= | ||
838 | sta_info_cleanup_expire_buffered_ac(local, sta, ac); | ||
839 | |||
840 | return have_buffered; | ||
784 | } | 841 | } |
785 | 842 | ||
786 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 843 | static int __must_check __sta_info_destroy(struct sta_info *sta) |
@@ -788,7 +845,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
788 | struct ieee80211_local *local; | 845 | struct ieee80211_local *local; |
789 | struct ieee80211_sub_if_data *sdata; | 846 | struct ieee80211_sub_if_data *sdata; |
790 | unsigned long flags; | 847 | unsigned long flags; |
791 | int ret, i; | 848 | int ret, i, ac; |
792 | 849 | ||
793 | might_sleep(); | 850 | might_sleep(); |
794 | 851 | ||
@@ -856,9 +913,11 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
856 | */ | 913 | */ |
857 | synchronize_rcu(); | 914 | synchronize_rcu(); |
858 | 915 | ||
859 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf); | 916 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
860 | __skb_queue_purge(&sta->ps_tx_buf); | 917 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); |
861 | __skb_queue_purge(&sta->tx_filtered); | 918 | __skb_queue_purge(&sta->ps_tx_buf[ac]); |
919 | __skb_queue_purge(&sta->tx_filtered[ac]); | ||
920 | } | ||
862 | 921 | ||
863 | #ifdef CONFIG_MAC80211_MESH | 922 | #ifdef CONFIG_MAC80211_MESH |
864 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 923 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
@@ -1055,17 +1114,33 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1055 | { | 1114 | { |
1056 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1115 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1057 | struct ieee80211_local *local = sdata->local; | 1116 | struct ieee80211_local *local = sdata->local; |
1058 | int sent, buffered; | 1117 | struct sk_buff_head pending; |
1118 | int filtered = 0, buffered = 0, ac; | ||
1119 | |||
1120 | BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); | ||
1121 | sta->driver_buffered_tids = 0; | ||
1059 | 1122 | ||
1060 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | ||
1061 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1123 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1062 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); | 1124 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); |
1063 | 1125 | ||
1126 | skb_queue_head_init(&pending); | ||
1127 | |||
1064 | /* Send all buffered frames to the station */ | 1128 | /* Send all buffered frames to the station */ |
1065 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); | 1129 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
1066 | buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf, | 1130 | int count = skb_queue_len(&pending), tmp; |
1067 | clear_sta_ps_flags, sta); | 1131 | |
1068 | sent += buffered; | 1132 | skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); |
1133 | tmp = skb_queue_len(&pending); | ||
1134 | filtered += tmp - count; | ||
1135 | count = tmp; | ||
1136 | |||
1137 | skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); | ||
1138 | tmp = skb_queue_len(&pending); | ||
1139 | buffered += tmp - count; | ||
1140 | } | ||
1141 | |||
1142 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | ||
1143 | |||
1069 | local->total_ps_buffered -= buffered; | 1144 | local->total_ps_buffered -= buffered; |
1070 | 1145 | ||
1071 | sta_info_recalc_tim(sta); | 1146 | sta_info_recalc_tim(sta); |
@@ -1073,7 +1148,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1073 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1148 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1074 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | 1149 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " |
1075 | "since STA not sleeping anymore\n", sdata->name, | 1150 | "since STA not sleeping anymore\n", sdata->name, |
1076 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); | 1151 | sta->sta.addr, sta->sta.aid, filtered, buffered); |
1077 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1152 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1078 | } | 1153 | } |
1079 | 1154 | ||
@@ -1081,17 +1156,43 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | |||
1081 | { | 1156 | { |
1082 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1157 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1083 | struct ieee80211_local *local = sdata->local; | 1158 | struct ieee80211_local *local = sdata->local; |
1084 | struct sk_buff *skb; | 1159 | struct sk_buff *skb = NULL; |
1085 | int no_pending_pkts; | 1160 | bool more_data = false; |
1161 | int ac; | ||
1162 | u8 ignore_for_response = sta->sta.uapsd_queues; | ||
1086 | 1163 | ||
1087 | skb = skb_dequeue(&sta->tx_filtered); | 1164 | /* |
1088 | if (!skb) { | 1165 | * If all ACs are delivery-enabled then we should reply |
1089 | skb = skb_dequeue(&sta->ps_tx_buf); | 1166 | * from any of them, if only some are enabled we reply |
1090 | if (skb) | 1167 | * only from the non-enabled ones. |
1091 | local->total_ps_buffered--; | 1168 | */ |
1169 | if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1) | ||
1170 | ignore_for_response = 0; | ||
1171 | |||
1172 | /* | ||
1173 | * Get response frame and more data bit for it. | ||
1174 | */ | ||
1175 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
1176 | if (ignore_for_response & BIT(ac)) | ||
1177 | continue; | ||
1178 | |||
1179 | if (!skb) { | ||
1180 | skb = skb_dequeue(&sta->tx_filtered[ac]); | ||
1181 | if (!skb) { | ||
1182 | skb = skb_dequeue(&sta->ps_tx_buf[ac]); | ||
1183 | if (skb) | ||
1184 | local->total_ps_buffered--; | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | /* FIXME: take into account driver-buffered frames */ | ||
1189 | |||
1190 | if (!skb_queue_empty(&sta->tx_filtered[ac]) || | ||
1191 | !skb_queue_empty(&sta->ps_tx_buf[ac])) { | ||
1192 | more_data = true; | ||
1193 | break; | ||
1194 | } | ||
1092 | } | 1195 | } |
1093 | no_pending_pkts = skb_queue_empty(&sta->tx_filtered) && | ||
1094 | skb_queue_empty(&sta->ps_tx_buf); | ||
1095 | 1196 | ||
1096 | if (skb) { | 1197 | if (skb) { |
1097 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1198 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1105,14 +1206,13 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | |||
1105 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; | 1206 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; |
1106 | 1207 | ||
1107 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1208 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1108 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", | 1209 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll\n", |
1109 | sta->sta.addr, sta->sta.aid, | 1210 | sta->sta.addr, sta->sta.aid); |
1110 | skb_queue_len(&sta->ps_tx_buf)); | ||
1111 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1211 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1112 | 1212 | ||
1113 | /* Use MoreData flag to indicate whether there are more | 1213 | /* Use MoreData flag to indicate whether there are more |
1114 | * buffered frames for this STA */ | 1214 | * buffered frames for this STA */ |
1115 | if (no_pending_pkts) | 1215 | if (!more_data) |
1116 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | 1216 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); |
1117 | else | 1217 | else |
1118 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 1218 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
@@ -1154,10 +1254,14 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | |||
1154 | { | 1254 | { |
1155 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 1255 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
1156 | 1256 | ||
1157 | if (!buffered) | 1257 | if (WARN_ON(tid >= STA_TID_NUM)) |
1158 | return; | 1258 | return; |
1159 | 1259 | ||
1160 | set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | 1260 | if (buffered) |
1261 | set_bit(tid, &sta->driver_buffered_tids); | ||
1262 | else | ||
1263 | clear_bit(tid, &sta->driver_buffered_tids); | ||
1264 | |||
1161 | sta_info_recalc_tim(sta); | 1265 | sta_info_recalc_tim(sta); |
1162 | } | 1266 | } |
1163 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); | 1267 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); |