diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 131 |
1 files changed, 55 insertions, 76 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b254879d8631..c817c9ef215a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -152,82 +152,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev) | |||
152 | ieee80211_configure_filter(local); | 152 | ieee80211_configure_filter(local); |
153 | } | 153 | } |
154 | 154 | ||
155 | /* everything else */ | ||
156 | |||
157 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | ||
158 | { | ||
159 | struct ieee80211_local *local = sdata->local; | ||
160 | struct ieee80211_if_conf conf; | ||
161 | |||
162 | if (WARN_ON(!netif_running(sdata->dev))) | ||
163 | return 0; | ||
164 | |||
165 | memset(&conf, 0, sizeof(conf)); | ||
166 | |||
167 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
168 | conf.bssid = sdata->u.mgd.bssid; | ||
169 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
170 | conf.bssid = sdata->u.ibss.bssid; | ||
171 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
172 | conf.bssid = sdata->dev->dev_addr; | ||
173 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
174 | static const u8 zero[ETH_ALEN] = { 0 }; | ||
175 | conf.bssid = zero; | ||
176 | } else { | ||
177 | WARN_ON(1); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | if (!local->ops->config_interface) | ||
182 | return 0; | ||
183 | |||
184 | switch (sdata->vif.type) { | ||
185 | case NL80211_IFTYPE_AP: | ||
186 | case NL80211_IFTYPE_ADHOC: | ||
187 | case NL80211_IFTYPE_MESH_POINT: | ||
188 | break; | ||
189 | default: | ||
190 | /* do not warn to simplify caller in scan.c */ | ||
191 | changed &= ~IEEE80211_IFCC_BEACON_ENABLED; | ||
192 | if (WARN_ON(changed & IEEE80211_IFCC_BEACON)) | ||
193 | return -EINVAL; | ||
194 | changed &= ~IEEE80211_IFCC_BEACON; | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | if (changed & IEEE80211_IFCC_BEACON_ENABLED) { | ||
199 | if (local->sw_scanning) { | ||
200 | conf.enable_beacon = false; | ||
201 | } else { | ||
202 | /* | ||
203 | * Beacon should be enabled, but AP mode must | ||
204 | * check whether there is a beacon configured. | ||
205 | */ | ||
206 | switch (sdata->vif.type) { | ||
207 | case NL80211_IFTYPE_AP: | ||
208 | conf.enable_beacon = | ||
209 | !!rcu_dereference(sdata->u.ap.beacon); | ||
210 | break; | ||
211 | case NL80211_IFTYPE_ADHOC: | ||
212 | conf.enable_beacon = !!sdata->u.ibss.presp; | ||
213 | break; | ||
214 | case NL80211_IFTYPE_MESH_POINT: | ||
215 | conf.enable_beacon = true; | ||
216 | break; | ||
217 | default: | ||
218 | /* not reached */ | ||
219 | WARN_ON(1); | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | conf.changed = changed; | ||
226 | |||
227 | return local->ops->config_interface(local_to_hw(local), | ||
228 | &sdata->vif, &conf); | ||
229 | } | ||
230 | |||
231 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 155 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
232 | { | 156 | { |
233 | struct ieee80211_channel *chan; | 157 | struct ieee80211_channel *chan; |
@@ -297,6 +221,61 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
297 | if (!changed) | 221 | if (!changed) |
298 | return; | 222 | return; |
299 | 223 | ||
224 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
225 | sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; | ||
226 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
227 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | ||
228 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
229 | sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; | ||
230 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
231 | static const u8 zero[ETH_ALEN] = { 0 }; | ||
232 | sdata->vif.bss_conf.bssid = zero; | ||
233 | } else { | ||
234 | WARN_ON(1); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | switch (sdata->vif.type) { | ||
239 | case NL80211_IFTYPE_AP: | ||
240 | case NL80211_IFTYPE_ADHOC: | ||
241 | case NL80211_IFTYPE_MESH_POINT: | ||
242 | break; | ||
243 | default: | ||
244 | /* do not warn to simplify caller in scan.c */ | ||
245 | changed &= ~BSS_CHANGED_BEACON_ENABLED; | ||
246 | if (WARN_ON(changed & BSS_CHANGED_BEACON)) | ||
247 | return; | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | ||
252 | if (local->sw_scanning) { | ||
253 | sdata->vif.bss_conf.enable_beacon = false; | ||
254 | } else { | ||
255 | /* | ||
256 | * Beacon should be enabled, but AP mode must | ||
257 | * check whether there is a beacon configured. | ||
258 | */ | ||
259 | switch (sdata->vif.type) { | ||
260 | case NL80211_IFTYPE_AP: | ||
261 | sdata->vif.bss_conf.enable_beacon = | ||
262 | !!rcu_dereference(sdata->u.ap.beacon); | ||
263 | break; | ||
264 | case NL80211_IFTYPE_ADHOC: | ||
265 | sdata->vif.bss_conf.enable_beacon = | ||
266 | !!rcu_dereference(sdata->u.ibss.presp); | ||
267 | break; | ||
268 | case NL80211_IFTYPE_MESH_POINT: | ||
269 | sdata->vif.bss_conf.enable_beacon = true; | ||
270 | break; | ||
271 | default: | ||
272 | /* not reached */ | ||
273 | WARN_ON(1); | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
300 | if (local->ops->bss_info_changed) | 279 | if (local->ops->bss_info_changed) |
301 | local->ops->bss_info_changed(local_to_hw(local), | 280 | local->ops->bss_info_changed(local_to_hw(local), |
302 | &sdata->vif, | 281 | &sdata->vif, |