diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Kconfig | 12 | ||||
-rw-r--r-- | net/mac80211/agg-rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 380 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 37 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 33 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 77 | ||||
-rw-r--r-- | net/mac80211/ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 16 | ||||
-rw-r--r-- | net/mac80211/iface.c | 4 | ||||
-rw-r--r-- | net/mac80211/key.c | 4 | ||||
-rw-r--r-- | net/mac80211/main.c | 18 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 58 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 4 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 12 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 34 | ||||
-rw-r--r-- | net/mac80211/pm.c | 2 | ||||
-rw-r--r-- | net/mac80211/rate.c | 8 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 118 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 636 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 136 | ||||
-rw-r--r-- | net/mac80211/status.c | 54 | ||||
-rw-r--r-- | net/mac80211/tx.c | 187 | ||||
-rw-r--r-- | net/mac80211/util.c | 76 | ||||
-rw-r--r-- | net/mac80211/wme.c | 4 |
27 files changed, 1470 insertions, 452 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index d1886b59bec4..7d3b438755f0 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -225,6 +225,18 @@ config MAC80211_VERBOSE_MHWMP_DEBUG | |||
225 | 225 | ||
226 | Do not select this option. | 226 | Do not select this option. |
227 | 227 | ||
228 | config MAC80211_VERBOSE_TDLS_DEBUG | ||
229 | bool "Verbose TDLS debugging" | ||
230 | depends on MAC80211_DEBUG_MENU | ||
231 | ---help--- | ||
232 | Selecting this option causes mac80211 to print out very | ||
233 | verbose TDLS selection debugging messages (when mac80211 | ||
234 | is a TDLS STA). | ||
235 | It should not be selected on production systems as those | ||
236 | messages are remotely triggerable. | ||
237 | |||
238 | Do not select this option. | ||
239 | |||
228 | config MAC80211_DEBUG_COUNTERS | 240 | config MAC80211_DEBUG_COUNTERS |
229 | bool "Extra statistics for TX/RX debugging" | 241 | bool "Extra statistics for TX/RX debugging" |
230 | depends on MAC80211_DEBUG_MENU | 242 | depends on MAC80211_DEBUG_MENU |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 7c366dfe8da9..97f33588b65f 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -223,7 +223,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
223 | 223 | ||
224 | status = WLAN_STATUS_REQUEST_DECLINED; | 224 | status = WLAN_STATUS_REQUEST_DECLINED; |
225 | 225 | ||
226 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { | 226 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
227 | #ifdef CONFIG_MAC80211_HT_DEBUG | 227 | #ifdef CONFIG_MAC80211_HT_DEBUG |
228 | printk(KERN_DEBUG "Suspend in progress. " | 228 | printk(KERN_DEBUG "Suspend in progress. " |
229 | "Denying ADDBA request\n"); | 229 | "Denying ADDBA request\n"); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 3cef5a7281cb..2ac033989e01 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -382,7 +382,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
382 | sdata->vif.type != NL80211_IFTYPE_AP) | 382 | sdata->vif.type != NL80211_IFTYPE_AP) |
383 | return -EINVAL; | 383 | return -EINVAL; |
384 | 384 | ||
385 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { | 385 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
386 | #ifdef CONFIG_MAC80211_HT_DEBUG | 386 | #ifdef CONFIG_MAC80211_HT_DEBUG |
387 | printk(KERN_DEBUG "BA sessions blocked. " | 387 | printk(KERN_DEBUG "BA sessions blocked. " |
388 | "Denying BA session request\n"); | 388 | "Denying BA session request\n"); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9b1a95e1f56a..55ee5a31756f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <net/net_namespace.h> | 13 | #include <net/net_namespace.h> |
14 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
15 | #include <linux/if_ether.h> | ||
15 | #include <net/cfg80211.h> | 16 | #include <net/cfg80211.h> |
16 | #include "ieee80211_i.h" | 17 | #include "ieee80211_i.h" |
17 | #include "driver-ops.h" | 18 | #include "driver-ops.h" |
@@ -667,7 +668,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
667 | struct sta_info *sta, | 668 | struct sta_info *sta, |
668 | struct station_parameters *params) | 669 | struct station_parameters *params) |
669 | { | 670 | { |
670 | unsigned long flags; | ||
671 | u32 rates; | 671 | u32 rates; |
672 | int i, j; | 672 | int i, j; |
673 | struct ieee80211_supported_band *sband; | 673 | struct ieee80211_supported_band *sband; |
@@ -676,46 +676,58 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
676 | 676 | ||
677 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 677 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
678 | 678 | ||
679 | spin_lock_irqsave(&sta->flaglock, flags); | ||
680 | mask = params->sta_flags_mask; | 679 | mask = params->sta_flags_mask; |
681 | set = params->sta_flags_set; | 680 | set = params->sta_flags_set; |
682 | 681 | ||
683 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { | 682 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { |
684 | sta->flags &= ~WLAN_STA_AUTHORIZED; | ||
685 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) | 683 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) |
686 | sta->flags |= WLAN_STA_AUTHORIZED; | 684 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
685 | else | ||
686 | clear_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
687 | } | 687 | } |
688 | 688 | ||
689 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { | 689 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { |
690 | sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; | ||
691 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) | 690 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) |
692 | sta->flags |= WLAN_STA_SHORT_PREAMBLE; | 691 | set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); |
692 | else | ||
693 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); | ||
693 | } | 694 | } |
694 | 695 | ||
695 | if (mask & BIT(NL80211_STA_FLAG_WME)) { | 696 | if (mask & BIT(NL80211_STA_FLAG_WME)) { |
696 | sta->flags &= ~WLAN_STA_WME; | ||
697 | sta->sta.wme = false; | ||
698 | if (set & BIT(NL80211_STA_FLAG_WME)) { | 697 | if (set & BIT(NL80211_STA_FLAG_WME)) { |
699 | sta->flags |= WLAN_STA_WME; | 698 | set_sta_flag(sta, WLAN_STA_WME); |
700 | sta->sta.wme = true; | 699 | sta->sta.wme = true; |
700 | } else { | ||
701 | clear_sta_flag(sta, WLAN_STA_WME); | ||
702 | sta->sta.wme = false; | ||
701 | } | 703 | } |
702 | } | 704 | } |
703 | 705 | ||
704 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { | 706 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { |
705 | sta->flags &= ~WLAN_STA_MFP; | ||
706 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 707 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
707 | sta->flags |= WLAN_STA_MFP; | 708 | set_sta_flag(sta, WLAN_STA_MFP); |
709 | else | ||
710 | clear_sta_flag(sta, WLAN_STA_MFP); | ||
708 | } | 711 | } |
709 | 712 | ||
710 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | 713 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { |
711 | sta->flags &= ~WLAN_STA_AUTH; | ||
712 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) | 714 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) |
713 | sta->flags |= WLAN_STA_AUTH; | 715 | set_sta_flag(sta, WLAN_STA_AUTH); |
716 | else | ||
717 | clear_sta_flag(sta, WLAN_STA_AUTH); | ||
714 | } | 718 | } |
715 | spin_unlock_irqrestore(&sta->flaglock, flags); | ||
716 | 719 | ||
717 | sta->sta.uapsd_queues = params->uapsd_queues; | 720 | if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { |
718 | sta->sta.max_sp = params->max_sp; | 721 | if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
722 | set_sta_flag(sta, WLAN_STA_TDLS_PEER); | ||
723 | else | ||
724 | clear_sta_flag(sta, WLAN_STA_TDLS_PEER); | ||
725 | } | ||
726 | |||
727 | if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { | ||
728 | sta->sta.uapsd_queues = params->uapsd_queues; | ||
729 | sta->sta.max_sp = params->max_sp; | ||
730 | } | ||
719 | 731 | ||
720 | /* | 732 | /* |
721 | * cfg80211 validates this (1-2007) and allows setting the AID | 733 | * cfg80211 validates this (1-2007) and allows setting the AID |
@@ -806,10 +818,17 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
806 | if (!sta) | 818 | if (!sta) |
807 | return -ENOMEM; | 819 | return -ENOMEM; |
808 | 820 | ||
809 | sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; | 821 | set_sta_flag(sta, WLAN_STA_AUTH); |
822 | set_sta_flag(sta, WLAN_STA_ASSOC); | ||
810 | 823 | ||
811 | sta_apply_parameters(local, sta, params); | 824 | sta_apply_parameters(local, sta, params); |
812 | 825 | ||
826 | /* Only TDLS-supporting stations can add TDLS peers */ | ||
827 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && | ||
828 | !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && | ||
829 | sdata->vif.type == NL80211_IFTYPE_STATION)) | ||
830 | return -ENOTSUPP; | ||
831 | |||
813 | rate_control_rate_init(sta); | 832 | rate_control_rate_init(sta); |
814 | 833 | ||
815 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 834 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
@@ -862,6 +881,14 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
862 | return -ENOENT; | 881 | return -ENOENT; |
863 | } | 882 | } |
864 | 883 | ||
884 | /* The TDLS bit cannot be toggled after the STA was added */ | ||
885 | if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) && | ||
886 | !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) != | ||
887 | !!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { | ||
888 | rcu_read_unlock(); | ||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
865 | if (params->vlan && params->vlan != sta->sdata->dev) { | 892 | if (params->vlan && params->vlan != sta->sdata->dev) { |
866 | vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); | 893 | vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); |
867 | 894 | ||
@@ -2126,6 +2153,323 @@ static int ieee80211_set_rekey_data(struct wiphy *wiphy, | |||
2126 | return 0; | 2153 | return 0; |
2127 | } | 2154 | } |
2128 | 2155 | ||
2156 | static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) | ||
2157 | { | ||
2158 | u8 *pos = (void *)skb_put(skb, 7); | ||
2159 | |||
2160 | *pos++ = WLAN_EID_EXT_CAPABILITY; | ||
2161 | *pos++ = 5; /* len */ | ||
2162 | *pos++ = 0x0; | ||
2163 | *pos++ = 0x0; | ||
2164 | *pos++ = 0x0; | ||
2165 | *pos++ = 0x0; | ||
2166 | *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; | ||
2167 | } | ||
2168 | |||
2169 | static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) | ||
2170 | { | ||
2171 | struct ieee80211_local *local = sdata->local; | ||
2172 | u16 capab; | ||
2173 | |||
2174 | capab = 0; | ||
2175 | if (local->oper_channel->band != IEEE80211_BAND_2GHZ) | ||
2176 | return capab; | ||
2177 | |||
2178 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) | ||
2179 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; | ||
2180 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) | ||
2181 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; | ||
2182 | |||
2183 | return capab; | ||
2184 | } | ||
2185 | |||
2186 | static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, | ||
2187 | u8 *peer, u8 *bssid) | ||
2188 | { | ||
2189 | struct ieee80211_tdls_lnkie *lnkid; | ||
2190 | |||
2191 | lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); | ||
2192 | |||
2193 | lnkid->ie_type = WLAN_EID_LINK_ID; | ||
2194 | lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; | ||
2195 | |||
2196 | memcpy(lnkid->bssid, bssid, ETH_ALEN); | ||
2197 | memcpy(lnkid->init_sta, src_addr, ETH_ALEN); | ||
2198 | memcpy(lnkid->resp_sta, peer, ETH_ALEN); | ||
2199 | } | ||
2200 | |||
2201 | static int | ||
2202 | ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | ||
2203 | u8 *peer, u8 action_code, u8 dialog_token, | ||
2204 | u16 status_code, struct sk_buff *skb) | ||
2205 | { | ||
2206 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2207 | struct ieee80211_tdls_data *tf; | ||
2208 | |||
2209 | tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); | ||
2210 | |||
2211 | memcpy(tf->da, peer, ETH_ALEN); | ||
2212 | memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); | ||
2213 | tf->ether_type = cpu_to_be16(ETH_P_TDLS); | ||
2214 | tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; | ||
2215 | |||
2216 | switch (action_code) { | ||
2217 | case WLAN_TDLS_SETUP_REQUEST: | ||
2218 | tf->category = WLAN_CATEGORY_TDLS; | ||
2219 | tf->action_code = WLAN_TDLS_SETUP_REQUEST; | ||
2220 | |||
2221 | skb_put(skb, sizeof(tf->u.setup_req)); | ||
2222 | tf->u.setup_req.dialog_token = dialog_token; | ||
2223 | tf->u.setup_req.capability = | ||
2224 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | ||
2225 | |||
2226 | ieee80211_add_srates_ie(&sdata->vif, skb); | ||
2227 | ieee80211_add_ext_srates_ie(&sdata->vif, skb); | ||
2228 | ieee80211_tdls_add_ext_capab(skb); | ||
2229 | break; | ||
2230 | case WLAN_TDLS_SETUP_RESPONSE: | ||
2231 | tf->category = WLAN_CATEGORY_TDLS; | ||
2232 | tf->action_code = WLAN_TDLS_SETUP_RESPONSE; | ||
2233 | |||
2234 | skb_put(skb, sizeof(tf->u.setup_resp)); | ||
2235 | tf->u.setup_resp.status_code = cpu_to_le16(status_code); | ||
2236 | tf->u.setup_resp.dialog_token = dialog_token; | ||
2237 | tf->u.setup_resp.capability = | ||
2238 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | ||
2239 | |||
2240 | ieee80211_add_srates_ie(&sdata->vif, skb); | ||
2241 | ieee80211_add_ext_srates_ie(&sdata->vif, skb); | ||
2242 | ieee80211_tdls_add_ext_capab(skb); | ||
2243 | break; | ||
2244 | case WLAN_TDLS_SETUP_CONFIRM: | ||
2245 | tf->category = WLAN_CATEGORY_TDLS; | ||
2246 | tf->action_code = WLAN_TDLS_SETUP_CONFIRM; | ||
2247 | |||
2248 | skb_put(skb, sizeof(tf->u.setup_cfm)); | ||
2249 | tf->u.setup_cfm.status_code = cpu_to_le16(status_code); | ||
2250 | tf->u.setup_cfm.dialog_token = dialog_token; | ||
2251 | break; | ||
2252 | case WLAN_TDLS_TEARDOWN: | ||
2253 | tf->category = WLAN_CATEGORY_TDLS; | ||
2254 | tf->action_code = WLAN_TDLS_TEARDOWN; | ||
2255 | |||
2256 | skb_put(skb, sizeof(tf->u.teardown)); | ||
2257 | tf->u.teardown.reason_code = cpu_to_le16(status_code); | ||
2258 | break; | ||
2259 | case WLAN_TDLS_DISCOVERY_REQUEST: | ||
2260 | tf->category = WLAN_CATEGORY_TDLS; | ||
2261 | tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; | ||
2262 | |||
2263 | skb_put(skb, sizeof(tf->u.discover_req)); | ||
2264 | tf->u.discover_req.dialog_token = dialog_token; | ||
2265 | break; | ||
2266 | default: | ||
2267 | return -EINVAL; | ||
2268 | } | ||
2269 | |||
2270 | return 0; | ||
2271 | } | ||
2272 | |||
2273 | static int | ||
2274 | ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | ||
2275 | u8 *peer, u8 action_code, u8 dialog_token, | ||
2276 | u16 status_code, struct sk_buff *skb) | ||
2277 | { | ||
2278 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2279 | struct ieee80211_mgmt *mgmt; | ||
2280 | |||
2281 | mgmt = (void *)skb_put(skb, 24); | ||
2282 | memset(mgmt, 0, 24); | ||
2283 | memcpy(mgmt->da, peer, ETH_ALEN); | ||
2284 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | ||
2285 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | ||
2286 | |||
2287 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
2288 | IEEE80211_STYPE_ACTION); | ||
2289 | |||
2290 | switch (action_code) { | ||
2291 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: | ||
2292 | skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); | ||
2293 | mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; | ||
2294 | mgmt->u.action.u.tdls_discover_resp.action_code = | ||
2295 | WLAN_PUB_ACTION_TDLS_DISCOVER_RES; | ||
2296 | mgmt->u.action.u.tdls_discover_resp.dialog_token = | ||
2297 | dialog_token; | ||
2298 | mgmt->u.action.u.tdls_discover_resp.capability = | ||
2299 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | ||
2300 | |||
2301 | ieee80211_add_srates_ie(&sdata->vif, skb); | ||
2302 | ieee80211_add_ext_srates_ie(&sdata->vif, skb); | ||
2303 | ieee80211_tdls_add_ext_capab(skb); | ||
2304 | break; | ||
2305 | default: | ||
2306 | return -EINVAL; | ||
2307 | } | ||
2308 | |||
2309 | return 0; | ||
2310 | } | ||
2311 | |||
2312 | static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | ||
2313 | u8 *peer, u8 action_code, u8 dialog_token, | ||
2314 | u16 status_code, const u8 *extra_ies, | ||
2315 | size_t extra_ies_len) | ||
2316 | { | ||
2317 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2318 | struct ieee80211_local *local = sdata->local; | ||
2319 | struct ieee80211_tx_info *info; | ||
2320 | struct sk_buff *skb = NULL; | ||
2321 | bool send_direct; | ||
2322 | int ret; | ||
2323 | |||
2324 | if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) | ||
2325 | return -ENOTSUPP; | ||
2326 | |||
2327 | /* make sure we are in managed mode, and associated */ | ||
2328 | if (sdata->vif.type != NL80211_IFTYPE_STATION || | ||
2329 | !sdata->u.mgd.associated) | ||
2330 | return -EINVAL; | ||
2331 | |||
2332 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | ||
2333 | printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer); | ||
2334 | #endif | ||
2335 | |||
2336 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
2337 | max(sizeof(struct ieee80211_mgmt), | ||
2338 | sizeof(struct ieee80211_tdls_data)) + | ||
2339 | 50 + /* supported rates */ | ||
2340 | 7 + /* ext capab */ | ||
2341 | extra_ies_len + | ||
2342 | sizeof(struct ieee80211_tdls_lnkie)); | ||
2343 | if (!skb) | ||
2344 | return -ENOMEM; | ||
2345 | |||
2346 | info = IEEE80211_SKB_CB(skb); | ||
2347 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2348 | |||
2349 | switch (action_code) { | ||
2350 | case WLAN_TDLS_SETUP_REQUEST: | ||
2351 | case WLAN_TDLS_SETUP_RESPONSE: | ||
2352 | case WLAN_TDLS_SETUP_CONFIRM: | ||
2353 | case WLAN_TDLS_TEARDOWN: | ||
2354 | case WLAN_TDLS_DISCOVERY_REQUEST: | ||
2355 | ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, | ||
2356 | action_code, dialog_token, | ||
2357 | status_code, skb); | ||
2358 | send_direct = false; | ||
2359 | break; | ||
2360 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: | ||
2361 | ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, | ||
2362 | dialog_token, status_code, | ||
2363 | skb); | ||
2364 | send_direct = true; | ||
2365 | break; | ||
2366 | default: | ||
2367 | ret = -ENOTSUPP; | ||
2368 | break; | ||
2369 | } | ||
2370 | |||
2371 | if (ret < 0) | ||
2372 | goto fail; | ||
2373 | |||
2374 | if (extra_ies_len) | ||
2375 | memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); | ||
2376 | |||
2377 | /* the TDLS link IE is always added last */ | ||
2378 | switch (action_code) { | ||
2379 | case WLAN_TDLS_SETUP_REQUEST: | ||
2380 | case WLAN_TDLS_SETUP_CONFIRM: | ||
2381 | case WLAN_TDLS_TEARDOWN: | ||
2382 | case WLAN_TDLS_DISCOVERY_REQUEST: | ||
2383 | /* we are the initiator */ | ||
2384 | ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, | ||
2385 | sdata->u.mgd.bssid); | ||
2386 | break; | ||
2387 | case WLAN_TDLS_SETUP_RESPONSE: | ||
2388 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: | ||
2389 | /* we are the responder */ | ||
2390 | ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, | ||
2391 | sdata->u.mgd.bssid); | ||
2392 | break; | ||
2393 | default: | ||
2394 | ret = -ENOTSUPP; | ||
2395 | goto fail; | ||
2396 | } | ||
2397 | |||
2398 | if (send_direct) { | ||
2399 | ieee80211_tx_skb(sdata, skb); | ||
2400 | return 0; | ||
2401 | } | ||
2402 | |||
2403 | /* | ||
2404 | * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise | ||
2405 | * we should default to AC_VI. | ||
2406 | */ | ||
2407 | switch (action_code) { | ||
2408 | case WLAN_TDLS_SETUP_REQUEST: | ||
2409 | case WLAN_TDLS_SETUP_RESPONSE: | ||
2410 | skb_set_queue_mapping(skb, IEEE80211_AC_BK); | ||
2411 | skb->priority = 2; | ||
2412 | break; | ||
2413 | default: | ||
2414 | skb_set_queue_mapping(skb, IEEE80211_AC_VI); | ||
2415 | skb->priority = 5; | ||
2416 | break; | ||
2417 | } | ||
2418 | |||
2419 | /* disable bottom halves when entering the Tx path */ | ||
2420 | local_bh_disable(); | ||
2421 | ret = ieee80211_subif_start_xmit(skb, dev); | ||
2422 | local_bh_enable(); | ||
2423 | |||
2424 | return ret; | ||
2425 | |||
2426 | fail: | ||
2427 | dev_kfree_skb(skb); | ||
2428 | return ret; | ||
2429 | } | ||
2430 | |||
2431 | static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | ||
2432 | u8 *peer, enum nl80211_tdls_operation oper) | ||
2433 | { | ||
2434 | struct sta_info *sta; | ||
2435 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2436 | |||
2437 | if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) | ||
2438 | return -ENOTSUPP; | ||
2439 | |||
2440 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
2441 | return -EINVAL; | ||
2442 | |||
2443 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | ||
2444 | printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer); | ||
2445 | #endif | ||
2446 | |||
2447 | switch (oper) { | ||
2448 | case NL80211_TDLS_ENABLE_LINK: | ||
2449 | rcu_read_lock(); | ||
2450 | sta = sta_info_get(sdata, peer); | ||
2451 | if (!sta) { | ||
2452 | rcu_read_unlock(); | ||
2453 | return -ENOLINK; | ||
2454 | } | ||
2455 | |||
2456 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); | ||
2457 | rcu_read_unlock(); | ||
2458 | break; | ||
2459 | case NL80211_TDLS_DISABLE_LINK: | ||
2460 | return sta_info_destroy_addr(sdata, peer); | ||
2461 | case NL80211_TDLS_TEARDOWN: | ||
2462 | case NL80211_TDLS_SETUP: | ||
2463 | case NL80211_TDLS_DISCOVERY_REQ: | ||
2464 | /* We don't support in-driver setup/teardown/discovery */ | ||
2465 | return -ENOTSUPP; | ||
2466 | default: | ||
2467 | return -ENOTSUPP; | ||
2468 | } | ||
2469 | |||
2470 | return 0; | ||
2471 | } | ||
2472 | |||
2129 | struct cfg80211_ops mac80211_config_ops = { | 2473 | struct cfg80211_ops mac80211_config_ops = { |
2130 | .add_virtual_intf = ieee80211_add_iface, | 2474 | .add_virtual_intf = ieee80211_add_iface, |
2131 | .del_virtual_intf = ieee80211_del_iface, | 2475 | .del_virtual_intf = ieee80211_del_iface, |
@@ -2189,4 +2533,6 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2189 | .set_ringparam = ieee80211_set_ringparam, | 2533 | .set_ringparam = ieee80211_set_ringparam, |
2190 | .get_ringparam = ieee80211_get_ringparam, | 2534 | .get_ringparam = ieee80211_get_ringparam, |
2191 | .set_rekey_data = ieee80211_set_rekey_data, | 2535 | .set_rekey_data = ieee80211_set_rekey_data, |
2536 | .tdls_oper = ieee80211_tdls_oper, | ||
2537 | .tdls_mgmt = ieee80211_tdls_mgmt, | ||
2192 | }; | 2538 | }; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index a01d2137fddc..c5f341798c16 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -56,19 +56,22 @@ STA_FILE(last_signal, last_signal, D); | |||
56 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 56 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
57 | size_t count, loff_t *ppos) | 57 | size_t count, loff_t *ppos) |
58 | { | 58 | { |
59 | char buf[100]; | 59 | char buf[121]; |
60 | struct sta_info *sta = file->private_data; | 60 | struct sta_info *sta = file->private_data; |
61 | u32 staflags = get_sta_flags(sta); | 61 | |
62 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", | 62 | #define TEST(flg) \ |
63 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", | 63 | test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" |
64 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 64 | |
65 | staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "", | 65 | int res = scnprintf(buf, sizeof(buf), |
66 | staflags & WLAN_STA_PS_DRIVER ? "PS (driver)\n" : "", | 66 | "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", |
67 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 67 | TEST(AUTH), TEST(ASSOC), TEST(PS_STA), |
68 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 68 | TEST(PS_DRIVER), TEST(AUTHORIZED), |
69 | staflags & WLAN_STA_WME ? "WME\n" : "", | 69 | TEST(SHORT_PREAMBLE), TEST(ASSOC_AP), |
70 | staflags & WLAN_STA_WDS ? "WDS\n" : "", | 70 | TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), |
71 | staflags & WLAN_STA_MFP ? "MFP\n" : ""); | 71 | TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), |
72 | TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), | ||
73 | TEST(TDLS_PEER_AUTH)); | ||
74 | #undef TEST | ||
72 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 75 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
73 | } | 76 | } |
74 | STA_OPS(flags); | 77 | STA_OPS(flags); |
@@ -78,8 +81,14 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file, | |||
78 | size_t count, loff_t *ppos) | 81 | size_t count, loff_t *ppos) |
79 | { | 82 | { |
80 | struct sta_info *sta = file->private_data; | 83 | struct sta_info *sta = file->private_data; |
81 | return mac80211_format_buffer(userbuf, count, ppos, "%u\n", | 84 | char buf[17*IEEE80211_NUM_ACS], *p = buf; |
82 | skb_queue_len(&sta->ps_tx_buf)); | 85 | int ac; |
86 | |||
87 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
88 | p += scnprintf(p, sizeof(buf)+buf-p, "AC%d: %d\n", ac, | ||
89 | skb_queue_len(&sta->ps_tx_buf[ac]) + | ||
90 | skb_queue_len(&sta->tx_filtered[ac])); | ||
91 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
83 | } | 92 | } |
84 | STA_OPS(num_ps_buf_frames); | 93 | STA_OPS(num_ps_buf_frames); |
85 | 94 | ||
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4f845c0845ee..5f165d7eb2db 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -423,7 +423,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local, | |||
423 | 423 | ||
424 | trace_drv_conf_tx(local, sdata, queue, params); | 424 | trace_drv_conf_tx(local, sdata, queue, params); |
425 | if (local->ops->conf_tx) | 425 | if (local->ops->conf_tx) |
426 | ret = local->ops->conf_tx(&local->hw, queue, params); | 426 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, |
427 | queue, params); | ||
427 | trace_drv_return_int(local, ret); | 428 | trace_drv_return_int(local, ret); |
428 | return ret; | 429 | return ret; |
429 | } | 430 | } |
@@ -670,4 +671,34 @@ static inline void drv_rssi_callback(struct ieee80211_local *local, | |||
670 | local->ops->rssi_callback(&local->hw, event); | 671 | local->ops->rssi_callback(&local->hw, event); |
671 | trace_drv_return_void(local); | 672 | trace_drv_return_void(local); |
672 | } | 673 | } |
674 | |||
675 | static inline void | ||
676 | drv_release_buffered_frames(struct ieee80211_local *local, | ||
677 | struct sta_info *sta, u16 tids, int num_frames, | ||
678 | enum ieee80211_frame_release_type reason, | ||
679 | bool more_data) | ||
680 | { | ||
681 | trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, | ||
682 | reason, more_data); | ||
683 | if (local->ops->release_buffered_frames) | ||
684 | local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, | ||
685 | num_frames, reason, | ||
686 | more_data); | ||
687 | trace_drv_return_void(local); | ||
688 | } | ||
689 | |||
690 | static inline void | ||
691 | drv_allow_buffered_frames(struct ieee80211_local *local, | ||
692 | struct sta_info *sta, u16 tids, int num_frames, | ||
693 | enum ieee80211_frame_release_type reason, | ||
694 | bool more_data) | ||
695 | { | ||
696 | trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, | ||
697 | reason, more_data); | ||
698 | if (local->ops->allow_buffered_frames) | ||
699 | local->ops->allow_buffered_frames(&local->hw, &sta->sta, | ||
700 | tids, num_frames, reason, | ||
701 | more_data); | ||
702 | trace_drv_return_void(local); | ||
703 | } | ||
673 | #endif /* __MAC80211_DRIVER_OPS */ | 704 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index a46b279bbbe4..2af4fca55337 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -1129,6 +1129,61 @@ TRACE_EVENT(drv_rssi_callback, | |||
1129 | ) | 1129 | ) |
1130 | ); | 1130 | ); |
1131 | 1131 | ||
1132 | DECLARE_EVENT_CLASS(release_evt, | ||
1133 | TP_PROTO(struct ieee80211_local *local, | ||
1134 | struct ieee80211_sta *sta, | ||
1135 | u16 tids, int num_frames, | ||
1136 | enum ieee80211_frame_release_type reason, | ||
1137 | bool more_data), | ||
1138 | |||
1139 | TP_ARGS(local, sta, tids, num_frames, reason, more_data), | ||
1140 | |||
1141 | TP_STRUCT__entry( | ||
1142 | LOCAL_ENTRY | ||
1143 | STA_ENTRY | ||
1144 | __field(u16, tids) | ||
1145 | __field(int, num_frames) | ||
1146 | __field(int, reason) | ||
1147 | __field(bool, more_data) | ||
1148 | ), | ||
1149 | |||
1150 | TP_fast_assign( | ||
1151 | LOCAL_ASSIGN; | ||
1152 | STA_ASSIGN; | ||
1153 | __entry->tids = tids; | ||
1154 | __entry->num_frames = num_frames; | ||
1155 | __entry->reason = reason; | ||
1156 | __entry->more_data = more_data; | ||
1157 | ), | ||
1158 | |||
1159 | TP_printk( | ||
1160 | LOCAL_PR_FMT STA_PR_FMT | ||
1161 | " TIDs:0x%.4x frames:%d reason:%d more:%d", | ||
1162 | LOCAL_PR_ARG, STA_PR_ARG, __entry->tids, __entry->num_frames, | ||
1163 | __entry->reason, __entry->more_data | ||
1164 | ) | ||
1165 | ); | ||
1166 | |||
1167 | DEFINE_EVENT(release_evt, drv_release_buffered_frames, | ||
1168 | TP_PROTO(struct ieee80211_local *local, | ||
1169 | struct ieee80211_sta *sta, | ||
1170 | u16 tids, int num_frames, | ||
1171 | enum ieee80211_frame_release_type reason, | ||
1172 | bool more_data), | ||
1173 | |||
1174 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) | ||
1175 | ); | ||
1176 | |||
1177 | DEFINE_EVENT(release_evt, drv_allow_buffered_frames, | ||
1178 | TP_PROTO(struct ieee80211_local *local, | ||
1179 | struct ieee80211_sta *sta, | ||
1180 | u16 tids, int num_frames, | ||
1181 | enum ieee80211_frame_release_type reason, | ||
1182 | bool more_data), | ||
1183 | |||
1184 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) | ||
1185 | ); | ||
1186 | |||
1132 | /* | 1187 | /* |
1133 | * Tracing for API calls that drivers call. | 1188 | * Tracing for API calls that drivers call. |
1134 | */ | 1189 | */ |
@@ -1443,6 +1498,28 @@ TRACE_EVENT(api_enable_rssi_reports, | |||
1443 | ) | 1498 | ) |
1444 | ); | 1499 | ); |
1445 | 1500 | ||
1501 | TRACE_EVENT(api_eosp, | ||
1502 | TP_PROTO(struct ieee80211_local *local, | ||
1503 | struct ieee80211_sta *sta), | ||
1504 | |||
1505 | TP_ARGS(local, sta), | ||
1506 | |||
1507 | TP_STRUCT__entry( | ||
1508 | LOCAL_ENTRY | ||
1509 | STA_ENTRY | ||
1510 | ), | ||
1511 | |||
1512 | TP_fast_assign( | ||
1513 | LOCAL_ASSIGN; | ||
1514 | STA_ASSIGN; | ||
1515 | ), | ||
1516 | |||
1517 | TP_printk( | ||
1518 | LOCAL_PR_FMT STA_PR_FMT, | ||
1519 | LOCAL_PR_ARG, STA_PR_FMT | ||
1520 | ) | ||
1521 | ); | ||
1522 | |||
1446 | /* | 1523 | /* |
1447 | * Tracing for internal functions | 1524 | * Tracing for internal functions |
1448 | * (which may also be called in response to driver calls) | 1525 | * (which may also be called in response to driver calls) |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 2b9b52c69569..f80a35c0d000 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -130,7 +130,7 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
130 | * down by the code that set the flag, so this | 130 | * down by the code that set the flag, so this |
131 | * need not run. | 131 | * need not run. |
132 | */ | 132 | */ |
133 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) | 133 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) |
134 | return; | 134 | return; |
135 | 135 | ||
136 | mutex_lock(&sta->ampdu_mlme.mtx); | 136 | mutex_lock(&sta->ampdu_mlme.mtx); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 41f16dd1a2b0..ede9a8b341ac 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -314,7 +314,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | if (sta && elems->wmm_info) | 316 | if (sta && elems->wmm_info) |
317 | set_sta_flags(sta, WLAN_STA_WME); | 317 | set_sta_flag(sta, WLAN_STA_WME); |
318 | 318 | ||
319 | rcu_read_unlock(); | 319 | rcu_read_unlock(); |
320 | } | 320 | } |
@@ -452,7 +452,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
452 | return NULL; | 452 | return NULL; |
453 | 453 | ||
454 | sta->last_rx = jiffies; | 454 | sta->last_rx = jiffies; |
455 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 455 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
456 | 456 | ||
457 | /* make sure mandatory rates are always added */ | 457 | /* make sure mandatory rates are always added */ |
458 | sta->sta.supp_rates[band] = supp_rates | | 458 | sta->sta.supp_rates[band] = supp_rates | |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 5cadcbbc9a57..9fa5f8a674bc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -664,6 +664,11 @@ enum sdata_queue_type { | |||
664 | enum { | 664 | enum { |
665 | IEEE80211_RX_MSG = 1, | 665 | IEEE80211_RX_MSG = 1, |
666 | IEEE80211_TX_STATUS_MSG = 2, | 666 | IEEE80211_TX_STATUS_MSG = 2, |
667 | IEEE80211_EOSP_MSG = 3, | ||
668 | }; | ||
669 | |||
670 | struct skb_eosp_msg_data { | ||
671 | u8 sta[ETH_ALEN], iface[ETH_ALEN]; | ||
667 | }; | 672 | }; |
668 | 673 | ||
669 | enum queue_stop_reason { | 674 | enum queue_stop_reason { |
@@ -1272,6 +1277,7 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke | |||
1272 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1277 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1273 | gfp_t gfp); | 1278 | gfp_t gfp); |
1274 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1279 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); |
1280 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | ||
1275 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1281 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
1276 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1282 | void ieee802_11_parse_elems(u8 *start, size_t len, |
1277 | struct ieee802_11_elems *elems); | 1283 | struct ieee802_11_elems *elems); |
@@ -1303,11 +1309,11 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
1303 | enum queue_stop_reason reason); | 1309 | enum queue_stop_reason reason); |
1304 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1310 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
1305 | struct sk_buff *skb); | 1311 | struct sk_buff *skb); |
1306 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 1312 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1307 | struct sk_buff_head *skbs); | 1313 | struct sk_buff_head *skbs); |
1308 | int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 1314 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, |
1309 | struct sk_buff_head *skbs, | 1315 | struct sk_buff_head *skbs, |
1310 | void (*fn)(void *data), void *data); | 1316 | void (*fn)(void *data), void *data); |
1311 | 1317 | ||
1312 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1318 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1313 | u16 transaction, u16 auth_alg, | 1319 | u16 transaction, u16 auth_alg, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index f4350262663f..30d73552e9ab 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -299,8 +299,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
299 | goto err_del_interface; | 299 | goto err_del_interface; |
300 | } | 300 | } |
301 | 301 | ||
302 | /* no locking required since STA is not live yet */ | 302 | /* no atomic bitop required since STA is not live yet */ |
303 | sta->flags |= WLAN_STA_AUTHORIZED; | 303 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
304 | 304 | ||
305 | res = sta_info_insert(sta); | 305 | res = sta_info_insert(sta); |
306 | if (res) { | 306 | if (res) { |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 5150c6d11b57..756b157c2edd 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -464,7 +464,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
464 | * some hardware cannot handle TKIP with QoS, so | 464 | * some hardware cannot handle TKIP with QoS, so |
465 | * we indicate whether QoS could be in use. | 465 | * we indicate whether QoS could be in use. |
466 | */ | 466 | */ |
467 | if (test_sta_flags(sta, WLAN_STA_WME)) | 467 | if (test_sta_flag(sta, WLAN_STA_WME)) |
468 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 468 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
469 | } else { | 469 | } else { |
470 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 470 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
@@ -478,7 +478,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
478 | /* same here, the AP could be using QoS */ | 478 | /* same here, the AP could be using QoS */ |
479 | ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid); | 479 | ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid); |
480 | if (ap) { | 480 | if (ap) { |
481 | if (test_sta_flags(ap, WLAN_STA_WME)) | 481 | if (test_sta_flag(ap, WLAN_STA_WME)) |
482 | key->conf.flags |= | 482 | key->conf.flags |= |
483 | IEEE80211_KEY_FLAG_WMM_STA; | 483 | IEEE80211_KEY_FLAG_WMM_STA; |
484 | } | 484 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a5809a1a6239..17b038aeac9b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -325,6 +325,8 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | |||
325 | static void ieee80211_tasklet_handler(unsigned long data) | 325 | static void ieee80211_tasklet_handler(unsigned long data) |
326 | { | 326 | { |
327 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 327 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
328 | struct sta_info *sta, *tmp; | ||
329 | struct skb_eosp_msg_data *eosp_data; | ||
328 | struct sk_buff *skb; | 330 | struct sk_buff *skb; |
329 | 331 | ||
330 | while ((skb = skb_dequeue(&local->skb_queue)) || | 332 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -340,6 +342,18 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
340 | skb->pkt_type = 0; | 342 | skb->pkt_type = 0; |
341 | ieee80211_tx_status(local_to_hw(local), skb); | 343 | ieee80211_tx_status(local_to_hw(local), skb); |
342 | break; | 344 | break; |
345 | case IEEE80211_EOSP_MSG: | ||
346 | eosp_data = (void *)skb->cb; | ||
347 | for_each_sta_info(local, eosp_data->sta, sta, tmp) { | ||
348 | /* skip wrong virtual interface */ | ||
349 | if (memcmp(eosp_data->iface, | ||
350 | sta->sdata->vif.addr, ETH_ALEN)) | ||
351 | continue; | ||
352 | clear_sta_flag(sta, WLAN_STA_SP); | ||
353 | break; | ||
354 | } | ||
355 | dev_kfree_skb(skb); | ||
356 | break; | ||
343 | default: | 357 | default: |
344 | WARN(1, "mac80211: Packet is of unknown type %d\n", | 358 | WARN(1, "mac80211: Packet is of unknown type %d\n", |
345 | skb->pkt_type); | 359 | skb->pkt_type); |
@@ -863,6 +877,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
863 | if (local->ops->sched_scan_start) | 877 | if (local->ops->sched_scan_start) |
864 | local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 878 | local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
865 | 879 | ||
880 | /* mac80211 based drivers don't support internal TDLS setup */ | ||
881 | if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) | ||
882 | local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; | ||
883 | |||
866 | result = wiphy_register(local->hw.wiphy); | 884 | result = wiphy_register(local->hw.wiphy); |
867 | if (result < 0) | 885 | if (result < 0) |
868 | goto fail_wiphy_register; | 886 | goto fail_wiphy_register; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index a4225ae69681..a7078fdba8ca 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -320,64 +320,6 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
320 | return 0; | 320 | return 0; |
321 | } | 321 | } |
322 | 322 | ||
323 | int | ||
324 | mesh_add_srates_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | ||
325 | { | ||
326 | struct ieee80211_local *local = sdata->local; | ||
327 | struct ieee80211_supported_band *sband; | ||
328 | int rate; | ||
329 | u8 i, rates, *pos; | ||
330 | |||
331 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
332 | rates = sband->n_bitrates; | ||
333 | if (rates > 8) | ||
334 | rates = 8; | ||
335 | |||
336 | if (skb_tailroom(skb) < rates + 2) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | pos = skb_put(skb, rates + 2); | ||
340 | *pos++ = WLAN_EID_SUPP_RATES; | ||
341 | *pos++ = rates; | ||
342 | for (i = 0; i < rates; i++) { | ||
343 | rate = sband->bitrates[i].bitrate; | ||
344 | *pos++ = (u8) (rate / 5); | ||
345 | } | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | int | ||
351 | mesh_add_ext_srates_ie(struct sk_buff *skb, | ||
352 | struct ieee80211_sub_if_data *sdata) | ||
353 | { | ||
354 | struct ieee80211_local *local = sdata->local; | ||
355 | struct ieee80211_supported_band *sband; | ||
356 | int rate; | ||
357 | u8 i, exrates, *pos; | ||
358 | |||
359 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
360 | exrates = sband->n_bitrates; | ||
361 | if (exrates > 8) | ||
362 | exrates -= 8; | ||
363 | else | ||
364 | exrates = 0; | ||
365 | |||
366 | if (skb_tailroom(skb) < exrates + 2) | ||
367 | return -ENOMEM; | ||
368 | |||
369 | if (exrates) { | ||
370 | pos = skb_put(skb, exrates + 2); | ||
371 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
372 | *pos++ = exrates; | ||
373 | for (i = 8; i < sband->n_bitrates; i++) { | ||
374 | rate = sband->bitrates[i].bitrate; | ||
375 | *pos++ = (u8) (rate / 5); | ||
376 | } | ||
377 | } | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 323 | int mesh_add_ds_params_ie(struct sk_buff *skb, |
382 | struct ieee80211_sub_if_data *sdata) | 324 | struct ieee80211_sub_if_data *sdata) |
383 | { | 325 | { |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 7118e8e8855c..8c00e2d1d636 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -210,10 +210,6 @@ int mesh_add_rsn_ie(struct sk_buff *skb, | |||
210 | struct ieee80211_sub_if_data *sdata); | 210 | struct ieee80211_sub_if_data *sdata); |
211 | int mesh_add_vendor_ies(struct sk_buff *skb, | 211 | int mesh_add_vendor_ies(struct sk_buff *skb, |
212 | struct ieee80211_sub_if_data *sdata); | 212 | struct ieee80211_sub_if_data *sdata); |
213 | int mesh_add_srates_ie(struct sk_buff *skb, | ||
214 | struct ieee80211_sub_if_data *sdata); | ||
215 | int mesh_add_ext_srates_ie(struct sk_buff *skb, | ||
216 | struct ieee80211_sub_if_data *sdata); | ||
217 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 213 | int mesh_add_ds_params_ie(struct sk_buff *skb, |
218 | struct ieee80211_sub_if_data *sdata); | 214 | struct ieee80211_sub_if_data *sdata); |
219 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | 215 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 1213a23ff0fa..7e57f5d07f66 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -92,7 +92,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
92 | if (!sta) | 92 | if (!sta) |
93 | return NULL; | 93 | return NULL; |
94 | 94 | ||
95 | sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH | WLAN_STA_WME; | 95 | set_sta_flag(sta, WLAN_STA_AUTH); |
96 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
97 | set_sta_flag(sta, WLAN_STA_WME); | ||
96 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 98 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
97 | rate_control_rate_init(sta); | 99 | rate_control_rate_init(sta); |
98 | 100 | ||
@@ -185,8 +187,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
185 | pos = skb_put(skb, 2); | 187 | pos = skb_put(skb, 2); |
186 | memcpy(pos + 2, &plid, 2); | 188 | memcpy(pos + 2, &plid, 2); |
187 | } | 189 | } |
188 | if (mesh_add_srates_ie(skb, sdata) || | 190 | if (ieee80211_add_srates_ie(&sdata->vif, skb) || |
189 | mesh_add_ext_srates_ie(skb, sdata) || | 191 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || |
190 | mesh_add_rsn_ie(skb, sdata) || | 192 | mesh_add_rsn_ie(skb, sdata) || |
191 | mesh_add_meshid_ie(skb, sdata) || | 193 | mesh_add_meshid_ie(skb, sdata) || |
192 | mesh_add_meshconf_ie(skb, sdata)) | 194 | mesh_add_meshconf_ie(skb, sdata)) |
@@ -383,7 +385,7 @@ int mesh_plink_open(struct sta_info *sta) | |||
383 | __le16 llid; | 385 | __le16 llid; |
384 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 386 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
385 | 387 | ||
386 | if (!test_sta_flags(sta, WLAN_STA_AUTH)) | 388 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) |
387 | return -EPERM; | 389 | return -EPERM; |
388 | 390 | ||
389 | spin_lock_bh(&sta->lock); | 391 | spin_lock_bh(&sta->lock); |
@@ -503,7 +505,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
503 | return; | 505 | return; |
504 | } | 506 | } |
505 | 507 | ||
506 | if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { | 508 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { |
507 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | 509 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); |
508 | rcu_read_unlock(); | 510 | rcu_read_unlock(); |
509 | return; | 511 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cd37a4e3c0d7..0e5d8daba1ee 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -348,6 +348,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
348 | { | 348 | { |
349 | struct sk_buff *skb; | 349 | struct sk_buff *skb; |
350 | struct ieee80211_hdr_3addr *nullfunc; | 350 | struct ieee80211_hdr_3addr *nullfunc; |
351 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
351 | 352 | ||
352 | skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif); | 353 | skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif); |
353 | if (!skb) | 354 | if (!skb) |
@@ -358,6 +359,10 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
358 | nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 359 | nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
359 | 360 | ||
360 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 361 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
362 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | ||
363 | IEEE80211_STA_CONNECTION_POLL)) | ||
364 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; | ||
365 | |||
361 | ieee80211_tx_skb(sdata, skb); | 366 | ieee80211_tx_skb(sdata, skb); |
362 | } | 367 | } |
363 | 368 | ||
@@ -627,7 +632,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
627 | { | 632 | { |
628 | struct ieee80211_if_managed *mgd = &sdata->u.mgd; | 633 | struct ieee80211_if_managed *mgd = &sdata->u.mgd; |
629 | struct sta_info *sta = NULL; | 634 | struct sta_info *sta = NULL; |
630 | u32 sta_flags = 0; | 635 | bool authorized = false; |
631 | 636 | ||
632 | if (!mgd->powersave) | 637 | if (!mgd->powersave) |
633 | return false; | 638 | return false; |
@@ -645,13 +650,10 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
645 | rcu_read_lock(); | 650 | rcu_read_lock(); |
646 | sta = sta_info_get(sdata, mgd->bssid); | 651 | sta = sta_info_get(sdata, mgd->bssid); |
647 | if (sta) | 652 | if (sta) |
648 | sta_flags = get_sta_flags(sta); | 653 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
649 | rcu_read_unlock(); | 654 | rcu_read_unlock(); |
650 | 655 | ||
651 | if (!(sta_flags & WLAN_STA_AUTHORIZED)) | 656 | return authorized; |
652 | return false; | ||
653 | |||
654 | return true; | ||
655 | } | 657 | } |
656 | 658 | ||
657 | /* need to hold RTNL or interface lock */ | 659 | /* need to hold RTNL or interface lock */ |
@@ -1095,7 +1097,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1095 | mutex_lock(&local->sta_mtx); | 1097 | mutex_lock(&local->sta_mtx); |
1096 | sta = sta_info_get(sdata, bssid); | 1098 | sta = sta_info_get(sdata, bssid); |
1097 | if (sta) { | 1099 | if (sta) { |
1098 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1100 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
1099 | ieee80211_sta_tear_down_BA_sessions(sta, tx); | 1101 | ieee80211_sta_tear_down_BA_sessions(sta, tx); |
1100 | } | 1102 | } |
1101 | mutex_unlock(&local->sta_mtx); | 1103 | mutex_unlock(&local->sta_mtx); |
@@ -1137,8 +1139,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1137 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; | 1139 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
1138 | ieee80211_bss_info_change_notify(sdata, changed); | 1140 | ieee80211_bss_info_change_notify(sdata, changed); |
1139 | 1141 | ||
1142 | /* remove AP and TDLS peers */ | ||
1140 | if (remove_sta) | 1143 | if (remove_sta) |
1141 | sta_info_destroy_addr(sdata, bssid); | 1144 | sta_info_flush(local, sdata); |
1142 | 1145 | ||
1143 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | 1146 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); |
1144 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | 1147 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); |
@@ -1512,10 +1515,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1512 | return false; | 1515 | return false; |
1513 | } | 1516 | } |
1514 | 1517 | ||
1515 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | | 1518 | set_sta_flag(sta, WLAN_STA_AUTH); |
1516 | WLAN_STA_ASSOC_AP); | 1519 | set_sta_flag(sta, WLAN_STA_ASSOC); |
1520 | set_sta_flag(sta, WLAN_STA_ASSOC_AP); | ||
1517 | if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 1521 | if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
1518 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 1522 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1519 | 1523 | ||
1520 | rates = 0; | 1524 | rates = 0; |
1521 | basic_rates = 0; | 1525 | basic_rates = 0; |
@@ -1574,10 +1578,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1574 | rate_control_rate_init(sta); | 1578 | rate_control_rate_init(sta); |
1575 | 1579 | ||
1576 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) | 1580 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) |
1577 | set_sta_flags(sta, WLAN_STA_MFP); | 1581 | set_sta_flag(sta, WLAN_STA_MFP); |
1578 | 1582 | ||
1579 | if (elems.wmm_param) | 1583 | if (elems.wmm_param) |
1580 | set_sta_flags(sta, WLAN_STA_WME); | 1584 | set_sta_flag(sta, WLAN_STA_WME); |
1581 | 1585 | ||
1582 | /* sta_info_reinsert will also unlock the mutex lock */ | 1586 | /* sta_info_reinsert will also unlock the mutex lock */ |
1583 | err = sta_info_reinsert(sta); | 1587 | err = sta_info_reinsert(sta); |
@@ -2738,7 +2742,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2738 | req->reason_code, cookie, | 2742 | req->reason_code, cookie, |
2739 | !req->local_state_change); | 2743 | !req->local_state_change); |
2740 | if (assoc_bss) | 2744 | if (assoc_bss) |
2741 | sta_info_destroy_addr(sdata, bssid); | 2745 | sta_info_flush(sdata->local, sdata); |
2742 | 2746 | ||
2743 | mutex_lock(&sdata->local->mtx); | 2747 | mutex_lock(&sdata->local->mtx); |
2744 | ieee80211_recalc_idle(sdata->local); | 2748 | ieee80211_recalc_idle(sdata->local); |
@@ -2778,7 +2782,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2778 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, | 2782 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, |
2779 | IEEE80211_STYPE_DISASSOC, req->reason_code, | 2783 | IEEE80211_STYPE_DISASSOC, req->reason_code, |
2780 | cookie, !req->local_state_change); | 2784 | cookie, !req->local_state_change); |
2781 | sta_info_destroy_addr(sdata, bssid); | 2785 | sta_info_flush(sdata->local, sdata); |
2782 | 2786 | ||
2783 | mutex_lock(&sdata->local->mtx); | 2787 | mutex_lock(&sdata->local->mtx); |
2784 | ieee80211_recalc_idle(sdata->local); | 2788 | ieee80211_recalc_idle(sdata->local); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 6326d3439861..9ee7164b207c 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -42,7 +42,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
42 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 42 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
43 | mutex_lock(&local->sta_mtx); | 43 | mutex_lock(&local->sta_mtx); |
44 | list_for_each_entry(sta, &local->sta_list, list) { | 44 | list_for_each_entry(sta, &local->sta_list, list) { |
45 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 45 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
46 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 46 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
47 | } | 47 | } |
48 | mutex_unlock(&local->sta_mtx); | 48 | mutex_unlock(&local->sta_mtx); |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index f61244c0e0a2..ff5c3aa48a15 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -199,7 +199,7 @@ static void rate_control_release(struct kref *kref) | |||
199 | kfree(ctrl_ref); | 199 | kfree(ctrl_ref); |
200 | } | 200 | } |
201 | 201 | ||
202 | static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) | 202 | static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) |
203 | { | 203 | { |
204 | struct sk_buff *skb = txrc->skb; | 204 | struct sk_buff *skb = txrc->skb; |
205 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 205 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -208,7 +208,9 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) | |||
208 | 208 | ||
209 | fc = hdr->frame_control; | 209 | fc = hdr->frame_control; |
210 | 210 | ||
211 | return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); | 211 | return (info->flags & (IEEE80211_TX_CTL_NO_ACK | |
212 | IEEE80211_TX_CTL_USE_MINRATE)) || | ||
213 | !ieee80211_is_data(fc); | ||
212 | } | 214 | } |
213 | 215 | ||
214 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, | 216 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, |
@@ -262,7 +264,7 @@ bool rate_control_send_low(struct ieee80211_sta *sta, | |||
262 | struct ieee80211_supported_band *sband = txrc->sband; | 264 | struct ieee80211_supported_band *sband = txrc->sband; |
263 | int mcast_rate; | 265 | int mcast_rate; |
264 | 266 | ||
265 | if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) { | 267 | if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { |
266 | if ((sband->band != IEEE80211_BAND_2GHZ) || | 268 | if ((sband->band != IEEE80211_BAND_2GHZ) || |
267 | !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)) | 269 | !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)) |
268 | info->control.rates[0].idx = | 270 | info->control.rates[0].idx = |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index e19249b0f971..cdb28535716b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -281,6 +281,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
281 | 281 | ||
282 | mr = minstrel_get_ratestats(mi, mg->max_tp_rate); | 282 | mr = minstrel_get_ratestats(mi, mg->max_tp_rate); |
283 | if (cur_tp < mr->cur_tp) { | 283 | if (cur_tp < mr->cur_tp) { |
284 | mi->max_tp_rate2 = mi->max_tp_rate; | ||
285 | cur_tp2 = cur_tp; | ||
284 | mi->max_tp_rate = mg->max_tp_rate; | 286 | mi->max_tp_rate = mg->max_tp_rate; |
285 | cur_tp = mr->cur_tp; | 287 | cur_tp = mr->cur_tp; |
286 | } | 288 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index db46601e50bf..b867bd55de7a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -841,7 +841,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
841 | ieee80211_is_pspoll(hdr->frame_control)) && | 841 | ieee80211_is_pspoll(hdr->frame_control)) && |
842 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 842 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
843 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | 843 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && |
844 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 844 | (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { |
845 | if (rx->sta && rx->sta->dummy && | 845 | if (rx->sta && rx->sta->dummy && |
846 | ieee80211_is_data_present(hdr->frame_control)) { | 846 | ieee80211_is_data_present(hdr->frame_control)) { |
847 | u16 ethertype; | 847 | u16 ethertype; |
@@ -1110,7 +1110,7 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1110 | struct ieee80211_local *local = sdata->local; | 1110 | struct ieee80211_local *local = sdata->local; |
1111 | 1111 | ||
1112 | atomic_inc(&sdata->bss->num_sta_ps); | 1112 | atomic_inc(&sdata->bss->num_sta_ps); |
1113 | set_sta_flags(sta, WLAN_STA_PS_STA); | 1113 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1114 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1114 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1115 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1115 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1116 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1116 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
@@ -1130,7 +1130,7 @@ static void ap_sta_ps_end(struct sta_info *sta) | |||
1130 | sdata->name, sta->sta.addr, sta->sta.aid); | 1130 | sdata->name, sta->sta.addr, sta->sta.aid); |
1131 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1131 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1132 | 1132 | ||
1133 | if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { | 1133 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1134 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1134 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1135 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 1135 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", |
1136 | sdata->name, sta->sta.addr, sta->sta.aid); | 1136 | sdata->name, sta->sta.addr, sta->sta.aid); |
@@ -1149,7 +1149,7 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start) | |||
1149 | WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS)); | 1149 | WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS)); |
1150 | 1150 | ||
1151 | /* Don't let the same PS state be set twice */ | 1151 | /* Don't let the same PS state be set twice */ |
1152 | in_ps = test_sta_flags(sta_inf, WLAN_STA_PS_STA); | 1152 | in_ps = test_sta_flag(sta_inf, WLAN_STA_PS_STA); |
1153 | if ((start && in_ps) || (!start && !in_ps)) | 1153 | if ((start && in_ps) || (!start && !in_ps)) |
1154 | return -EINVAL; | 1154 | return -EINVAL; |
1155 | 1155 | ||
@@ -1163,6 +1163,81 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start) | |||
1163 | EXPORT_SYMBOL(ieee80211_sta_ps_transition); | 1163 | EXPORT_SYMBOL(ieee80211_sta_ps_transition); |
1164 | 1164 | ||
1165 | static ieee80211_rx_result debug_noinline | 1165 | static ieee80211_rx_result debug_noinline |
1166 | ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) | ||
1167 | { | ||
1168 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1169 | struct ieee80211_hdr *hdr = (void *)rx->skb->data; | ||
1170 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1171 | int tid, ac; | ||
1172 | |||
1173 | if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1174 | return RX_CONTINUE; | ||
1175 | |||
1176 | if (sdata->vif.type != NL80211_IFTYPE_AP && | ||
1177 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN) | ||
1178 | return RX_CONTINUE; | ||
1179 | |||
1180 | /* | ||
1181 | * The device handles station powersave, so don't do anything about | ||
1182 | * uAPSD and PS-Poll frames (the latter shouldn't even come up from | ||
1183 | * it to mac80211 since they're handled.) | ||
1184 | */ | ||
1185 | if (sdata->local->hw.flags & IEEE80211_HW_AP_LINK_PS) | ||
1186 | return RX_CONTINUE; | ||
1187 | |||
1188 | /* | ||
1189 | * Don't do anything if the station isn't already asleep. In | ||
1190 | * the uAPSD case, the station will probably be marked asleep, | ||
1191 | * in the PS-Poll case the station must be confused ... | ||
1192 | */ | ||
1193 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_STA)) | ||
1194 | return RX_CONTINUE; | ||
1195 | |||
1196 | if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) { | ||
1197 | if (!test_sta_flag(rx->sta, WLAN_STA_SP)) { | ||
1198 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER)) | ||
1199 | ieee80211_sta_ps_deliver_poll_response(rx->sta); | ||
1200 | else | ||
1201 | set_sta_flag(rx->sta, WLAN_STA_PSPOLL); | ||
1202 | } | ||
1203 | |||
1204 | /* Free PS Poll skb here instead of returning RX_DROP that would | ||
1205 | * count as an dropped frame. */ | ||
1206 | dev_kfree_skb(rx->skb); | ||
1207 | |||
1208 | return RX_QUEUED; | ||
1209 | } else if (!ieee80211_has_morefrags(hdr->frame_control) && | ||
1210 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && | ||
1211 | ieee80211_has_pm(hdr->frame_control) && | ||
1212 | (ieee80211_is_data_qos(hdr->frame_control) || | ||
1213 | ieee80211_is_qos_nullfunc(hdr->frame_control))) { | ||
1214 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
1215 | ac = ieee802_1d_to_ac[tid & 7]; | ||
1216 | |||
1217 | /* | ||
1218 | * If this AC is not trigger-enabled do nothing. | ||
1219 | * | ||
1220 | * NB: This could/should check a separate bitmap of trigger- | ||
1221 | * enabled queues, but for now we only implement uAPSD w/o | ||
1222 | * TSPEC changes to the ACs, so they're always the same. | ||
1223 | */ | ||
1224 | if (!(rx->sta->sta.uapsd_queues & BIT(ac))) | ||
1225 | return RX_CONTINUE; | ||
1226 | |||
1227 | /* if we are in a service period, do nothing */ | ||
1228 | if (test_sta_flag(rx->sta, WLAN_STA_SP)) | ||
1229 | return RX_CONTINUE; | ||
1230 | |||
1231 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER)) | ||
1232 | ieee80211_sta_ps_deliver_uapsd(rx->sta); | ||
1233 | else | ||
1234 | set_sta_flag(rx->sta, WLAN_STA_UAPSD); | ||
1235 | } | ||
1236 | |||
1237 | return RX_CONTINUE; | ||
1238 | } | ||
1239 | |||
1240 | static ieee80211_rx_result debug_noinline | ||
1166 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 1241 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
1167 | { | 1242 | { |
1168 | struct sta_info *sta = rx->sta; | 1243 | struct sta_info *sta = rx->sta; |
@@ -1220,7 +1295,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1220 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && | 1295 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && |
1221 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 1296 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
1222 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 1297 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
1223 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { | 1298 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { |
1224 | /* | 1299 | /* |
1225 | * Ignore doze->wake transitions that are | 1300 | * Ignore doze->wake transitions that are |
1226 | * indicated by non-data frames, the standard | 1301 | * indicated by non-data frames, the standard |
@@ -1473,33 +1548,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1473 | } | 1548 | } |
1474 | 1549 | ||
1475 | static ieee80211_rx_result debug_noinline | 1550 | static ieee80211_rx_result debug_noinline |
1476 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | ||
1477 | { | ||
1478 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1479 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | ||
1480 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1481 | |||
1482 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | ||
1483 | !(status->rx_flags & IEEE80211_RX_RA_MATCH))) | ||
1484 | return RX_CONTINUE; | ||
1485 | |||
1486 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && | ||
1487 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) | ||
1488 | return RX_DROP_UNUSABLE; | ||
1489 | |||
1490 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) | ||
1491 | ieee80211_sta_ps_deliver_poll_response(rx->sta); | ||
1492 | else | ||
1493 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | ||
1494 | |||
1495 | /* Free PS Poll skb here instead of returning RX_DROP that would | ||
1496 | * count as an dropped frame. */ | ||
1497 | dev_kfree_skb(rx->skb); | ||
1498 | |||
1499 | return RX_QUEUED; | ||
1500 | } | ||
1501 | |||
1502 | static ieee80211_rx_result debug_noinline | ||
1503 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1551 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
1504 | { | 1552 | { |
1505 | u8 *data = rx->skb->data; | 1553 | u8 *data = rx->skb->data; |
@@ -1522,7 +1570,7 @@ static int | |||
1522 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1570 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1523 | { | 1571 | { |
1524 | if (unlikely(!rx->sta || | 1572 | if (unlikely(!rx->sta || |
1525 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) | 1573 | !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED))) |
1526 | return -EACCES; | 1574 | return -EACCES; |
1527 | 1575 | ||
1528 | return 0; | 1576 | return 0; |
@@ -1565,7 +1613,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1565 | if (status->flag & RX_FLAG_DECRYPTED) | 1613 | if (status->flag & RX_FLAG_DECRYPTED) |
1566 | return 0; | 1614 | return 0; |
1567 | 1615 | ||
1568 | if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { | 1616 | if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) { |
1569 | if (unlikely(!ieee80211_has_protected(fc) && | 1617 | if (unlikely(!ieee80211_has_protected(fc) && |
1570 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && | 1618 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && |
1571 | rx->key)) { | 1619 | rx->key)) { |
@@ -2567,9 +2615,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) | |||
2567 | 2615 | ||
2568 | CALL_RXH(ieee80211_rx_h_decrypt) | 2616 | CALL_RXH(ieee80211_rx_h_decrypt) |
2569 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2617 | CALL_RXH(ieee80211_rx_h_check_more_data) |
2618 | CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll) | ||
2570 | CALL_RXH(ieee80211_rx_h_sta_process) | 2619 | CALL_RXH(ieee80211_rx_h_sta_process) |
2571 | CALL_RXH(ieee80211_rx_h_defragment) | 2620 | CALL_RXH(ieee80211_rx_h_defragment) |
2572 | CALL_RXH(ieee80211_rx_h_ps_poll) | ||
2573 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) | 2621 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
2574 | /* must be after MMIC verify so header is counted in MPDU mic */ | 2622 | /* must be after MMIC verify so header is counted in MPDU mic */ |
2575 | #ifdef CONFIG_MAC80211_MESH | 2623 | #ifdef CONFIG_MAC80211_MESH |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0a7e0fed3251..58b1c2bb26d2 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "sta_info.h" | 24 | #include "sta_info.h" |
25 | #include "debugfs_sta.h" | 25 | #include "debugfs_sta.h" |
26 | #include "mesh.h" | 26 | #include "mesh.h" |
27 | #include "wme.h" | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * DOC: STA information lifetime rules | 30 | * DOC: STA information lifetime rules |
@@ -243,13 +244,22 @@ static void sta_unblock(struct work_struct *wk) | |||
243 | if (sta->dead) | 244 | if (sta->dead) |
244 | return; | 245 | return; |
245 | 246 | ||
246 | if (!test_sta_flags(sta, WLAN_STA_PS_STA)) | 247 | if (!test_sta_flag(sta, WLAN_STA_PS_STA)) |
247 | ieee80211_sta_ps_deliver_wakeup(sta); | 248 | ieee80211_sta_ps_deliver_wakeup(sta); |
248 | else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { | 249 | else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) { |
249 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | 250 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
251 | |||
252 | local_bh_disable(); | ||
250 | ieee80211_sta_ps_deliver_poll_response(sta); | 253 | ieee80211_sta_ps_deliver_poll_response(sta); |
254 | local_bh_enable(); | ||
255 | } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) { | ||
256 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
257 | |||
258 | local_bh_disable(); | ||
259 | ieee80211_sta_ps_deliver_uapsd(sta); | ||
260 | local_bh_enable(); | ||
251 | } else | 261 | } else |
252 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | 262 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
253 | } | 263 | } |
254 | 264 | ||
255 | static int sta_prepare_rate_control(struct ieee80211_local *local, | 265 | static int sta_prepare_rate_control(struct ieee80211_local *local, |
@@ -282,7 +292,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
282 | return NULL; | 292 | return NULL; |
283 | 293 | ||
284 | spin_lock_init(&sta->lock); | 294 | spin_lock_init(&sta->lock); |
285 | spin_lock_init(&sta->flaglock); | ||
286 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 295 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
287 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 296 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
288 | mutex_init(&sta->ampdu_mlme.mtx); | 297 | mutex_init(&sta->ampdu_mlme.mtx); |
@@ -309,8 +318,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
309 | */ | 318 | */ |
310 | sta->timer_to_tid[i] = i; | 319 | sta->timer_to_tid[i] = i; |
311 | } | 320 | } |
312 | skb_queue_head_init(&sta->ps_tx_buf); | 321 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
313 | skb_queue_head_init(&sta->tx_filtered); | 322 | skb_queue_head_init(&sta->ps_tx_buf[i]); |
323 | skb_queue_head_init(&sta->tx_filtered[i]); | ||
324 | } | ||
314 | 325 | ||
315 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 326 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
316 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 327 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
@@ -641,54 +652,84 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | |||
641 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | 652 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); |
642 | } | 653 | } |
643 | 654 | ||
644 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | 655 | static unsigned long ieee80211_tids_for_ac(int ac) |
645 | struct sta_info *sta) | ||
646 | { | 656 | { |
647 | BUG_ON(!bss); | 657 | /* If we ever support TIDs > 7, this obviously needs to be adjusted */ |
648 | 658 | switch (ac) { | |
649 | __bss_tim_set(bss, sta->sta.aid); | 659 | case IEEE80211_AC_VO: |
650 | 660 | return BIT(6) | BIT(7); | |
651 | if (sta->local->ops->set_tim) { | 661 | case IEEE80211_AC_VI: |
652 | sta->local->tim_in_locked_section = true; | 662 | return BIT(4) | BIT(5); |
653 | drv_set_tim(sta->local, &sta->sta, true); | 663 | case IEEE80211_AC_BE: |
654 | sta->local->tim_in_locked_section = false; | 664 | return BIT(0) | BIT(3); |
665 | case IEEE80211_AC_BK: | ||
666 | return BIT(1) | BIT(2); | ||
667 | default: | ||
668 | WARN_ON(1); | ||
669 | return 0; | ||
655 | } | 670 | } |
656 | } | 671 | } |
657 | 672 | ||
658 | void sta_info_set_tim_bit(struct sta_info *sta) | 673 | void sta_info_recalc_tim(struct sta_info *sta) |
659 | { | 674 | { |
675 | struct ieee80211_local *local = sta->local; | ||
676 | struct ieee80211_if_ap *bss = sta->sdata->bss; | ||
660 | unsigned long flags; | 677 | unsigned long flags; |
678 | bool indicate_tim = false; | ||
679 | u8 ignore_for_tim = sta->sta.uapsd_queues; | ||
680 | int ac; | ||
661 | 681 | ||
662 | BUG_ON(!sta->sdata->bss); | 682 | if (WARN_ON_ONCE(!sta->sdata->bss)) |
683 | return; | ||
663 | 684 | ||
664 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 685 | /* No need to do anything if the driver does all */ |
665 | __sta_info_set_tim_bit(sta->sdata->bss, sta); | 686 | if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) |
666 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 687 | return; |
667 | } | ||
668 | 688 | ||
669 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | 689 | if (sta->dead) |
670 | struct sta_info *sta) | 690 | goto done; |
671 | { | 691 | |
672 | BUG_ON(!bss); | 692 | /* |
693 | * If all ACs are delivery-enabled then we should build | ||
694 | * the TIM bit for all ACs anyway; if only some are then | ||
695 | * we ignore those and build the TIM bit using only the | ||
696 | * non-enabled ones. | ||
697 | */ | ||
698 | if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1) | ||
699 | ignore_for_tim = 0; | ||
700 | |||
701 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
702 | unsigned long tids; | ||
673 | 703 | ||
674 | __bss_tim_clear(bss, sta->sta.aid); | 704 | if (ignore_for_tim & BIT(ac)) |
705 | continue; | ||
706 | |||
707 | indicate_tim |= !skb_queue_empty(&sta->tx_filtered[ac]) || | ||
708 | !skb_queue_empty(&sta->ps_tx_buf[ac]); | ||
709 | if (indicate_tim) | ||
710 | break; | ||
675 | 711 | ||
676 | if (sta->local->ops->set_tim) { | 712 | tids = ieee80211_tids_for_ac(ac); |
677 | sta->local->tim_in_locked_section = true; | 713 | |
678 | drv_set_tim(sta->local, &sta->sta, false); | 714 | indicate_tim |= |
679 | sta->local->tim_in_locked_section = false; | 715 | sta->driver_buffered_tids & tids; |
680 | } | 716 | } |
681 | } | ||
682 | 717 | ||
683 | void sta_info_clear_tim_bit(struct sta_info *sta) | 718 | done: |
684 | { | 719 | spin_lock_irqsave(&local->sta_lock, flags); |
685 | unsigned long flags; | ||
686 | 720 | ||
687 | BUG_ON(!sta->sdata->bss); | 721 | if (indicate_tim) |
722 | __bss_tim_set(bss, sta->sta.aid); | ||
723 | else | ||
724 | __bss_tim_clear(bss, sta->sta.aid); | ||
725 | |||
726 | if (local->ops->set_tim) { | ||
727 | local->tim_in_locked_section = true; | ||
728 | drv_set_tim(local, &sta->sta, indicate_tim); | ||
729 | local->tim_in_locked_section = false; | ||
730 | } | ||
688 | 731 | ||
689 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 732 | spin_unlock_irqrestore(&local->sta_lock, flags); |
690 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); | ||
691 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | ||
692 | } | 733 | } |
693 | 734 | ||
694 | static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) | 735 | static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) |
@@ -711,21 +752,59 @@ static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) | |||
711 | } | 752 | } |
712 | 753 | ||
713 | 754 | ||
714 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | 755 | static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, |
715 | struct sta_info *sta) | 756 | struct sta_info *sta, int ac) |
716 | { | 757 | { |
717 | unsigned long flags; | 758 | unsigned long flags; |
718 | struct sk_buff *skb; | 759 | struct sk_buff *skb; |
719 | 760 | ||
761 | /* | ||
762 | * First check for frames that should expire on the filtered | ||
763 | * queue. Frames here were rejected by the driver and are on | ||
764 | * a separate queue to avoid reordering with normal PS-buffered | ||
765 | * frames. They also aren't accounted for right now in the | ||
766 | * total_ps_buffered counter. | ||
767 | */ | ||
768 | for (;;) { | ||
769 | spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); | ||
770 | skb = skb_peek(&sta->tx_filtered[ac]); | ||
771 | if (sta_info_buffer_expired(sta, skb)) | ||
772 | skb = __skb_dequeue(&sta->tx_filtered[ac]); | ||
773 | else | ||
774 | skb = NULL; | ||
775 | spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); | ||
776 | |||
777 | /* | ||
778 | * Frames are queued in order, so if this one | ||
779 | * hasn't expired yet we can stop testing. If | ||
780 | * we actually reached the end of the queue we | ||
781 | * also need to stop, of course. | ||
782 | */ | ||
783 | if (!skb) | ||
784 | break; | ||
785 | dev_kfree_skb(skb); | ||
786 | } | ||
787 | |||
788 | /* | ||
789 | * Now also check the normal PS-buffered queue, this will | ||
790 | * only find something if the filtered queue was emptied | ||
791 | * since the filtered frames are all before the normal PS | ||
792 | * buffered frames. | ||
793 | */ | ||
720 | for (;;) { | 794 | for (;;) { |
721 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 795 | spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); |
722 | skb = skb_peek(&sta->ps_tx_buf); | 796 | skb = skb_peek(&sta->ps_tx_buf[ac]); |
723 | if (sta_info_buffer_expired(sta, skb)) | 797 | if (sta_info_buffer_expired(sta, skb)) |
724 | skb = __skb_dequeue(&sta->ps_tx_buf); | 798 | skb = __skb_dequeue(&sta->ps_tx_buf[ac]); |
725 | else | 799 | else |
726 | skb = NULL; | 800 | skb = NULL; |
727 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); | 801 | spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); |
728 | 802 | ||
803 | /* | ||
804 | * frames are queued in order, so if this one | ||
805 | * hasn't expired yet (or we reached the end of | ||
806 | * the queue) we can stop testing | ||
807 | */ | ||
729 | if (!skb) | 808 | if (!skb) |
730 | break; | 809 | break; |
731 | 810 | ||
@@ -735,22 +814,47 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
735 | sta->sta.addr); | 814 | sta->sta.addr); |
736 | #endif | 815 | #endif |
737 | dev_kfree_skb(skb); | 816 | dev_kfree_skb(skb); |
738 | |||
739 | if (skb_queue_empty(&sta->ps_tx_buf) && | ||
740 | !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF)) | ||
741 | sta_info_clear_tim_bit(sta); | ||
742 | } | 817 | } |
743 | 818 | ||
744 | return !skb_queue_empty(&sta->ps_tx_buf); | 819 | /* |
820 | * Finally, recalculate the TIM bit for this station -- it might | ||
821 | * now be clear because the station was too slow to retrieve its | ||
822 | * frames. | ||
823 | */ | ||
824 | sta_info_recalc_tim(sta); | ||
825 | |||
826 | /* | ||
827 | * Return whether there are any frames still buffered, this is | ||
828 | * used to check whether the cleanup timer still needs to run, | ||
829 | * if there are no frames we don't need to rearm the timer. | ||
830 | */ | ||
831 | return !(skb_queue_empty(&sta->ps_tx_buf[ac]) && | ||
832 | skb_queue_empty(&sta->tx_filtered[ac])); | ||
833 | } | ||
834 | |||
835 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | ||
836 | struct sta_info *sta) | ||
837 | { | ||
838 | bool have_buffered = false; | ||
839 | int ac; | ||
840 | |||
841 | /* This is only necessary for stations on BSS interfaces */ | ||
842 | if (!sta->sdata->bss) | ||
843 | return false; | ||
844 | |||
845 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
846 | have_buffered |= | ||
847 | sta_info_cleanup_expire_buffered_ac(local, sta, ac); | ||
848 | |||
849 | return have_buffered; | ||
745 | } | 850 | } |
746 | 851 | ||
747 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 852 | static int __must_check __sta_info_destroy(struct sta_info *sta) |
748 | { | 853 | { |
749 | struct ieee80211_local *local; | 854 | struct ieee80211_local *local; |
750 | struct ieee80211_sub_if_data *sdata; | 855 | struct ieee80211_sub_if_data *sdata; |
751 | struct sk_buff *skb; | ||
752 | unsigned long flags; | 856 | unsigned long flags; |
753 | int ret, i; | 857 | int ret, i, ac; |
754 | 858 | ||
755 | might_sleep(); | 859 | might_sleep(); |
756 | 860 | ||
@@ -766,7 +870,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
766 | * sessions -- block that to make sure the tear-down | 870 | * sessions -- block that to make sure the tear-down |
767 | * will be sufficient. | 871 | * will be sufficient. |
768 | */ | 872 | */ |
769 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 873 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
770 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 874 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
771 | 875 | ||
772 | spin_lock_irqsave(&local->sta_lock, flags); | 876 | spin_lock_irqsave(&local->sta_lock, flags); |
@@ -787,12 +891,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
787 | 891 | ||
788 | sta->dead = true; | 892 | sta->dead = true; |
789 | 893 | ||
790 | if (test_and_clear_sta_flags(sta, | 894 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || |
791 | WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) { | 895 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
792 | BUG_ON(!sdata->bss); | 896 | BUG_ON(!sdata->bss); |
793 | 897 | ||
898 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
899 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
900 | |||
794 | atomic_dec(&sdata->bss->num_sta_ps); | 901 | atomic_dec(&sdata->bss->num_sta_ps); |
795 | sta_info_clear_tim_bit(sta); | 902 | sta_info_recalc_tim(sta); |
796 | } | 903 | } |
797 | 904 | ||
798 | local->num_sta--; | 905 | local->num_sta--; |
@@ -818,6 +925,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
818 | */ | 925 | */ |
819 | synchronize_rcu(); | 926 | synchronize_rcu(); |
820 | 927 | ||
928 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
929 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); | ||
930 | __skb_queue_purge(&sta->ps_tx_buf[ac]); | ||
931 | __skb_queue_purge(&sta->tx_filtered[ac]); | ||
932 | } | ||
933 | |||
821 | #ifdef CONFIG_MAC80211_MESH | 934 | #ifdef CONFIG_MAC80211_MESH |
822 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 935 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
823 | mesh_accept_plinks_update(sdata); | 936 | mesh_accept_plinks_update(sdata); |
@@ -840,14 +953,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
840 | } | 953 | } |
841 | #endif | 954 | #endif |
842 | 955 | ||
843 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | ||
844 | local->total_ps_buffered--; | ||
845 | dev_kfree_skb_any(skb); | ||
846 | } | ||
847 | |||
848 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) | ||
849 | dev_kfree_skb_any(skb); | ||
850 | |||
851 | __sta_info_free(local, sta); | 956 | __sta_info_free(local, sta); |
852 | 957 | ||
853 | return 0; | 958 | return 0; |
@@ -1013,7 +1118,8 @@ static void clear_sta_ps_flags(void *_sta) | |||
1013 | { | 1118 | { |
1014 | struct sta_info *sta = _sta; | 1119 | struct sta_info *sta = _sta; |
1015 | 1120 | ||
1016 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA); | 1121 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1122 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
1017 | } | 1123 | } |
1018 | 1124 | ||
1019 | /* powersave support code */ | 1125 | /* powersave support code */ |
@@ -1021,88 +1127,343 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1021 | { | 1127 | { |
1022 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1128 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1023 | struct ieee80211_local *local = sdata->local; | 1129 | struct ieee80211_local *local = sdata->local; |
1024 | int sent, buffered; | 1130 | struct sk_buff_head pending; |
1131 | int filtered = 0, buffered = 0, ac; | ||
1132 | |||
1133 | clear_sta_flag(sta, WLAN_STA_SP); | ||
1134 | |||
1135 | BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); | ||
1136 | sta->driver_buffered_tids = 0; | ||
1025 | 1137 | ||
1026 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | ||
1027 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1138 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1028 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); | 1139 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); |
1029 | 1140 | ||
1030 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 1141 | skb_queue_head_init(&pending); |
1031 | sta_info_clear_tim_bit(sta); | ||
1032 | 1142 | ||
1033 | /* Send all buffered frames to the station */ | 1143 | /* Send all buffered frames to the station */ |
1034 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); | 1144 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
1035 | buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf, | 1145 | int count = skb_queue_len(&pending), tmp; |
1036 | clear_sta_ps_flags, sta); | 1146 | |
1037 | sent += buffered; | 1147 | skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); |
1148 | tmp = skb_queue_len(&pending); | ||
1149 | filtered += tmp - count; | ||
1150 | count = tmp; | ||
1151 | |||
1152 | skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); | ||
1153 | tmp = skb_queue_len(&pending); | ||
1154 | buffered += tmp - count; | ||
1155 | } | ||
1156 | |||
1157 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | ||
1158 | |||
1038 | local->total_ps_buffered -= buffered; | 1159 | local->total_ps_buffered -= buffered; |
1039 | 1160 | ||
1161 | sta_info_recalc_tim(sta); | ||
1162 | |||
1040 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1163 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1041 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | 1164 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " |
1042 | "since STA not sleeping anymore\n", sdata->name, | 1165 | "since STA not sleeping anymore\n", sdata->name, |
1043 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); | 1166 | sta->sta.addr, sta->sta.aid, filtered, buffered); |
1044 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1167 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1045 | } | 1168 | } |
1046 | 1169 | ||
1047 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | 1170 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, |
1171 | struct sta_info *sta, int tid, | ||
1172 | enum ieee80211_frame_release_type reason) | ||
1048 | { | 1173 | { |
1049 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
1050 | struct ieee80211_local *local = sdata->local; | 1174 | struct ieee80211_local *local = sdata->local; |
1175 | struct ieee80211_qos_hdr *nullfunc; | ||
1051 | struct sk_buff *skb; | 1176 | struct sk_buff *skb; |
1052 | int no_pending_pkts; | 1177 | int size = sizeof(*nullfunc); |
1178 | __le16 fc; | ||
1179 | bool qos = test_sta_flag(sta, WLAN_STA_WME); | ||
1180 | struct ieee80211_tx_info *info; | ||
1053 | 1181 | ||
1054 | skb = skb_dequeue(&sta->tx_filtered); | 1182 | if (qos) { |
1055 | if (!skb) { | 1183 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | |
1056 | skb = skb_dequeue(&sta->ps_tx_buf); | 1184 | IEEE80211_STYPE_QOS_NULLFUNC | |
1057 | if (skb) | 1185 | IEEE80211_FCTL_FROMDS); |
1058 | local->total_ps_buffered--; | 1186 | } else { |
1187 | size -= 2; | ||
1188 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
1189 | IEEE80211_STYPE_NULLFUNC | | ||
1190 | IEEE80211_FCTL_FROMDS); | ||
1059 | } | 1191 | } |
1060 | no_pending_pkts = skb_queue_empty(&sta->tx_filtered) && | ||
1061 | skb_queue_empty(&sta->ps_tx_buf); | ||
1062 | 1192 | ||
1063 | if (skb) { | 1193 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); |
1064 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1194 | if (!skb) |
1065 | struct ieee80211_hdr *hdr = | 1195 | return; |
1066 | (struct ieee80211_hdr *) skb->data; | 1196 | |
1197 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1198 | |||
1199 | nullfunc = (void *) skb_put(skb, size); | ||
1200 | nullfunc->frame_control = fc; | ||
1201 | nullfunc->duration_id = 0; | ||
1202 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); | ||
1203 | memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); | ||
1204 | memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); | ||
1205 | |||
1206 | if (qos) { | ||
1207 | skb->priority = tid; | ||
1208 | |||
1209 | skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]); | ||
1210 | |||
1211 | nullfunc->qos_ctrl = cpu_to_le16(tid); | ||
1212 | |||
1213 | if (reason == IEEE80211_FRAME_RELEASE_UAPSD) | ||
1214 | nullfunc->qos_ctrl |= | ||
1215 | cpu_to_le16(IEEE80211_QOS_CTL_EOSP); | ||
1216 | } | ||
1217 | |||
1218 | info = IEEE80211_SKB_CB(skb); | ||
1219 | |||
1220 | /* | ||
1221 | * Tell TX path to send this frame even though the | ||
1222 | * STA may still remain is PS mode after this frame | ||
1223 | * exchange. Also set EOSP to indicate this packet | ||
1224 | * ends the poll/service period. | ||
1225 | */ | ||
1226 | info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE | | ||
1227 | IEEE80211_TX_STATUS_EOSP | | ||
1228 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1229 | |||
1230 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); | ||
1231 | |||
1232 | ieee80211_xmit(sdata, skb); | ||
1233 | } | ||
1234 | |||
1235 | static void | ||
1236 | ieee80211_sta_ps_deliver_response(struct sta_info *sta, | ||
1237 | int n_frames, u8 ignored_acs, | ||
1238 | enum ieee80211_frame_release_type reason) | ||
1239 | { | ||
1240 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
1241 | struct ieee80211_local *local = sdata->local; | ||
1242 | bool found = false; | ||
1243 | bool more_data = false; | ||
1244 | int ac; | ||
1245 | unsigned long driver_release_tids = 0; | ||
1246 | struct sk_buff_head frames; | ||
1247 | |||
1248 | /* Service or PS-Poll period starts */ | ||
1249 | set_sta_flag(sta, WLAN_STA_SP); | ||
1250 | |||
1251 | __skb_queue_head_init(&frames); | ||
1252 | |||
1253 | /* | ||
1254 | * Get response frame(s) and more data bit for it. | ||
1255 | */ | ||
1256 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
1257 | unsigned long tids; | ||
1258 | |||
1259 | if (ignored_acs & BIT(ac)) | ||
1260 | continue; | ||
1261 | |||
1262 | tids = ieee80211_tids_for_ac(ac); | ||
1263 | |||
1264 | if (!found) { | ||
1265 | driver_release_tids = sta->driver_buffered_tids & tids; | ||
1266 | if (driver_release_tids) { | ||
1267 | found = true; | ||
1268 | } else { | ||
1269 | struct sk_buff *skb; | ||
1270 | |||
1271 | while (n_frames > 0) { | ||
1272 | skb = skb_dequeue(&sta->tx_filtered[ac]); | ||
1273 | if (!skb) { | ||
1274 | skb = skb_dequeue( | ||
1275 | &sta->ps_tx_buf[ac]); | ||
1276 | if (skb) | ||
1277 | local->total_ps_buffered--; | ||
1278 | } | ||
1279 | if (!skb) | ||
1280 | break; | ||
1281 | n_frames--; | ||
1282 | found = true; | ||
1283 | __skb_queue_tail(&frames, skb); | ||
1284 | } | ||
1285 | } | ||
1286 | |||
1287 | /* | ||
1288 | * If the driver has data on more than one TID then | ||
1289 | * certainly there's more data if we release just a | ||
1290 | * single frame now (from a single TID). | ||
1291 | */ | ||
1292 | if (reason == IEEE80211_FRAME_RELEASE_PSPOLL && | ||
1293 | hweight16(driver_release_tids) > 1) { | ||
1294 | more_data = true; | ||
1295 | driver_release_tids = | ||
1296 | BIT(ffs(driver_release_tids) - 1); | ||
1297 | break; | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1301 | if (!skb_queue_empty(&sta->tx_filtered[ac]) || | ||
1302 | !skb_queue_empty(&sta->ps_tx_buf[ac])) { | ||
1303 | more_data = true; | ||
1304 | break; | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1308 | if (!found) { | ||
1309 | int tid; | ||
1067 | 1310 | ||
1068 | /* | 1311 | /* |
1069 | * Tell TX path to send this frame even though the STA may | 1312 | * For PS-Poll, this can only happen due to a race condition |
1070 | * still remain is PS mode after this frame exchange. | 1313 | * when we set the TIM bit and the station notices it, but |
1314 | * before it can poll for the frame we expire it. | ||
1315 | * | ||
1316 | * For uAPSD, this is said in the standard (11.2.1.5 h): | ||
1317 | * At each unscheduled SP for a non-AP STA, the AP shall | ||
1318 | * attempt to transmit at least one MSDU or MMPDU, but no | ||
1319 | * more than the value specified in the Max SP Length field | ||
1320 | * in the QoS Capability element from delivery-enabled ACs, | ||
1321 | * that are destined for the non-AP STA. | ||
1322 | * | ||
1323 | * Since we have no other MSDU/MMPDU, transmit a QoS null frame. | ||
1071 | */ | 1324 | */ |
1072 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; | ||
1073 | 1325 | ||
1074 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1326 | /* This will evaluate to 1, 3, 5 or 7. */ |
1075 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", | 1327 | tid = 7 - ((ffs(~ignored_acs) - 1) << 1); |
1076 | sta->sta.addr, sta->sta.aid, | ||
1077 | skb_queue_len(&sta->ps_tx_buf)); | ||
1078 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1079 | 1328 | ||
1080 | /* Use MoreData flag to indicate whether there are more | 1329 | ieee80211_send_null_response(sdata, sta, tid, reason); |
1081 | * buffered frames for this STA */ | 1330 | return; |
1082 | if (no_pending_pkts) | 1331 | } |
1083 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
1084 | else | ||
1085 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
1086 | 1332 | ||
1087 | ieee80211_add_pending_skb(local, skb); | 1333 | if (!driver_release_tids) { |
1334 | struct sk_buff_head pending; | ||
1335 | struct sk_buff *skb; | ||
1336 | int num = 0; | ||
1337 | u16 tids = 0; | ||
1338 | |||
1339 | skb_queue_head_init(&pending); | ||
1340 | |||
1341 | while ((skb = __skb_dequeue(&frames))) { | ||
1342 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1343 | struct ieee80211_hdr *hdr = (void *) skb->data; | ||
1344 | u8 *qoshdr = NULL; | ||
1345 | |||
1346 | num++; | ||
1347 | |||
1348 | /* | ||
1349 | * Tell TX path to send this frame even though the | ||
1350 | * STA may still remain is PS mode after this frame | ||
1351 | * exchange. | ||
1352 | */ | ||
1353 | info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE; | ||
1354 | |||
1355 | /* | ||
1356 | * Use MoreData flag to indicate whether there are | ||
1357 | * more buffered frames for this STA | ||
1358 | */ | ||
1359 | if (!more_data) | ||
1360 | hdr->frame_control &= | ||
1361 | cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
1362 | else | ||
1363 | hdr->frame_control |= | ||
1364 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
1365 | |||
1366 | if (ieee80211_is_data_qos(hdr->frame_control) || | ||
1367 | ieee80211_is_qos_nullfunc(hdr->frame_control)) | ||
1368 | qoshdr = ieee80211_get_qos_ctl(hdr); | ||
1369 | |||
1370 | /* set EOSP for the frame */ | ||
1371 | if (reason == IEEE80211_FRAME_RELEASE_UAPSD && | ||
1372 | qoshdr && skb_queue_empty(&frames)) | ||
1373 | *qoshdr |= IEEE80211_QOS_CTL_EOSP; | ||
1374 | |||
1375 | info->flags |= IEEE80211_TX_STATUS_EOSP | | ||
1376 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1377 | |||
1378 | if (qoshdr) | ||
1379 | tids |= BIT(*qoshdr & IEEE80211_QOS_CTL_TID_MASK); | ||
1380 | else | ||
1381 | tids |= BIT(0); | ||
1382 | |||
1383 | __skb_queue_tail(&pending, skb); | ||
1384 | } | ||
1088 | 1385 | ||
1089 | if (no_pending_pkts) | 1386 | drv_allow_buffered_frames(local, sta, tids, num, |
1090 | sta_info_clear_tim_bit(sta); | 1387 | reason, more_data); |
1091 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1388 | |
1389 | ieee80211_add_pending_skbs(local, &pending); | ||
1390 | |||
1391 | sta_info_recalc_tim(sta); | ||
1092 | } else { | 1392 | } else { |
1093 | /* | 1393 | /* |
1094 | * FIXME: This can be the result of a race condition between | 1394 | * We need to release a frame that is buffered somewhere in the |
1095 | * us expiring a frame and the station polling for it. | 1395 | * driver ... it'll have to handle that. |
1096 | * Should we send it a null-func frame indicating we | 1396 | * Note that, as per the comment above, it'll also have to see |
1097 | * have nothing buffered for it? | 1397 | * if there is more than just one frame on the specific TID that |
1398 | * we're releasing from, and it needs to set the more-data bit | ||
1399 | * accordingly if we tell it that there's no more data. If we do | ||
1400 | * tell it there's more data, then of course the more-data bit | ||
1401 | * needs to be set anyway. | ||
1402 | */ | ||
1403 | drv_release_buffered_frames(local, sta, driver_release_tids, | ||
1404 | n_frames, reason, more_data); | ||
1405 | |||
1406 | /* | ||
1407 | * Note that we don't recalculate the TIM bit here as it would | ||
1408 | * most likely have no effect at all unless the driver told us | ||
1409 | * that the TID became empty before returning here from the | ||
1410 | * release function. | ||
1411 | * Either way, however, when the driver tells us that the TID | ||
1412 | * became empty we'll do the TIM recalculation. | ||
1098 | */ | 1413 | */ |
1099 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " | ||
1100 | "though there are no buffered frames for it\n", | ||
1101 | sdata->name, sta->sta.addr); | ||
1102 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1103 | } | 1414 | } |
1104 | } | 1415 | } |
1105 | 1416 | ||
1417 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | ||
1418 | { | ||
1419 | u8 ignore_for_response = sta->sta.uapsd_queues; | ||
1420 | |||
1421 | /* | ||
1422 | * If all ACs are delivery-enabled then we should reply | ||
1423 | * from any of them, if only some are enabled we reply | ||
1424 | * only from the non-enabled ones. | ||
1425 | */ | ||
1426 | if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1) | ||
1427 | ignore_for_response = 0; | ||
1428 | |||
1429 | ieee80211_sta_ps_deliver_response(sta, 1, ignore_for_response, | ||
1430 | IEEE80211_FRAME_RELEASE_PSPOLL); | ||
1431 | } | ||
1432 | |||
1433 | void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta) | ||
1434 | { | ||
1435 | int n_frames = sta->sta.max_sp; | ||
1436 | u8 delivery_enabled = sta->sta.uapsd_queues; | ||
1437 | |||
1438 | /* | ||
1439 | * If we ever grow support for TSPEC this might happen if | ||
1440 | * the TSPEC update from hostapd comes in between a trigger | ||
1441 | * frame setting WLAN_STA_UAPSD in the RX path and this | ||
1442 | * actually getting called. | ||
1443 | */ | ||
1444 | if (!delivery_enabled) | ||
1445 | return; | ||
1446 | |||
1447 | switch (sta->sta.max_sp) { | ||
1448 | case 1: | ||
1449 | n_frames = 2; | ||
1450 | break; | ||
1451 | case 2: | ||
1452 | n_frames = 4; | ||
1453 | break; | ||
1454 | case 3: | ||
1455 | n_frames = 6; | ||
1456 | break; | ||
1457 | case 0: | ||
1458 | /* XXX: what is a good value? */ | ||
1459 | n_frames = 8; | ||
1460 | break; | ||
1461 | } | ||
1462 | |||
1463 | ieee80211_sta_ps_deliver_response(sta, n_frames, ~delivery_enabled, | ||
1464 | IEEE80211_FRAME_RELEASE_UAPSD); | ||
1465 | } | ||
1466 | |||
1106 | void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | 1467 | void ieee80211_sta_block_awake(struct ieee80211_hw *hw, |
1107 | struct ieee80211_sta *pubsta, bool block) | 1468 | struct ieee80211_sta *pubsta, bool block) |
1108 | { | 1469 | { |
@@ -1111,17 +1472,50 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
1111 | trace_api_sta_block_awake(sta->local, pubsta, block); | 1472 | trace_api_sta_block_awake(sta->local, pubsta, block); |
1112 | 1473 | ||
1113 | if (block) | 1474 | if (block) |
1114 | set_sta_flags(sta, WLAN_STA_PS_DRIVER); | 1475 | set_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1115 | else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) | 1476 | else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) |
1116 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); | 1477 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); |
1117 | } | 1478 | } |
1118 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 1479 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
1119 | 1480 | ||
1120 | void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta) | 1481 | void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) |
1482 | { | ||
1483 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | ||
1484 | struct ieee80211_local *local = sta->local; | ||
1485 | struct sk_buff *skb; | ||
1486 | struct skb_eosp_msg_data *data; | ||
1487 | |||
1488 | trace_api_eosp(local, pubsta); | ||
1489 | |||
1490 | skb = alloc_skb(0, GFP_ATOMIC); | ||
1491 | if (!skb) { | ||
1492 | /* too bad ... but race is better than loss */ | ||
1493 | clear_sta_flag(sta, WLAN_STA_SP); | ||
1494 | return; | ||
1495 | } | ||
1496 | |||
1497 | data = (void *)skb->cb; | ||
1498 | memcpy(data->sta, pubsta->addr, ETH_ALEN); | ||
1499 | memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN); | ||
1500 | skb->pkt_type = IEEE80211_EOSP_MSG; | ||
1501 | skb_queue_tail(&local->skb_queue, skb); | ||
1502 | tasklet_schedule(&local->tasklet); | ||
1503 | } | ||
1504 | EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); | ||
1505 | |||
1506 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | ||
1507 | u8 tid, bool buffered) | ||
1121 | { | 1508 | { |
1122 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 1509 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
1123 | 1510 | ||
1124 | set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | 1511 | if (WARN_ON(tid >= STA_TID_NUM)) |
1125 | sta_info_set_tim_bit(sta); | 1512 | return; |
1513 | |||
1514 | if (buffered) | ||
1515 | set_bit(tid, &sta->driver_buffered_tids); | ||
1516 | else | ||
1517 | clear_bit(tid, &sta->driver_buffered_tids); | ||
1518 | |||
1519 | sta_info_recalc_tim(sta); | ||
1126 | } | 1520 | } |
1127 | EXPORT_SYMBOL(ieee80211_sta_set_tim); | 1521 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 56a3d38a2cd1..8c8ce05ad26f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -19,7 +19,8 @@ | |||
19 | /** | 19 | /** |
20 | * enum ieee80211_sta_info_flags - Stations flags | 20 | * enum ieee80211_sta_info_flags - Stations flags |
21 | * | 21 | * |
22 | * These flags are used with &struct sta_info's @flags member. | 22 | * These flags are used with &struct sta_info's @flags member, but |
23 | * only indirectly with set_sta_flag() and friends. | ||
23 | * | 24 | * |
24 | * @WLAN_STA_AUTH: Station is authenticated. | 25 | * @WLAN_STA_AUTH: Station is authenticated. |
25 | * @WLAN_STA_ASSOC: Station is associated. | 26 | * @WLAN_STA_ASSOC: Station is associated. |
@@ -43,24 +44,33 @@ | |||
43 | * be in the queues | 44 | * be in the queues |
44 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping | 45 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping |
45 | * station in power-save mode, reply when the driver unblocks. | 46 | * station in power-save mode, reply when the driver unblocks. |
46 | * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal | 47 | * @WLAN_STA_TDLS_PEER: Station is a TDLS peer. |
47 | * buffers. Automatically cleared on station wake-up. | 48 | * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct |
49 | * packets. This means the link is enabled. | ||
50 | * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was | ||
51 | * keeping station in power-save mode, reply when the driver | ||
52 | * unblocks the station. | ||
53 | * @WLAN_STA_SP: Station is in a service period, so don't try to | ||
54 | * reply to other uAPSD trigger frames or PS-Poll. | ||
48 | */ | 55 | */ |
49 | enum ieee80211_sta_info_flags { | 56 | enum ieee80211_sta_info_flags { |
50 | WLAN_STA_AUTH = 1<<0, | 57 | WLAN_STA_AUTH, |
51 | WLAN_STA_ASSOC = 1<<1, | 58 | WLAN_STA_ASSOC, |
52 | WLAN_STA_PS_STA = 1<<2, | 59 | WLAN_STA_PS_STA, |
53 | WLAN_STA_AUTHORIZED = 1<<3, | 60 | WLAN_STA_AUTHORIZED, |
54 | WLAN_STA_SHORT_PREAMBLE = 1<<4, | 61 | WLAN_STA_SHORT_PREAMBLE, |
55 | WLAN_STA_ASSOC_AP = 1<<5, | 62 | WLAN_STA_ASSOC_AP, |
56 | WLAN_STA_WME = 1<<6, | 63 | WLAN_STA_WME, |
57 | WLAN_STA_WDS = 1<<7, | 64 | WLAN_STA_WDS, |
58 | WLAN_STA_CLEAR_PS_FILT = 1<<9, | 65 | WLAN_STA_CLEAR_PS_FILT, |
59 | WLAN_STA_MFP = 1<<10, | 66 | WLAN_STA_MFP, |
60 | WLAN_STA_BLOCK_BA = 1<<11, | 67 | WLAN_STA_BLOCK_BA, |
61 | WLAN_STA_PS_DRIVER = 1<<12, | 68 | WLAN_STA_PS_DRIVER, |
62 | WLAN_STA_PSPOLL = 1<<13, | 69 | WLAN_STA_PSPOLL, |
63 | WLAN_STA_PS_DRIVER_BUF = 1<<14, | 70 | WLAN_STA_TDLS_PEER, |
71 | WLAN_STA_TDLS_PEER_AUTH, | ||
72 | WLAN_STA_UAPSD, | ||
73 | WLAN_STA_SP, | ||
64 | }; | 74 | }; |
65 | 75 | ||
66 | #define STA_TID_NUM 16 | 76 | #define STA_TID_NUM 16 |
@@ -203,15 +213,16 @@ struct sta_ampdu_mlme { | |||
203 | * @last_rx_rate_flag: rx status flag of the last data packet | 213 | * @last_rx_rate_flag: rx status flag of the last data packet |
204 | * @lock: used for locking all fields that require locking, see comments | 214 | * @lock: used for locking all fields that require locking, see comments |
205 | * in the header file. | 215 | * in the header file. |
206 | * @flaglock: spinlock for flags accesses | ||
207 | * @drv_unblock_wk: used for driver PS unblocking | 216 | * @drv_unblock_wk: used for driver PS unblocking |
208 | * @listen_interval: listen interval of this station, when we're acting as AP | 217 | * @listen_interval: listen interval of this station, when we're acting as AP |
209 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 218 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly |
210 | * @ps_tx_buf: buffer of frames to transmit to this station | 219 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station |
211 | * when it leaves power saving state | 220 | * when it leaves power saving state or polls |
212 | * @tx_filtered: buffer of frames we already tried to transmit | 221 | * @tx_filtered: buffers (per AC) of frames we already tried to |
213 | * but were filtered by hardware due to STA having entered | 222 | * transmit but were filtered by hardware due to STA having |
214 | * power saving state | 223 | * entered power saving state, these are also delivered to |
224 | * the station when it leaves powersave or polls for frames | ||
225 | * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on | ||
215 | * @rx_packets: Number of MSDUs received from this STA | 226 | * @rx_packets: Number of MSDUs received from this STA |
216 | * @rx_bytes: Number of bytes received from this STA | 227 | * @rx_bytes: Number of bytes received from this STA |
217 | * @wep_weak_iv_count: number of weak WEP IVs received from this station | 228 | * @wep_weak_iv_count: number of weak WEP IVs received from this station |
@@ -261,7 +272,6 @@ struct sta_info { | |||
261 | struct rate_control_ref *rate_ctrl; | 272 | struct rate_control_ref *rate_ctrl; |
262 | void *rate_ctrl_priv; | 273 | void *rate_ctrl_priv; |
263 | spinlock_t lock; | 274 | spinlock_t lock; |
264 | spinlock_t flaglock; | ||
265 | 275 | ||
266 | struct work_struct drv_unblock_wk; | 276 | struct work_struct drv_unblock_wk; |
267 | 277 | ||
@@ -271,18 +281,16 @@ struct sta_info { | |||
271 | 281 | ||
272 | bool uploaded; | 282 | bool uploaded; |
273 | 283 | ||
274 | /* | 284 | /* use the accessors defined below */ |
275 | * frequently updated, locked with own spinlock (flaglock), | 285 | unsigned long _flags; |
276 | * use the accessors defined below | ||
277 | */ | ||
278 | u32 flags; | ||
279 | 286 | ||
280 | /* | 287 | /* |
281 | * STA powersave frame queues, no more than the internal | 288 | * STA powersave frame queues, no more than the internal |
282 | * locking required. | 289 | * locking required. |
283 | */ | 290 | */ |
284 | struct sk_buff_head ps_tx_buf; | 291 | struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; |
285 | struct sk_buff_head tx_filtered; | 292 | struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; |
293 | unsigned long driver_buffered_tids; | ||
286 | 294 | ||
287 | /* Updated from RX path only, no locking requirements */ | 295 | /* Updated from RX path only, no locking requirements */ |
288 | unsigned long rx_packets, rx_bytes; | 296 | unsigned long rx_packets, rx_bytes; |
@@ -358,60 +366,28 @@ static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta) | |||
358 | return NL80211_PLINK_LISTEN; | 366 | return NL80211_PLINK_LISTEN; |
359 | } | 367 | } |
360 | 368 | ||
361 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | 369 | static inline void set_sta_flag(struct sta_info *sta, |
370 | enum ieee80211_sta_info_flags flag) | ||
362 | { | 371 | { |
363 | unsigned long irqfl; | 372 | set_bit(flag, &sta->_flags); |
364 | |||
365 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
366 | sta->flags |= flags; | ||
367 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
368 | } | 373 | } |
369 | 374 | ||
370 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | 375 | static inline void clear_sta_flag(struct sta_info *sta, |
376 | enum ieee80211_sta_info_flags flag) | ||
371 | { | 377 | { |
372 | unsigned long irqfl; | 378 | clear_bit(flag, &sta->_flags); |
373 | |||
374 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
375 | sta->flags &= ~flags; | ||
376 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
377 | } | 379 | } |
378 | 380 | ||
379 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | 381 | static inline int test_sta_flag(struct sta_info *sta, |
382 | enum ieee80211_sta_info_flags flag) | ||
380 | { | 383 | { |
381 | u32 ret; | 384 | return test_bit(flag, &sta->_flags); |
382 | unsigned long irqfl; | ||
383 | |||
384 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
385 | ret = sta->flags & flags; | ||
386 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
387 | |||
388 | return ret; | ||
389 | } | 385 | } |
390 | 386 | ||
391 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | 387 | static inline int test_and_clear_sta_flag(struct sta_info *sta, |
392 | const u32 flags) | 388 | enum ieee80211_sta_info_flags flag) |
393 | { | 389 | { |
394 | u32 ret; | 390 | return test_and_clear_bit(flag, &sta->_flags); |
395 | unsigned long irqfl; | ||
396 | |||
397 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
398 | ret = sta->flags & flags; | ||
399 | sta->flags &= ~flags; | ||
400 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
401 | |||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
406 | { | ||
407 | u32 ret; | ||
408 | unsigned long irqfl; | ||
409 | |||
410 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
411 | ret = sta->flags; | ||
412 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
413 | |||
414 | return ret; | ||
415 | } | 391 | } |
416 | 392 | ||
417 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, | 393 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, |
@@ -429,8 +405,8 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid) | |||
429 | #define STA_HASH(sta) (sta[5]) | 405 | #define STA_HASH(sta) (sta[5]) |
430 | 406 | ||
431 | 407 | ||
432 | /* Maximum number of frames to buffer per power saving station */ | 408 | /* Maximum number of frames to buffer per power saving station per AC */ |
433 | #define STA_MAX_TX_BUFFER 128 | 409 | #define STA_MAX_TX_BUFFER 64 |
434 | 410 | ||
435 | /* Minimum buffered frame expiry time. If STA uses listen interval that is | 411 | /* Minimum buffered frame expiry time. If STA uses listen interval that is |
436 | * smaller than this value, the minimum value here is used instead. */ | 412 | * smaller than this value, the minimum value here is used instead. */ |
@@ -523,8 +499,7 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, | |||
523 | int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, | 499 | int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, |
524 | const u8 *addr); | 500 | const u8 *addr); |
525 | 501 | ||
526 | void sta_info_set_tim_bit(struct sta_info *sta); | 502 | void sta_info_recalc_tim(struct sta_info *sta); |
527 | void sta_info_clear_tim_bit(struct sta_info *sta); | ||
528 | 503 | ||
529 | void sta_info_init(struct ieee80211_local *local); | 504 | void sta_info_init(struct ieee80211_local *local); |
530 | void sta_info_stop(struct ieee80211_local *local); | 505 | void sta_info_stop(struct ieee80211_local *local); |
@@ -535,5 +510,6 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
535 | 510 | ||
536 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); | 511 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); |
537 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); | 512 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); |
513 | void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); | ||
538 | 514 | ||
539 | #endif /* STA_INFO_H */ | 515 | #endif /* STA_INFO_H */ |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index d50358c45ab0..864a9c3bcf46 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "rate.h" | 14 | #include "rate.h" |
15 | #include "mesh.h" | 15 | #include "mesh.h" |
16 | #include "led.h" | 16 | #include "led.h" |
17 | #include "wme.h" | ||
17 | 18 | ||
18 | 19 | ||
19 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 20 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
@@ -43,6 +44,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
43 | struct sk_buff *skb) | 44 | struct sk_buff *skb) |
44 | { | 45 | { |
45 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 46 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
47 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
48 | int ac; | ||
46 | 49 | ||
47 | /* | 50 | /* |
48 | * This skb 'survived' a round-trip through the driver, and | 51 | * This skb 'survived' a round-trip through the driver, and |
@@ -63,11 +66,37 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
63 | sta->tx_filtered_count++; | 66 | sta->tx_filtered_count++; |
64 | 67 | ||
65 | /* | 68 | /* |
69 | * Clear more-data bit on filtered frames, it might be set | ||
70 | * but later frames might time out so it might have to be | ||
71 | * clear again ... It's all rather unlikely (this frame | ||
72 | * should time out first, right?) but let's not confuse | ||
73 | * peers unnecessarily. | ||
74 | */ | ||
75 | if (hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) | ||
76 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
77 | |||
78 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
79 | u8 *p = ieee80211_get_qos_ctl(hdr); | ||
80 | int tid = *p & IEEE80211_QOS_CTL_TID_MASK; | ||
81 | |||
82 | /* | ||
83 | * Clear EOSP if set, this could happen e.g. | ||
84 | * if an absence period (us being a P2P GO) | ||
85 | * shortens the SP. | ||
86 | */ | ||
87 | if (*p & IEEE80211_QOS_CTL_EOSP) | ||
88 | *p &= ~IEEE80211_QOS_CTL_EOSP; | ||
89 | ac = ieee802_1d_to_ac[tid & 7]; | ||
90 | } else { | ||
91 | ac = IEEE80211_AC_BE; | ||
92 | } | ||
93 | |||
94 | /* | ||
66 | * Clear the TX filter mask for this STA when sending the next | 95 | * Clear the TX filter mask for this STA when sending the next |
67 | * packet. If the STA went to power save mode, this will happen | 96 | * packet. If the STA went to power save mode, this will happen |
68 | * when it wakes up for the next time. | 97 | * when it wakes up for the next time. |
69 | */ | 98 | */ |
70 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); | 99 | set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT); |
71 | 100 | ||
72 | /* | 101 | /* |
73 | * This code races in the following way: | 102 | * This code races in the following way: |
@@ -103,13 +132,19 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
103 | * changes before calling TX status events if ordering can be | 132 | * changes before calling TX status events if ordering can be |
104 | * unknown. | 133 | * unknown. |
105 | */ | 134 | */ |
106 | if (test_sta_flags(sta, WLAN_STA_PS_STA) && | 135 | if (test_sta_flag(sta, WLAN_STA_PS_STA) && |
107 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 136 | skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) { |
108 | skb_queue_tail(&sta->tx_filtered, skb); | 137 | skb_queue_tail(&sta->tx_filtered[ac], skb); |
138 | sta_info_recalc_tim(sta); | ||
139 | |||
140 | if (!timer_pending(&local->sta_cleanup)) | ||
141 | mod_timer(&local->sta_cleanup, | ||
142 | round_jiffies(jiffies + | ||
143 | STA_INFO_CLEANUP_INTERVAL)); | ||
109 | return; | 144 | return; |
110 | } | 145 | } |
111 | 146 | ||
112 | if (!test_sta_flags(sta, WLAN_STA_PS_STA) && | 147 | if (!test_sta_flag(sta, WLAN_STA_PS_STA) && |
113 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | 148 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { |
114 | /* Software retry the packet once */ | 149 | /* Software retry the packet once */ |
115 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | 150 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
@@ -121,8 +156,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
121 | if (net_ratelimit()) | 156 | if (net_ratelimit()) |
122 | wiphy_debug(local->hw.wiphy, | 157 | wiphy_debug(local->hw.wiphy, |
123 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", | 158 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
124 | skb_queue_len(&sta->tx_filtered), | 159 | skb_queue_len(&sta->tx_filtered[ac]), |
125 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); | 160 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); |
126 | #endif | 161 | #endif |
127 | dev_kfree_skb(skb); | 162 | dev_kfree_skb(skb); |
128 | } | 163 | } |
@@ -249,8 +284,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
249 | if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) | 284 | if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) |
250 | continue; | 285 | continue; |
251 | 286 | ||
287 | if (info->flags & IEEE80211_TX_STATUS_EOSP) | ||
288 | clear_sta_flag(sta, WLAN_STA_SP); | ||
289 | |||
252 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); | 290 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); |
253 | if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) { | 291 | if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) { |
254 | /* | 292 | /* |
255 | * The STA is in power save mode, so assume | 293 | * The STA is in power save mode, so assume |
256 | * that this TX packet failed because of that. | 294 | * that this TX packet failed because of that. |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 7cd6c28968b2..ad2ee4a90ec4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -253,7 +253,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
253 | 253 | ||
254 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 254 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
255 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 255 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
256 | u32 sta_flags; | 256 | bool assoc = false; |
257 | 257 | ||
258 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) | 258 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) |
259 | return TX_CONTINUE; | 259 | return TX_CONTINUE; |
@@ -284,10 +284,11 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
284 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 284 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
285 | return TX_CONTINUE; | 285 | return TX_CONTINUE; |
286 | 286 | ||
287 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; | 287 | if (tx->sta) |
288 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); | ||
288 | 289 | ||
289 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 290 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
290 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 291 | if (unlikely(!assoc && |
291 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 292 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
292 | ieee80211_is_data(hdr->frame_control))) { | 293 | ieee80211_is_data(hdr->frame_control))) { |
293 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 294 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -343,13 +344,22 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
343 | total += skb_queue_len(&ap->ps_bc_buf); | 344 | total += skb_queue_len(&ap->ps_bc_buf); |
344 | } | 345 | } |
345 | 346 | ||
347 | /* | ||
348 | * Drop one frame from each station from the lowest-priority | ||
349 | * AC that has frames at all. | ||
350 | */ | ||
346 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 351 | list_for_each_entry_rcu(sta, &local->sta_list, list) { |
347 | skb = skb_dequeue(&sta->ps_tx_buf); | 352 | int ac; |
348 | if (skb) { | 353 | |
349 | purged++; | 354 | for (ac = IEEE80211_AC_BK; ac >= IEEE80211_AC_VO; ac--) { |
350 | dev_kfree_skb(skb); | 355 | skb = skb_dequeue(&sta->ps_tx_buf[ac]); |
356 | total += skb_queue_len(&sta->ps_tx_buf[ac]); | ||
357 | if (skb) { | ||
358 | purged++; | ||
359 | dev_kfree_skb(skb); | ||
360 | break; | ||
361 | } | ||
351 | } | 362 | } |
352 | total += skb_queue_len(&sta->ps_tx_buf); | ||
353 | } | 363 | } |
354 | 364 | ||
355 | rcu_read_unlock(); | 365 | rcu_read_unlock(); |
@@ -418,7 +428,7 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta, | |||
418 | if (!ieee80211_is_mgmt(fc)) | 428 | if (!ieee80211_is_mgmt(fc)) |
419 | return 0; | 429 | return 0; |
420 | 430 | ||
421 | if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP)) | 431 | if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP)) |
422 | return 0; | 432 | return 0; |
423 | 433 | ||
424 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) | 434 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) |
@@ -435,7 +445,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
435 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 445 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
436 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 446 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
437 | struct ieee80211_local *local = tx->local; | 447 | struct ieee80211_local *local = tx->local; |
438 | u32 staflags; | ||
439 | 448 | ||
440 | if (unlikely(!sta || | 449 | if (unlikely(!sta || |
441 | ieee80211_is_probe_resp(hdr->frame_control) || | 450 | ieee80211_is_probe_resp(hdr->frame_control) || |
@@ -444,57 +453,52 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
444 | ieee80211_is_reassoc_resp(hdr->frame_control))) | 453 | ieee80211_is_reassoc_resp(hdr->frame_control))) |
445 | return TX_CONTINUE; | 454 | return TX_CONTINUE; |
446 | 455 | ||
447 | staflags = get_sta_flags(sta); | 456 | if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) || |
457 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) && | ||
458 | !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) { | ||
459 | int ac = skb_get_queue_mapping(tx->skb); | ||
448 | 460 | ||
449 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && | ||
450 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { | ||
451 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 461 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
452 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " | 462 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", |
453 | "before %d)\n", | 463 | sta->sta.addr, sta->sta.aid, ac); |
454 | sta->sta.addr, sta->sta.aid, | ||
455 | skb_queue_len(&sta->ps_tx_buf)); | ||
456 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 464 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
457 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 465 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
458 | purge_old_ps_buffers(tx->local); | 466 | purge_old_ps_buffers(tx->local); |
459 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 467 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { |
460 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 468 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); |
461 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 469 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
462 | if (net_ratelimit()) { | 470 | if (net_ratelimit()) |
463 | printk(KERN_DEBUG "%s: STA %pM TX " | 471 | printk(KERN_DEBUG "%s: STA %pM TX buffer for " |
464 | "buffer full - dropping oldest frame\n", | 472 | "AC %d full - dropping oldest frame\n", |
465 | tx->sdata->name, sta->sta.addr); | 473 | tx->sdata->name, sta->sta.addr, ac); |
466 | } | ||
467 | #endif | 474 | #endif |
468 | dev_kfree_skb(old); | 475 | dev_kfree_skb(old); |
469 | } else | 476 | } else |
470 | tx->local->total_ps_buffered++; | 477 | tx->local->total_ps_buffered++; |
471 | 478 | ||
472 | /* | ||
473 | * Queue frame to be sent after STA wakes up/polls, | ||
474 | * but don't set the TIM bit if the driver is blocking | ||
475 | * wakeup or poll response transmissions anyway. | ||
476 | */ | ||
477 | if (skb_queue_empty(&sta->ps_tx_buf) && | ||
478 | !(staflags & WLAN_STA_PS_DRIVER)) | ||
479 | sta_info_set_tim_bit(sta); | ||
480 | |||
481 | info->control.jiffies = jiffies; | 479 | info->control.jiffies = jiffies; |
482 | info->control.vif = &tx->sdata->vif; | 480 | info->control.vif = &tx->sdata->vif; |
483 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 481 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
484 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 482 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
485 | 483 | ||
486 | if (!timer_pending(&local->sta_cleanup)) | 484 | if (!timer_pending(&local->sta_cleanup)) |
487 | mod_timer(&local->sta_cleanup, | 485 | mod_timer(&local->sta_cleanup, |
488 | round_jiffies(jiffies + | 486 | round_jiffies(jiffies + |
489 | STA_INFO_CLEANUP_INTERVAL)); | 487 | STA_INFO_CLEANUP_INTERVAL)); |
490 | 488 | ||
489 | /* | ||
490 | * We queued up some frames, so the TIM bit might | ||
491 | * need to be set, recalculate it. | ||
492 | */ | ||
493 | sta_info_recalc_tim(sta); | ||
494 | |||
491 | return TX_QUEUED; | 495 | return TX_QUEUED; |
492 | } | 496 | } |
493 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 497 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
494 | else if (unlikely(staflags & WLAN_STA_PS_STA)) { | 498 | else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { |
495 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " | 499 | printk(KERN_DEBUG |
496 | "set -> send frame\n", tx->sdata->name, | 500 | "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", |
497 | sta->sta.addr); | 501 | tx->sdata->name, sta->sta.addr); |
498 | } | 502 | } |
499 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 503 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
500 | 504 | ||
@@ -552,7 +556,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
552 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 556 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
553 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 557 | (!ieee80211_is_robust_mgmt_frame(hdr) || |
554 | (ieee80211_is_action(hdr->frame_control) && | 558 | (ieee80211_is_action(hdr->frame_control) && |
555 | tx->sta && test_sta_flags(tx->sta, WLAN_STA_MFP)))) { | 559 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) { |
556 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 560 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
557 | return TX_DROP; | 561 | return TX_DROP; |
558 | } else | 562 | } else |
@@ -611,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
611 | u32 len; | 615 | u32 len; |
612 | bool inval = false, rts = false, short_preamble = false; | 616 | bool inval = false, rts = false, short_preamble = false; |
613 | struct ieee80211_tx_rate_control txrc; | 617 | struct ieee80211_tx_rate_control txrc; |
614 | u32 sta_flags; | 618 | bool assoc = false; |
615 | 619 | ||
616 | memset(&txrc, 0, sizeof(txrc)); | 620 | memset(&txrc, 0, sizeof(txrc)); |
617 | 621 | ||
@@ -647,17 +651,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
647 | */ | 651 | */ |
648 | if (tx->sdata->vif.bss_conf.use_short_preamble && | 652 | if (tx->sdata->vif.bss_conf.use_short_preamble && |
649 | (ieee80211_is_data(hdr->frame_control) || | 653 | (ieee80211_is_data(hdr->frame_control) || |
650 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | 654 | (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) |
651 | txrc.short_preamble = short_preamble = true; | 655 | txrc.short_preamble = short_preamble = true; |
652 | 656 | ||
653 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; | 657 | if (tx->sta) |
658 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); | ||
654 | 659 | ||
655 | /* | 660 | /* |
656 | * Lets not bother rate control if we're associated and cannot | 661 | * Lets not bother rate control if we're associated and cannot |
657 | * talk to the sta. This should not happen. | 662 | * talk to the sta. This should not happen. |
658 | */ | 663 | */ |
659 | if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && | 664 | if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc && |
660 | (sta_flags & WLAN_STA_ASSOC) && | ||
661 | !rate_usable_index_exists(sband, &tx->sta->sta), | 665 | !rate_usable_index_exists(sband, &tx->sta->sta), |
662 | "%s: Dropped data frame as no usable bitrate found while " | 666 | "%s: Dropped data frame as no usable bitrate found while " |
663 | "scanning and associated. Target station: " | 667 | "scanning and associated. Target station: " |
@@ -800,6 +804,9 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
800 | if (ieee80211_hdrlen(hdr->frame_control) < 24) | 804 | if (ieee80211_hdrlen(hdr->frame_control) < 24) |
801 | return TX_CONTINUE; | 805 | return TX_CONTINUE; |
802 | 806 | ||
807 | if (ieee80211_is_qos_nullfunc(hdr->frame_control)) | ||
808 | return TX_CONTINUE; | ||
809 | |||
803 | /* | 810 | /* |
804 | * Anything but QoS data that has a sequence number field | 811 | * Anything but QoS data that has a sequence number field |
805 | * (is long enough) gets a sequence number from the global | 812 | * (is long enough) gets a sequence number from the global |
@@ -1047,6 +1054,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1047 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1054 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1048 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, | 1055 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1049 | NULL); | 1056 | NULL); |
1057 | u16 txflags; | ||
1050 | 1058 | ||
1051 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1059 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1052 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1060 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
@@ -1095,6 +1103,13 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1095 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1103 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1096 | break; | 1104 | break; |
1097 | 1105 | ||
1106 | case IEEE80211_RADIOTAP_TX_FLAGS: | ||
1107 | txflags = le16_to_cpu(get_unaligned((__le16*) | ||
1108 | iterator.this_arg)); | ||
1109 | if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK) | ||
1110 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
1111 | break; | ||
1112 | |||
1098 | /* | 1113 | /* |
1099 | * Please update the file | 1114 | * Please update the file |
1100 | * Documentation/networking/mac80211-injection.txt | 1115 | * Documentation/networking/mac80211-injection.txt |
@@ -1232,6 +1247,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1232 | tx->sta = sta_info_get(sdata, hdr->addr1); | 1247 | tx->sta = sta_info_get(sdata, hdr->addr1); |
1233 | 1248 | ||
1234 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && | 1249 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && |
1250 | !ieee80211_is_qos_nullfunc(hdr->frame_control) && | ||
1235 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) && | 1251 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) && |
1236 | !(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) { | 1252 | !(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) { |
1237 | struct tid_ampdu_tx *tid_tx; | 1253 | struct tid_ampdu_tx *tid_tx; |
@@ -1258,8 +1274,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1258 | tx->flags |= IEEE80211_TX_UNICAST; | 1274 | tx->flags |= IEEE80211_TX_UNICAST; |
1259 | if (unlikely(local->wifi_wme_noack_test)) | 1275 | if (unlikely(local->wifi_wme_noack_test)) |
1260 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1276 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1261 | else | 1277 | /* |
1262 | info->flags &= ~IEEE80211_TX_CTL_NO_ACK; | 1278 | * Flags are initialized to 0. Hence, no need to |
1279 | * explicitly unset IEEE80211_TX_CTL_NO_ACK since | ||
1280 | * it might already be set for injected frames. | ||
1281 | */ | ||
1263 | } | 1282 | } |
1264 | 1283 | ||
1265 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 1284 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
@@ -1273,7 +1292,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1273 | 1292 | ||
1274 | if (!tx->sta) | 1293 | if (!tx->sta) |
1275 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1294 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1276 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) | 1295 | else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
1277 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1296 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1278 | 1297 | ||
1279 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1298 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1515,8 +1534,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1515 | return 0; | 1534 | return 0; |
1516 | } | 1535 | } |
1517 | 1536 | ||
1518 | static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | 1537 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
1519 | struct sk_buff *skb) | ||
1520 | { | 1538 | { |
1521 | struct ieee80211_local *local = sdata->local; | 1539 | struct ieee80211_local *local = sdata->local; |
1522 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1540 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1724,8 +1742,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1724 | int encaps_len, skip_header_bytes; | 1742 | int encaps_len, skip_header_bytes; |
1725 | int nh_pos, h_pos; | 1743 | int nh_pos, h_pos; |
1726 | struct sta_info *sta = NULL; | 1744 | struct sta_info *sta = NULL; |
1727 | u32 sta_flags = 0; | 1745 | bool wme_sta = false, authorized = false, tdls_auth = false; |
1728 | struct sk_buff *tmp_skb; | 1746 | struct sk_buff *tmp_skb; |
1747 | bool tdls_direct = false; | ||
1729 | 1748 | ||
1730 | if (unlikely(skb->len < ETH_HLEN)) { | 1749 | if (unlikely(skb->len < ETH_HLEN)) { |
1731 | ret = NETDEV_TX_OK; | 1750 | ret = NETDEV_TX_OK; |
@@ -1749,7 +1768,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1749 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1768 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1750 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1769 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
1751 | hdrlen = 30; | 1770 | hdrlen = 30; |
1752 | sta_flags = get_sta_flags(sta); | 1771 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1772 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1753 | } | 1773 | } |
1754 | rcu_read_unlock(); | 1774 | rcu_read_unlock(); |
1755 | if (sta) | 1775 | if (sta) |
@@ -1837,11 +1857,50 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1837 | break; | 1857 | break; |
1838 | #endif | 1858 | #endif |
1839 | case NL80211_IFTYPE_STATION: | 1859 | case NL80211_IFTYPE_STATION: |
1840 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1860 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { |
1841 | if (sdata->u.mgd.use_4addr && | 1861 | bool tdls_peer = false; |
1842 | cpu_to_be16(ethertype) != sdata->control_port_protocol) { | 1862 | |
1843 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1863 | rcu_read_lock(); |
1864 | sta = sta_info_get(sdata, skb->data); | ||
1865 | if (sta) { | ||
1866 | authorized = test_sta_flag(sta, | ||
1867 | WLAN_STA_AUTHORIZED); | ||
1868 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1869 | tdls_peer = test_sta_flag(sta, | ||
1870 | WLAN_STA_TDLS_PEER); | ||
1871 | tdls_auth = test_sta_flag(sta, | ||
1872 | WLAN_STA_TDLS_PEER_AUTH); | ||
1873 | } | ||
1874 | rcu_read_unlock(); | ||
1875 | |||
1876 | /* | ||
1877 | * If the TDLS link is enabled, send everything | ||
1878 | * directly. Otherwise, allow TDLS setup frames | ||
1879 | * to be transmitted indirectly. | ||
1880 | */ | ||
1881 | tdls_direct = tdls_peer && (tdls_auth || | ||
1882 | !(ethertype == ETH_P_TDLS && skb->len > 14 && | ||
1883 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE)); | ||
1884 | } | ||
1885 | |||
1886 | if (tdls_direct) { | ||
1887 | /* link during setup - throw out frames to peer */ | ||
1888 | if (!tdls_auth) { | ||
1889 | ret = NETDEV_TX_OK; | ||
1890 | goto fail; | ||
1891 | } | ||
1892 | |||
1893 | /* DA SA BSSID */ | ||
1894 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | ||
1895 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | ||
1896 | memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN); | ||
1897 | hdrlen = 24; | ||
1898 | } else if (sdata->u.mgd.use_4addr && | ||
1899 | cpu_to_be16(ethertype) != sdata->control_port_protocol) { | ||
1900 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | | ||
1901 | IEEE80211_FCTL_TODS); | ||
1844 | /* RA TA DA SA */ | 1902 | /* RA TA DA SA */ |
1903 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | ||
1845 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | 1904 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
1846 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1905 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1847 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1906 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
@@ -1849,6 +1908,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1849 | } else { | 1908 | } else { |
1850 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | 1909 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
1851 | /* BSSID SA DA */ | 1910 | /* BSSID SA DA */ |
1911 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | ||
1852 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1912 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
1853 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1913 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1854 | hdrlen = 24; | 1914 | hdrlen = 24; |
@@ -1874,17 +1934,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1874 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1934 | if (!is_multicast_ether_addr(hdr.addr1)) { |
1875 | rcu_read_lock(); | 1935 | rcu_read_lock(); |
1876 | sta = sta_info_get(sdata, hdr.addr1); | 1936 | sta = sta_info_get(sdata, hdr.addr1); |
1877 | if (sta) | 1937 | if (sta) { |
1878 | sta_flags = get_sta_flags(sta); | 1938 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1939 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1940 | } | ||
1879 | rcu_read_unlock(); | 1941 | rcu_read_unlock(); |
1880 | } | 1942 | } |
1881 | 1943 | ||
1882 | /* For mesh, the use of the QoS header is mandatory */ | 1944 | /* For mesh, the use of the QoS header is mandatory */ |
1883 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1945 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
1884 | sta_flags |= WLAN_STA_WME; | 1946 | wme_sta = true; |
1885 | 1947 | ||
1886 | /* receiver and we are QoS enabled, use a QoS type frame */ | 1948 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1887 | if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) { | 1949 | if (wme_sta && local->hw.queues >= 4) { |
1888 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | 1950 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
1889 | hdrlen += 2; | 1951 | hdrlen += 2; |
1890 | } | 1952 | } |
@@ -1894,8 +1956,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1894 | * EAPOL frames from the local station. | 1956 | * EAPOL frames from the local station. |
1895 | */ | 1957 | */ |
1896 | if (!ieee80211_vif_is_mesh(&sdata->vif) && | 1958 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1897 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1959 | unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized && |
1898 | !(sta_flags & WLAN_STA_AUTHORIZED) && | ||
1899 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && | 1960 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && |
1900 | compare_ether_addr(sdata->vif.addr, | 1961 | compare_ether_addr(sdata->vif.addr, |
1901 | skb->data + ETH_ALEN) == 0))) { | 1962 | skb->data + ETH_ALEN) == 0))) { |
@@ -2307,9 +2368,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2307 | *pos++ = WLAN_EID_SSID; | 2368 | *pos++ = WLAN_EID_SSID; |
2308 | *pos++ = 0x0; | 2369 | *pos++ = 0x0; |
2309 | 2370 | ||
2310 | if (mesh_add_srates_ie(skb, sdata) || | 2371 | if (ieee80211_add_srates_ie(&sdata->vif, skb) || |
2311 | mesh_add_ds_params_ie(skb, sdata) || | 2372 | mesh_add_ds_params_ie(skb, sdata) || |
2312 | mesh_add_ext_srates_ie(skb, sdata) || | 2373 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || |
2313 | mesh_add_rsn_ie(skb, sdata) || | 2374 | mesh_add_rsn_ie(skb, sdata) || |
2314 | mesh_add_meshid_ie(skb, sdata) || | 2375 | mesh_add_meshid_ie(skb, sdata) || |
2315 | mesh_add_meshconf_ie(skb, sdata) || | 2376 | mesh_add_meshconf_ie(skb, sdata) || |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 2c9dc360dc6d..7439d26bf5f9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -367,14 +367,14 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
367 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 367 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
368 | } | 368 | } |
369 | 369 | ||
370 | int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 370 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, |
371 | struct sk_buff_head *skbs, | 371 | struct sk_buff_head *skbs, |
372 | void (*fn)(void *data), void *data) | 372 | void (*fn)(void *data), void *data) |
373 | { | 373 | { |
374 | struct ieee80211_hw *hw = &local->hw; | 374 | struct ieee80211_hw *hw = &local->hw; |
375 | struct sk_buff *skb; | 375 | struct sk_buff *skb; |
376 | unsigned long flags; | 376 | unsigned long flags; |
377 | int queue, ret = 0, i; | 377 | int queue, i; |
378 | 378 | ||
379 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 379 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
380 | for (i = 0; i < hw->queues; i++) | 380 | for (i = 0; i < hw->queues; i++) |
@@ -389,7 +389,6 @@ int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
389 | continue; | 389 | continue; |
390 | } | 390 | } |
391 | 391 | ||
392 | ret++; | ||
393 | queue = skb_get_queue_mapping(skb); | 392 | queue = skb_get_queue_mapping(skb); |
394 | __skb_queue_tail(&local->pending[queue], skb); | 393 | __skb_queue_tail(&local->pending[queue], skb); |
395 | } | 394 | } |
@@ -401,14 +400,12 @@ int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
401 | __ieee80211_wake_queue(hw, i, | 400 | __ieee80211_wake_queue(hw, i, |
402 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 401 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
403 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 402 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
404 | |||
405 | return ret; | ||
406 | } | 403 | } |
407 | 404 | ||
408 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 405 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
409 | struct sk_buff_head *skbs) | 406 | struct sk_buff_head *skbs) |
410 | { | 407 | { |
411 | return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | 408 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); |
412 | } | 409 | } |
413 | 410 | ||
414 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 411 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
@@ -1125,7 +1122,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1125 | 1122 | ||
1126 | list_for_each_entry(sta, &local->sta_list, list) { | 1123 | list_for_each_entry(sta, &local->sta_list, list) { |
1127 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 1124 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
1128 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1125 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA); |
1129 | } | 1126 | } |
1130 | 1127 | ||
1131 | mutex_unlock(&local->sta_mtx); | 1128 | mutex_unlock(&local->sta_mtx); |
@@ -1364,3 +1361,60 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | |||
1364 | _ieee80211_enable_rssi_reports(sdata, 0, 0); | 1361 | _ieee80211_enable_rssi_reports(sdata, 0, 0); |
1365 | } | 1362 | } |
1366 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | 1363 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); |
1364 | |||
1365 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | ||
1366 | { | ||
1367 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1368 | struct ieee80211_local *local = sdata->local; | ||
1369 | struct ieee80211_supported_band *sband; | ||
1370 | int rate; | ||
1371 | u8 i, rates, *pos; | ||
1372 | |||
1373 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1374 | rates = sband->n_bitrates; | ||
1375 | if (rates > 8) | ||
1376 | rates = 8; | ||
1377 | |||
1378 | if (skb_tailroom(skb) < rates + 2) | ||
1379 | return -ENOMEM; | ||
1380 | |||
1381 | pos = skb_put(skb, rates + 2); | ||
1382 | *pos++ = WLAN_EID_SUPP_RATES; | ||
1383 | *pos++ = rates; | ||
1384 | for (i = 0; i < rates; i++) { | ||
1385 | rate = sband->bitrates[i].bitrate; | ||
1386 | *pos++ = (u8) (rate / 5); | ||
1387 | } | ||
1388 | |||
1389 | return 0; | ||
1390 | } | ||
1391 | |||
1392 | int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | ||
1393 | { | ||
1394 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1395 | struct ieee80211_local *local = sdata->local; | ||
1396 | struct ieee80211_supported_band *sband; | ||
1397 | int rate; | ||
1398 | u8 i, exrates, *pos; | ||
1399 | |||
1400 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1401 | exrates = sband->n_bitrates; | ||
1402 | if (exrates > 8) | ||
1403 | exrates -= 8; | ||
1404 | else | ||
1405 | exrates = 0; | ||
1406 | |||
1407 | if (skb_tailroom(skb) < exrates + 2) | ||
1408 | return -ENOMEM; | ||
1409 | |||
1410 | if (exrates) { | ||
1411 | pos = skb_put(skb, exrates + 2); | ||
1412 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1413 | *pos++ = exrates; | ||
1414 | for (i = 8; i < sband->n_bitrates; i++) { | ||
1415 | rate = sband->bitrates[i].bitrate; | ||
1416 | *pos++ = (u8) (rate / 5); | ||
1417 | } | ||
1418 | } | ||
1419 | return 0; | ||
1420 | } | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 971004c9b04f..fd52e695c071 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -72,7 +72,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
72 | case NL80211_IFTYPE_AP_VLAN: | 72 | case NL80211_IFTYPE_AP_VLAN: |
73 | sta = rcu_dereference(sdata->u.vlan.sta); | 73 | sta = rcu_dereference(sdata->u.vlan.sta); |
74 | if (sta) { | 74 | if (sta) { |
75 | qos = get_sta_flags(sta) & WLAN_STA_WME; | 75 | qos = test_sta_flag(sta, WLAN_STA_WME); |
76 | break; | 76 | break; |
77 | } | 77 | } |
78 | case NL80211_IFTYPE_AP: | 78 | case NL80211_IFTYPE_AP: |
@@ -99,7 +99,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
99 | if (!sta && ra && !is_multicast_ether_addr(ra)) { | 99 | if (!sta && ra && !is_multicast_ether_addr(ra)) { |
100 | sta = sta_info_get(sdata, ra); | 100 | sta = sta_info_get(sdata, ra); |
101 | if (sta) | 101 | if (sta) |
102 | qos = get_sta_flags(sta) & WLAN_STA_WME; | 102 | qos = test_sta_flag(sta, WLAN_STA_WME); |
103 | } | 103 | } |
104 | rcu_read_unlock(); | 104 | rcu_read_unlock(); |
105 | 105 | ||