aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 13e8c30adf01..b83870bf60fa 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -67,7 +67,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
67{ 67{
68 struct sta_info *s; 68 struct sta_info *s;
69 69
70 s = local->sta_hash[STA_HASH(sta->sta.addr)]; 70 s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
71 lockdep_is_held(&local->sta_lock));
71 if (!s) 72 if (!s)
72 return -ENOENT; 73 return -ENOENT;
73 if (s == sta) { 74 if (s == sta) {
@@ -76,9 +77,11 @@ static int sta_info_hash_del(struct ieee80211_local *local,
76 return 0; 77 return 0;
77 } 78 }
78 79
79 while (s->hnext && s->hnext != sta) 80 while (rcu_access_pointer(s->hnext) &&
80 s = s->hnext; 81 rcu_access_pointer(s->hnext) != sta)
81 if (s->hnext) { 82 s = rcu_dereference_protected(s->hnext,
83 lockdep_is_held(&local->sta_lock));
84 if (rcu_access_pointer(s->hnext)) {
82 rcu_assign_pointer(s->hnext, sta->hnext); 85 rcu_assign_pointer(s->hnext, sta->hnext);
83 return 0; 86 return 0;
84 } 87 }
@@ -228,6 +231,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
228{ 231{
229 struct ieee80211_local *local = sdata->local; 232 struct ieee80211_local *local = sdata->local;
230 struct sta_info *sta; 233 struct sta_info *sta;
234 struct timespec uptime;
231 int i; 235 int i;
232 236
233 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); 237 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -245,6 +249,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
245 sta->sdata = sdata; 249 sta->sdata = sdata;
246 sta->last_rx = jiffies; 250 sta->last_rx = jiffies;
247 251
252 do_posix_clock_monotonic_gettime(&uptime);
253 sta->last_connected = uptime.tv_sec;
248 ewma_init(&sta->avg_signal, 1024, 8); 254 ewma_init(&sta->avg_signal, 1024, 8);
249 255
250 if (sta_prepare_rate_control(local, sta, gfp)) { 256 if (sta_prepare_rate_control(local, sta, gfp)) {
@@ -271,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
271#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 277#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
272 278
273#ifdef CONFIG_MAC80211_MESH 279#ifdef CONFIG_MAC80211_MESH
274 sta->plink_state = PLINK_LISTEN; 280 sta->plink_state = NL80211_PLINK_LISTEN;
275 init_timer(&sta->plink_timer); 281 init_timer(&sta->plink_timer);
276#endif 282#endif
277 283
@@ -584,7 +590,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
584{ 590{
585 unsigned long flags; 591 unsigned long flags;
586 struct sk_buff *skb; 592 struct sk_buff *skb;
587 struct ieee80211_sub_if_data *sdata;
588 593
589 if (skb_queue_empty(&sta->ps_tx_buf)) 594 if (skb_queue_empty(&sta->ps_tx_buf))
590 return false; 595 return false;
@@ -601,7 +606,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
601 if (!skb) 606 if (!skb)
602 break; 607 break;
603 608
604 sdata = sta->sdata;
605 local->total_ps_buffered--; 609 local->total_ps_buffered--;
606#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 610#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
607 printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", 611 printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n",
@@ -609,7 +613,8 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
609#endif 613#endif
610 dev_kfree_skb(skb); 614 dev_kfree_skb(skb);
611 615
612 if (skb_queue_empty(&sta->ps_tx_buf)) 616 if (skb_queue_empty(&sta->ps_tx_buf) &&
617 !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF))
613 sta_info_clear_tim_bit(sta); 618 sta_info_clear_tim_bit(sta);
614 } 619 }
615 620
@@ -650,10 +655,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
650 if (ret) 655 if (ret)
651 return ret; 656 return ret;
652 657
658 mutex_lock(&local->key_mtx);
653 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 659 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
654 ieee80211_key_free(local, sta->gtk[i]); 660 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
655 if (sta->ptk) 661 if (sta->ptk)
656 ieee80211_key_free(local, sta->ptk); 662 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
663 mutex_unlock(&local->key_mtx);
657 664
658 sta->dead = true; 665 sta->dead = true;
659 666
@@ -698,6 +705,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
698#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 705#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
699 cancel_work_sync(&sta->drv_unblock_wk); 706 cancel_work_sync(&sta->drv_unblock_wk);
700 707
708 cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL);
709
701 rate_control_remove_sta_debugfs(sta); 710 rate_control_remove_sta_debugfs(sta);
702 ieee80211_sta_debugfs_remove(sta); 711 ieee80211_sta_debugfs_remove(sta);
703 712
@@ -766,9 +775,8 @@ static void sta_info_cleanup(unsigned long data)
766 if (!timer_needed) 775 if (!timer_needed)
767 return; 776 return;
768 777
769 local->sta_cleanup.expires = 778 mod_timer(&local->sta_cleanup,
770 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 779 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL));
771 add_timer(&local->sta_cleanup);
772} 780}
773 781
774void sta_info_init(struct ieee80211_local *local) 782void sta_info_init(struct ieee80211_local *local)
@@ -781,14 +789,6 @@ void sta_info_init(struct ieee80211_local *local)
781 789
782 setup_timer(&local->sta_cleanup, sta_info_cleanup, 790 setup_timer(&local->sta_cleanup, sta_info_cleanup,
783 (unsigned long)local); 791 (unsigned long)local);
784 local->sta_cleanup.expires =
785 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
786}
787
788int sta_info_start(struct ieee80211_local *local)
789{
790 add_timer(&local->sta_cleanup);
791 return 0;
792} 792}
793 793
794void sta_info_stop(struct ieee80211_local *local) 794void sta_info_stop(struct ieee80211_local *local)
@@ -900,6 +900,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
900 struct ieee80211_local *local = sdata->local; 900 struct ieee80211_local *local = sdata->local;
901 int sent, buffered; 901 int sent, buffered;
902 902
903 clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
903 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 904 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
904 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); 905 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
905 906
@@ -992,3 +993,12 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
992 ieee80211_queue_work(hw, &sta->drv_unblock_wk); 993 ieee80211_queue_work(hw, &sta->drv_unblock_wk);
993} 994}
994EXPORT_SYMBOL(ieee80211_sta_block_awake); 995EXPORT_SYMBOL(ieee80211_sta_block_awake);
996
997void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta)
998{
999 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1000
1001 set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
1002 sta_info_set_tim_bit(sta);
1003}
1004EXPORT_SYMBOL(ieee80211_sta_set_tim);