aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-04-10 10:39:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-10 10:39:27 -0400
commitd3641409a05dcb8e28116bb2ad638f5a42805d9d (patch)
tree1d43a5e0129709502edb631a4fd66de369ee5620 /net/mac80211
parent953c96e0d85615d1ab1f100e525d376053294dc2 (diff)
parent6fe5468f452c0c40348ebd4e737758a842286ca8 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/rt2x00/rt2x00pci.c net/mac80211/sta_info.c net/wireless/core.h
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c29
-rw-r--r--net/mac80211/debugfs_key.c10
-rw-r--r--net/mac80211/debugfs_netdev.c22
-rw-r--r--net/mac80211/driver-ops.h60
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/iface.c17
-rw-r--r--net/mac80211/key.c129
-rw-r--r--net/mac80211/key.h15
-rw-r--r--net/mac80211/main.c22
-rw-r--r--net/mac80211/mesh.c5
-rw-r--r--net/mac80211/mlme.c12
-rw-r--r--net/mac80211/offchannel.c8
-rw-r--r--net/mac80211/pm.c6
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c24
-rw-r--r--net/mac80211/scan.c7
-rw-r--r--net/mac80211/sta_info.c54
-rw-r--r--net/mac80211/sta_info.h9
-rw-r--r--net/mac80211/trace.h35
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/util.c48
20 files changed, 314 insertions, 217 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c34e6d78a592..c50c19402588 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
175 * add it to the device after the station. 175 * add it to the device after the station.
176 */ 176 */
177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { 177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
178 ieee80211_key_free(sdata->local, key); 178 ieee80211_key_free_unused(key);
179 err = -ENOENT; 179 err = -ENOENT;
180 goto out_unlock; 180 goto out_unlock;
181 } 181 }
@@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
214 } 214 }
215 215
216 err = ieee80211_key_link(key, sdata, sta); 216 err = ieee80211_key_link(key, sdata, sta);
217 if (err)
218 ieee80211_key_free(sdata->local, key);
219 217
220 out_unlock: 218 out_unlock:
221 mutex_unlock(&sdata->local->sta_mtx); 219 mutex_unlock(&sdata->local->sta_mtx);
@@ -254,7 +252,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
254 goto out_unlock; 252 goto out_unlock;
255 } 253 }
256 254
257 __ieee80211_key_free(key, true); 255 ieee80211_key_free(key, true);
258 256
259 ret = 0; 257 ret = 0;
260 out_unlock: 258 out_unlock:
@@ -445,12 +443,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
445 struct ieee80211_sub_if_data *sdata = sta->sdata; 443 struct ieee80211_sub_if_data *sdata = sta->sdata;
446 struct ieee80211_local *local = sdata->local; 444 struct ieee80211_local *local = sdata->local;
447 struct timespec uptime; 445 struct timespec uptime;
446 u64 packets = 0;
447 int ac;
448 448
449 sinfo->generation = sdata->local->sta_generation; 449 sinfo->generation = sdata->local->sta_generation;
450 450
451 sinfo->filled = STATION_INFO_INACTIVE_TIME | 451 sinfo->filled = STATION_INFO_INACTIVE_TIME |
452 STATION_INFO_RX_BYTES | 452 STATION_INFO_RX_BYTES64 |
453 STATION_INFO_TX_BYTES | 453 STATION_INFO_TX_BYTES64 |
454 STATION_INFO_RX_PACKETS | 454 STATION_INFO_RX_PACKETS |
455 STATION_INFO_TX_PACKETS | 455 STATION_INFO_TX_PACKETS |
456 STATION_INFO_TX_RETRIES | 456 STATION_INFO_TX_RETRIES |
@@ -467,10 +467,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
467 sinfo->connected_time = uptime.tv_sec - sta->last_connected; 467 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
468 468
469 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 469 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
470 sinfo->tx_bytes = 0;
471 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
472 sinfo->tx_bytes += sta->tx_bytes[ac];
473 packets += sta->tx_packets[ac];
474 }
475 sinfo->tx_packets = packets;
470 sinfo->rx_bytes = sta->rx_bytes; 476 sinfo->rx_bytes = sta->rx_bytes;
471 sinfo->tx_bytes = sta->tx_bytes;
472 sinfo->rx_packets = sta->rx_packets; 477 sinfo->rx_packets = sta->rx_packets;
473 sinfo->tx_packets = sta->tx_packets;
474 sinfo->tx_retries = sta->tx_retry_count; 478 sinfo->tx_retries = sta->tx_retry_count;
475 sinfo->tx_failed = sta->tx_retry_failed; 479 sinfo->tx_failed = sta->tx_retry_failed;
476 sinfo->rx_dropped_misc = sta->rx_dropped; 480 sinfo->rx_dropped_misc = sta->rx_dropped;
@@ -598,8 +602,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
598 data[i++] += sta->rx_fragments; \ 602 data[i++] += sta->rx_fragments; \
599 data[i++] += sta->rx_dropped; \ 603 data[i++] += sta->rx_dropped; \
600 \ 604 \
601 data[i++] += sta->tx_packets; \ 605 data[i++] += sinfo.tx_packets; \
602 data[i++] += sta->tx_bytes; \ 606 data[i++] += sinfo.tx_bytes; \
603 data[i++] += sta->tx_fragments; \ 607 data[i++] += sta->tx_fragments; \
604 data[i++] += sta->tx_filtered_count; \ 608 data[i++] += sta->tx_filtered_count; \
605 data[i++] += sta->tx_retry_failed; \ 609 data[i++] += sta->tx_retry_failed; \
@@ -621,13 +625,14 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
621 if (!(sta && !WARN_ON(sta->sdata->dev != dev))) 625 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
622 goto do_survey; 626 goto do_survey;
623 627
628 sinfo.filled = 0;
629 sta_set_sinfo(sta, &sinfo);
630
624 i = 0; 631 i = 0;
625 ADD_STA_STATS(sta); 632 ADD_STA_STATS(sta);
626 633
627 data[i++] = sta->sta_state; 634 data[i++] = sta->sta_state;
628 635
629 sinfo.filled = 0;
630 sta_set_sinfo(sta, &sinfo);
631 636
632 if (sinfo.filled & STATION_INFO_TX_BITRATE) 637 if (sinfo.filled & STATION_INFO_TX_BITRATE)
633 data[i] = 100000 * 638 data[i] = 100000 *
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index c3a3082b72e5..1521cabad3d6 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -295,7 +295,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
295 char buf[50]; 295 char buf[50];
296 struct ieee80211_key *key; 296 struct ieee80211_key *key;
297 297
298 if (!sdata->debugfs.dir) 298 if (!sdata->vif.debugfs_dir)
299 return; 299 return;
300 300
301 lockdep_assert_held(&sdata->local->key_mtx); 301 lockdep_assert_held(&sdata->local->key_mtx);
@@ -311,7 +311,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
311 sprintf(buf, "../keys/%d", key->debugfs.cnt); 311 sprintf(buf, "../keys/%d", key->debugfs.cnt);
312 sdata->debugfs.default_unicast_key = 312 sdata->debugfs.default_unicast_key =
313 debugfs_create_symlink("default_unicast_key", 313 debugfs_create_symlink("default_unicast_key",
314 sdata->debugfs.dir, buf); 314 sdata->vif.debugfs_dir, buf);
315 } 315 }
316 316
317 if (sdata->debugfs.default_multicast_key) { 317 if (sdata->debugfs.default_multicast_key) {
@@ -325,7 +325,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
325 sprintf(buf, "../keys/%d", key->debugfs.cnt); 325 sprintf(buf, "../keys/%d", key->debugfs.cnt);
326 sdata->debugfs.default_multicast_key = 326 sdata->debugfs.default_multicast_key =
327 debugfs_create_symlink("default_multicast_key", 327 debugfs_create_symlink("default_multicast_key",
328 sdata->debugfs.dir, buf); 328 sdata->vif.debugfs_dir, buf);
329 } 329 }
330} 330}
331 331
@@ -334,7 +334,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
334 char buf[50]; 334 char buf[50];
335 struct ieee80211_key *key; 335 struct ieee80211_key *key;
336 336
337 if (!sdata->debugfs.dir) 337 if (!sdata->vif.debugfs_dir)
338 return; 338 return;
339 339
340 key = key_mtx_dereference(sdata->local, 340 key = key_mtx_dereference(sdata->local,
@@ -343,7 +343,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
343 sprintf(buf, "../keys/%d", key->debugfs.cnt); 343 sprintf(buf, "../keys/%d", key->debugfs.cnt);
344 sdata->debugfs.default_mgmt_key = 344 sdata->debugfs.default_mgmt_key =
345 debugfs_create_symlink("default_mgmt_key", 345 debugfs_create_symlink("default_mgmt_key",
346 sdata->debugfs.dir, buf); 346 sdata->vif.debugfs_dir, buf);
347 } else 347 } else
348 ieee80211_debugfs_key_remove_mgmt_default(sdata); 348 ieee80211_debugfs_key_remove_mgmt_default(sdata);
349} 349}
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 059bbb82e84f..ddb426867904 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -521,7 +521,7 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
521#endif 521#endif
522 522
523#define DEBUGFS_ADD_MODE(name, mode) \ 523#define DEBUGFS_ADD_MODE(name, mode) \
524 debugfs_create_file(#name, mode, sdata->debugfs.dir, \ 524 debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
525 sdata, &name##_ops); 525 sdata, &name##_ops);
526 526
527#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400) 527#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
@@ -577,7 +577,7 @@ static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
577static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) 577static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
578{ 578{
579 struct dentry *dir = debugfs_create_dir("mesh_stats", 579 struct dentry *dir = debugfs_create_dir("mesh_stats",
580 sdata->debugfs.dir); 580 sdata->vif.debugfs_dir);
581#define MESHSTATS_ADD(name)\ 581#define MESHSTATS_ADD(name)\
582 debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); 582 debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
583 583
@@ -594,7 +594,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
594static void add_mesh_config(struct ieee80211_sub_if_data *sdata) 594static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
595{ 595{
596 struct dentry *dir = debugfs_create_dir("mesh_config", 596 struct dentry *dir = debugfs_create_dir("mesh_config",
597 sdata->debugfs.dir); 597 sdata->vif.debugfs_dir);
598 598
599#define MESHPARAMS_ADD(name) \ 599#define MESHPARAMS_ADD(name) \
600 debugfs_create_file(#name, 0600, dir, sdata, &name##_ops); 600 debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
@@ -631,7 +631,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
631 631
632static void add_files(struct ieee80211_sub_if_data *sdata) 632static void add_files(struct ieee80211_sub_if_data *sdata)
633{ 633{
634 if (!sdata->debugfs.dir) 634 if (!sdata->vif.debugfs_dir)
635 return; 635 return;
636 636
637 DEBUGFS_ADD(flags); 637 DEBUGFS_ADD(flags);
@@ -673,21 +673,21 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
673 char buf[10+IFNAMSIZ]; 673 char buf[10+IFNAMSIZ];
674 674
675 sprintf(buf, "netdev:%s", sdata->name); 675 sprintf(buf, "netdev:%s", sdata->name);
676 sdata->debugfs.dir = debugfs_create_dir(buf, 676 sdata->vif.debugfs_dir = debugfs_create_dir(buf,
677 sdata->local->hw.wiphy->debugfsdir); 677 sdata->local->hw.wiphy->debugfsdir);
678 if (sdata->debugfs.dir) 678 if (sdata->vif.debugfs_dir)
679 sdata->debugfs.subdir_stations = debugfs_create_dir("stations", 679 sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
680 sdata->debugfs.dir); 680 sdata->vif.debugfs_dir);
681 add_files(sdata); 681 add_files(sdata);
682} 682}
683 683
684void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) 684void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
685{ 685{
686 if (!sdata->debugfs.dir) 686 if (!sdata->vif.debugfs_dir)
687 return; 687 return;
688 688
689 debugfs_remove_recursive(sdata->debugfs.dir); 689 debugfs_remove_recursive(sdata->vif.debugfs_dir);
690 sdata->debugfs.dir = NULL; 690 sdata->vif.debugfs_dir = NULL;
691} 691}
692 692
693void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) 693void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
@@ -695,7 +695,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
695 struct dentry *dir; 695 struct dentry *dir;
696 char buf[10 + IFNAMSIZ]; 696 char buf[10 + IFNAMSIZ];
697 697
698 dir = sdata->debugfs.dir; 698 dir = sdata->vif.debugfs_dir;
699 699
700 if (!dir) 700 if (!dir)
701 return; 701 return;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 832acea4a5cb..169664c122e2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -241,6 +241,22 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
241 return ret; 241 return ret;
242} 242}
243 243
244static inline void drv_set_multicast_list(struct ieee80211_local *local,
245 struct ieee80211_sub_if_data *sdata,
246 struct netdev_hw_addr_list *mc_list)
247{
248 bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
249
250 trace_drv_set_multicast_list(local, sdata, mc_list->count);
251
252 check_sdata_in_driver(sdata);
253
254 if (local->ops->set_multicast_list)
255 local->ops->set_multicast_list(&local->hw, &sdata->vif,
256 allmulti, mc_list);
257 trace_drv_return_void(local);
258}
259
244static inline void drv_configure_filter(struct ieee80211_local *local, 260static inline void drv_configure_filter(struct ieee80211_local *local,
245 unsigned int changed_flags, 261 unsigned int changed_flags,
246 unsigned int *total_flags, 262 unsigned int *total_flags,
@@ -531,43 +547,6 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
531 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, 547 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
532 sta, dir); 548 sta, dir);
533} 549}
534
535static inline
536void drv_add_interface_debugfs(struct ieee80211_local *local,
537 struct ieee80211_sub_if_data *sdata)
538{
539 might_sleep();
540
541 check_sdata_in_driver(sdata);
542
543 if (!local->ops->add_interface_debugfs)
544 return;
545
546 local->ops->add_interface_debugfs(&local->hw, &sdata->vif,
547 sdata->debugfs.dir);
548}
549
550static inline
551void drv_remove_interface_debugfs(struct ieee80211_local *local,
552 struct ieee80211_sub_if_data *sdata)
553{
554 might_sleep();
555
556 check_sdata_in_driver(sdata);
557
558 if (!local->ops->remove_interface_debugfs)
559 return;
560
561 local->ops->remove_interface_debugfs(&local->hw, &sdata->vif,
562 sdata->debugfs.dir);
563}
564#else
565static inline
566void drv_add_interface_debugfs(struct ieee80211_local *local,
567 struct ieee80211_sub_if_data *sdata) {}
568static inline
569void drv_remove_interface_debugfs(struct ieee80211_local *local,
570 struct ieee80211_sub_if_data *sdata) {}
571#endif 550#endif
572 551
573static inline __must_check 552static inline __must_check
@@ -741,13 +720,14 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local)
741 local->ops->rfkill_poll(&local->hw); 720 local->ops->rfkill_poll(&local->hw);
742} 721}
743 722
744static inline void drv_flush(struct ieee80211_local *local, bool drop) 723static inline void drv_flush(struct ieee80211_local *local,
724 u32 queues, bool drop)
745{ 725{
746 might_sleep(); 726 might_sleep();
747 727
748 trace_drv_flush(local, drop); 728 trace_drv_flush(local, queues, drop);
749 if (local->ops->flush) 729 if (local->ops->flush)
750 local->ops->flush(&local->hw, drop); 730 local->ops->flush(&local->hw, queues, drop);
751 trace_drv_return_void(local); 731 trace_drv_return_void(local);
752} 732}
753 733
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e140184c28ce..0b09716d22ad 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -759,7 +759,6 @@ struct ieee80211_sub_if_data {
759 759
760#ifdef CONFIG_MAC80211_DEBUGFS 760#ifdef CONFIG_MAC80211_DEBUGFS
761 struct { 761 struct {
762 struct dentry *dir;
763 struct dentry *subdir_stations; 762 struct dentry *subdir_stations;
764 struct dentry *default_unicast_key; 763 struct dentry *default_unicast_key;
765 struct dentry *default_multicast_key; 764 struct dentry *default_multicast_key;
@@ -801,11 +800,6 @@ enum sdata_queue_type {
801enum { 800enum {
802 IEEE80211_RX_MSG = 1, 801 IEEE80211_RX_MSG = 1,
803 IEEE80211_TX_STATUS_MSG = 2, 802 IEEE80211_TX_STATUS_MSG = 2,
804 IEEE80211_EOSP_MSG = 3,
805};
806
807struct skb_eosp_msg_data {
808 u8 sta[ETH_ALEN], iface[ETH_ALEN];
809}; 803};
810 804
811enum queue_stop_reason { 805enum queue_stop_reason {
@@ -816,6 +810,7 @@ enum queue_stop_reason {
816 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 810 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
817 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 811 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
818 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, 812 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
813 IEEE80211_QUEUE_STOP_REASON_FLUSH,
819}; 814};
820 815
821#ifdef CONFIG_MAC80211_LEDS 816#ifdef CONFIG_MAC80211_LEDS
@@ -1530,8 +1525,10 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1530 struct ieee80211_hdr *hdr, bool ack); 1525 struct ieee80211_hdr *hdr, bool ack);
1531 1526
1532void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1527void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1528 unsigned long queues,
1533 enum queue_stop_reason reason); 1529 enum queue_stop_reason reason);
1534void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 1530void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
1531 unsigned long queues,
1535 enum queue_stop_reason reason); 1532 enum queue_stop_reason reason);
1536void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 1533void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
1537 enum queue_stop_reason reason); 1534 enum queue_stop_reason reason);
@@ -1548,6 +1545,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
1548{ 1545{
1549 ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); 1546 ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
1550} 1547}
1548void ieee80211_flush_queues(struct ieee80211_local *local,
1549 struct ieee80211_sub_if_data *sdata);
1551 1550
1552void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1551void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1553 u16 transaction, u16 auth_alg, u16 status, 1552 u16 transaction, u16 auth_alg, u16 status,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a2b5e17036bb..69aaba79a9f7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -92,7 +92,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
92 if (local->hw.conf.flags & IEEE80211_CONF_IDLE) 92 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
93 return 0; 93 return 0;
94 94
95 drv_flush(local, false); 95 ieee80211_flush_queues(local, NULL);
96 96
97 local->hw.conf.flags |= IEEE80211_CONF_IDLE; 97 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
98 return IEEE80211_CONF_CHANGE_IDLE; 98 return IEEE80211_CONF_CHANGE_IDLE;
@@ -560,8 +560,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
560 goto err_del_interface; 560 goto err_del_interface;
561 } 561 }
562 562
563 drv_add_interface_debugfs(local, sdata);
564
565 if (sdata->vif.type == NL80211_IFTYPE_AP) { 563 if (sdata->vif.type == NL80211_IFTYPE_AP) {
566 local->fif_pspoll++; 564 local->fif_pspoll++;
567 local->fif_probe_req++; 565 local->fif_probe_req++;
@@ -849,8 +847,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
849 case NL80211_IFTYPE_AP: 847 case NL80211_IFTYPE_AP:
850 skb_queue_purge(&sdata->skb_queue); 848 skb_queue_purge(&sdata->skb_queue);
851 849
852 drv_remove_interface_debugfs(local, sdata);
853
854 if (going_down) 850 if (going_down)
855 drv_remove_interface(local, sdata); 851 drv_remove_interface(local, sdata);
856 } 852 }
@@ -922,6 +918,17 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
922 atomic_dec(&local->iff_promiscs); 918 atomic_dec(&local->iff_promiscs);
923 sdata->flags ^= IEEE80211_SDATA_PROMISC; 919 sdata->flags ^= IEEE80211_SDATA_PROMISC;
924 } 920 }
921
922 /*
923 * TODO: If somebody needs this on AP interfaces,
924 * it can be enabled easily but multicast
925 * addresses from VLANs need to be synced.
926 */
927 if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
928 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
929 sdata->vif.type != NL80211_IFTYPE_AP)
930 drv_set_multicast_list(local, sdata, &dev->mc);
931
925 spin_lock_bh(&local->filter_lock); 932 spin_lock_bh(&local->filter_lock);
926 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); 933 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
927 spin_unlock_bh(&local->filter_lock); 934 spin_unlock_bh(&local->filter_lock);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 99e9f6ae6a54..67059b88fea5 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -248,11 +248,11 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
248} 248}
249 249
250 250
251static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 251static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
252 struct sta_info *sta, 252 struct sta_info *sta,
253 bool pairwise, 253 bool pairwise,
254 struct ieee80211_key *old, 254 struct ieee80211_key *old,
255 struct ieee80211_key *new) 255 struct ieee80211_key *new)
256{ 256{
257 int idx; 257 int idx;
258 bool defunikey, defmultikey, defmgmtkey; 258 bool defunikey, defmultikey, defmgmtkey;
@@ -397,25 +397,21 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
397 return key; 397 return key;
398} 398}
399 399
400static void ieee80211_key_free_common(struct ieee80211_key *key)
401{
402 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
403 ieee80211_aes_key_free(key->u.ccmp.tfm);
404 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
405 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
406 kfree(key);
407}
408
400static void __ieee80211_key_destroy(struct ieee80211_key *key, 409static void __ieee80211_key_destroy(struct ieee80211_key *key,
401 bool delay_tailroom) 410 bool delay_tailroom)
402{ 411{
403 if (!key)
404 return;
405
406 /*
407 * Synchronize so the TX path can no longer be using
408 * this key before we free/remove it.
409 */
410 synchronize_net();
411
412 if (key->local) 412 if (key->local)
413 ieee80211_key_disable_hw_accel(key); 413 ieee80211_key_disable_hw_accel(key);
414 414
415 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
416 ieee80211_aes_key_free(key->u.ccmp.tfm);
417 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
418 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
419 if (key->local) { 415 if (key->local) {
420 struct ieee80211_sub_if_data *sdata = key->sdata; 416 struct ieee80211_sub_if_data *sdata = key->sdata;
421 417
@@ -431,7 +427,28 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
431 } 427 }
432 } 428 }
433 429
434 kfree(key); 430 ieee80211_key_free_common(key);
431}
432
433static void ieee80211_key_destroy(struct ieee80211_key *key,
434 bool delay_tailroom)
435{
436 if (!key)
437 return;
438
439 /*
440 * Synchronize so the TX path can no longer be using
441 * this key before we free/remove it.
442 */
443 synchronize_net();
444
445 __ieee80211_key_destroy(key, delay_tailroom);
446}
447
448void ieee80211_key_free_unused(struct ieee80211_key *key)
449{
450 WARN_ON(key->sdata || key->local);
451 ieee80211_key_free_common(key);
435} 452}
436 453
437int ieee80211_key_link(struct ieee80211_key *key, 454int ieee80211_key_link(struct ieee80211_key *key,
@@ -462,19 +479,22 @@ int ieee80211_key_link(struct ieee80211_key *key,
462 479
463 increment_tailroom_need_count(sdata); 480 increment_tailroom_need_count(sdata);
464 481
465 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); 482 ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
466 __ieee80211_key_destroy(old_key, true); 483 ieee80211_key_destroy(old_key, true);
467 484
468 ieee80211_debugfs_key_add(key); 485 ieee80211_debugfs_key_add(key);
469 486
470 ret = ieee80211_key_enable_hw_accel(key); 487 ret = ieee80211_key_enable_hw_accel(key);
471 488
489 if (ret)
490 ieee80211_key_free(key, true);
491
472 mutex_unlock(&sdata->local->key_mtx); 492 mutex_unlock(&sdata->local->key_mtx);
473 493
474 return ret; 494 return ret;
475} 495}
476 496
477void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) 497void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
478{ 498{
479 if (!key) 499 if (!key)
480 return; 500 return;
@@ -483,18 +503,10 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
483 * Replace key with nothingness if it was ever used. 503 * Replace key with nothingness if it was ever used.
484 */ 504 */
485 if (key->sdata) 505 if (key->sdata)
486 __ieee80211_key_replace(key->sdata, key->sta, 506 ieee80211_key_replace(key->sdata, key->sta,
487 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 507 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
488 key, NULL); 508 key, NULL);
489 __ieee80211_key_destroy(key, delay_tailroom); 509 ieee80211_key_destroy(key, delay_tailroom);
490}
491
492void ieee80211_key_free(struct ieee80211_local *local,
493 struct ieee80211_key *key)
494{
495 mutex_lock(&local->key_mtx);
496 __ieee80211_key_free(key, true);
497 mutex_unlock(&local->key_mtx);
498} 510}
499 511
500void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) 512void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
@@ -554,6 +566,7 @@ EXPORT_SYMBOL(ieee80211_iter_keys);
554void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) 566void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
555{ 567{
556 struct ieee80211_key *key, *tmp; 568 struct ieee80211_key *key, *tmp;
569 LIST_HEAD(keys);
557 570
558 cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); 571 cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk);
559 572
@@ -565,17 +578,65 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
565 578
566 ieee80211_debugfs_key_remove_mgmt_default(sdata); 579 ieee80211_debugfs_key_remove_mgmt_default(sdata);
567 580
568 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 581 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) {
569 __ieee80211_key_free(key, false); 582 ieee80211_key_replace(key->sdata, key->sta,
583 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
584 key, NULL);
585 list_add_tail(&key->list, &keys);
586 }
570 587
571 ieee80211_debugfs_key_update_default(sdata); 588 ieee80211_debugfs_key_update_default(sdata);
572 589
590 if (!list_empty(&keys)) {
591 synchronize_net();
592 list_for_each_entry_safe(key, tmp, &keys, list)
593 __ieee80211_key_destroy(key, false);
594 }
595
573 WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || 596 WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
574 sdata->crypto_tx_tailroom_pending_dec); 597 sdata->crypto_tx_tailroom_pending_dec);
575 598
576 mutex_unlock(&sdata->local->key_mtx); 599 mutex_unlock(&sdata->local->key_mtx);
577} 600}
578 601
602void ieee80211_free_sta_keys(struct ieee80211_local *local,
603 struct sta_info *sta)
604{
605 struct ieee80211_key *key, *tmp;
606 LIST_HEAD(keys);
607 int i;
608
609 mutex_lock(&local->key_mtx);
610 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
611 key = key_mtx_dereference(local, sta->gtk[i]);
612 if (!key)
613 continue;
614 ieee80211_key_replace(key->sdata, key->sta,
615 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
616 key, NULL);
617 list_add(&key->list, &keys);
618 }
619
620 key = key_mtx_dereference(local, sta->ptk);
621 if (key) {
622 ieee80211_key_replace(key->sdata, key->sta,
623 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
624 key, NULL);
625 list_add(&key->list, &keys);
626 }
627
628 /*
629 * NB: the station code relies on this being
630 * done even if there aren't any keys
631 */
632 synchronize_net();
633
634 list_for_each_entry_safe(key, tmp, &keys, list)
635 __ieee80211_key_destroy(key, true);
636
637 mutex_unlock(&local->key_mtx);
638}
639
579void ieee80211_delayed_tailroom_dec(struct work_struct *wk) 640void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
580{ 641{
581 struct ieee80211_sub_if_data *sdata; 642 struct ieee80211_sub_if_data *sdata;
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 2a682d81cee9..e8de3e6d7804 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -129,19 +129,20 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
129 size_t seq_len, const u8 *seq); 129 size_t seq_len, const u8 *seq);
130/* 130/*
131 * Insert a key into data structures (sdata, sta if necessary) 131 * Insert a key into data structures (sdata, sta if necessary)
132 * to make it used, free old key. 132 * to make it used, free old key. On failure, also free the new key.
133 */ 133 */
134int __must_check ieee80211_key_link(struct ieee80211_key *key, 134int ieee80211_key_link(struct ieee80211_key *key,
135 struct ieee80211_sub_if_data *sdata, 135 struct ieee80211_sub_if_data *sdata,
136 struct sta_info *sta); 136 struct sta_info *sta);
137void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); 137void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
138void ieee80211_key_free(struct ieee80211_local *local, 138void ieee80211_key_free_unused(struct ieee80211_key *key);
139 struct ieee80211_key *key);
140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 139void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
141 bool uni, bool multi); 140 bool uni, bool multi);
142void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 141void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
143 int idx); 142 int idx);
144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); 143void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
144void ieee80211_free_sta_keys(struct ieee80211_local *local,
145 struct sta_info *sta);
145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 146void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
146 147
147#define key_mtx_dereference(local, ref) \ 148#define key_mtx_dereference(local, ref) \
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5a53aa5ede80..c6f81ecc36a1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -100,7 +100,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
100 int power; 100 int power;
101 enum nl80211_channel_type channel_type; 101 enum nl80211_channel_type channel_type;
102 u32 offchannel_flag; 102 u32 offchannel_flag;
103 bool scanning = false;
104 103
105 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 104 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
106 if (local->scan_channel) { 105 if (local->scan_channel) {
@@ -147,9 +146,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
147 changed |= IEEE80211_CONF_CHANGE_SMPS; 146 changed |= IEEE80211_CONF_CHANGE_SMPS;
148 } 147 }
149 148
150 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
151 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
152 test_bit(SCAN_HW_SCANNING, &local->scanning);
153 power = chan->max_power; 149 power = chan->max_power;
154 150
155 rcu_read_lock(); 151 rcu_read_lock();
@@ -226,8 +222,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
226static void ieee80211_tasklet_handler(unsigned long data) 222static void ieee80211_tasklet_handler(unsigned long data)
227{ 223{
228 struct ieee80211_local *local = (struct ieee80211_local *) data; 224 struct ieee80211_local *local = (struct ieee80211_local *) data;
229 struct sta_info *sta, *tmp;
230 struct skb_eosp_msg_data *eosp_data;
231 struct sk_buff *skb; 225 struct sk_buff *skb;
232 226
233 while ((skb = skb_dequeue(&local->skb_queue)) || 227 while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -243,18 +237,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
243 skb->pkt_type = 0; 237 skb->pkt_type = 0;
244 ieee80211_tx_status(&local->hw, skb); 238 ieee80211_tx_status(&local->hw, skb);
245 break; 239 break;
246 case IEEE80211_EOSP_MSG:
247 eosp_data = (void *)skb->cb;
248 for_each_sta_info(local, eosp_data->sta, sta, tmp) {
249 /* skip wrong virtual interface */
250 if (memcmp(eosp_data->iface,
251 sta->sdata->vif.addr, ETH_ALEN))
252 continue;
253 clear_sta_flag(sta, WLAN_STA_SP);
254 break;
255 }
256 dev_kfree_skb(skb);
257 break;
258 default: 240 default:
259 WARN(1, "mac80211: Packet is of unknown type %d\n", 241 WARN(1, "mac80211: Packet is of unknown type %d\n",
260 skb->pkt_type); 242 skb->pkt_type);
@@ -295,8 +277,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
295 "Hardware restart was requested\n"); 277 "Hardware restart was requested\n");
296 278
297 /* use this reason, ieee80211_reconfig will unblock it */ 279 /* use this reason, ieee80211_reconfig will unblock it */
298 ieee80211_stop_queues_by_reason(hw, 280 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
299 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 281 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
300 282
301 /* 283 /*
302 * Stop all Rx during the reconfig. We don't want state changes 284 * Stop all Rx during the reconfig. We don't want state changes
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 77b5710db241..123a300cef57 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -699,10 +699,8 @@ out_free:
699static int 699static int
700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) 700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh)
701{ 701{
702 struct ieee80211_sub_if_data *sdata;
703 struct beacon_data *old_bcn; 702 struct beacon_data *old_bcn;
704 int ret; 703 int ret;
705 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
706 704
707 mutex_lock(&ifmsh->mtx); 705 mutex_lock(&ifmsh->mtx);
708 706
@@ -833,9 +831,8 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
833 struct ieee80211_mgmt *hdr; 831 struct ieee80211_mgmt *hdr;
834 struct ieee802_11_elems elems; 832 struct ieee802_11_elems elems;
835 size_t baselen; 833 size_t baselen;
836 u8 *pos, *end; 834 u8 *pos;
837 835
838 end = ((u8 *) mgmt) + len;
839 pos = mgmt->u.probe_req.variable; 836 pos = mgmt->u.probe_req.variable;
840 baselen = (u8 *) pos - (u8 *) mgmt; 837 baselen = (u8 *) pos - (u8 *) mgmt;
841 if (baselen > len) 838 if (baselen > len)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 167158646593..e06dbbf8cb4c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1009,6 +1009,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
1009 1009
1010 /* XXX: wait for a beacon first? */ 1010 /* XXX: wait for a beacon first? */
1011 ieee80211_wake_queues_by_reason(&sdata->local->hw, 1011 ieee80211_wake_queues_by_reason(&sdata->local->hw,
1012 IEEE80211_MAX_QUEUE_MAP,
1012 IEEE80211_QUEUE_STOP_REASON_CSA); 1013 IEEE80211_QUEUE_STOP_REASON_CSA);
1013 out: 1014 out:
1014 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 1015 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
@@ -1108,6 +1109,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1108 1109
1109 if (sw_elem->mode) 1110 if (sw_elem->mode)
1110 ieee80211_stop_queues_by_reason(&sdata->local->hw, 1111 ieee80211_stop_queues_by_reason(&sdata->local->hw,
1112 IEEE80211_MAX_QUEUE_MAP,
1111 IEEE80211_QUEUE_STOP_REASON_CSA); 1113 IEEE80211_QUEUE_STOP_REASON_CSA);
1112 1114
1113 if (sdata->local->ops->channel_switch) { 1115 if (sdata->local->ops->channel_switch) {
@@ -1375,6 +1377,7 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
1375 } 1377 }
1376 1378
1377 ieee80211_wake_queues_by_reason(&local->hw, 1379 ieee80211_wake_queues_by_reason(&local->hw,
1380 IEEE80211_MAX_QUEUE_MAP,
1378 IEEE80211_QUEUE_STOP_REASON_PS); 1381 IEEE80211_QUEUE_STOP_REASON_PS);
1379} 1382}
1380 1383
@@ -1436,7 +1439,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1436 else { 1439 else {
1437 ieee80211_send_nullfunc(local, sdata, 1); 1440 ieee80211_send_nullfunc(local, sdata, 1);
1438 /* Flush to get the tx status of nullfunc frame */ 1441 /* Flush to get the tx status of nullfunc frame */
1439 drv_flush(local, false); 1442 ieee80211_flush_queues(local, sdata);
1440 } 1443 }
1441 } 1444 }
1442 1445
@@ -1767,7 +1770,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1767 1770
1768 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ 1771 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
1769 if (tx) 1772 if (tx)
1770 drv_flush(local, false); 1773 ieee80211_flush_queues(local, sdata);
1771 1774
1772 /* deauthenticate/disassociate now */ 1775 /* deauthenticate/disassociate now */
1773 if (tx || frame_buf) 1776 if (tx || frame_buf)
@@ -1776,7 +1779,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1776 1779
1777 /* flush out frame */ 1780 /* flush out frame */
1778 if (tx) 1781 if (tx)
1779 drv_flush(local, false); 1782 ieee80211_flush_queues(local, sdata);
1780 1783
1781 /* clear bssid only after building the needed mgmt frames */ 1784 /* clear bssid only after building the needed mgmt frames */
1782 memset(ifmgd->bssid, 0, ETH_ALEN); 1785 memset(ifmgd->bssid, 0, ETH_ALEN);
@@ -1948,7 +1951,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1948 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 1951 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
1949 run_again(ifmgd, ifmgd->probe_timeout); 1952 run_again(ifmgd, ifmgd->probe_timeout);
1950 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 1953 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1951 drv_flush(sdata->local, false); 1954 ieee80211_flush_queues(sdata->local, sdata);
1952} 1955}
1953 1956
1954static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 1957static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -2071,6 +2074,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2071 true, frame_buf); 2074 true, frame_buf);
2072 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 2075 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
2073 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2076 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2077 IEEE80211_MAX_QUEUE_MAP,
2074 IEEE80211_QUEUE_STOP_REASON_CSA); 2078 IEEE80211_QUEUE_STOP_REASON_CSA);
2075 mutex_unlock(&ifmgd->mtx); 2079 mutex_unlock(&ifmgd->mtx);
2076 2080
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 950c95bec13d..cce795871ab1 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -118,9 +118,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
118 * Stop queues and transmit all frames queued by the driver 118 * Stop queues and transmit all frames queued by the driver
119 * before sending nullfunc to enable powersave at the AP. 119 * before sending nullfunc to enable powersave at the AP.
120 */ 120 */
121 ieee80211_stop_queues_by_reason(&local->hw, 121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
123 drv_flush(local, false); 123 ieee80211_flush_queues(local, NULL);
124 124
125 mutex_lock(&local->iflist_mtx); 125 mutex_lock(&local->iflist_mtx);
126 list_for_each_entry(sdata, &local->interfaces, list) { 126 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -181,7 +181,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
181 } 181 }
182 mutex_unlock(&local->iflist_mtx); 182 mutex_unlock(&local->iflist_mtx);
183 183
184 ieee80211_wake_queues_by_reason(&local->hw, 184 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
186} 186}
187 187
@@ -382,7 +382,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
382 ieee80211_roc_notify_destroy(roc, !roc->abort); 382 ieee80211_roc_notify_destroy(roc, !roc->abort);
383 383
384 if (started) { 384 if (started) {
385 drv_flush(local, false); 385 ieee80211_flush_queues(local, NULL);
386 386
387 local->tmp_channel = NULL; 387 local->tmp_channel = NULL;
388 ieee80211_hw_config(local, 0); 388 ieee80211_hw_config(local, 0);
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index b471a67f224d..3d16f4e61743 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -30,12 +30,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
30 } 30 }
31 31
32 ieee80211_stop_queues_by_reason(hw, 32 ieee80211_stop_queues_by_reason(hw,
33 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 33 IEEE80211_MAX_QUEUE_MAP,
34 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
34 35
35 /* flush out all packets */ 36 /* flush out all packets */
36 synchronize_net(); 37 synchronize_net();
37 38
38 drv_flush(local, false); 39 ieee80211_flush_queues(local, NULL);
39 40
40 local->quiescing = true; 41 local->quiescing = true;
41 /* make quiescing visible to timers everywhere */ 42 /* make quiescing visible to timers everywhere */
@@ -68,6 +69,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
68 mutex_unlock(&local->sta_mtx); 69 mutex_unlock(&local->sta_mtx);
69 } 70 }
70 ieee80211_wake_queues_by_reason(hw, 71 ieee80211_wake_queues_by_reason(hw,
72 IEEE80211_MAX_QUEUE_MAP,
71 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 73 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
72 return err; 74 return err;
73 } else if (err > 0) { 75 } else if (err > 0) {
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 749552bdcfe1..d2b264d1311d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -202,14 +202,23 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
202 struct minstrel_rate_stats *mr; 202 struct minstrel_rate_stats *mr;
203 unsigned int nsecs = 0; 203 unsigned int nsecs = 0;
204 unsigned int tp; 204 unsigned int tp;
205 unsigned int prob;
205 206
206 mr = &mi->groups[group].rates[rate]; 207 mr = &mi->groups[group].rates[rate];
208 prob = mr->probability;
207 209
208 if (mr->probability < MINSTREL_FRAC(1, 10)) { 210 if (prob < MINSTREL_FRAC(1, 10)) {
209 mr->cur_tp = 0; 211 mr->cur_tp = 0;
210 return; 212 return;
211 } 213 }
212 214
215 /*
216 * For the throughput calculation, limit the probability value to 90% to
217 * account for collision related packet error rate fluctuation
218 */
219 if (prob > MINSTREL_FRAC(9, 10))
220 prob = MINSTREL_FRAC(9, 10);
221
213 if (group != MINSTREL_CCK_GROUP) 222 if (group != MINSTREL_CCK_GROUP)
214 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 223 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
215 224
@@ -639,15 +648,18 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
639 /* 648 /*
640 * Sampling might add some overhead (RTS, no aggregation) 649 * Sampling might add some overhead (RTS, no aggregation)
641 * to the frame. Hence, don't use sampling for the currently 650 * to the frame. Hence, don't use sampling for the currently
642 * used max TP rate. 651 * used rates.
643 */ 652 */
644 if (sample_idx == mi->max_tp_rate) 653 if (sample_idx == mi->max_tp_rate ||
654 sample_idx == mi->max_tp_rate2 ||
655 sample_idx == mi->max_prob_rate)
645 return -1; 656 return -1;
657
646 /* 658 /*
647 * When not using MRR, do not sample if the probability is already 659 * Do not sample if the probability is already higher than 95%
648 * higher than 95% to avoid wasting airtime 660 * to avoid wasting airtime.
649 */ 661 */
650 if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) 662 if (mr->probability > MINSTREL_FRAC(95, 100))
651 return -1; 663 return -1;
652 664
653 /* 665 /*
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 43a45cf00e06..cb34cbbaa20c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -153,7 +153,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
153 u8 *elements; 153 u8 *elements;
154 struct ieee80211_channel *channel; 154 struct ieee80211_channel *channel;
155 size_t baselen; 155 size_t baselen;
156 bool beacon;
157 struct ieee802_11_elems elems; 156 struct ieee802_11_elems elems;
158 157
159 if (skb->len < 24 || 158 if (skb->len < 24 ||
@@ -175,11 +174,9 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
175 174
176 elements = mgmt->u.probe_resp.variable; 175 elements = mgmt->u.probe_resp.variable;
177 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); 176 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
178 beacon = false;
179 } else { 177 } else {
180 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); 178 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
181 elements = mgmt->u.beacon.variable; 179 elements = mgmt->u.beacon.variable;
182 beacon = true;
183 } 180 }
184 181
185 if (baselen > skb->len) 182 if (baselen > skb->len)
@@ -335,7 +332,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
335 ieee80211_offchannel_stop_vifs(local); 332 ieee80211_offchannel_stop_vifs(local);
336 333
337 /* ensure nullfunc is transmitted before leaving operating channel */ 334 /* ensure nullfunc is transmitted before leaving operating channel */
338 drv_flush(local, false); 335 ieee80211_flush_queues(local, NULL);
339 336
340 ieee80211_configure_filter(local); 337 ieee80211_configure_filter(local);
341 338
@@ -671,7 +668,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local,
671 ieee80211_offchannel_stop_vifs(local); 668 ieee80211_offchannel_stop_vifs(local);
672 669
673 if (local->ops->flush) { 670 if (local->ops->flush) {
674 drv_flush(local, false); 671 ieee80211_flush_queues(local, NULL);
675 *next_delay = 0; 672 *next_delay = 0;
676 } else 673 } else
677 *next_delay = HZ / 10; 674 *next_delay = HZ / 10;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 85458a28ffa0..11216bc13b27 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -556,6 +556,15 @@ static inline void __bss_tim_clear(u8 *tim, u16 id)
556 tim[id / 8] &= ~(1 << (id % 8)); 556 tim[id / 8] &= ~(1 << (id % 8));
557} 557}
558 558
559static inline bool __bss_tim_get(u8 *tim, u16 id)
560{
561 /*
562 * This format has been mandated by the IEEE specifications,
563 * so this line may not be changed to use the test_bit() format.
564 */
565 return tim[id / 8] & (1 << (id % 8));
566}
567
559static unsigned long ieee80211_tids_for_ac(int ac) 568static unsigned long ieee80211_tids_for_ac(int ac)
560{ 569{
561 /* If we ever support TIDs > 7, this obviously needs to be adjusted */ 570 /* If we ever support TIDs > 7, this obviously needs to be adjusted */
@@ -636,6 +645,9 @@ void sta_info_recalc_tim(struct sta_info *sta)
636 done: 645 done:
637 spin_lock_bh(&local->tim_lock); 646 spin_lock_bh(&local->tim_lock);
638 647
648 if (indicate_tim == __bss_tim_get(ps->tim, id))
649 goto out_unlock;
650
639 if (indicate_tim) 651 if (indicate_tim)
640 __bss_tim_set(ps->tim, id); 652 __bss_tim_set(ps->tim, id);
641 else 653 else
@@ -647,6 +659,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
647 local->tim_in_locked_section = false; 659 local->tim_in_locked_section = false;
648 } 660 }
649 661
662out_unlock:
650 spin_unlock_bh(&local->tim_lock); 663 spin_unlock_bh(&local->tim_lock);
651} 664}
652 665
@@ -770,8 +783,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
770{ 783{
771 struct ieee80211_local *local; 784 struct ieee80211_local *local;
772 struct ieee80211_sub_if_data *sdata; 785 struct ieee80211_sub_if_data *sdata;
773 int ret, i; 786 int ret;
774 bool have_key = false;
775 787
776 might_sleep(); 788 might_sleep();
777 789
@@ -798,22 +810,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
798 810
799 list_del_rcu(&sta->list); 811 list_del_rcu(&sta->list);
800 812
801 mutex_lock(&local->key_mtx); 813 /* this always calls synchronize_net() */
802 for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 814 ieee80211_free_sta_keys(local, sta);
803 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]),
804 true);
805 have_key = true;
806 }
807 if (sta->ptk) {
808 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk),
809 true);
810 have_key = true;
811 }
812
813 mutex_unlock(&local->key_mtx);
814
815 if (!have_key)
816 synchronize_net();
817 815
818 sta->dead = true; 816 sta->dead = true;
819 817
@@ -1399,30 +1397,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
1399} 1397}
1400EXPORT_SYMBOL(ieee80211_sta_block_awake); 1398EXPORT_SYMBOL(ieee80211_sta_block_awake);
1401 1399
1402void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) 1400void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
1403{ 1401{
1404 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 1402 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1405 struct ieee80211_local *local = sta->local; 1403 struct ieee80211_local *local = sta->local;
1406 struct sk_buff *skb;
1407 struct skb_eosp_msg_data *data;
1408 1404
1409 trace_api_eosp(local, pubsta); 1405 trace_api_eosp(local, pubsta);
1410 1406
1411 skb = alloc_skb(0, GFP_ATOMIC); 1407 clear_sta_flag(sta, WLAN_STA_SP);
1412 if (!skb) {
1413 /* too bad ... but race is better than loss */
1414 clear_sta_flag(sta, WLAN_STA_SP);
1415 return;
1416 }
1417
1418 data = (void *)skb->cb;
1419 memcpy(data->sta, pubsta->addr, ETH_ALEN);
1420 memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
1421 skb->pkt_type = IEEE80211_EOSP_MSG;
1422 skb_queue_tail(&local->skb_queue, skb);
1423 tasklet_schedule(&local->tasklet);
1424} 1408}
1425EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); 1409EXPORT_SYMBOL(ieee80211_sta_eosp);
1426 1410
1427void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, 1411void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
1428 u8 tid, bool buffered) 1412 u8 tid, bool buffered)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index e5868c32d1a3..adc30045f99e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -333,7 +333,8 @@ struct sta_info {
333 unsigned long driver_buffered_tids; 333 unsigned long driver_buffered_tids;
334 334
335 /* Updated from RX path only, no locking requirements */ 335 /* Updated from RX path only, no locking requirements */
336 unsigned long rx_packets, rx_bytes; 336 unsigned long rx_packets;
337 u64 rx_bytes;
337 unsigned long wep_weak_iv_count; 338 unsigned long wep_weak_iv_count;
338 unsigned long last_rx; 339 unsigned long last_rx;
339 long last_connected; 340 long last_connected;
@@ -353,9 +354,9 @@ struct sta_info {
353 unsigned int fail_avg; 354 unsigned int fail_avg;
354 355
355 /* Updated from TX path only, no locking requirements */ 356 /* Updated from TX path only, no locking requirements */
356 unsigned long tx_packets; 357 u32 tx_fragments;
357 unsigned long tx_bytes; 358 u64 tx_packets[IEEE80211_NUM_ACS];
358 unsigned long tx_fragments; 359 u64 tx_bytes[IEEE80211_NUM_ACS];
359 struct ieee80211_tx_rate last_tx_rate; 360 struct ieee80211_tx_rate last_tx_rate;
360 int last_rx_rate_idx; 361 int last_rx_rate_idx;
361 u32 last_rx_rate_flag; 362 u32 last_rx_rate_flag;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e7db2b804e0c..c5899797a8d4 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -431,6 +431,30 @@ TRACE_EVENT(drv_prepare_multicast,
431 ) 431 )
432); 432);
433 433
434TRACE_EVENT(drv_set_multicast_list,
435 TP_PROTO(struct ieee80211_local *local,
436 struct ieee80211_sub_if_data *sdata, int mc_count),
437
438 TP_ARGS(local, sdata, mc_count),
439
440 TP_STRUCT__entry(
441 LOCAL_ENTRY
442 __field(bool, allmulti)
443 __field(int, mc_count)
444 ),
445
446 TP_fast_assign(
447 LOCAL_ASSIGN;
448 __entry->allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
449 __entry->mc_count = mc_count;
450 ),
451
452 TP_printk(
453 LOCAL_PR_FMT " configure mc filter, count=%d, allmulti=%d",
454 LOCAL_PR_ARG, __entry->mc_count, __entry->allmulti
455 )
456);
457
434TRACE_EVENT(drv_configure_filter, 458TRACE_EVENT(drv_configure_filter,
435 TP_PROTO(struct ieee80211_local *local, 459 TP_PROTO(struct ieee80211_local *local,
436 unsigned int changed_flags, 460 unsigned int changed_flags,
@@ -940,23 +964,26 @@ TRACE_EVENT(drv_get_survey,
940); 964);
941 965
942TRACE_EVENT(drv_flush, 966TRACE_EVENT(drv_flush,
943 TP_PROTO(struct ieee80211_local *local, bool drop), 967 TP_PROTO(struct ieee80211_local *local,
968 u32 queues, bool drop),
944 969
945 TP_ARGS(local, drop), 970 TP_ARGS(local, queues, drop),
946 971
947 TP_STRUCT__entry( 972 TP_STRUCT__entry(
948 LOCAL_ENTRY 973 LOCAL_ENTRY
949 __field(bool, drop) 974 __field(bool, drop)
975 __field(u32, queues)
950 ), 976 ),
951 977
952 TP_fast_assign( 978 TP_fast_assign(
953 LOCAL_ASSIGN; 979 LOCAL_ASSIGN;
954 __entry->drop = drop; 980 __entry->drop = drop;
981 __entry->queues = queues;
955 ), 982 ),
956 983
957 TP_printk( 984 TP_printk(
958 LOCAL_PR_FMT " drop:%d", 985 LOCAL_PR_FMT " queues:0x%x drop:%d",
959 LOCAL_PR_ARG, __entry->drop 986 LOCAL_PR_ARG, __entry->queues, __entry->drop
960 ) 987 )
961); 988);
962 989
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4e8a86163fc7..9e67cc97b87b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -233,6 +233,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
233 233
234 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 234 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
235 ieee80211_stop_queues_by_reason(&local->hw, 235 ieee80211_stop_queues_by_reason(&local->hw,
236 IEEE80211_MAX_QUEUE_MAP,
236 IEEE80211_QUEUE_STOP_REASON_PS); 237 IEEE80211_QUEUE_STOP_REASON_PS);
237 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 238 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
238 ieee80211_queue_work(&local->hw, 239 ieee80211_queue_work(&local->hw,
@@ -991,15 +992,18 @@ static ieee80211_tx_result debug_noinline
991ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) 992ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
992{ 993{
993 struct sk_buff *skb; 994 struct sk_buff *skb;
995 int ac = -1;
994 996
995 if (!tx->sta) 997 if (!tx->sta)
996 return TX_CONTINUE; 998 return TX_CONTINUE;
997 999
998 tx->sta->tx_packets++;
999 skb_queue_walk(&tx->skbs, skb) { 1000 skb_queue_walk(&tx->skbs, skb) {
1001 ac = skb_get_queue_mapping(skb);
1000 tx->sta->tx_fragments++; 1002 tx->sta->tx_fragments++;
1001 tx->sta->tx_bytes += skb->len; 1003 tx->sta->tx_bytes[ac] += skb->len;
1002 } 1004 }
1005 if (ac >= 0)
1006 tx->sta->tx_packets[ac]++;
1003 1007
1004 return TX_CONTINUE; 1008 return TX_CONTINUE;
1005} 1009}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b7a856e3281b..a7368870c8ee 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -453,7 +453,8 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
453} 453}
454 454
455void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 455void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
456 enum queue_stop_reason reason) 456 unsigned long queues,
457 enum queue_stop_reason reason)
457{ 458{
458 struct ieee80211_local *local = hw_to_local(hw); 459 struct ieee80211_local *local = hw_to_local(hw);
459 unsigned long flags; 460 unsigned long flags;
@@ -461,7 +462,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
461 462
462 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 463 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
463 464
464 for (i = 0; i < hw->queues; i++) 465 for_each_set_bit(i, &queues, hw->queues)
465 __ieee80211_stop_queue(hw, i, reason); 466 __ieee80211_stop_queue(hw, i, reason);
466 467
467 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 468 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@@ -469,7 +470,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
469 470
470void ieee80211_stop_queues(struct ieee80211_hw *hw) 471void ieee80211_stop_queues(struct ieee80211_hw *hw)
471{ 472{
472 ieee80211_stop_queues_by_reason(hw, 473 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
473 IEEE80211_QUEUE_STOP_REASON_DRIVER); 474 IEEE80211_QUEUE_STOP_REASON_DRIVER);
474} 475}
475EXPORT_SYMBOL(ieee80211_stop_queues); 476EXPORT_SYMBOL(ieee80211_stop_queues);
@@ -491,6 +492,7 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
491EXPORT_SYMBOL(ieee80211_queue_stopped); 492EXPORT_SYMBOL(ieee80211_queue_stopped);
492 493
493void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 494void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
495 unsigned long queues,
494 enum queue_stop_reason reason) 496 enum queue_stop_reason reason)
495{ 497{
496 struct ieee80211_local *local = hw_to_local(hw); 498 struct ieee80211_local *local = hw_to_local(hw);
@@ -499,7 +501,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
499 501
500 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 502 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
501 503
502 for (i = 0; i < hw->queues; i++) 504 for_each_set_bit(i, &queues, hw->queues)
503 __ieee80211_wake_queue(hw, i, reason); 505 __ieee80211_wake_queue(hw, i, reason);
504 506
505 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 507 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@@ -507,10 +509,42 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
507 509
508void ieee80211_wake_queues(struct ieee80211_hw *hw) 510void ieee80211_wake_queues(struct ieee80211_hw *hw)
509{ 511{
510 ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); 512 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
513 IEEE80211_QUEUE_STOP_REASON_DRIVER);
511} 514}
512EXPORT_SYMBOL(ieee80211_wake_queues); 515EXPORT_SYMBOL(ieee80211_wake_queues);
513 516
517void ieee80211_flush_queues(struct ieee80211_local *local,
518 struct ieee80211_sub_if_data *sdata)
519{
520 u32 queues;
521
522 if (!local->ops->flush)
523 return;
524
525 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
526 int ac;
527
528 queues = 0;
529
530 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
531 queues |= BIT(sdata->vif.hw_queue[ac]);
532 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
533 queues |= BIT(sdata->vif.cab_queue);
534 } else {
535 /* all queues */
536 queues = BIT(local->hw.queues) - 1;
537 }
538
539 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
540 IEEE80211_QUEUE_STOP_REASON_FLUSH);
541
542 drv_flush(local, queues, false);
543
544 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
545 IEEE80211_QUEUE_STOP_REASON_FLUSH);
546}
547
514void ieee80211_iterate_active_interfaces( 548void ieee80211_iterate_active_interfaces(
515 struct ieee80211_hw *hw, u32 iter_flags, 549 struct ieee80211_hw *hw, u32 iter_flags,
516 void (*iterator)(void *data, u8 *mac, 550 void (*iterator)(void *data, u8 *mac,
@@ -1651,8 +1685,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1651 mutex_unlock(&local->sta_mtx); 1685 mutex_unlock(&local->sta_mtx);
1652 } 1686 }
1653 1687
1654 ieee80211_wake_queues_by_reason(hw, 1688 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
1655 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1689 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1656 1690
1657 /* 1691 /*
1658 * If this is for hw restart things are still running. 1692 * If this is for hw restart things are still running.