diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-02-06 18:14:51 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-11 12:45:01 -0500 |
commit | fd0f979a1b67f0889aea24a7c7d2a54d6706a1cf (patch) | |
tree | fce94dd9fa9783eb4dc8b0ed6a2c322650889991 /net/mac80211/iface.c | |
parent | f1e3e0515646dd0f4c783c1c39839d2706501344 (diff) |
mac80211: simplify idle handling
Now that we have channel contexts, idle is (pretty
much) equivalent to not having a channel context.
Change the code to use this relation so that there
no longer is a need for a lot of idle recalculate
calls everywhere.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 94 |
1 files changed, 12 insertions, 82 deletions
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) { |