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.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ff0eb948917..730197591ab 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -575,7 +575,7 @@ static int sta_info_buffer_expired(struct sta_info *sta,
575} 575}
576 576
577 577
578static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 578static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
579 struct sta_info *sta) 579 struct sta_info *sta)
580{ 580{
581 unsigned long flags; 581 unsigned long flags;
@@ -583,7 +583,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
583 struct ieee80211_sub_if_data *sdata; 583 struct ieee80211_sub_if_data *sdata;
584 584
585 if (skb_queue_empty(&sta->ps_tx_buf)) 585 if (skb_queue_empty(&sta->ps_tx_buf))
586 return; 586 return false;
587 587
588 for (;;) { 588 for (;;) {
589 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 589 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
@@ -608,6 +608,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
608 if (skb_queue_empty(&sta->ps_tx_buf)) 608 if (skb_queue_empty(&sta->ps_tx_buf))
609 sta_info_clear_tim_bit(sta); 609 sta_info_clear_tim_bit(sta);
610 } 610 }
611
612 return true;
611} 613}
612 614
613static int __must_check __sta_info_destroy(struct sta_info *sta) 615static int __must_check __sta_info_destroy(struct sta_info *sta)
@@ -755,15 +757,20 @@ static void sta_info_cleanup(unsigned long data)
755{ 757{
756 struct ieee80211_local *local = (struct ieee80211_local *) data; 758 struct ieee80211_local *local = (struct ieee80211_local *) data;
757 struct sta_info *sta; 759 struct sta_info *sta;
760 bool timer_needed = false;
758 761
759 rcu_read_lock(); 762 rcu_read_lock();
760 list_for_each_entry_rcu(sta, &local->sta_list, list) 763 list_for_each_entry_rcu(sta, &local->sta_list, list)
761 sta_info_cleanup_expire_buffered(local, sta); 764 if (sta_info_cleanup_expire_buffered(local, sta))
765 timer_needed = true;
762 rcu_read_unlock(); 766 rcu_read_unlock();
763 767
764 if (local->quiescing) 768 if (local->quiescing)
765 return; 769 return;
766 770
771 if (!timer_needed)
772 return;
773
767 local->sta_cleanup.expires = 774 local->sta_cleanup.expires =
768 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 775 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
769 add_timer(&local->sta_cleanup); 776 add_timer(&local->sta_cleanup);
@@ -848,8 +855,12 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
848 struct sta_info *sta, *nxt; 855 struct sta_info *sta, *nxt;
849 856
850 /* Just return a random station ... first in list ... */ 857 /* Just return a random station ... first in list ... */
851 for_each_sta_info(hw_to_local(hw), addr, sta, nxt) 858 for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
859 if (!sta->uploaded)
860 return NULL;
852 return &sta->sta; 861 return &sta->sta;
862 }
863
853 return NULL; 864 return NULL;
854} 865}
855EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); 866EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
@@ -857,14 +868,19 @@ EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
857struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, 868struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
858 const u8 *addr) 869 const u8 *addr)
859{ 870{
860 struct ieee80211_sub_if_data *sdata; 871 struct sta_info *sta;
861 872
862 if (!vif) 873 if (!vif)
863 return NULL; 874 return NULL;
864 875
865 sdata = vif_to_sdata(vif); 876 sta = sta_info_get_bss(vif_to_sdata(vif), addr);
877 if (!sta)
878 return NULL;
879
880 if (!sta->uploaded)
881 return NULL;
866 882
867 return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); 883 return &sta->sta;
868} 884}
869EXPORT_SYMBOL(ieee80211_find_sta); 885EXPORT_SYMBOL(ieee80211_find_sta);
870 886