aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c49
1 files changed, 8 insertions, 41 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a4f98123d0bf..d624ed49a7d9 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -786,10 +786,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
786 * This is relevant only in WDS mode, in all other modes we've 786 * This is relevant only in WDS mode, in all other modes we've
787 * already removed all stations when disconnecting or similar, 787 * already removed all stations when disconnecting or similar,
788 * so warn otherwise. 788 * so warn otherwise.
789 *
790 * We call sta_info_flush_cleanup() later, to combine RCU waits.
791 */ 789 */
792 flushed = sta_info_flush_defer(sdata); 790 flushed = sta_info_flush(sdata);
793 WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || 791 WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
794 (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); 792 (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
795 793
@@ -891,23 +889,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
891 cancel_work_sync(&sdata->work); 889 cancel_work_sync(&sdata->work);
892 /* 890 /*
893 * When we get here, the interface is marked down. 891 * When we get here, the interface is marked down.
892 * Free the remaining keys, if there are any
893 * (shouldn't be, except maybe in WDS mode?)
894 * 894 *
895 * sta_info_flush_cleanup() requires rcu_barrier() 895 * Force the key freeing to always synchronize_net()
896 * first to wait for the station call_rcu() calls 896 * to wait for the RX path in case it is using this
897 * to complete, and we also need synchronize_rcu() 897 * interface enqueuing frames * at this very time on
898 * to wait for the RX path in case it is using the
899 * interface and enqueuing frames at this very time on
900 * another CPU. 898 * another CPU.
901 */ 899 */
902 synchronize_rcu(); 900 ieee80211_free_keys(sdata, true);
903 rcu_barrier();
904 sta_info_flush_cleanup(sdata);
905
906 /*
907 * Free all remaining keys, there shouldn't be any,
908 * except maybe in WDS mode?
909 */
910 ieee80211_free_keys(sdata);
911 901
912 /* fall through */ 902 /* fall through */
913 case NL80211_IFTYPE_AP: 903 case NL80211_IFTYPE_AP:
@@ -1018,17 +1008,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
1018 atomic_dec(&local->iff_promiscs); 1008 atomic_dec(&local->iff_promiscs);
1019 sdata->flags ^= IEEE80211_SDATA_PROMISC; 1009 sdata->flags ^= IEEE80211_SDATA_PROMISC;
1020 } 1010 }
1021
1022 /*
1023 * TODO: If somebody needs this on AP interfaces,
1024 * it can be enabled easily but multicast
1025 * addresses from VLANs need to be synced.
1026 */
1027 if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1028 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1029 sdata->vif.type != NL80211_IFTYPE_AP)
1030 drv_set_multicast_list(local, sdata, &dev->mc);
1031
1032 spin_lock_bh(&local->filter_lock); 1011 spin_lock_bh(&local->filter_lock);
1033 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); 1012 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
1034 spin_unlock_bh(&local->filter_lock); 1013 spin_unlock_bh(&local->filter_lock);
@@ -1044,7 +1023,7 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
1044 int i; 1023 int i;
1045 1024
1046 /* free extra data */ 1025 /* free extra data */
1047 ieee80211_free_keys(sdata); 1026 ieee80211_free_keys(sdata, false);
1048 1027
1049 ieee80211_debugfs_remove_netdev(sdata); 1028 ieee80211_debugfs_remove_netdev(sdata);
1050 1029
@@ -1578,15 +1557,6 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
1578 mutex_unlock(&local->iflist_mtx); 1557 mutex_unlock(&local->iflist_mtx);
1579} 1558}
1580 1559
1581static void ieee80211_cleanup_sdata_stas_wk(struct work_struct *wk)
1582{
1583 struct ieee80211_sub_if_data *sdata;
1584
1585 sdata = container_of(wk, struct ieee80211_sub_if_data, cleanup_stations_wk);
1586
1587 ieee80211_cleanup_sdata_stas(sdata);
1588}
1589
1590int ieee80211_if_add(struct ieee80211_local *local, const char *name, 1560int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1591 struct wireless_dev **new_wdev, enum nl80211_iftype type, 1561 struct wireless_dev **new_wdev, enum nl80211_iftype type,
1592 struct vif_params *params) 1562 struct vif_params *params)
@@ -1659,9 +1629,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1659 1629
1660 INIT_LIST_HEAD(&sdata->key_list); 1630 INIT_LIST_HEAD(&sdata->key_list);
1661 1631
1662 spin_lock_init(&sdata->cleanup_stations_lock);
1663 INIT_LIST_HEAD(&sdata->cleanup_stations);
1664 INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk);
1665 INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work, 1632 INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work,
1666 ieee80211_dfs_cac_timer_work); 1633 ieee80211_dfs_cac_timer_work);
1667 INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk, 1634 INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk,