aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2013-08-28 07:41:30 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-09-26 07:27:14 -0400
commit871a4180b8b62dbed54cd203c33bdab7fce24e6f (patch)
treec104bb4f569f18331df3bf3a293d4ecf31d9d620 /net/mac80211/ibss.c
parente6b7cde4d3e155f118b81f1f62f86554c529083a (diff)
mac80211: split off ibss disconnect
IBSS CSA will require to disconnect if a channel switch fails, but mac80211 should search and re-connect after this disconnect. To allow such usage, split off the ibss disconnect process in a separate function which only performs the disconnect without overwriting nl80211-supplied parameters. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c172
1 files changed, 92 insertions, 80 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a12afe77bb26..0c3ec082e4f5 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -499,6 +499,96 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
499 return ieee80211_ibss_finish_sta(sta); 499 return ieee80211_ibss_finish_sta(sta);
500} 500}
501 501
502static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
503{
504 struct ieee80211_local *local = sdata->local;
505 int active = 0;
506 struct sta_info *sta;
507
508 sdata_assert_lock(sdata);
509
510 rcu_read_lock();
511
512 list_for_each_entry_rcu(sta, &local->sta_list, list) {
513 if (sta->sdata == sdata &&
514 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
515 jiffies)) {
516 active++;
517 break;
518 }
519 }
520
521 rcu_read_unlock();
522
523 return active;
524}
525
526static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
527{
528 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
529 struct ieee80211_local *local = sdata->local;
530 struct cfg80211_bss *cbss;
531 struct beacon_data *presp;
532 struct sta_info *sta;
533 int active_ibss;
534 u16 capability;
535
536 active_ibss = ieee80211_sta_active_ibss(sdata);
537
538 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
539 capability = WLAN_CAPABILITY_IBSS;
540
541 if (ifibss->privacy)
542 capability |= WLAN_CAPABILITY_PRIVACY;
543
544 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
545 ifibss->bssid, ifibss->ssid,
546 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
547 WLAN_CAPABILITY_PRIVACY,
548 capability);
549
550 if (cbss) {
551 cfg80211_unlink_bss(local->hw.wiphy, cbss);
552 cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
553 }
554 }
555
556 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
557
558 sta_info_flush(sdata);
559
560 spin_lock_bh(&ifibss->incomplete_lock);
561 while (!list_empty(&ifibss->incomplete_stations)) {
562 sta = list_first_entry(&ifibss->incomplete_stations,
563 struct sta_info, list);
564 list_del(&sta->list);
565 spin_unlock_bh(&ifibss->incomplete_lock);
566
567 sta_info_free(local, sta);
568 spin_lock_bh(&ifibss->incomplete_lock);
569 }
570 spin_unlock_bh(&ifibss->incomplete_lock);
571
572 netif_carrier_off(sdata->dev);
573
574 sdata->vif.bss_conf.ibss_joined = false;
575 sdata->vif.bss_conf.ibss_creator = false;
576 sdata->vif.bss_conf.enable_beacon = false;
577 sdata->vif.bss_conf.ssid_len = 0;
578
579 /* remove beacon */
580 presp = rcu_dereference_protected(ifibss->presp,
581 lockdep_is_held(&sdata->wdev.mtx));
582 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
583 if (presp)
584 kfree_rcu(presp, rcu_head);
585
586 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
587 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
588 BSS_CHANGED_IBSS);
589 ieee80211_vif_release_channel(sdata);
590}
591
502static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, 592static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
503 struct ieee80211_mgmt *mgmt, 593 struct ieee80211_mgmt *mgmt,
504 size_t len) 594 size_t len)
@@ -775,30 +865,6 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
775 ieee80211_queue_work(&local->hw, &sdata->work); 865 ieee80211_queue_work(&local->hw, &sdata->work);
776} 866}
777 867
778static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
779{
780 struct ieee80211_local *local = sdata->local;
781 int active = 0;
782 struct sta_info *sta;
783
784 sdata_assert_lock(sdata);
785
786 rcu_read_lock();
787
788 list_for_each_entry_rcu(sta, &local->sta_list, list) {
789 if (sta->sdata == sdata &&
790 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
791 jiffies)) {
792 active++;
793 break;
794 }
795 }
796
797 rcu_read_unlock();
798
799 return active;
800}
801
802static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) 868static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
803{ 869{
804 struct ieee80211_local *local = sdata->local; 870 struct ieee80211_local *local = sdata->local;
@@ -1265,73 +1331,19 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1265int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) 1331int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1266{ 1332{
1267 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 1333 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
1268 struct ieee80211_local *local = sdata->local;
1269 struct cfg80211_bss *cbss;
1270 u16 capability;
1271 int active_ibss;
1272 struct sta_info *sta;
1273 struct beacon_data *presp;
1274
1275 active_ibss = ieee80211_sta_active_ibss(sdata);
1276
1277 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
1278 capability = WLAN_CAPABILITY_IBSS;
1279
1280 if (ifibss->privacy)
1281 capability |= WLAN_CAPABILITY_PRIVACY;
1282 1334
1283 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan, 1335 ieee80211_ibss_disconnect(sdata);
1284 ifibss->bssid, ifibss->ssid,
1285 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
1286 WLAN_CAPABILITY_PRIVACY,
1287 capability);
1288
1289 if (cbss) {
1290 cfg80211_unlink_bss(local->hw.wiphy, cbss);
1291 cfg80211_put_bss(local->hw.wiphy, cbss);
1292 }
1293 }
1294
1295 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
1296 memset(ifibss->bssid, 0, ETH_ALEN);
1297 ifibss->ssid_len = 0; 1336 ifibss->ssid_len = 0;
1298 1337 memset(ifibss->bssid, 0, ETH_ALEN);
1299 sta_info_flush(sdata);
1300
1301 spin_lock_bh(&ifibss->incomplete_lock);
1302 while (!list_empty(&ifibss->incomplete_stations)) {
1303 sta = list_first_entry(&ifibss->incomplete_stations,
1304 struct sta_info, list);
1305 list_del(&sta->list);
1306 spin_unlock_bh(&ifibss->incomplete_lock);
1307
1308 sta_info_free(local, sta);
1309 spin_lock_bh(&ifibss->incomplete_lock);
1310 }
1311 spin_unlock_bh(&ifibss->incomplete_lock);
1312
1313 netif_carrier_off(sdata->dev);
1314 1338
1315 /* remove beacon */ 1339 /* remove beacon */
1316 kfree(sdata->u.ibss.ie); 1340 kfree(sdata->u.ibss.ie);
1317 presp = rcu_dereference_protected(ifibss->presp,
1318 lockdep_is_held(&sdata->wdev.mtx));
1319 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1320 1341
1321 /* on the next join, re-program HT parameters */ 1342 /* on the next join, re-program HT parameters */
1322 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa)); 1343 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa));
1323 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask)); 1344 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask));
1324 1345
1325 sdata->vif.bss_conf.ibss_joined = false;
1326 sdata->vif.bss_conf.ibss_creator = false;
1327 sdata->vif.bss_conf.enable_beacon = false;
1328 sdata->vif.bss_conf.ssid_len = 0;
1329 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
1330 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
1331 BSS_CHANGED_IBSS);
1332 ieee80211_vif_release_channel(sdata);
1333 synchronize_rcu(); 1346 synchronize_rcu();
1334 kfree(presp);
1335 1347
1336 skb_queue_purge(&sdata->skb_queue); 1348 skb_queue_purge(&sdata->skb_queue);
1337 1349