aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-12-15 05:17:37 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-15 14:46:34 -0500
commit8bf11d8d081106c3cce8281a0150e716f8ac5d22 (patch)
tree2b026b9638f7acad90d4712f1675d80f3247a0d1 /net/mac80211/ibss.c
parent56544160d44c3043c0a7faffa506f616c1bb45f0 (diff)
mac80211: delay IBSS station insertion
In order to notify drivers and simplify the station management code, defer IBSS station insertion to a work item and don't do it directly while receiving a frame. This increases the complexity in IBSS a little bit, but it's pretty straight forward and it allows us to reduce the station management complexity (next patch) considerably. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c154
1 files changed, 122 insertions, 32 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 47e2db9133cb..f8a32bf98216 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -275,6 +275,80 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
275 cbss->tsf); 275 cbss->tsf);
276} 276}
277 277
278static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
279 __acquires(RCU)
280{
281 struct ieee80211_sub_if_data *sdata = sta->sdata;
282 u8 addr[ETH_ALEN];
283
284 memcpy(addr, sta->sta.addr, ETH_ALEN);
285
286#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
287 wiphy_debug(sdata->local->hw.wiphy,
288 "Adding new IBSS station %pM (dev=%s)\n",
289 addr, sdata->name);
290#endif
291
292 sta_info_move_state(sta, IEEE80211_STA_AUTH);
293 sta_info_move_state(sta, IEEE80211_STA_ASSOC);
294 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
295
296 rate_control_rate_init(sta);
297
298 /* If it fails, maybe we raced another insertion? */
299 if (sta_info_insert_rcu(sta))
300 return sta_info_get(sdata, addr);
301 return sta;
302}
303
304static struct sta_info *
305ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
306 const u8 *bssid, const u8 *addr,
307 u32 supp_rates)
308 __acquires(RCU)
309{
310 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
311 struct ieee80211_local *local = sdata->local;
312 struct sta_info *sta;
313 int band = local->hw.conf.channel->band;
314
315 /*
316 * XXX: Consider removing the least recently used entry and
317 * allow new one to be added.
318 */
319 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
320 if (net_ratelimit())
321 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
322 sdata->name, addr);
323 rcu_read_lock();
324 return NULL;
325 }
326
327 if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) {
328 rcu_read_lock();
329 return NULL;
330 }
331
332 if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) {
333 rcu_read_lock();
334 return NULL;
335 }
336
337 sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
338 if (!sta) {
339 rcu_read_lock();
340 return NULL;
341 }
342
343 sta->last_rx = jiffies;
344
345 /* make sure mandatory rates are always added */
346 sta->sta.supp_rates[band] = supp_rates |
347 ieee80211_mandatory_rates(local, band);
348
349 return ieee80211_ibss_finish_sta(sta);
350}
351
278static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 352static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
279 struct ieee80211_mgmt *mgmt, 353 struct ieee80211_mgmt *mgmt,
280 size_t len, 354 size_t len,
@@ -334,10 +408,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
334#endif 408#endif
335 rates_updated = true; 409 rates_updated = true;
336 } 410 }
337 } else 411 } else {
412 rcu_read_unlock();
338 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, 413 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
339 mgmt->sa, supp_rates, 414 mgmt->sa, supp_rates);
340 GFP_ATOMIC); 415 }
341 } 416 }
342 417
343 if (sta && elems->wmm_info) 418 if (sta && elems->wmm_info)
@@ -464,21 +539,17 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
464 ieee80211_sta_join_ibss(sdata, bss); 539 ieee80211_sta_join_ibss(sdata, bss);
465 supp_rates = ieee80211_sta_get_rates(local, elems, band); 540 supp_rates = ieee80211_sta_get_rates(local, elems, band);
466 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 541 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
467 supp_rates, GFP_KERNEL); 542 supp_rates);
543 rcu_read_unlock();
468 } 544 }
469 545
470 put_bss: 546 put_bss:
471 ieee80211_rx_bss_put(local, bss); 547 ieee80211_rx_bss_put(local, bss);
472} 548}
473 549
474/* 550void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
475 * Add a new IBSS station, will also be called by the RX code when, 551 const u8 *bssid, const u8 *addr,
476 * in IBSS mode, receiving a frame from a yet-unknown station, hence 552 u32 supp_rates)
477 * must be callable in atomic context.
478 */
479struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
480 u8 *bssid, u8 *addr, u32 supp_rates,
481 gfp_t gfp)
482{ 553{
483 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 554 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
484 struct ieee80211_local *local = sdata->local; 555 struct ieee80211_local *local = sdata->local;
@@ -493,40 +564,29 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
493 if (net_ratelimit()) 564 if (net_ratelimit())
494 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", 565 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
495 sdata->name, addr); 566 sdata->name, addr);
496 return NULL; 567 return;
497 } 568 }
498 569
499 if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) 570 if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH)
500 return NULL; 571 return;
501 572
502 if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) 573 if (compare_ether_addr(bssid, sdata->u.ibss.bssid))
503 return NULL; 574 return;
504
505#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
506 wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n",
507 addr, sdata->name);
508#endif
509 575
510 sta = sta_info_alloc(sdata, addr, gfp); 576 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
511 if (!sta) 577 if (!sta)
512 return NULL; 578 return;
513 579
514 sta->last_rx = jiffies; 580 sta->last_rx = jiffies;
515 581
516 sta_info_move_state(sta, IEEE80211_STA_AUTH);
517 sta_info_move_state(sta, IEEE80211_STA_ASSOC);
518 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
519
520 /* make sure mandatory rates are always added */ 582 /* make sure mandatory rates are always added */
521 sta->sta.supp_rates[band] = supp_rates | 583 sta->sta.supp_rates[band] = supp_rates |
522 ieee80211_mandatory_rates(local, band); 584 ieee80211_mandatory_rates(local, band);
523 585
524 rate_control_rate_init(sta); 586 spin_lock(&ifibss->incomplete_lock);
525 587 list_add(&sta->list, &ifibss->incomplete_stations);
526 /* If it fails, maybe we raced another insertion? */ 588 spin_unlock(&ifibss->incomplete_lock);
527 if (sta_info_insert(sta)) 589 ieee80211_queue_work(&local->hw, &sdata->work);
528 return sta_info_get(sdata, addr);
529 return sta;
530} 590}
531 591
532static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) 592static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
@@ -865,6 +925,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
865void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) 925void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
866{ 926{
867 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 927 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
928 struct sta_info *sta;
868 929
869 mutex_lock(&ifibss->mtx); 930 mutex_lock(&ifibss->mtx);
870 931
@@ -876,6 +937,19 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
876 if (!ifibss->ssid_len) 937 if (!ifibss->ssid_len)
877 goto out; 938 goto out;
878 939
940 spin_lock_bh(&ifibss->incomplete_lock);
941 while (!list_empty(&ifibss->incomplete_stations)) {
942 sta = list_first_entry(&ifibss->incomplete_stations,
943 struct sta_info, list);
944 list_del(&sta->list);
945 spin_unlock_bh(&ifibss->incomplete_lock);
946
947 ieee80211_ibss_finish_sta(sta);
948 rcu_read_unlock();
949 spin_lock_bh(&ifibss->incomplete_lock);
950 }
951 spin_unlock_bh(&ifibss->incomplete_lock);
952
879 switch (ifibss->state) { 953 switch (ifibss->state) {
880 case IEEE80211_IBSS_MLME_SEARCH: 954 case IEEE80211_IBSS_MLME_SEARCH:
881 ieee80211_sta_find_ibss(sdata); 955 ieee80211_sta_find_ibss(sdata);
@@ -934,6 +1008,8 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
934 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 1008 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
935 (unsigned long) sdata); 1009 (unsigned long) sdata);
936 mutex_init(&ifibss->mtx); 1010 mutex_init(&ifibss->mtx);
1011 INIT_LIST_HEAD(&ifibss->incomplete_stations);
1012 spin_lock_init(&ifibss->incomplete_lock);
937} 1013}
938 1014
939/* scan finished notification */ 1015/* scan finished notification */
@@ -1053,6 +1129,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1053 struct cfg80211_bss *cbss; 1129 struct cfg80211_bss *cbss;
1054 u16 capability; 1130 u16 capability;
1055 int active_ibss; 1131 int active_ibss;
1132 struct sta_info *sta;
1056 1133
1057 mutex_lock(&sdata->u.ibss.mtx); 1134 mutex_lock(&sdata->u.ibss.mtx);
1058 1135
@@ -1081,6 +1158,19 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1081 } 1158 }
1082 1159
1083 sta_info_flush(sdata->local, sdata); 1160 sta_info_flush(sdata->local, sdata);
1161
1162 spin_lock_bh(&ifibss->incomplete_lock);
1163 while (!list_empty(&ifibss->incomplete_stations)) {
1164 sta = list_first_entry(&ifibss->incomplete_stations,
1165 struct sta_info, list);
1166 list_del(&sta->list);
1167 spin_unlock_bh(&ifibss->incomplete_lock);
1168
1169 sta_info_free(local, sta);
1170 spin_lock_bh(&ifibss->incomplete_lock);
1171 }
1172 spin_unlock_bh(&ifibss->incomplete_lock);
1173
1084 netif_carrier_off(sdata->dev); 1174 netif_carrier_off(sdata->dev);
1085 1175
1086 /* remove beacon */ 1176 /* remove beacon */