diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-01-17 14:43:17 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-01-17 14:43:17 -0500 |
commit | 7916a075571f0ccd0830cf3da293188a8b6045e3 (patch) | |
tree | 119c5bb9e513c8205efed485c2dc7b8271123326 /net/mac80211 | |
parent | cf84eb0b09c0f09b4c70a648b9dfeec78be61f07 (diff) | |
parent | e4e19c031901e95dc7d1cf0a2c9c50525d71651f (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 3 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 61 | ||||
-rw-r--r-- | net/mac80211/ht.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 22 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 1 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 1 | ||||
-rw-r--r-- | net/mac80211/rx.c | 40 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 238 | ||||
-rw-r--r-- | net/mac80211/trace.h | 27 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 41 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 2 |
13 files changed, 295 insertions, 150 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 09d2e58a2ba7..f9ae9b85d4c1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1035,6 +1035,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
1035 | return err; | 1035 | return err; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | ieee80211_recalc_dtim(local, sdata); | ||
1038 | ieee80211_bss_info_change_notify(sdata, changed); | 1039 | ieee80211_bss_info_change_notify(sdata, changed); |
1039 | 1040 | ||
1040 | netif_carrier_on(dev); | 1041 | netif_carrier_on(dev); |
@@ -3854,7 +3855,7 @@ static int ieee80211_set_qos_map(struct wiphy *wiphy, | |||
3854 | new_qos_map = NULL; | 3855 | new_qos_map = NULL; |
3855 | } | 3856 | } |
3856 | 3857 | ||
3857 | old_qos_map = rtnl_dereference(sdata->qos_map); | 3858 | old_qos_map = sdata_dereference(sdata->qos_map, sdata); |
3858 | rcu_assign_pointer(sdata->qos_map, new_qos_map); | 3859 | rcu_assign_pointer(sdata->qos_map, new_qos_map); |
3859 | if (old_qos_map) | 3860 | if (old_qos_map) |
3860 | kfree_rcu(old_qos_map, rcu_head); | 3861 | kfree_rcu(old_qos_map, rcu_head); |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 04b5a14c8a05..ebf80f3abd83 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -133,7 +133,15 @@ static ssize_t ieee80211_if_fmt_##name( \ | |||
133 | jiffies_to_msecs(sdata->field)); \ | 133 | jiffies_to_msecs(sdata->field)); \ |
134 | } | 134 | } |
135 | 135 | ||
136 | #define __IEEE80211_IF_FILE(name, _write) \ | 136 | #define _IEEE80211_IF_FILE_OPS(name, _read, _write) \ |
137 | static const struct file_operations name##_ops = { \ | ||
138 | .read = (_read), \ | ||
139 | .write = (_write), \ | ||
140 | .open = simple_open, \ | ||
141 | .llseek = generic_file_llseek, \ | ||
142 | } | ||
143 | |||
144 | #define _IEEE80211_IF_FILE_R_FN(name) \ | ||
137 | static ssize_t ieee80211_if_read_##name(struct file *file, \ | 145 | static ssize_t ieee80211_if_read_##name(struct file *file, \ |
138 | char __user *userbuf, \ | 146 | char __user *userbuf, \ |
139 | size_t count, loff_t *ppos) \ | 147 | size_t count, loff_t *ppos) \ |
@@ -141,28 +149,34 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \ | |||
141 | return ieee80211_if_read(file->private_data, \ | 149 | return ieee80211_if_read(file->private_data, \ |
142 | userbuf, count, ppos, \ | 150 | userbuf, count, ppos, \ |
143 | ieee80211_if_fmt_##name); \ | 151 | ieee80211_if_fmt_##name); \ |
144 | } \ | ||
145 | static const struct file_operations name##_ops = { \ | ||
146 | .read = ieee80211_if_read_##name, \ | ||
147 | .write = (_write), \ | ||
148 | .open = simple_open, \ | ||
149 | .llseek = generic_file_llseek, \ | ||
150 | } | 152 | } |
151 | 153 | ||
152 | #define __IEEE80211_IF_FILE_W(name) \ | 154 | #define _IEEE80211_IF_FILE_W_FN(name) \ |
153 | static ssize_t ieee80211_if_write_##name(struct file *file, \ | 155 | static ssize_t ieee80211_if_write_##name(struct file *file, \ |
154 | const char __user *userbuf, \ | 156 | const char __user *userbuf, \ |
155 | size_t count, loff_t *ppos) \ | 157 | size_t count, loff_t *ppos) \ |
156 | { \ | 158 | { \ |
157 | return ieee80211_if_write(file->private_data, userbuf, count, \ | 159 | return ieee80211_if_write(file->private_data, userbuf, count, \ |
158 | ppos, ieee80211_if_parse_##name); \ | 160 | ppos, ieee80211_if_parse_##name); \ |
159 | } \ | 161 | } |
160 | __IEEE80211_IF_FILE(name, ieee80211_if_write_##name) | 162 | |
163 | #define IEEE80211_IF_FILE_R(name) \ | ||
164 | _IEEE80211_IF_FILE_R_FN(name) \ | ||
165 | _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, NULL) | ||
166 | |||
167 | #define IEEE80211_IF_FILE_W(name) \ | ||
168 | _IEEE80211_IF_FILE_W_FN(name) \ | ||
169 | _IEEE80211_IF_FILE_OPS(name, NULL, ieee80211_if_write_##name) | ||
161 | 170 | ||
171 | #define IEEE80211_IF_FILE_RW(name) \ | ||
172 | _IEEE80211_IF_FILE_R_FN(name) \ | ||
173 | _IEEE80211_IF_FILE_W_FN(name) \ | ||
174 | _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, \ | ||
175 | ieee80211_if_write_##name) | ||
162 | 176 | ||
163 | #define IEEE80211_IF_FILE(name, field, format) \ | 177 | #define IEEE80211_IF_FILE(name, field, format) \ |
164 | IEEE80211_IF_FMT_##format(name, field) \ | 178 | IEEE80211_IF_FMT_##format(name, field) \ |
165 | __IEEE80211_IF_FILE(name, NULL) | 179 | IEEE80211_IF_FILE_R(name) |
166 | 180 | ||
167 | /* common attributes */ | 181 | /* common attributes */ |
168 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 182 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
@@ -199,7 +213,7 @@ ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata, | |||
199 | 213 | ||
200 | return len; | 214 | return len; |
201 | } | 215 | } |
202 | __IEEE80211_IF_FILE(hw_queues, NULL); | 216 | IEEE80211_IF_FILE_R(hw_queues); |
203 | 217 | ||
204 | /* STA attributes */ | 218 | /* STA attributes */ |
205 | IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); | 219 | IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); |
@@ -275,14 +289,7 @@ static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, | |||
275 | 289 | ||
276 | return -EINVAL; | 290 | return -EINVAL; |
277 | } | 291 | } |
278 | 292 | IEEE80211_IF_FILE_RW(smps); | |
279 | __IEEE80211_IF_FILE_W(smps); | ||
280 | |||
281 | static ssize_t ieee80211_if_fmt_tkip_mic_test( | ||
282 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | ||
283 | { | ||
284 | return -EOPNOTSUPP; | ||
285 | } | ||
286 | 293 | ||
287 | static ssize_t ieee80211_if_parse_tkip_mic_test( | 294 | static ssize_t ieee80211_if_parse_tkip_mic_test( |
288 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) | 295 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) |
@@ -349,8 +356,7 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
349 | 356 | ||
350 | return buflen; | 357 | return buflen; |
351 | } | 358 | } |
352 | 359 | IEEE80211_IF_FILE_W(tkip_mic_test); | |
353 | __IEEE80211_IF_FILE_W(tkip_mic_test); | ||
354 | 360 | ||
355 | static ssize_t ieee80211_if_fmt_uapsd_queues( | 361 | static ssize_t ieee80211_if_fmt_uapsd_queues( |
356 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 362 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
@@ -378,7 +384,7 @@ static ssize_t ieee80211_if_parse_uapsd_queues( | |||
378 | 384 | ||
379 | return buflen; | 385 | return buflen; |
380 | } | 386 | } |
381 | __IEEE80211_IF_FILE_W(uapsd_queues); | 387 | IEEE80211_IF_FILE_RW(uapsd_queues); |
382 | 388 | ||
383 | static ssize_t ieee80211_if_fmt_uapsd_max_sp_len( | 389 | static ssize_t ieee80211_if_fmt_uapsd_max_sp_len( |
384 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 390 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
@@ -406,7 +412,7 @@ static ssize_t ieee80211_if_parse_uapsd_max_sp_len( | |||
406 | 412 | ||
407 | return buflen; | 413 | return buflen; |
408 | } | 414 | } |
409 | __IEEE80211_IF_FILE_W(uapsd_max_sp_len); | 415 | IEEE80211_IF_FILE_RW(uapsd_max_sp_len); |
410 | 416 | ||
411 | /* AP attributes */ | 417 | /* AP attributes */ |
412 | IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); | 418 | IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); |
@@ -419,7 +425,7 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast( | |||
419 | return scnprintf(buf, buflen, "%u\n", | 425 | return scnprintf(buf, buflen, "%u\n", |
420 | skb_queue_len(&sdata->u.ap.ps.bc_buf)); | 426 | skb_queue_len(&sdata->u.ap.ps.bc_buf)); |
421 | } | 427 | } |
422 | __IEEE80211_IF_FILE(num_buffered_multicast, NULL); | 428 | IEEE80211_IF_FILE_R(num_buffered_multicast); |
423 | 429 | ||
424 | /* IBSS attributes */ | 430 | /* IBSS attributes */ |
425 | static ssize_t ieee80211_if_fmt_tsf( | 431 | static ssize_t ieee80211_if_fmt_tsf( |
@@ -468,9 +474,10 @@ static ssize_t ieee80211_if_parse_tsf( | |||
468 | } | 474 | } |
469 | } | 475 | } |
470 | 476 | ||
477 | ieee80211_recalc_dtim(local, sdata); | ||
471 | return buflen; | 478 | return buflen; |
472 | } | 479 | } |
473 | __IEEE80211_IF_FILE_W(tsf); | 480 | IEEE80211_IF_FILE_RW(tsf); |
474 | 481 | ||
475 | 482 | ||
476 | /* WDS attributes */ | 483 | /* WDS attributes */ |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9a8be8f69224..fab7b91923e0 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -479,10 +479,9 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, | |||
479 | vif->type != NL80211_IFTYPE_AP)) | 479 | vif->type != NL80211_IFTYPE_AP)) |
480 | return; | 480 | return; |
481 | 481 | ||
482 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
483 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
484 | |||
485 | if (vif->type == NL80211_IFTYPE_STATION) { | 482 | if (vif->type == NL80211_IFTYPE_STATION) { |
483 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
484 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
486 | if (sdata->u.mgd.driver_smps_mode == smps_mode) | 485 | if (sdata->u.mgd.driver_smps_mode == smps_mode) |
487 | return; | 486 | return; |
488 | sdata->u.mgd.driver_smps_mode = smps_mode; | 487 | sdata->u.mgd.driver_smps_mode = smps_mode; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 953b9e294547..3701930c6649 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1800,6 +1800,8 @@ ieee80211_cs_get(struct ieee80211_local *local, u32 cipher, | |||
1800 | int ieee80211_cs_headroom(struct ieee80211_local *local, | 1800 | int ieee80211_cs_headroom(struct ieee80211_local *local, |
1801 | struct cfg80211_crypto_settings *crypto, | 1801 | struct cfg80211_crypto_settings *crypto, |
1802 | enum nl80211_iftype iftype); | 1802 | enum nl80211_iftype iftype); |
1803 | void ieee80211_recalc_dtim(struct ieee80211_local *local, | ||
1804 | struct ieee80211_sub_if_data *sdata); | ||
1803 | 1805 | ||
1804 | #ifdef CONFIG_MAC80211_NOINLINE | 1806 | #ifdef CONFIG_MAC80211_NOINLINE |
1805 | #define debug_noinline noinline | 1807 | #define debug_noinline noinline |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2bd5b552b2f6..d767cfb9b45f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -846,17 +846,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
846 | /* TODO: consider VHT for RX chains, hopefully it's the same */ | 846 | /* TODO: consider VHT for RX chains, hopefully it's the same */ |
847 | } | 847 | } |
848 | 848 | ||
849 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + | ||
850 | sizeof(void *) * channels, GFP_KERNEL); | ||
851 | if (!local->int_scan_req) | ||
852 | return -ENOMEM; | ||
853 | |||
854 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
855 | if (!local->hw.wiphy->bands[band]) | ||
856 | continue; | ||
857 | local->int_scan_req->rates[band] = (u32) -1; | ||
858 | } | ||
859 | |||
860 | /* if low-level driver supports AP, we also support VLAN */ | 849 | /* if low-level driver supports AP, we also support VLAN */ |
861 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | 850 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { |
862 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | 851 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); |
@@ -880,6 +869,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
880 | return -EINVAL; | 869 | return -EINVAL; |
881 | } | 870 | } |
882 | 871 | ||
872 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + | ||
873 | sizeof(void *) * channels, GFP_KERNEL); | ||
874 | if (!local->int_scan_req) | ||
875 | return -ENOMEM; | ||
876 | |||
877 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
878 | if (!local->hw.wiphy->bands[band]) | ||
879 | continue; | ||
880 | local->int_scan_req->rates[band] = (u32) -1; | ||
881 | } | ||
882 | |||
883 | #ifndef CONFIG_MAC80211_MESH | 883 | #ifndef CONFIG_MAC80211_MESH |
884 | /* mesh depends on Kconfig, but drivers should set it if they want */ | 884 | /* mesh depends on Kconfig, but drivers should set it if they want */ |
885 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | 885 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 5a74b249ba35..5b919cab1de0 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -807,6 +807,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
807 | return -ENOMEM; | 807 | return -ENOMEM; |
808 | } | 808 | } |
809 | 809 | ||
810 | ieee80211_recalc_dtim(local, sdata); | ||
810 | ieee80211_bss_info_change_notify(sdata, changed); | 811 | ieee80211_bss_info_change_notify(sdata, changed); |
811 | 812 | ||
812 | netif_carrier_on(sdata->dev); | 813 | netif_carrier_on(sdata->dev); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index cf83217103f9..e8f60aa2e848 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -437,6 +437,7 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) | |||
437 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); | 437 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); |
438 | 438 | ||
439 | set_sta_flag(sta, WLAN_STA_WME); | 439 | set_sta_flag(sta, WLAN_STA_WME); |
440 | sta->sta.wme = true; | ||
440 | 441 | ||
441 | return sta; | 442 | return sta; |
442 | } | 443 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5a2afe9583a8..c24ca0d0f469 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3076,8 +3076,8 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
3076 | 3076 | ||
3077 | /* main receive path */ | 3077 | /* main receive path */ |
3078 | 3078 | ||
3079 | static int prepare_for_handlers(struct ieee80211_rx_data *rx, | 3079 | static bool prepare_for_handlers(struct ieee80211_rx_data *rx, |
3080 | struct ieee80211_hdr *hdr) | 3080 | struct ieee80211_hdr *hdr) |
3081 | { | 3081 | { |
3082 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 3082 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
3083 | struct sk_buff *skb = rx->skb; | 3083 | struct sk_buff *skb = rx->skb; |
@@ -3088,29 +3088,29 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3088 | switch (sdata->vif.type) { | 3088 | switch (sdata->vif.type) { |
3089 | case NL80211_IFTYPE_STATION: | 3089 | case NL80211_IFTYPE_STATION: |
3090 | if (!bssid && !sdata->u.mgd.use_4addr) | 3090 | if (!bssid && !sdata->u.mgd.use_4addr) |
3091 | return 0; | 3091 | return false; |
3092 | if (!multicast && | 3092 | if (!multicast && |
3093 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3093 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
3094 | if (!(sdata->dev->flags & IFF_PROMISC) || | 3094 | if (!(sdata->dev->flags & IFF_PROMISC) || |
3095 | sdata->u.mgd.use_4addr) | 3095 | sdata->u.mgd.use_4addr) |
3096 | return 0; | 3096 | return false; |
3097 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3097 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
3098 | } | 3098 | } |
3099 | break; | 3099 | break; |
3100 | case NL80211_IFTYPE_ADHOC: | 3100 | case NL80211_IFTYPE_ADHOC: |
3101 | if (!bssid) | 3101 | if (!bssid) |
3102 | return 0; | 3102 | return false; |
3103 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || | 3103 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || |
3104 | ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) | 3104 | ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) |
3105 | return 0; | 3105 | return false; |
3106 | if (ieee80211_is_beacon(hdr->frame_control)) { | 3106 | if (ieee80211_is_beacon(hdr->frame_control)) { |
3107 | return 1; | 3107 | return true; |
3108 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 3108 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
3109 | return 0; | 3109 | return false; |
3110 | } else if (!multicast && | 3110 | } else if (!multicast && |
3111 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3111 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
3112 | if (!(sdata->dev->flags & IFF_PROMISC)) | 3112 | if (!(sdata->dev->flags & IFF_PROMISC)) |
3113 | return 0; | 3113 | return false; |
3114 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3114 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
3115 | } else if (!rx->sta) { | 3115 | } else if (!rx->sta) { |
3116 | int rate_idx; | 3116 | int rate_idx; |
@@ -3126,7 +3126,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3126 | if (!multicast && | 3126 | if (!multicast && |
3127 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3127 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
3128 | if (!(sdata->dev->flags & IFF_PROMISC)) | 3128 | if (!(sdata->dev->flags & IFF_PROMISC)) |
3129 | return 0; | 3129 | return false; |
3130 | 3130 | ||
3131 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3131 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
3132 | } | 3132 | } |
@@ -3135,7 +3135,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3135 | case NL80211_IFTYPE_AP: | 3135 | case NL80211_IFTYPE_AP: |
3136 | if (!bssid) { | 3136 | if (!bssid) { |
3137 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) | 3137 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) |
3138 | return 0; | 3138 | return false; |
3139 | } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { | 3139 | } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { |
3140 | /* | 3140 | /* |
3141 | * Accept public action frames even when the | 3141 | * Accept public action frames even when the |
@@ -3145,26 +3145,26 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3145 | */ | 3145 | */ |
3146 | if (!multicast && | 3146 | if (!multicast && |
3147 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) | 3147 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) |
3148 | return 0; | 3148 | return false; |
3149 | if (ieee80211_is_public_action(hdr, skb->len)) | 3149 | if (ieee80211_is_public_action(hdr, skb->len)) |
3150 | return 1; | 3150 | return true; |
3151 | if (!ieee80211_is_beacon(hdr->frame_control)) | 3151 | if (!ieee80211_is_beacon(hdr->frame_control)) |
3152 | return 0; | 3152 | return false; |
3153 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3153 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
3154 | } | 3154 | } |
3155 | break; | 3155 | break; |
3156 | case NL80211_IFTYPE_WDS: | 3156 | case NL80211_IFTYPE_WDS: |
3157 | if (bssid || !ieee80211_is_data(hdr->frame_control)) | 3157 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
3158 | return 0; | 3158 | return false; |
3159 | if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) | 3159 | if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) |
3160 | return 0; | 3160 | return false; |
3161 | break; | 3161 | break; |
3162 | case NL80211_IFTYPE_P2P_DEVICE: | 3162 | case NL80211_IFTYPE_P2P_DEVICE: |
3163 | if (!ieee80211_is_public_action(hdr, skb->len) && | 3163 | if (!ieee80211_is_public_action(hdr, skb->len) && |
3164 | !ieee80211_is_probe_req(hdr->frame_control) && | 3164 | !ieee80211_is_probe_req(hdr->frame_control) && |
3165 | !ieee80211_is_probe_resp(hdr->frame_control) && | 3165 | !ieee80211_is_probe_resp(hdr->frame_control) && |
3166 | !ieee80211_is_beacon(hdr->frame_control)) | 3166 | !ieee80211_is_beacon(hdr->frame_control)) |
3167 | return 0; | 3167 | return false; |
3168 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) && | 3168 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) && |
3169 | !multicast) | 3169 | !multicast) |
3170 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3170 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
@@ -3175,7 +3175,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3175 | break; | 3175 | break; |
3176 | } | 3176 | } |
3177 | 3177 | ||
3178 | return 1; | 3178 | return true; |
3179 | } | 3179 | } |
3180 | 3180 | ||
3181 | /* | 3181 | /* |
@@ -3191,13 +3191,11 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
3191 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 3191 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
3192 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 3192 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
3193 | struct ieee80211_hdr *hdr = (void *)skb->data; | 3193 | struct ieee80211_hdr *hdr = (void *)skb->data; |
3194 | int prepares; | ||
3195 | 3194 | ||
3196 | rx->skb = skb; | 3195 | rx->skb = skb; |
3197 | status->rx_flags |= IEEE80211_RX_RA_MATCH; | 3196 | status->rx_flags |= IEEE80211_RX_RA_MATCH; |
3198 | prepares = prepare_for_handlers(rx, hdr); | ||
3199 | 3197 | ||
3200 | if (!prepares) | 3198 | if (!prepare_for_handlers(rx, hdr)) |
3201 | return false; | 3199 | return false; |
3202 | 3200 | ||
3203 | if (!consume) { | 3201 | if (!consume) { |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 4576ba0ff221..decd30c1e290 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -300,6 +300,35 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
300 | if (!sta) | 300 | if (!sta) |
301 | return NULL; | 301 | return NULL; |
302 | 302 | ||
303 | rcu_read_lock(); | ||
304 | tx_latency = rcu_dereference(local->tx_latency); | ||
305 | /* init stations Tx latency statistics && TID bins */ | ||
306 | if (tx_latency) { | ||
307 | sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS * | ||
308 | sizeof(struct ieee80211_tx_latency_stat), | ||
309 | GFP_ATOMIC); | ||
310 | if (!sta->tx_lat) { | ||
311 | rcu_read_unlock(); | ||
312 | goto free; | ||
313 | } | ||
314 | |||
315 | if (tx_latency->n_ranges) { | ||
316 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | ||
317 | /* size of bins is size of the ranges +1 */ | ||
318 | sta->tx_lat[i].bin_count = | ||
319 | tx_latency->n_ranges + 1; | ||
320 | sta->tx_lat[i].bins = | ||
321 | kcalloc(sta->tx_lat[i].bin_count, | ||
322 | sizeof(u32), GFP_ATOMIC); | ||
323 | if (!sta->tx_lat[i].bins) { | ||
324 | rcu_read_unlock(); | ||
325 | goto free; | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | rcu_read_unlock(); | ||
331 | |||
303 | spin_lock_init(&sta->lock); | 332 | spin_lock_init(&sta->lock); |
304 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 333 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
305 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 334 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
@@ -324,10 +353,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
324 | for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) | 353 | for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) |
325 | ewma_init(&sta->chain_signal_avg[i], 1024, 8); | 354 | ewma_init(&sta->chain_signal_avg[i], 1024, 8); |
326 | 355 | ||
327 | if (sta_prepare_rate_control(local, sta, gfp)) { | 356 | if (sta_prepare_rate_control(local, sta, gfp)) |
328 | kfree(sta); | 357 | goto free; |
329 | return NULL; | ||
330 | } | ||
331 | 358 | ||
332 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 359 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
333 | /* | 360 | /* |
@@ -371,34 +398,17 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
371 | } | 398 | } |
372 | } | 399 | } |
373 | 400 | ||
374 | rcu_read_lock(); | ||
375 | |||
376 | tx_latency = rcu_dereference(local->tx_latency); | ||
377 | /* init stations Tx latency statistics && TID bins */ | ||
378 | if (tx_latency) | ||
379 | sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS * | ||
380 | sizeof(struct ieee80211_tx_latency_stat), | ||
381 | GFP_ATOMIC); | ||
382 | |||
383 | /* | ||
384 | * if Tx latency and bins are enabled and the previous allocation | ||
385 | * succeeded | ||
386 | */ | ||
387 | if (tx_latency && tx_latency->n_ranges && sta->tx_lat) | ||
388 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | ||
389 | /* size of bins is size of the ranges +1 */ | ||
390 | sta->tx_lat[i].bin_count = | ||
391 | tx_latency->n_ranges + 1; | ||
392 | sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count, | ||
393 | sizeof(u32), | ||
394 | GFP_ATOMIC); | ||
395 | } | ||
396 | |||
397 | rcu_read_unlock(); | ||
398 | |||
399 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); | 401 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); |
400 | |||
401 | return sta; | 402 | return sta; |
403 | |||
404 | free: | ||
405 | if (sta->tx_lat) { | ||
406 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | ||
407 | kfree(sta->tx_lat[i].bins); | ||
408 | kfree(sta->tx_lat); | ||
409 | } | ||
410 | kfree(sta); | ||
411 | return NULL; | ||
402 | } | 412 | } |
403 | 413 | ||
404 | static int sta_info_insert_check(struct sta_info *sta) | 414 | static int sta_info_insert_check(struct sta_info *sta) |
@@ -1143,7 +1153,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1143 | 1153 | ||
1144 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | 1154 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, |
1145 | struct sta_info *sta, int tid, | 1155 | struct sta_info *sta, int tid, |
1146 | enum ieee80211_frame_release_type reason) | 1156 | enum ieee80211_frame_release_type reason, |
1157 | bool call_driver) | ||
1147 | { | 1158 | { |
1148 | struct ieee80211_local *local = sdata->local; | 1159 | struct ieee80211_local *local = sdata->local; |
1149 | struct ieee80211_qos_hdr *nullfunc; | 1160 | struct ieee80211_qos_hdr *nullfunc; |
@@ -1201,7 +1212,9 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1201 | IEEE80211_TX_STATUS_EOSP | | 1212 | IEEE80211_TX_STATUS_EOSP | |
1202 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 1213 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
1203 | 1214 | ||
1204 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); | 1215 | if (call_driver) |
1216 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, | ||
1217 | reason, false); | ||
1205 | 1218 | ||
1206 | skb->dev = sdata->dev; | 1219 | skb->dev = sdata->dev; |
1207 | 1220 | ||
@@ -1217,6 +1230,17 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1217 | rcu_read_unlock(); | 1230 | rcu_read_unlock(); |
1218 | } | 1231 | } |
1219 | 1232 | ||
1233 | static int find_highest_prio_tid(unsigned long tids) | ||
1234 | { | ||
1235 | /* lower 3 TIDs aren't ordered perfectly */ | ||
1236 | if (tids & 0xF8) | ||
1237 | return fls(tids) - 1; | ||
1238 | /* TID 0 is BE just like TID 3 */ | ||
1239 | if (tids & BIT(0)) | ||
1240 | return 0; | ||
1241 | return fls(tids) - 1; | ||
1242 | } | ||
1243 | |||
1220 | static void | 1244 | static void |
1221 | ieee80211_sta_ps_deliver_response(struct sta_info *sta, | 1245 | ieee80211_sta_ps_deliver_response(struct sta_info *sta, |
1222 | int n_frames, u8 ignored_acs, | 1246 | int n_frames, u8 ignored_acs, |
@@ -1224,7 +1248,6 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1224 | { | 1248 | { |
1225 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1249 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1226 | struct ieee80211_local *local = sdata->local; | 1250 | struct ieee80211_local *local = sdata->local; |
1227 | bool found = false; | ||
1228 | bool more_data = false; | 1251 | bool more_data = false; |
1229 | int ac; | 1252 | int ac; |
1230 | unsigned long driver_release_tids = 0; | 1253 | unsigned long driver_release_tids = 0; |
@@ -1235,9 +1258,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1235 | 1258 | ||
1236 | __skb_queue_head_init(&frames); | 1259 | __skb_queue_head_init(&frames); |
1237 | 1260 | ||
1238 | /* | 1261 | /* Get response frame(s) and more data bit for the last one. */ |
1239 | * Get response frame(s) and more data bit for it. | ||
1240 | */ | ||
1241 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 1262 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
1242 | unsigned long tids; | 1263 | unsigned long tids; |
1243 | 1264 | ||
@@ -1246,43 +1267,48 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1246 | 1267 | ||
1247 | tids = ieee80211_tids_for_ac(ac); | 1268 | tids = ieee80211_tids_for_ac(ac); |
1248 | 1269 | ||
1249 | if (!found) { | 1270 | /* if we already have frames from software, then we can't also |
1250 | driver_release_tids = sta->driver_buffered_tids & tids; | 1271 | * release from hardware queues |
1251 | if (driver_release_tids) { | 1272 | */ |
1252 | found = true; | 1273 | if (skb_queue_empty(&frames)) |
1253 | } else { | 1274 | driver_release_tids |= sta->driver_buffered_tids & tids; |
1254 | struct sk_buff *skb; | ||
1255 | |||
1256 | while (n_frames > 0) { | ||
1257 | skb = skb_dequeue(&sta->tx_filtered[ac]); | ||
1258 | if (!skb) { | ||
1259 | skb = skb_dequeue( | ||
1260 | &sta->ps_tx_buf[ac]); | ||
1261 | if (skb) | ||
1262 | local->total_ps_buffered--; | ||
1263 | } | ||
1264 | if (!skb) | ||
1265 | break; | ||
1266 | n_frames--; | ||
1267 | found = true; | ||
1268 | __skb_queue_tail(&frames, skb); | ||
1269 | } | ||
1270 | } | ||
1271 | 1275 | ||
1272 | /* | 1276 | if (driver_release_tids) { |
1273 | * If the driver has data on more than one TID then | 1277 | /* If the driver has data on more than one TID then |
1274 | * certainly there's more data if we release just a | 1278 | * certainly there's more data if we release just a |
1275 | * single frame now (from a single TID). | 1279 | * single frame now (from a single TID). This will |
1280 | * only happen for PS-Poll. | ||
1276 | */ | 1281 | */ |
1277 | if (reason == IEEE80211_FRAME_RELEASE_PSPOLL && | 1282 | if (reason == IEEE80211_FRAME_RELEASE_PSPOLL && |
1278 | hweight16(driver_release_tids) > 1) { | 1283 | hweight16(driver_release_tids) > 1) { |
1279 | more_data = true; | 1284 | more_data = true; |
1280 | driver_release_tids = | 1285 | driver_release_tids = |
1281 | BIT(ffs(driver_release_tids) - 1); | 1286 | BIT(find_highest_prio_tid( |
1287 | driver_release_tids)); | ||
1282 | break; | 1288 | break; |
1283 | } | 1289 | } |
1290 | } else { | ||
1291 | struct sk_buff *skb; | ||
1292 | |||
1293 | while (n_frames > 0) { | ||
1294 | skb = skb_dequeue(&sta->tx_filtered[ac]); | ||
1295 | if (!skb) { | ||
1296 | skb = skb_dequeue( | ||
1297 | &sta->ps_tx_buf[ac]); | ||
1298 | if (skb) | ||
1299 | local->total_ps_buffered--; | ||
1300 | } | ||
1301 | if (!skb) | ||
1302 | break; | ||
1303 | n_frames--; | ||
1304 | __skb_queue_tail(&frames, skb); | ||
1305 | } | ||
1284 | } | 1306 | } |
1285 | 1307 | ||
1308 | /* If we have more frames buffered on this AC, then set the | ||
1309 | * more-data bit and abort the loop since we can't send more | ||
1310 | * data from other ACs before the buffered frames from this. | ||
1311 | */ | ||
1286 | if (!skb_queue_empty(&sta->tx_filtered[ac]) || | 1312 | if (!skb_queue_empty(&sta->tx_filtered[ac]) || |
1287 | !skb_queue_empty(&sta->ps_tx_buf[ac])) { | 1313 | !skb_queue_empty(&sta->ps_tx_buf[ac])) { |
1288 | more_data = true; | 1314 | more_data = true; |
@@ -1290,7 +1316,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1290 | } | 1316 | } |
1291 | } | 1317 | } |
1292 | 1318 | ||
1293 | if (!found) { | 1319 | if (skb_queue_empty(&frames) && !driver_release_tids) { |
1294 | int tid; | 1320 | int tid; |
1295 | 1321 | ||
1296 | /* | 1322 | /* |
@@ -1311,15 +1337,13 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1311 | /* This will evaluate to 1, 3, 5 or 7. */ | 1337 | /* This will evaluate to 1, 3, 5 or 7. */ |
1312 | tid = 7 - ((ffs(~ignored_acs) - 1) << 1); | 1338 | tid = 7 - ((ffs(~ignored_acs) - 1) << 1); |
1313 | 1339 | ||
1314 | ieee80211_send_null_response(sdata, sta, tid, reason); | 1340 | ieee80211_send_null_response(sdata, sta, tid, reason, true); |
1315 | return; | 1341 | } else if (!driver_release_tids) { |
1316 | } | ||
1317 | |||
1318 | if (!driver_release_tids) { | ||
1319 | struct sk_buff_head pending; | 1342 | struct sk_buff_head pending; |
1320 | struct sk_buff *skb; | 1343 | struct sk_buff *skb; |
1321 | int num = 0; | 1344 | int num = 0; |
1322 | u16 tids = 0; | 1345 | u16 tids = 0; |
1346 | bool need_null = false; | ||
1323 | 1347 | ||
1324 | skb_queue_head_init(&pending); | 1348 | skb_queue_head_init(&pending); |
1325 | 1349 | ||
@@ -1353,22 +1377,57 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1353 | ieee80211_is_qos_nullfunc(hdr->frame_control)) | 1377 | ieee80211_is_qos_nullfunc(hdr->frame_control)) |
1354 | qoshdr = ieee80211_get_qos_ctl(hdr); | 1378 | qoshdr = ieee80211_get_qos_ctl(hdr); |
1355 | 1379 | ||
1356 | /* end service period after last frame */ | 1380 | tids |= BIT(skb->priority); |
1357 | if (skb_queue_empty(&frames)) { | 1381 | |
1358 | if (reason == IEEE80211_FRAME_RELEASE_UAPSD && | 1382 | __skb_queue_tail(&pending, skb); |
1359 | qoshdr) | 1383 | |
1360 | *qoshdr |= IEEE80211_QOS_CTL_EOSP; | 1384 | /* end service period after last frame or add one */ |
1385 | if (!skb_queue_empty(&frames)) | ||
1386 | continue; | ||
1361 | 1387 | ||
1388 | if (reason != IEEE80211_FRAME_RELEASE_UAPSD) { | ||
1389 | /* for PS-Poll, there's only one frame */ | ||
1362 | info->flags |= IEEE80211_TX_STATUS_EOSP | | 1390 | info->flags |= IEEE80211_TX_STATUS_EOSP | |
1363 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 1391 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
1392 | break; | ||
1364 | } | 1393 | } |
1365 | 1394 | ||
1366 | if (qoshdr) | 1395 | /* For uAPSD, things are a bit more complicated. If the |
1367 | tids |= BIT(*qoshdr & IEEE80211_QOS_CTL_TID_MASK); | 1396 | * last frame has a QoS header (i.e. is a QoS-data or |
1368 | else | 1397 | * QoS-nulldata frame) then just set the EOSP bit there |
1369 | tids |= BIT(0); | 1398 | * and be done. |
1399 | * If the frame doesn't have a QoS header (which means | ||
1400 | * it should be a bufferable MMPDU) then we can't set | ||
1401 | * the EOSP bit in the QoS header; add a QoS-nulldata | ||
1402 | * frame to the list to send it after the MMPDU. | ||
1403 | * | ||
1404 | * Note that this code is only in the mac80211-release | ||
1405 | * code path, we assume that the driver will not buffer | ||
1406 | * anything but QoS-data frames, or if it does, will | ||
1407 | * create the QoS-nulldata frame by itself if needed. | ||
1408 | * | ||
1409 | * Cf. 802.11-2012 10.2.1.10 (c). | ||
1410 | */ | ||
1411 | if (qoshdr) { | ||
1412 | *qoshdr |= IEEE80211_QOS_CTL_EOSP; | ||
1370 | 1413 | ||
1371 | __skb_queue_tail(&pending, skb); | 1414 | info->flags |= IEEE80211_TX_STATUS_EOSP | |
1415 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1416 | } else { | ||
1417 | /* The standard isn't completely clear on this | ||
1418 | * as it says the more-data bit should be set | ||
1419 | * if there are more BUs. The QoS-Null frame | ||
1420 | * we're about to send isn't buffered yet, we | ||
1421 | * only create it below, but let's pretend it | ||
1422 | * was buffered just in case some clients only | ||
1423 | * expect more-data=0 when eosp=1. | ||
1424 | */ | ||
1425 | hdr->frame_control |= | ||
1426 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
1427 | need_null = true; | ||
1428 | num++; | ||
1429 | } | ||
1430 | break; | ||
1372 | } | 1431 | } |
1373 | 1432 | ||
1374 | drv_allow_buffered_frames(local, sta, tids, num, | 1433 | drv_allow_buffered_frames(local, sta, tids, num, |
@@ -1376,17 +1435,22 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1376 | 1435 | ||
1377 | ieee80211_add_pending_skbs(local, &pending); | 1436 | ieee80211_add_pending_skbs(local, &pending); |
1378 | 1437 | ||
1438 | if (need_null) | ||
1439 | ieee80211_send_null_response( | ||
1440 | sdata, sta, find_highest_prio_tid(tids), | ||
1441 | reason, false); | ||
1442 | |||
1379 | sta_info_recalc_tim(sta); | 1443 | sta_info_recalc_tim(sta); |
1380 | } else { | 1444 | } else { |
1381 | /* | 1445 | /* |
1382 | * We need to release a frame that is buffered somewhere in the | 1446 | * We need to release a frame that is buffered somewhere in the |
1383 | * driver ... it'll have to handle that. | 1447 | * driver ... it'll have to handle that. |
1384 | * Note that, as per the comment above, it'll also have to see | 1448 | * Note that the driver also has to check the number of frames |
1385 | * if there is more than just one frame on the specific TID that | 1449 | * on the TIDs we're releasing from - if there are more than |
1386 | * we're releasing from, and it needs to set the more-data bit | 1450 | * n_frames it has to set the more-data bit (if we didn't ask |
1387 | * accordingly if we tell it that there's no more data. If we do | 1451 | * it to set it anyway due to other buffered frames); if there |
1388 | * tell it there's more data, then of course the more-data bit | 1452 | * are fewer than n_frames it has to make sure to adjust that |
1389 | * needs to be set anyway. | 1453 | * to allow the service period to end properly. |
1390 | */ | 1454 | */ |
1391 | drv_release_buffered_frames(local, sta, driver_release_tids, | 1455 | drv_release_buffered_frames(local, sta, driver_release_tids, |
1392 | n_frames, reason, more_data); | 1456 | n_frames, reason, more_data); |
@@ -1394,9 +1458,9 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1394 | /* | 1458 | /* |
1395 | * Note that we don't recalculate the TIM bit here as it would | 1459 | * Note that we don't recalculate the TIM bit here as it would |
1396 | * most likely have no effect at all unless the driver told us | 1460 | * most likely have no effect at all unless the driver told us |
1397 | * that the TID became empty before returning here from the | 1461 | * that the TID(s) became empty before returning here from the |
1398 | * release function. | 1462 | * release function. |
1399 | * Either way, however, when the driver tells us that the TID | 1463 | * Either way, however, when the driver tells us that the TID(s) |
1400 | * became empty we'll do the TIM recalculation. | 1464 | * became empty we'll do the TIM recalculation. |
1401 | */ | 1465 | */ |
1402 | } | 1466 | } |
@@ -1485,6 +1549,8 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | |||
1485 | if (WARN_ON(tid >= IEEE80211_NUM_TIDS)) | 1549 | if (WARN_ON(tid >= IEEE80211_NUM_TIDS)) |
1486 | return; | 1550 | return; |
1487 | 1551 | ||
1552 | trace_api_sta_set_buffered(sta->local, pubsta, tid, buffered); | ||
1553 | |||
1488 | if (buffered) | 1554 | if (buffered) |
1489 | set_bit(tid, &sta->driver_buffered_tids); | 1555 | set_bit(tid, &sta->driver_buffered_tids); |
1490 | else | 1556 | else |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index da9366632f37..a0b0aea76525 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -1835,6 +1835,33 @@ TRACE_EVENT(api_eosp, | |||
1835 | ) | 1835 | ) |
1836 | ); | 1836 | ); |
1837 | 1837 | ||
1838 | TRACE_EVENT(api_sta_set_buffered, | ||
1839 | TP_PROTO(struct ieee80211_local *local, | ||
1840 | struct ieee80211_sta *sta, | ||
1841 | u8 tid, bool buffered), | ||
1842 | |||
1843 | TP_ARGS(local, sta, tid, buffered), | ||
1844 | |||
1845 | TP_STRUCT__entry( | ||
1846 | LOCAL_ENTRY | ||
1847 | STA_ENTRY | ||
1848 | __field(u8, tid) | ||
1849 | __field(bool, buffered) | ||
1850 | ), | ||
1851 | |||
1852 | TP_fast_assign( | ||
1853 | LOCAL_ASSIGN; | ||
1854 | STA_ASSIGN; | ||
1855 | __entry->tid = tid; | ||
1856 | __entry->buffered = buffered; | ||
1857 | ), | ||
1858 | |||
1859 | TP_printk( | ||
1860 | LOCAL_PR_FMT STA_PR_FMT " tid:%d buffered:%d", | ||
1861 | LOCAL_PR_ARG, STA_PR_ARG, __entry->tid, __entry->buffered | ||
1862 | ) | ||
1863 | ); | ||
1864 | |||
1838 | /* | 1865 | /* |
1839 | * Tracing for internal functions | 1866 | * Tracing for internal functions |
1840 | * (which may also be called in response to driver calls) | 1867 | * (which may also be called in response to driver calls) |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ef3555e16cf9..27c990bf2320 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -490,6 +490,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
490 | info->control.jiffies = jiffies; | 490 | info->control.jiffies = jiffies; |
491 | info->control.vif = &tx->sdata->vif; | 491 | info->control.vif = &tx->sdata->vif; |
492 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 492 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
493 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
493 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); | 494 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
494 | 495 | ||
495 | if (!timer_pending(&local->sta_cleanup)) | 496 | if (!timer_pending(&local->sta_cleanup)) |
@@ -1076,6 +1077,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1076 | queued = true; | 1077 | queued = true; |
1077 | info->control.vif = &tx->sdata->vif; | 1078 | info->control.vif = &tx->sdata->vif; |
1078 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1079 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1080 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
1079 | __skb_queue_tail(&tid_tx->pending, skb); | 1081 | __skb_queue_tail(&tid_tx->pending, skb); |
1080 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) | 1082 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) |
1081 | purge_skb = __skb_dequeue(&tid_tx->pending); | 1083 | purge_skb = __skb_dequeue(&tid_tx->pending); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index df00f1978a77..676dc0967f37 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2734,3 +2734,44 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr, | |||
2734 | return ret; | 2734 | return ret; |
2735 | } | 2735 | } |
2736 | EXPORT_SYMBOL(ieee80211_parse_p2p_noa); | 2736 | EXPORT_SYMBOL(ieee80211_parse_p2p_noa); |
2737 | |||
2738 | void ieee80211_recalc_dtim(struct ieee80211_local *local, | ||
2739 | struct ieee80211_sub_if_data *sdata) | ||
2740 | { | ||
2741 | u64 tsf = drv_get_tsf(local, sdata); | ||
2742 | u64 dtim_count = 0; | ||
2743 | u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; | ||
2744 | u8 dtim_period = sdata->vif.bss_conf.dtim_period; | ||
2745 | struct ps_data *ps; | ||
2746 | u8 bcns_from_dtim; | ||
2747 | |||
2748 | if (tsf == -1ULL || !beacon_int || !dtim_period) | ||
2749 | return; | ||
2750 | |||
2751 | if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
2752 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
2753 | if (!sdata->bss) | ||
2754 | return; | ||
2755 | |||
2756 | ps = &sdata->bss->ps; | ||
2757 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
2758 | ps = &sdata->u.mesh.ps; | ||
2759 | } else { | ||
2760 | return; | ||
2761 | } | ||
2762 | |||
2763 | /* | ||
2764 | * actually finds last dtim_count, mac80211 will update in | ||
2765 | * __beacon_add_tim(). | ||
2766 | * dtim_count = dtim_period - (tsf / bcn_int) % dtim_period | ||
2767 | */ | ||
2768 | do_div(tsf, beacon_int); | ||
2769 | bcns_from_dtim = do_div(tsf, dtim_period); | ||
2770 | /* just had a DTIM */ | ||
2771 | if (!bcns_from_dtim) | ||
2772 | dtim_count = 0; | ||
2773 | else | ||
2774 | dtim_count = dtim_period - bcns_from_dtim; | ||
2775 | |||
2776 | ps->dtim_count = dtim_count; | ||
2777 | } | ||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 7313d379c0d3..21448d629b15 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -127,7 +127,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
127 | * APs with pairwise keys should never receive Michael MIC | 127 | * APs with pairwise keys should never receive Michael MIC |
128 | * errors for non-zero keyidx because these are reserved for | 128 | * errors for non-zero keyidx because these are reserved for |
129 | * group keys and only the AP is sending real multicast | 129 | * group keys and only the AP is sending real multicast |
130 | * frames in the BSS. ( | 130 | * frames in the BSS. |
131 | */ | 131 | */ |
132 | return RX_DROP_UNUSABLE; | 132 | return RX_DROP_UNUSABLE; |
133 | } | 133 | } |