aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-06 18:14:51 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-11 12:45:01 -0500
commitfd0f979a1b67f0889aea24a7c7d2a54d6706a1cf (patch)
treefce94dd9fa9783eb4dc8b0ed6a2c322650889991 /net/mac80211/iface.c
parentf1e3e0515646dd0f4c783c1c39839d2706501344 (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.c94
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
81static u32 ieee80211_idle_off(struct ieee80211_local *local, 81static 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
102static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) 101void 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
193void 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
204static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) 142static 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) {