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.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8be854e86cd9..06fac2991d40 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -747,7 +747,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
747 unsigned long flags; 747 unsigned long flags;
748 struct sk_buff *skb, *tmp; 748 struct sk_buff *skb, *tmp;
749 u32 hw_reconf_flags = 0; 749 u32 hw_reconf_flags = 0;
750 int i; 750 int i, flushed;
751 751
752 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 752 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
753 753
@@ -772,11 +772,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
772 * (because if we remove a STA after ops->remove_interface() 772 * (because if we remove a STA after ops->remove_interface()
773 * the driver will have removed the vif info already!) 773 * the driver will have removed the vif info already!)
774 * 774 *
775 * This is relevant only in AP, WDS and mesh modes, since in 775 * This is relevant only in WDS mode, in all other modes we've
776 * all other modes we've already removed all stations when 776 * already removed all stations when disconnecting or similar,
777 * disconnecting etc. 777 * so warn otherwise.
778 *
779 * We call sta_info_flush_cleanup() later, to combine RCU waits.
778 */ 780 */
779 sta_info_flush(local, sdata); 781 flushed = sta_info_flush_defer(sdata);
782 WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
783 (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
780 784
781 /* 785 /*
782 * Don't count this interface for promisc/allmulti while it 786 * Don't count this interface for promisc/allmulti while it
@@ -859,11 +863,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
859 cancel_work_sync(&sdata->work); 863 cancel_work_sync(&sdata->work);
860 /* 864 /*
861 * When we get here, the interface is marked down. 865 * When we get here, the interface is marked down.
862 * Call synchronize_rcu() to wait for the RX path 866 *
863 * should it be using the interface and enqueuing 867 * sta_info_flush_cleanup() requires rcu_barrier()
864 * frames at this very time on another CPU. 868 * first to wait for the station call_rcu() calls
869 * to complete, here we need at least sychronize_rcu()
870 * it to wait for the RX path in case it is using the
871 * interface and enqueuing frames at this very time on
872 * another CPU.
865 */ 873 */
866 synchronize_rcu(); 874 rcu_barrier();
875 sta_info_flush_cleanup(sdata);
876
867 skb_queue_purge(&sdata->skb_queue); 877 skb_queue_purge(&sdata->skb_queue);
868 878
869 /* 879 /*
@@ -961,7 +971,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
961 */ 971 */
962static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) 972static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
963{ 973{
964 struct ieee80211_local *local = sdata->local;
965 int flushed; 974 int flushed;
966 int i; 975 int i;
967 976
@@ -977,7 +986,7 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
977 if (ieee80211_vif_is_mesh(&sdata->vif)) 986 if (ieee80211_vif_is_mesh(&sdata->vif))
978 mesh_rmc_free(sdata); 987 mesh_rmc_free(sdata);
979 988
980 flushed = sta_info_flush(local, sdata); 989 flushed = sta_info_flush(sdata);
981 WARN_ON(flushed); 990 WARN_ON(flushed);
982} 991}
983 992
@@ -1218,6 +1227,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1218 case NL80211_IFTYPE_AP: 1227 case NL80211_IFTYPE_AP:
1219 skb_queue_head_init(&sdata->u.ap.ps.bc_buf); 1228 skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
1220 INIT_LIST_HEAD(&sdata->u.ap.vlans); 1229 INIT_LIST_HEAD(&sdata->u.ap.vlans);
1230 sdata->vif.bss_conf.bssid = sdata->vif.addr;
1221 break; 1231 break;
1222 case NL80211_IFTYPE_P2P_CLIENT: 1232 case NL80211_IFTYPE_P2P_CLIENT:
1223 type = NL80211_IFTYPE_STATION; 1233 type = NL80211_IFTYPE_STATION;
@@ -1225,9 +1235,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1225 sdata->vif.p2p = true; 1235 sdata->vif.p2p = true;
1226 /* fall through */ 1236 /* fall through */
1227 case NL80211_IFTYPE_STATION: 1237 case NL80211_IFTYPE_STATION:
1238 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
1228 ieee80211_sta_setup_sdata(sdata); 1239 ieee80211_sta_setup_sdata(sdata);
1229 break; 1240 break;
1230 case NL80211_IFTYPE_ADHOC: 1241 case NL80211_IFTYPE_ADHOC:
1242 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
1231 ieee80211_ibss_setup_sdata(sdata); 1243 ieee80211_ibss_setup_sdata(sdata);
1232 break; 1244 break;
1233 case NL80211_IFTYPE_MESH_POINT: 1245 case NL80211_IFTYPE_MESH_POINT:
@@ -1241,8 +1253,12 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1241 MONITOR_FLAG_OTHER_BSS; 1253 MONITOR_FLAG_OTHER_BSS;
1242 break; 1254 break;
1243 case NL80211_IFTYPE_WDS: 1255 case NL80211_IFTYPE_WDS:
1256 sdata->vif.bss_conf.bssid = NULL;
1257 break;
1244 case NL80211_IFTYPE_AP_VLAN: 1258 case NL80211_IFTYPE_AP_VLAN:
1259 break;
1245 case NL80211_IFTYPE_P2P_DEVICE: 1260 case NL80211_IFTYPE_P2P_DEVICE:
1261 sdata->vif.bss_conf.bssid = sdata->vif.addr;
1246 break; 1262 break;
1247 case NL80211_IFTYPE_UNSPECIFIED: 1263 case NL80211_IFTYPE_UNSPECIFIED:
1248 case NUM_NL80211_IFTYPES: 1264 case NUM_NL80211_IFTYPES: