diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 71 |
1 files changed, 1 insertions, 70 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index c5f14e6bbde2..654a8e963ccb 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -686,41 +686,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work) | |||
686 | } | 686 | } |
687 | #endif | 687 | #endif |
688 | 688 | ||
689 | static void __ieee80211_run_pending_flush(struct ieee80211_local *local) | ||
690 | { | ||
691 | struct sta_info *sta; | ||
692 | unsigned long flags; | ||
693 | |||
694 | ASSERT_RTNL(); | ||
695 | |||
696 | spin_lock_irqsave(&local->sta_lock, flags); | ||
697 | while (!list_empty(&local->sta_flush_list)) { | ||
698 | sta = list_first_entry(&local->sta_flush_list, | ||
699 | struct sta_info, list); | ||
700 | list_del(&sta->list); | ||
701 | spin_unlock_irqrestore(&local->sta_lock, flags); | ||
702 | sta_info_destroy(sta); | ||
703 | spin_lock_irqsave(&local->sta_lock, flags); | ||
704 | } | ||
705 | spin_unlock_irqrestore(&local->sta_lock, flags); | ||
706 | } | ||
707 | |||
708 | static void ieee80211_sta_flush_work(struct work_struct *work) | ||
709 | { | ||
710 | struct ieee80211_local *local = | ||
711 | container_of(work, struct ieee80211_local, sta_flush_work); | ||
712 | |||
713 | rtnl_lock(); | ||
714 | __ieee80211_run_pending_flush(local); | ||
715 | rtnl_unlock(); | ||
716 | } | ||
717 | |||
718 | void sta_info_init(struct ieee80211_local *local) | 689 | void sta_info_init(struct ieee80211_local *local) |
719 | { | 690 | { |
720 | spin_lock_init(&local->sta_lock); | 691 | spin_lock_init(&local->sta_lock); |
721 | INIT_LIST_HEAD(&local->sta_list); | 692 | INIT_LIST_HEAD(&local->sta_list); |
722 | INIT_LIST_HEAD(&local->sta_flush_list); | ||
723 | INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work); | ||
724 | 693 | ||
725 | setup_timer(&local->sta_cleanup, sta_info_cleanup, | 694 | setup_timer(&local->sta_cleanup, sta_info_cleanup, |
726 | (unsigned long)local); | 695 | (unsigned long)local); |
@@ -741,7 +710,6 @@ int sta_info_start(struct ieee80211_local *local) | |||
741 | void sta_info_stop(struct ieee80211_local *local) | 710 | void sta_info_stop(struct ieee80211_local *local) |
742 | { | 711 | { |
743 | del_timer(&local->sta_cleanup); | 712 | del_timer(&local->sta_cleanup); |
744 | cancel_work_sync(&local->sta_flush_work); | ||
745 | #ifdef CONFIG_MAC80211_DEBUGFS | 713 | #ifdef CONFIG_MAC80211_DEBUGFS |
746 | /* | 714 | /* |
747 | * Make sure the debugfs adding work isn't pending after this | 715 | * Make sure the debugfs adding work isn't pending after this |
@@ -752,10 +720,7 @@ void sta_info_stop(struct ieee80211_local *local) | |||
752 | cancel_work_sync(&local->sta_debugfs_add); | 720 | cancel_work_sync(&local->sta_debugfs_add); |
753 | #endif | 721 | #endif |
754 | 722 | ||
755 | rtnl_lock(); | ||
756 | sta_info_flush(local, NULL); | 723 | sta_info_flush(local, NULL); |
757 | __ieee80211_run_pending_flush(local); | ||
758 | rtnl_unlock(); | ||
759 | } | 724 | } |
760 | 725 | ||
761 | /** | 726 | /** |
@@ -767,7 +732,7 @@ void sta_info_stop(struct ieee80211_local *local) | |||
767 | * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs | 732 | * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs |
768 | */ | 733 | */ |
769 | int sta_info_flush(struct ieee80211_local *local, | 734 | int sta_info_flush(struct ieee80211_local *local, |
770 | struct ieee80211_sub_if_data *sdata) | 735 | struct ieee80211_sub_if_data *sdata) |
771 | { | 736 | { |
772 | struct sta_info *sta, *tmp; | 737 | struct sta_info *sta, *tmp; |
773 | LIST_HEAD(tmp_list); | 738 | LIST_HEAD(tmp_list); |
@@ -775,7 +740,6 @@ int sta_info_flush(struct ieee80211_local *local, | |||
775 | unsigned long flags; | 740 | unsigned long flags; |
776 | 741 | ||
777 | might_sleep(); | 742 | might_sleep(); |
778 | ASSERT_RTNL(); | ||
779 | 743 | ||
780 | spin_lock_irqsave(&local->sta_lock, flags); | 744 | spin_lock_irqsave(&local->sta_lock, flags); |
781 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { | 745 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { |
@@ -795,39 +759,6 @@ int sta_info_flush(struct ieee80211_local *local, | |||
795 | return ret; | 759 | return ret; |
796 | } | 760 | } |
797 | 761 | ||
798 | /** | ||
799 | * sta_info_flush_delayed - flush matching STA entries from the STA table | ||
800 | * | ||
801 | * This function unlinks all stations for a given interface and queues | ||
802 | * them for freeing. Note that the workqueue function scheduled here has | ||
803 | * to run before any new keys can be added to the system to avoid set_key() | ||
804 | * callback ordering issues. | ||
805 | * | ||
806 | * @sdata: the interface | ||
807 | */ | ||
808 | void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata) | ||
809 | { | ||
810 | struct ieee80211_local *local = sdata->local; | ||
811 | struct sta_info *sta, *tmp; | ||
812 | unsigned long flags; | ||
813 | bool work = false; | ||
814 | |||
815 | spin_lock_irqsave(&local->sta_lock, flags); | ||
816 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { | ||
817 | if (sdata == sta->sdata) { | ||
818 | __sta_info_unlink(&sta); | ||
819 | if (sta) { | ||
820 | list_add_tail(&sta->list, | ||
821 | &local->sta_flush_list); | ||
822 | work = true; | ||
823 | } | ||
824 | } | ||
825 | } | ||
826 | if (work) | ||
827 | schedule_work(&local->sta_flush_work); | ||
828 | spin_unlock_irqrestore(&local->sta_lock, flags); | ||
829 | } | ||
830 | |||
831 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 762 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, |
832 | unsigned long exp_time) | 763 | unsigned long exp_time) |
833 | { | 764 | { |