diff options
-rw-r--r-- | net/mac80211/chan.c | 13 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/iface.c | 94 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 34 |
5 files changed, 25 insertions, 127 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index b5b50762f03e..038f249966d6 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -91,6 +91,10 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
91 | 91 | ||
92 | list_add_rcu(&ctx->list, &local->chanctx_list); | 92 | list_add_rcu(&ctx->list, &local->chanctx_list); |
93 | 93 | ||
94 | mutex_lock(&local->mtx); | ||
95 | ieee80211_recalc_idle(local); | ||
96 | mutex_unlock(&local->mtx); | ||
97 | |||
94 | return ctx; | 98 | return ctx; |
95 | } | 99 | } |
96 | 100 | ||
@@ -110,6 +114,10 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, | |||
110 | 114 | ||
111 | list_del_rcu(&ctx->list); | 115 | list_del_rcu(&ctx->list); |
112 | kfree_rcu(ctx, rcu_head); | 116 | kfree_rcu(ctx, rcu_head); |
117 | |||
118 | mutex_lock(&local->mtx); | ||
119 | ieee80211_recalc_idle(local); | ||
120 | mutex_unlock(&local->mtx); | ||
113 | } | 121 | } |
114 | 122 | ||
115 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | 123 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, |
@@ -128,6 +136,8 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | |||
128 | ctx->refcount++; | 136 | ctx->refcount++; |
129 | 137 | ||
130 | ieee80211_recalc_txpower(sdata); | 138 | ieee80211_recalc_txpower(sdata); |
139 | sdata->vif.bss_conf.idle = false; | ||
140 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
131 | 141 | ||
132 | return 0; | 142 | return 0; |
133 | } | 143 | } |
@@ -175,6 +185,9 @@ static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | |||
175 | ctx->refcount--; | 185 | ctx->refcount--; |
176 | rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); | 186 | rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); |
177 | 187 | ||
188 | sdata->vif.bss_conf.idle = true; | ||
189 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
190 | |||
178 | drv_unassign_vif_chanctx(local, sdata, ctx); | 191 | drv_unassign_vif_chanctx(local, sdata, ctx); |
179 | 192 | ||
180 | if (ctx->refcount > 0) { | 193 | if (ctx->refcount > 0) { |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 055fa9436e95..2db1f2b90bfe 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1108,10 +1108,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1108 | 1108 | ||
1109 | mutex_unlock(&sdata->u.ibss.mtx); | 1109 | mutex_unlock(&sdata->u.ibss.mtx); |
1110 | 1110 | ||
1111 | mutex_lock(&sdata->local->mtx); | ||
1112 | ieee80211_recalc_idle(sdata->local); | ||
1113 | mutex_unlock(&sdata->local->mtx); | ||
1114 | |||
1115 | /* | 1111 | /* |
1116 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is | 1112 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is |
1117 | * reserved, but an HT STA shall protect HT transmissions as though | 1113 | * reserved, but an HT STA shall protect HT transmissions as though |
@@ -1209,9 +1205,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1209 | 1205 | ||
1210 | mutex_unlock(&sdata->u.ibss.mtx); | 1206 | mutex_unlock(&sdata->u.ibss.mtx); |
1211 | 1207 | ||
1212 | mutex_lock(&local->mtx); | ||
1213 | ieee80211_recalc_idle(sdata->local); | ||
1214 | mutex_unlock(&local->mtx); | ||
1215 | |||
1216 | return 0; | 1208 | return 0; |
1217 | } | 1209 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fafeb309a5fe..5635dfc7da34 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -689,9 +689,6 @@ struct ieee80211_sub_if_data { | |||
689 | 689 | ||
690 | char name[IFNAMSIZ]; | 690 | char name[IFNAMSIZ]; |
691 | 691 | ||
692 | /* to detect idle changes */ | ||
693 | bool old_idle; | ||
694 | |||
695 | /* Fragment table for host-based reassembly */ | 692 | /* Fragment table for host-based reassembly */ |
696 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 693 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
697 | unsigned int fragment_next; | 694 | unsigned int fragment_next; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3ece8eb6d2df..40ff0307d089 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -78,8 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
79 | } | 79 | } |
80 | 80 | ||
81 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | 81 | static u32 ieee80211_idle_off(struct ieee80211_local *local) |
82 | const char *reason) | ||
83 | { | 82 | { |
84 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
85 | return 0; | 84 | return 0; |
@@ -99,106 +98,45 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
99 | return IEEE80211_CONF_CHANGE_IDLE; | 98 | return IEEE80211_CONF_CHANGE_IDLE; |
100 | } | 99 | } |
101 | 100 | ||
102 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | 101 | void ieee80211_recalc_idle(struct ieee80211_local *local) |
103 | { | 102 | { |
104 | struct ieee80211_sub_if_data *sdata; | 103 | bool working = false, scanning, active; |
105 | int count = 0; | ||
106 | bool working = false, scanning = false; | ||
107 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 104 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
108 | struct ieee80211_roc_work *roc; | 105 | struct ieee80211_roc_work *roc; |
106 | u32 change; | ||
109 | 107 | ||
110 | #ifdef CONFIG_PROVE_LOCKING | ||
111 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
112 | !lockdep_is_held(&local->iflist_mtx)); | ||
113 | #endif | ||
114 | lockdep_assert_held(&local->mtx); | 108 | lockdep_assert_held(&local->mtx); |
115 | 109 | ||
116 | list_for_each_entry(sdata, &local->interfaces, list) { | 110 | active = !list_empty(&local->chanctx_list); |
117 | if (!ieee80211_sdata_running(sdata)) { | ||
118 | sdata->vif.bss_conf.idle = true; | ||
119 | continue; | ||
120 | } | ||
121 | |||
122 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
123 | |||
124 | /* do not count disabled managed interfaces */ | ||
125 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
126 | !sdata->u.mgd.associated && | ||
127 | !sdata->u.mgd.auth_data && | ||
128 | !sdata->u.mgd.assoc_data) { | ||
129 | sdata->vif.bss_conf.idle = true; | ||
130 | continue; | ||
131 | } | ||
132 | /* do not count unused IBSS interfaces */ | ||
133 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
134 | !sdata->u.ibss.ssid_len) { | ||
135 | sdata->vif.bss_conf.idle = true; | ||
136 | continue; | ||
137 | } | ||
138 | |||
139 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
140 | continue; | ||
141 | |||
142 | /* count everything else */ | ||
143 | sdata->vif.bss_conf.idle = false; | ||
144 | count++; | ||
145 | } | ||
146 | 111 | ||
147 | if (!local->ops->remain_on_channel) { | 112 | if (!local->ops->remain_on_channel) { |
148 | list_for_each_entry(roc, &local->roc_list, list) { | 113 | list_for_each_entry(roc, &local->roc_list, list) { |
149 | working = true; | 114 | working = true; |
150 | roc->sdata->vif.bss_conf.idle = false; | 115 | break; |
151 | } | 116 | } |
152 | } | 117 | } |
153 | 118 | ||
154 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || | 119 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || |
155 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); | 120 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); |
156 | 121 | ||
157 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
158 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
159 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | ||
160 | sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
161 | continue; | ||
162 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
163 | continue; | ||
164 | if (!ieee80211_sdata_running(sdata)) | ||
165 | continue; | ||
166 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
167 | } | ||
168 | |||
169 | if (working || scanning) | 122 | if (working || scanning) |
170 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 123 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
171 | else | 124 | else |
172 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 125 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
173 | 126 | ||
174 | if (count) | 127 | if (active) |
175 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | 128 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; |
176 | else | 129 | else |
177 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | 130 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; |
178 | 131 | ||
179 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | 132 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
180 | 133 | ||
181 | if (working) | 134 | if (working || scanning || active) |
182 | return ieee80211_idle_off(local, "working"); | 135 | change = ieee80211_idle_off(local); |
183 | if (scanning) | ||
184 | return ieee80211_idle_off(local, "scanning"); | ||
185 | if (!count) | ||
186 | return ieee80211_idle_on(local); | ||
187 | else | 136 | else |
188 | return ieee80211_idle_off(local, "in use"); | 137 | change = ieee80211_idle_on(local); |
189 | 138 | if (change) | |
190 | return 0; | 139 | ieee80211_hw_config(local, change); |
191 | } | ||
192 | |||
193 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
194 | { | ||
195 | u32 chg; | ||
196 | |||
197 | mutex_lock(&local->iflist_mtx); | ||
198 | chg = __ieee80211_recalc_idle(local); | ||
199 | mutex_unlock(&local->iflist_mtx); | ||
200 | if (chg) | ||
201 | ieee80211_hw_config(local, chg); | ||
202 | } | 140 | } |
203 | 141 | ||
204 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | 142 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) |
@@ -692,10 +630,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
692 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 630 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
693 | atomic_inc(&local->iff_promiscs); | 631 | atomic_inc(&local->iff_promiscs); |
694 | 632 | ||
695 | mutex_lock(&local->mtx); | ||
696 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
697 | mutex_unlock(&local->mtx); | ||
698 | |||
699 | if (coming_up) | 633 | if (coming_up) |
700 | local->open_count++; | 634 | local->open_count++; |
701 | 635 | ||
@@ -888,10 +822,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
888 | 822 | ||
889 | sdata->bss = NULL; | 823 | sdata->bss = NULL; |
890 | 824 | ||
891 | mutex_lock(&local->mtx); | ||
892 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
893 | mutex_unlock(&local->mtx); | ||
894 | |||
895 | ieee80211_recalc_ps(local, -1); | 825 | ieee80211_recalc_ps(local, -1); |
896 | 826 | ||
897 | if (local->open_count == 0) { | 827 | if (local->open_count == 0) { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1e7662c5788e..3bcf39365be8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1792,7 +1792,6 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get); | |||
1792 | static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | 1792 | static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) |
1793 | { | 1793 | { |
1794 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1794 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1795 | struct ieee80211_local *local = sdata->local; | ||
1796 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 1795 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
1797 | 1796 | ||
1798 | mutex_lock(&ifmgd->mtx); | 1797 | mutex_lock(&ifmgd->mtx); |
@@ -1812,10 +1811,6 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
1812 | * but that's not a problem. | 1811 | * but that's not a problem. |
1813 | */ | 1812 | */ |
1814 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 1813 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); |
1815 | |||
1816 | mutex_lock(&local->mtx); | ||
1817 | ieee80211_recalc_idle(local); | ||
1818 | mutex_unlock(&local->mtx); | ||
1819 | } | 1814 | } |
1820 | 1815 | ||
1821 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) | 1816 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) |
@@ -2048,10 +2043,6 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2048 | 2043 | ||
2049 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2044 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2050 | 2045 | ||
2051 | mutex_lock(&sdata->local->mtx); | ||
2052 | ieee80211_recalc_idle(sdata->local); | ||
2053 | mutex_unlock(&sdata->local->mtx); | ||
2054 | |||
2055 | return RX_MGMT_CFG80211_DEAUTH; | 2046 | return RX_MGMT_CFG80211_DEAUTH; |
2056 | } | 2047 | } |
2057 | 2048 | ||
@@ -2079,10 +2070,6 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2079 | 2070 | ||
2080 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2071 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2081 | 2072 | ||
2082 | mutex_lock(&sdata->local->mtx); | ||
2083 | ieee80211_recalc_idle(sdata->local); | ||
2084 | mutex_unlock(&sdata->local->mtx); | ||
2085 | |||
2086 | return RX_MGMT_CFG80211_DISASSOC; | 2073 | return RX_MGMT_CFG80211_DISASSOC; |
2087 | } | 2074 | } |
2088 | 2075 | ||
@@ -2839,7 +2826,6 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2839 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 2826 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, |
2840 | u8 *bssid, u8 reason, bool tx) | 2827 | u8 *bssid, u8 reason, bool tx) |
2841 | { | 2828 | { |
2842 | struct ieee80211_local *local = sdata->local; | ||
2843 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2829 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2844 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 2830 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
2845 | 2831 | ||
@@ -2853,10 +2839,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
2853 | */ | 2839 | */ |
2854 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 2840 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); |
2855 | 2841 | ||
2856 | mutex_lock(&local->mtx); | ||
2857 | ieee80211_recalc_idle(local); | ||
2858 | mutex_unlock(&local->mtx); | ||
2859 | |||
2860 | mutex_lock(&ifmgd->mtx); | 2842 | mutex_lock(&ifmgd->mtx); |
2861 | } | 2843 | } |
2862 | 2844 | ||
@@ -3127,10 +3109,6 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3127 | } | 3109 | } |
3128 | 3110 | ||
3129 | mutex_unlock(&ifmgd->mtx); | 3111 | mutex_unlock(&ifmgd->mtx); |
3130 | |||
3131 | mutex_lock(&local->mtx); | ||
3132 | ieee80211_recalc_idle(local); | ||
3133 | mutex_unlock(&local->mtx); | ||
3134 | } | 3112 | } |
3135 | 3113 | ||
3136 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) | 3114 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) |
@@ -3644,10 +3622,6 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3644 | return -ENOMEM; | 3622 | return -ENOMEM; |
3645 | } | 3623 | } |
3646 | 3624 | ||
3647 | mutex_lock(&local->mtx); | ||
3648 | ieee80211_recalc_idle(sdata->local); | ||
3649 | mutex_unlock(&local->mtx); | ||
3650 | |||
3651 | if (new_sta) { | 3625 | if (new_sta) { |
3652 | u32 rates = 0, basic_rates = 0; | 3626 | u32 rates = 0, basic_rates = 0; |
3653 | bool have_higher_than_11mbit; | 3627 | bool have_higher_than_11mbit; |
@@ -4138,10 +4112,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4138 | mutex_unlock(&ifmgd->mtx); | 4112 | mutex_unlock(&ifmgd->mtx); |
4139 | 4113 | ||
4140 | out: | 4114 | out: |
4141 | mutex_lock(&sdata->local->mtx); | ||
4142 | ieee80211_recalc_idle(sdata->local); | ||
4143 | mutex_unlock(&sdata->local->mtx); | ||
4144 | |||
4145 | if (sent_frame) | 4115 | if (sent_frame) |
4146 | __cfg80211_send_deauth(sdata->dev, frame_buf, | 4116 | __cfg80211_send_deauth(sdata->dev, frame_buf, |
4147 | IEEE80211_DEAUTH_FRAME_LEN); | 4117 | IEEE80211_DEAUTH_FRAME_LEN); |
@@ -4182,10 +4152,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4182 | __cfg80211_send_disassoc(sdata->dev, frame_buf, | 4152 | __cfg80211_send_disassoc(sdata->dev, frame_buf, |
4183 | IEEE80211_DEAUTH_FRAME_LEN); | 4153 | IEEE80211_DEAUTH_FRAME_LEN); |
4184 | 4154 | ||
4185 | mutex_lock(&sdata->local->mtx); | ||
4186 | ieee80211_recalc_idle(sdata->local); | ||
4187 | mutex_unlock(&sdata->local->mtx); | ||
4188 | |||
4189 | return 0; | 4155 | return 0; |
4190 | } | 4156 | } |
4191 | 4157 | ||