aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-12-15 05:24:20 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-15 14:46:35 -0500
commit4d33960bf9fa2c0ee82ba7120e7b56c766dd3a86 (patch)
treeb75891edc02c3aa754a9fd32e34f408051e77983 /net/mac80211
parent8bf11d8d081106c3cce8281a0150e716f8ac5d22 (diff)
mac80211: reduce station management complexity
Now that IBSS no longer needs to insert stations from atomic context, we can get rid of all the special cases for that, and even get rid of the sta_lock (though it needs to stay as tim_lock.) This makes the station management code much more straight-forward. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/sta_info.c251
-rw-r--r--net/mac80211/tx.c4
3 files changed, 63 insertions, 203 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index eca6063e287c..8e5b892834bc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -855,18 +855,15 @@ struct ieee80211_local {
855 855
856 /* Station data */ 856 /* Station data */
857 /* 857 /*
858 * The mutex only protects the list and counter, 858 * The mutex only protects the list, hash table and
859 * reads are done in RCU. 859 * counter, reads are done with RCU.
860 * Additionally, the lock protects the hash table,
861 * the pending list and each BSS's TIM bitmap.
862 */ 860 */
863 struct mutex sta_mtx; 861 struct mutex sta_mtx;
864 spinlock_t sta_lock; 862 spinlock_t tim_lock;
865 unsigned long num_sta; 863 unsigned long num_sta;
866 struct list_head sta_list, sta_pending_list; 864 struct list_head sta_list;
867 struct sta_info __rcu *sta_hash[STA_HASH_SIZE]; 865 struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
868 struct timer_list sta_cleanup; 866 struct timer_list sta_cleanup;
869 struct work_struct sta_finish_work;
870 int sta_generation; 867 int sta_generation;
871 868
872 struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; 869 struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index aa9293d7f3f0..2db01e9541e7 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -62,14 +62,14 @@
62 * freed before they are done using it. 62 * freed before they are done using it.
63 */ 63 */
64 64
65/* Caller must hold local->sta_lock */ 65/* Caller must hold local->sta_mtx */
66static int sta_info_hash_del(struct ieee80211_local *local, 66static int sta_info_hash_del(struct ieee80211_local *local,
67 struct sta_info *sta) 67 struct sta_info *sta)
68{ 68{
69 struct sta_info *s; 69 struct sta_info *s;
70 70
71 s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)], 71 s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
72 lockdep_is_held(&local->sta_lock)); 72 lockdep_is_held(&local->sta_mtx));
73 if (!s) 73 if (!s)
74 return -ENOENT; 74 return -ENOENT;
75 if (s == sta) { 75 if (s == sta) {
@@ -81,7 +81,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
81 while (rcu_access_pointer(s->hnext) && 81 while (rcu_access_pointer(s->hnext) &&
82 rcu_access_pointer(s->hnext) != sta) 82 rcu_access_pointer(s->hnext) != sta)
83 s = rcu_dereference_protected(s->hnext, 83 s = rcu_dereference_protected(s->hnext,
84 lockdep_is_held(&local->sta_lock)); 84 lockdep_is_held(&local->sta_mtx));
85 if (rcu_access_pointer(s->hnext)) { 85 if (rcu_access_pointer(s->hnext)) {
86 RCU_INIT_POINTER(s->hnext, sta->hnext); 86 RCU_INIT_POINTER(s->hnext, sta->hnext);
87 return 0; 87 return 0;
@@ -98,14 +98,12 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
98 struct sta_info *sta; 98 struct sta_info *sta;
99 99
100 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], 100 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
101 lockdep_is_held(&local->sta_lock) ||
102 lockdep_is_held(&local->sta_mtx)); 101 lockdep_is_held(&local->sta_mtx));
103 while (sta) { 102 while (sta) {
104 if (sta->sdata == sdata && !sta->dummy && 103 if (sta->sdata == sdata && !sta->dummy &&
105 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
106 break; 105 break;
107 sta = rcu_dereference_check(sta->hnext, 106 sta = rcu_dereference_check(sta->hnext,
108 lockdep_is_held(&local->sta_lock) ||
109 lockdep_is_held(&local->sta_mtx)); 107 lockdep_is_held(&local->sta_mtx));
110 } 108 }
111 return sta; 109 return sta;
@@ -119,14 +117,12 @@ struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
119 struct sta_info *sta; 117 struct sta_info *sta;
120 118
121 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], 119 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
122 lockdep_is_held(&local->sta_lock) ||
123 lockdep_is_held(&local->sta_mtx)); 120 lockdep_is_held(&local->sta_mtx));
124 while (sta) { 121 while (sta) {
125 if (sta->sdata == sdata && 122 if (sta->sdata == sdata &&
126 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 123 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
127 break; 124 break;
128 sta = rcu_dereference_check(sta->hnext, 125 sta = rcu_dereference_check(sta->hnext,
129 lockdep_is_held(&local->sta_lock) ||
130 lockdep_is_held(&local->sta_mtx)); 126 lockdep_is_held(&local->sta_mtx));
131 } 127 }
132 return sta; 128 return sta;
@@ -143,7 +139,6 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
143 struct sta_info *sta; 139 struct sta_info *sta;
144 140
145 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], 141 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
146 lockdep_is_held(&local->sta_lock) ||
147 lockdep_is_held(&local->sta_mtx)); 142 lockdep_is_held(&local->sta_mtx));
148 while (sta) { 143 while (sta) {
149 if ((sta->sdata == sdata || 144 if ((sta->sdata == sdata ||
@@ -152,7 +147,6 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
152 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 147 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
153 break; 148 break;
154 sta = rcu_dereference_check(sta->hnext, 149 sta = rcu_dereference_check(sta->hnext,
155 lockdep_is_held(&local->sta_lock) ||
156 lockdep_is_held(&local->sta_mtx)); 150 lockdep_is_held(&local->sta_mtx));
157 } 151 }
158 return sta; 152 return sta;
@@ -169,7 +163,6 @@ struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
169 struct sta_info *sta; 163 struct sta_info *sta;
170 164
171 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], 165 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
172 lockdep_is_held(&local->sta_lock) ||
173 lockdep_is_held(&local->sta_mtx)); 166 lockdep_is_held(&local->sta_mtx));
174 while (sta) { 167 while (sta) {
175 if ((sta->sdata == sdata || 168 if ((sta->sdata == sdata ||
@@ -177,7 +170,6 @@ struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
177 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 170 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
178 break; 171 break;
179 sta = rcu_dereference_check(sta->hnext, 172 sta = rcu_dereference_check(sta->hnext,
180 lockdep_is_held(&local->sta_lock) ||
181 lockdep_is_held(&local->sta_mtx)); 173 lockdep_is_held(&local->sta_mtx));
182 } 174 }
183 return sta; 175 return sta;
@@ -228,10 +220,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
228 kfree(sta); 220 kfree(sta);
229} 221}
230 222
231/* Caller must hold local->sta_lock */ 223/* Caller must hold local->sta_mtx */
232static void sta_info_hash_add(struct ieee80211_local *local, 224static void sta_info_hash_add(struct ieee80211_local *local,
233 struct sta_info *sta) 225 struct sta_info *sta)
234{ 226{
227 lockdep_assert_held(&local->sta_mtx);
235 sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)]; 228 sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)];
236 RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)], sta); 229 RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
237} 230}
@@ -339,89 +332,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
339 return sta; 332 return sta;
340} 333}
341 334
342static int sta_info_finish_insert(struct sta_info *sta,
343 bool async, bool dummy_reinsert)
344{
345 struct ieee80211_local *local = sta->local;
346 struct ieee80211_sub_if_data *sdata = sta->sdata;
347 struct station_info sinfo;
348 unsigned long flags;
349 int err = 0;
350
351 lockdep_assert_held(&local->sta_mtx);
352
353 if (!sta->dummy || dummy_reinsert) {
354 /* notify driver */
355 err = drv_sta_add(local, sdata, &sta->sta);
356 if (err) {
357 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
358 return err;
359 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
360 "driver (%d) - keeping it anyway.\n",
361 sdata->name, sta->sta.addr, err);
362 } else
363 sta->uploaded = true;
364
365 sdata = sta->sdata;
366 }
367
368 if (!dummy_reinsert) {
369 local->num_sta++;
370 local->sta_generation++;
371 smp_mb();
372
373 /* make the station visible */
374 spin_lock_irqsave(&local->sta_lock, flags);
375 sta_info_hash_add(local, sta);
376 spin_unlock_irqrestore(&local->sta_lock, flags);
377
378 list_add(&sta->list, &local->sta_list);
379 } else {
380 sta->dummy = false;
381 }
382
383 if (!sta->dummy) {
384 ieee80211_sta_debugfs_add(sta);
385 rate_control_add_sta_debugfs(sta);
386
387 memset(&sinfo, 0, sizeof(sinfo));
388 sinfo.filled = 0;
389 sinfo.generation = local->sta_generation;
390 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
391 }
392
393 return 0;
394}
395
396static void sta_info_finish_pending(struct ieee80211_local *local)
397{
398 struct sta_info *sta;
399 unsigned long flags;
400
401 spin_lock_irqsave(&local->sta_lock, flags);
402 while (!list_empty(&local->sta_pending_list)) {
403 sta = list_first_entry(&local->sta_pending_list,
404 struct sta_info, list);
405 list_del(&sta->list);
406 spin_unlock_irqrestore(&local->sta_lock, flags);
407
408 sta_info_finish_insert(sta, true, false);
409
410 spin_lock_irqsave(&local->sta_lock, flags);
411 }
412 spin_unlock_irqrestore(&local->sta_lock, flags);
413}
414
415static void sta_info_finish_work(struct work_struct *work)
416{
417 struct ieee80211_local *local =
418 container_of(work, struct ieee80211_local, sta_finish_work);
419
420 mutex_lock(&local->sta_mtx);
421 sta_info_finish_pending(local);
422 mutex_unlock(&local->sta_mtx);
423}
424
425static int sta_info_insert_check(struct sta_info *sta) 335static int sta_info_insert_check(struct sta_info *sta)
426{ 336{
427 struct ieee80211_sub_if_data *sdata = sta->sdata; 337 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -441,50 +351,15 @@ static int sta_info_insert_check(struct sta_info *sta)
441 return 0; 351 return 0;
442} 352}
443 353
444static int sta_info_insert_ibss(struct sta_info *sta) __acquires(RCU)
445{
446 struct ieee80211_local *local = sta->local;
447 struct ieee80211_sub_if_data *sdata = sta->sdata;
448 unsigned long flags;
449
450 spin_lock_irqsave(&local->sta_lock, flags);
451 /* check if STA exists already */
452 if (sta_info_get_bss_rx(sdata, sta->sta.addr)) {
453 spin_unlock_irqrestore(&local->sta_lock, flags);
454 rcu_read_lock();
455 return -EEXIST;
456 }
457
458 local->num_sta++;
459 local->sta_generation++;
460 smp_mb();
461 sta_info_hash_add(local, sta);
462
463 list_add_tail(&sta->list, &local->sta_pending_list);
464
465 rcu_read_lock();
466 spin_unlock_irqrestore(&local->sta_lock, flags);
467
468#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
469 wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n",
470 sta->sta.addr);
471#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
472
473 ieee80211_queue_work(&local->hw, &local->sta_finish_work);
474
475 return 0;
476}
477
478/* 354/*
479 * should be called with sta_mtx locked 355 * should be called with sta_mtx locked
480 * this function replaces the mutex lock 356 * this function replaces the mutex lock
481 * with a RCU lock 357 * with a RCU lock
482 */ 358 */
483static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU) 359static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
484{ 360{
485 struct ieee80211_local *local = sta->local; 361 struct ieee80211_local *local = sta->local;
486 struct ieee80211_sub_if_data *sdata = sta->sdata; 362 struct ieee80211_sub_if_data *sdata = sta->sdata;
487 unsigned long flags;
488 struct sta_info *exist_sta; 363 struct sta_info *exist_sta;
489 bool dummy_reinsert = false; 364 bool dummy_reinsert = false;
490 int err = 0; 365 int err = 0;
@@ -492,19 +367,8 @@ static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU)
492 lockdep_assert_held(&local->sta_mtx); 367 lockdep_assert_held(&local->sta_mtx);
493 368
494 /* 369 /*
495 * On first glance, this will look racy, because the code
496 * in this function, which inserts a station with sleeping,
497 * unlocks the sta_lock between checking existence in the
498 * hash table and inserting into it.
499 *
500 * However, it is not racy against itself because it keeps
501 * the mutex locked.
502 */
503
504 spin_lock_irqsave(&local->sta_lock, flags);
505 /*
506 * check if STA exists already. 370 * check if STA exists already.
507 * only accept a scenario of a second call to sta_info_insert_non_ibss 371 * only accept a scenario of a second call to sta_info_insert_finish
508 * with a dummy station entry that was inserted earlier 372 * with a dummy station entry that was inserted earlier
509 * in that case - assume that the dummy station flag should 373 * in that case - assume that the dummy station flag should
510 * be removed. 374 * be removed.
@@ -514,20 +378,47 @@ static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU)
514 if (exist_sta == sta && sta->dummy) { 378 if (exist_sta == sta && sta->dummy) {
515 dummy_reinsert = true; 379 dummy_reinsert = true;
516 } else { 380 } else {
517 spin_unlock_irqrestore(&local->sta_lock, flags); 381 err = -EEXIST;
518 mutex_unlock(&local->sta_mtx); 382 goto out_err;
519 rcu_read_lock();
520 return -EEXIST;
521 } 383 }
522 } 384 }
523 385
524 spin_unlock_irqrestore(&local->sta_lock, flags); 386 if (!sta->dummy || dummy_reinsert) {
387 /* notify driver */
388 err = drv_sta_add(local, sdata, &sta->sta);
389 if (err) {
390 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
391 goto out_err;
392 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
393 "driver (%d) - keeping it anyway.\n",
394 sdata->name, sta->sta.addr, err);
395 } else
396 sta->uploaded = true;
397 }
525 398
526 err = sta_info_finish_insert(sta, false, dummy_reinsert); 399 if (!dummy_reinsert) {
527 if (err) { 400 local->num_sta++;
528 mutex_unlock(&local->sta_mtx); 401 local->sta_generation++;
529 rcu_read_lock(); 402 smp_mb();
530 return err; 403
404 /* make the station visible */
405 sta_info_hash_add(local, sta);
406
407 list_add(&sta->list, &local->sta_list);
408 } else {
409 sta->dummy = false;
410 }
411
412 if (!sta->dummy) {
413 struct station_info sinfo;
414
415 ieee80211_sta_debugfs_add(sta);
416 rate_control_add_sta_debugfs(sta);
417
418 memset(&sinfo, 0, sizeof(sinfo));
419 sinfo.filled = 0;
420 sinfo.generation = local->sta_generation;
421 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
531 } 422 }
532 423
533#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 424#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -543,47 +434,28 @@ static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU)
543 mesh_accept_plinks_update(sdata); 434 mesh_accept_plinks_update(sdata);
544 435
545 return 0; 436 return 0;
437 out_err:
438 mutex_unlock(&local->sta_mtx);
439 rcu_read_lock();
440 return err;
546} 441}
547 442
548int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) 443int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
549{ 444{
550 struct ieee80211_local *local = sta->local; 445 struct ieee80211_local *local = sta->local;
551 struct ieee80211_sub_if_data *sdata = sta->sdata;
552 int err = 0; 446 int err = 0;
553 447
448 might_sleep();
449
554 err = sta_info_insert_check(sta); 450 err = sta_info_insert_check(sta);
555 if (err) { 451 if (err) {
556 rcu_read_lock(); 452 rcu_read_lock();
557 goto out_free; 453 goto out_free;
558 } 454 }
559 455
560 /*
561 * In ad-hoc mode, we sometimes need to insert stations
562 * from tasklet context from the RX path. To avoid races,
563 * always do so in that case -- see the comment below.
564 */
565 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
566 err = sta_info_insert_ibss(sta);
567 if (err)
568 goto out_free;
569
570 return 0;
571 }
572
573 /*
574 * It might seem that the function called below is in race against
575 * the function call above that atomically inserts the station... That,
576 * however, is not true because the above code can only
577 * be invoked for IBSS interfaces, and the below code will
578 * not be -- and the two do not race against each other as
579 * the hash table also keys off the interface.
580 */
581
582 might_sleep();
583
584 mutex_lock(&local->sta_mtx); 456 mutex_lock(&local->sta_mtx);
585 457
586 err = sta_info_insert_non_ibss(sta); 458 err = sta_info_insert_finish(sta);
587 if (err) 459 if (err)
588 goto out_free; 460 goto out_free;
589 461
@@ -617,7 +489,7 @@ int sta_info_reinsert(struct sta_info *sta)
617 489
618 might_sleep(); 490 might_sleep();
619 491
620 err = sta_info_insert_non_ibss(sta); 492 err = sta_info_insert_finish(sta);
621 rcu_read_unlock(); 493 rcu_read_unlock();
622 return err; 494 return err;
623} 495}
@@ -704,7 +576,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
704 } 576 }
705 577
706 done: 578 done:
707 spin_lock_irqsave(&local->sta_lock, flags); 579 spin_lock_irqsave(&local->tim_lock, flags);
708 580
709 if (indicate_tim) 581 if (indicate_tim)
710 __bss_tim_set(bss, sta->sta.aid); 582 __bss_tim_set(bss, sta->sta.aid);
@@ -717,7 +589,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
717 local->tim_in_locked_section = false; 589 local->tim_in_locked_section = false;
718 } 590 }
719 591
720 spin_unlock_irqrestore(&local->sta_lock, flags); 592 spin_unlock_irqrestore(&local->tim_lock, flags);
721} 593}
722 594
723static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) 595static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb)
@@ -841,7 +713,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
841{ 713{
842 struct ieee80211_local *local; 714 struct ieee80211_local *local;
843 struct ieee80211_sub_if_data *sdata; 715 struct ieee80211_sub_if_data *sdata;
844 unsigned long flags;
845 int ret, i, ac; 716 int ret, i, ac;
846 struct tid_ampdu_tx *tid_tx; 717 struct tid_ampdu_tx *tid_tx;
847 718
@@ -862,15 +733,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
862 set_sta_flag(sta, WLAN_STA_BLOCK_BA); 733 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
863 ieee80211_sta_tear_down_BA_sessions(sta, true); 734 ieee80211_sta_tear_down_BA_sessions(sta, true);
864 735
865 spin_lock_irqsave(&local->sta_lock, flags);
866 ret = sta_info_hash_del(local, sta); 736 ret = sta_info_hash_del(local, sta);
867 /* this might still be the pending list ... which is fine */
868 if (!ret)
869 list_del(&sta->list);
870 spin_unlock_irqrestore(&local->sta_lock, flags);
871 if (ret) 737 if (ret)
872 return ret; 738 return ret;
873 739
740 list_del(&sta->list);
741
874 mutex_lock(&local->key_mtx); 742 mutex_lock(&local->key_mtx);
875 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 743 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
876 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); 744 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
@@ -1025,11 +893,9 @@ static void sta_info_cleanup(unsigned long data)
1025 893
1026void sta_info_init(struct ieee80211_local *local) 894void sta_info_init(struct ieee80211_local *local)
1027{ 895{
1028 spin_lock_init(&local->sta_lock); 896 spin_lock_init(&local->tim_lock);
1029 mutex_init(&local->sta_mtx); 897 mutex_init(&local->sta_mtx);
1030 INIT_LIST_HEAD(&local->sta_list); 898 INIT_LIST_HEAD(&local->sta_list);
1031 INIT_LIST_HEAD(&local->sta_pending_list);
1032 INIT_WORK(&local->sta_finish_work, sta_info_finish_work);
1033 899
1034 setup_timer(&local->sta_cleanup, sta_info_cleanup, 900 setup_timer(&local->sta_cleanup, sta_info_cleanup,
1035 (unsigned long)local); 901 (unsigned long)local);
@@ -1058,9 +924,6 @@ int sta_info_flush(struct ieee80211_local *local,
1058 might_sleep(); 924 might_sleep();
1059 925
1060 mutex_lock(&local->sta_mtx); 926 mutex_lock(&local->sta_mtx);
1061
1062 sta_info_finish_pending(local);
1063
1064 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 927 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
1065 if (!sdata || sdata == sta->sdata) 928 if (!sdata || sdata == sta->sdata)
1066 WARN_ON(__sta_info_destroy(sta)); 929 WARN_ON(__sta_info_destroy(sta));
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6bbd6cccb4a0..ab033fd00b72 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2333,9 +2333,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2333 } else { 2333 } else {
2334 unsigned long flags; 2334 unsigned long flags;
2335 2335
2336 spin_lock_irqsave(&local->sta_lock, flags); 2336 spin_lock_irqsave(&local->tim_lock, flags);
2337 ieee80211_beacon_add_tim(ap, skb, beacon); 2337 ieee80211_beacon_add_tim(ap, skb, beacon);
2338 spin_unlock_irqrestore(&local->sta_lock, flags); 2338 spin_unlock_irqrestore(&local->tim_lock, flags);
2339 } 2339 }
2340 2340
2341 if (tim_offset) 2341 if (tim_offset)