aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c131
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
157int 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
231int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 155int 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,