aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c8
-rw-r--r--net/mac80211/scan.c30
-rw-r--r--net/mac80211/work.c35
5 files changed, 38 insertions, 43 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 79d56454484a..fb4363e148f2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -634,7 +634,6 @@ struct ieee80211_local {
634 /* 634 /*
635 * work stuff, potentially off-channel (in the future) 635 * work stuff, potentially off-channel (in the future)
636 */ 636 */
637 struct mutex work_mtx;
638 struct list_head work_list; 637 struct list_head work_list;
639 struct timer_list work_timer; 638 struct timer_list work_timer;
640 struct work_struct work_work; 639 struct work_struct work_work;
@@ -746,9 +745,10 @@ struct ieee80211_local {
746 */ 745 */
747 struct mutex key_mtx; 746 struct mutex key_mtx;
748 747
748 /* mutex for scan and work locking */
749 struct mutex mtx;
749 750
750 /* Scanning and BSS list */ 751 /* Scanning and BSS list */
751 struct mutex scan_mtx;
752 unsigned long scanning; 752 unsigned long scanning;
753 struct cfg80211_ssid scan_ssid; 753 struct cfg80211_ssid scan_ssid;
754 struct cfg80211_scan_request *int_scan_req; 754 struct cfg80211_scan_request *int_scan_req;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 18b8df922c60..06b9608a2130 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -482,7 +482,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
482 __hw_addr_init(&local->mc_list); 482 __hw_addr_init(&local->mc_list);
483 483
484 mutex_init(&local->iflist_mtx); 484 mutex_init(&local->iflist_mtx);
485 mutex_init(&local->scan_mtx); 485 mutex_init(&local->mtx);
486 486
487 mutex_init(&local->key_mtx); 487 mutex_init(&local->key_mtx);
488 spin_lock_init(&local->filter_lock); 488 spin_lock_init(&local->filter_lock);
@@ -791,7 +791,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
791 struct ieee80211_local *local = hw_to_local(hw); 791 struct ieee80211_local *local = hw_to_local(hw);
792 792
793 mutex_destroy(&local->iflist_mtx); 793 mutex_destroy(&local->iflist_mtx);
794 mutex_destroy(&local->scan_mtx); 794 mutex_destroy(&local->mtx);
795 795
796 wiphy_free(local->hw.wiphy); 796 wiphy_free(local->hw.wiphy);
797} 797}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6c163ac22da..17e9257a61d8 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1751,7 +1751,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1751 struct ieee80211_local *local = sdata->local; 1751 struct ieee80211_local *local = sdata->local;
1752 struct ieee80211_work *wk; 1752 struct ieee80211_work *wk;
1753 1753
1754 mutex_lock(&local->work_mtx); 1754 mutex_lock(&local->mtx);
1755 list_for_each_entry(wk, &local->work_list, list) { 1755 list_for_each_entry(wk, &local->work_list, list) {
1756 if (wk->sdata != sdata) 1756 if (wk->sdata != sdata)
1757 continue; 1757 continue;
@@ -1783,7 +1783,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1783 free_work(wk); 1783 free_work(wk);
1784 break; 1784 break;
1785 } 1785 }
1786 mutex_unlock(&local->work_mtx); 1786 mutex_unlock(&local->mtx);
1787 1787
1788 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 1788 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
1789 } 1789 }
@@ -2275,7 +2275,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2275 2275
2276 mutex_unlock(&ifmgd->mtx); 2276 mutex_unlock(&ifmgd->mtx);
2277 2277
2278 mutex_lock(&local->work_mtx); 2278 mutex_lock(&local->mtx);
2279 list_for_each_entry(wk, &local->work_list, list) { 2279 list_for_each_entry(wk, &local->work_list, list) {
2280 if (wk->sdata != sdata) 2280 if (wk->sdata != sdata)
2281 continue; 2281 continue;
@@ -2294,7 +2294,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2294 free_work(wk); 2294 free_work(wk);
2295 break; 2295 break;
2296 } 2296 }
2297 mutex_unlock(&local->work_mtx); 2297 mutex_unlock(&local->mtx);
2298 2298
2299 /* 2299 /*
2300 * If somebody requests authentication and we haven't 2300 * If somebody requests authentication and we haven't
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 872d7b6ef6b3..f31f549733b1 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -255,7 +255,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
255 255
256 trace_api_scan_completed(local, aborted); 256 trace_api_scan_completed(local, aborted);
257 257
258 mutex_lock(&local->scan_mtx); 258 mutex_lock(&local->mtx);
259 259
260 /* 260 /*
261 * It's ok to abort a not-yet-running scan (that 261 * It's ok to abort a not-yet-running scan (that
@@ -267,7 +267,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
267 aborted = true; 267 aborted = true;
268 268
269 if (WARN_ON(!local->scan_req)) { 269 if (WARN_ON(!local->scan_req)) {
270 mutex_unlock(&local->scan_mtx); 270 mutex_unlock(&local->mtx);
271 return; 271 return;
272 } 272 }
273 273
@@ -275,7 +275,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
275 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 275 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
276 ieee80211_queue_delayed_work(&local->hw, 276 ieee80211_queue_delayed_work(&local->hw,
277 &local->scan_work, 0); 277 &local->scan_work, 0);
278 mutex_unlock(&local->scan_mtx); 278 mutex_unlock(&local->mtx);
279 return; 279 return;
280 } 280 }
281 281
@@ -291,7 +291,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
291 local->scan_channel = NULL; 291 local->scan_channel = NULL;
292 292
293 /* we only have to protect scan_req and hw/sw scan */ 293 /* we only have to protect scan_req and hw/sw scan */
294 mutex_unlock(&local->scan_mtx); 294 mutex_unlock(&local->mtx);
295 295
296 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 296 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
297 if (was_hw_scan) 297 if (was_hw_scan)
@@ -639,15 +639,15 @@ void ieee80211_scan_work(struct work_struct *work)
639 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 639 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
640 unsigned long next_delay = 0; 640 unsigned long next_delay = 0;
641 641
642 mutex_lock(&local->scan_mtx); 642 mutex_lock(&local->mtx);
643 if (!sdata || !local->scan_req) { 643 if (!sdata || !local->scan_req) {
644 mutex_unlock(&local->scan_mtx); 644 mutex_unlock(&local->mtx);
645 return; 645 return;
646 } 646 }
647 647
648 if (local->hw_scan_req) { 648 if (local->hw_scan_req) {
649 int rc = drv_hw_scan(local, sdata, local->hw_scan_req); 649 int rc = drv_hw_scan(local, sdata, local->hw_scan_req);
650 mutex_unlock(&local->scan_mtx); 650 mutex_unlock(&local->mtx);
651 if (rc) 651 if (rc)
652 ieee80211_scan_completed(&local->hw, true); 652 ieee80211_scan_completed(&local->hw, true);
653 return; 653 return;
@@ -661,14 +661,14 @@ void ieee80211_scan_work(struct work_struct *work)
661 local->scan_sdata = NULL; 661 local->scan_sdata = NULL;
662 662
663 rc = __ieee80211_start_scan(sdata, req); 663 rc = __ieee80211_start_scan(sdata, req);
664 mutex_unlock(&local->scan_mtx); 664 mutex_unlock(&local->mtx);
665 665
666 if (rc) 666 if (rc)
667 ieee80211_scan_completed(&local->hw, true); 667 ieee80211_scan_completed(&local->hw, true);
668 return; 668 return;
669 } 669 }
670 670
671 mutex_unlock(&local->scan_mtx); 671 mutex_unlock(&local->mtx);
672 672
673 /* 673 /*
674 * Avoid re-scheduling when the sdata is going away. 674 * Avoid re-scheduling when the sdata is going away.
@@ -711,9 +711,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
711{ 711{
712 int res; 712 int res;
713 713
714 mutex_lock(&sdata->local->scan_mtx); 714 mutex_lock(&sdata->local->mtx);
715 res = __ieee80211_start_scan(sdata, req); 715 res = __ieee80211_start_scan(sdata, req);
716 mutex_unlock(&sdata->local->scan_mtx); 716 mutex_unlock(&sdata->local->mtx);
717 717
718 return res; 718 return res;
719} 719}
@@ -726,7 +726,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
726 int ret = -EBUSY; 726 int ret = -EBUSY;
727 enum ieee80211_band band; 727 enum ieee80211_band band;
728 728
729 mutex_lock(&local->scan_mtx); 729 mutex_lock(&local->mtx);
730 730
731 /* busy scanning */ 731 /* busy scanning */
732 if (local->scan_req) 732 if (local->scan_req)
@@ -761,7 +761,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
761 761
762 ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); 762 ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
763 unlock: 763 unlock:
764 mutex_unlock(&local->scan_mtx); 764 mutex_unlock(&local->mtx);
765 return ret; 765 return ret;
766} 766}
767 767
@@ -775,10 +775,10 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
775 * Only call this function when a scan can't be 775 * Only call this function when a scan can't be
776 * queued -- mostly at suspend under RTNL. 776 * queued -- mostly at suspend under RTNL.
777 */ 777 */
778 mutex_lock(&local->scan_mtx); 778 mutex_lock(&local->mtx);
779 abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || 779 abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
780 (!local->scanning && local->scan_req); 780 (!local->scanning && local->scan_req);
781 mutex_unlock(&local->scan_mtx); 781 mutex_unlock(&local->mtx);
782 782
783 if (abortscan) 783 if (abortscan)
784 ieee80211_scan_completed(&local->hw, true); 784 ieee80211_scan_completed(&local->hw, true);
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 81d4ad64184a..b98af64f5862 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -43,7 +43,7 @@ enum work_action {
43/* utils */ 43/* utils */
44static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) 44static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
45{ 45{
46 WARN_ON(!mutex_is_locked(&local->work_mtx)); 46 lockdep_assert_held(&local->mtx);
47} 47}
48 48
49/* 49/*
@@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
757 mgmt = (struct ieee80211_mgmt *) skb->data; 757 mgmt = (struct ieee80211_mgmt *) skb->data;
758 fc = le16_to_cpu(mgmt->frame_control); 758 fc = le16_to_cpu(mgmt->frame_control);
759 759
760 mutex_lock(&local->work_mtx); 760 mutex_lock(&local->mtx);
761 761
762 list_for_each_entry(wk, &local->work_list, list) { 762 list_for_each_entry(wk, &local->work_list, list) {
763 const u8 *bssid = NULL; 763 const u8 *bssid = NULL;
@@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
833 WARN(1, "unexpected: %d", rma); 833 WARN(1, "unexpected: %d", rma);
834 } 834 }
835 835
836 mutex_unlock(&local->work_mtx); 836 mutex_unlock(&local->mtx);
837 837
838 if (rma != WORK_ACT_DONE) 838 if (rma != WORK_ACT_DONE)
839 goto out; 839 goto out;
@@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
845 case WORK_DONE_REQUEUE: 845 case WORK_DONE_REQUEUE:
846 synchronize_rcu(); 846 synchronize_rcu();
847 wk->started = false; /* restart */ 847 wk->started = false; /* restart */
848 mutex_lock(&local->work_mtx); 848 mutex_lock(&local->mtx);
849 list_add_tail(&wk->list, &local->work_list); 849 list_add_tail(&wk->list, &local->work_list);
850 mutex_unlock(&local->work_mtx); 850 mutex_unlock(&local->mtx);
851 } 851 }
852 852
853 out: 853 out:
@@ -890,7 +890,7 @@ static void ieee80211_work_work(struct work_struct *work)
890 890
891 ieee80211_recalc_idle(local); 891 ieee80211_recalc_idle(local);
892 892
893 mutex_lock(&local->work_mtx); 893 mutex_lock(&local->mtx);
894 894
895 list_for_each_entry_safe(wk, tmp, &local->work_list, list) { 895 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
896 bool started = wk->started; 896 bool started = wk->started;
@@ -995,17 +995,13 @@ static void ieee80211_work_work(struct work_struct *work)
995 run_again(local, jiffies + HZ/2); 995 run_again(local, jiffies + HZ/2);
996 } 996 }
997 997
998 mutex_lock(&local->scan_mtx);
999
1000 if (list_empty(&local->work_list) && local->scan_req && 998 if (list_empty(&local->work_list) && local->scan_req &&
1001 !local->scanning) 999 !local->scanning)
1002 ieee80211_queue_delayed_work(&local->hw, 1000 ieee80211_queue_delayed_work(&local->hw,
1003 &local->scan_work, 1001 &local->scan_work,
1004 round_jiffies_relative(0)); 1002 round_jiffies_relative(0));
1005 1003
1006 mutex_unlock(&local->scan_mtx); 1004 mutex_unlock(&local->mtx);
1007
1008 mutex_unlock(&local->work_mtx);
1009 1005
1010 ieee80211_recalc_idle(local); 1006 ieee80211_recalc_idle(local);
1011 1007
@@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk)
1035 wk->started = false; 1031 wk->started = false;
1036 1032
1037 local = wk->sdata->local; 1033 local = wk->sdata->local;
1038 mutex_lock(&local->work_mtx); 1034 mutex_lock(&local->mtx);
1039 list_add_tail(&wk->list, &local->work_list); 1035 list_add_tail(&wk->list, &local->work_list);
1040 mutex_unlock(&local->work_mtx); 1036 mutex_unlock(&local->mtx);
1041 1037
1042 ieee80211_queue_work(&local->hw, &local->work_work); 1038 ieee80211_queue_work(&local->hw, &local->work_work);
1043} 1039}
1044 1040
1045void ieee80211_work_init(struct ieee80211_local *local) 1041void ieee80211_work_init(struct ieee80211_local *local)
1046{ 1042{
1047 mutex_init(&local->work_mtx);
1048 INIT_LIST_HEAD(&local->work_list); 1043 INIT_LIST_HEAD(&local->work_list);
1049 setup_timer(&local->work_timer, ieee80211_work_timer, 1044 setup_timer(&local->work_timer, ieee80211_work_timer,
1050 (unsigned long)local); 1045 (unsigned long)local);
@@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1057 struct ieee80211_local *local = sdata->local; 1052 struct ieee80211_local *local = sdata->local;
1058 struct ieee80211_work *wk; 1053 struct ieee80211_work *wk;
1059 1054
1060 mutex_lock(&local->work_mtx); 1055 mutex_lock(&local->mtx);
1061 list_for_each_entry(wk, &local->work_list, list) { 1056 list_for_each_entry(wk, &local->work_list, list) {
1062 if (wk->sdata != sdata) 1057 if (wk->sdata != sdata)
1063 continue; 1058 continue;
@@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1065 wk->started = true; 1060 wk->started = true;
1066 wk->timeout = jiffies; 1061 wk->timeout = jiffies;
1067 } 1062 }
1068 mutex_unlock(&local->work_mtx); 1063 mutex_unlock(&local->mtx);
1069 1064
1070 /* run cleanups etc. */ 1065 /* run cleanups etc. */
1071 ieee80211_work_work(&local->work_work); 1066 ieee80211_work_work(&local->work_work);
1072 1067
1073 mutex_lock(&local->work_mtx); 1068 mutex_lock(&local->mtx);
1074 list_for_each_entry(wk, &local->work_list, list) { 1069 list_for_each_entry(wk, &local->work_list, list) {
1075 if (wk->sdata != sdata) 1070 if (wk->sdata != sdata)
1076 continue; 1071 continue;
1077 WARN_ON(1); 1072 WARN_ON(1);
1078 break; 1073 break;
1079 } 1074 }
1080 mutex_unlock(&local->work_mtx); 1075 mutex_unlock(&local->mtx);
1081} 1076}
1082 1077
1083ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, 1078ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1163 struct ieee80211_work *wk, *tmp; 1158 struct ieee80211_work *wk, *tmp;
1164 bool found = false; 1159 bool found = false;
1165 1160
1166 mutex_lock(&local->work_mtx); 1161 mutex_lock(&local->mtx);
1167 list_for_each_entry_safe(wk, tmp, &local->work_list, list) { 1162 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
1168 if ((unsigned long) wk == cookie) { 1163 if ((unsigned long) wk == cookie) {
1169 wk->timeout = jiffies; 1164 wk->timeout = jiffies;
@@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1171 break; 1166 break;
1172 } 1167 }
1173 } 1168 }
1174 mutex_unlock(&local->work_mtx); 1169 mutex_unlock(&local->mtx);
1175 1170
1176 if (!found) 1171 if (!found)
1177 return -ENOENT; 1172 return -ENOENT;