aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/sta_info.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 62a5f0889583..ffc1ee6a2ec1 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
91 return -ENOENT; 91 return -ENOENT;
92} 92}
93 93
94static void cleanup_single_sta(struct sta_info *sta) 94static void __cleanup_single_sta(struct sta_info *sta)
95{ 95{
96 int ac, i; 96 int ac, i;
97 struct tid_ampdu_tx *tid_tx; 97 struct tid_ampdu_tx *tid_tx;
@@ -139,7 +139,14 @@ static void cleanup_single_sta(struct sta_info *sta)
139 ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); 139 ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
140 kfree(tid_tx); 140 kfree(tid_tx);
141 } 141 }
142}
142 143
144static void cleanup_single_sta(struct sta_info *sta)
145{
146 struct ieee80211_sub_if_data *sdata = sta->sdata;
147 struct ieee80211_local *local = sdata->local;
148
149 __cleanup_single_sta(sta);
143 sta_info_free(local, sta); 150 sta_info_free(local, sta);
144} 151}
145 152
@@ -488,21 +495,26 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
488 goto out_err; 495 goto out_err;
489 } 496 }
490 497
491 /* notify driver */
492 err = sta_info_insert_drv_state(local, sdata, sta);
493 if (err)
494 goto out_err;
495
496 local->num_sta++; 498 local->num_sta++;
497 local->sta_generation++; 499 local->sta_generation++;
498 smp_mb(); 500 smp_mb();
499 501
502 /* simplify things and don't accept BA sessions yet */
503 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
504
500 /* make the station visible */ 505 /* make the station visible */
501 sta_info_hash_add(local, sta); 506 sta_info_hash_add(local, sta);
502 507
503 list_add_rcu(&sta->list, &local->sta_list); 508 list_add_rcu(&sta->list, &local->sta_list);
504 509
510 /* notify driver */
511 err = sta_info_insert_drv_state(local, sdata, sta);
512 if (err)
513 goto out_remove;
514
505 set_sta_flag(sta, WLAN_STA_INSERTED); 515 set_sta_flag(sta, WLAN_STA_INSERTED);
516 /* accept BA sessions now */
517 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
506 518
507 ieee80211_recalc_min_chandef(sdata); 519 ieee80211_recalc_min_chandef(sdata);
508 ieee80211_sta_debugfs_add(sta); 520 ieee80211_sta_debugfs_add(sta);
@@ -523,6 +535,12 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
523 mesh_accept_plinks_update(sdata); 535 mesh_accept_plinks_update(sdata);
524 536
525 return 0; 537 return 0;
538 out_remove:
539 sta_info_hash_del(local, sta);
540 list_del_rcu(&sta->list);
541 local->num_sta--;
542 synchronize_net();
543 __cleanup_single_sta(sta);
526 out_err: 544 out_err:
527 mutex_unlock(&local->sta_mtx); 545 mutex_unlock(&local->sta_mtx);
528 rcu_read_lock(); 546 rcu_read_lock();