diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 608 |
1 files changed, 53 insertions, 555 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6a7f4fae18c2..c307dba7ec03 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -45,16 +45,9 @@ struct ieee80211_tx_status_rtap_hdr { | |||
45 | u8 data_retries; | 45 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 46 | } __attribute__ ((packed)); |
47 | 47 | ||
48 | /* common interface routines */ | ||
49 | |||
50 | static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) | ||
51 | { | ||
52 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
53 | return ETH_ALEN; | ||
54 | } | ||
55 | 48 | ||
56 | /* must be called under mdev tx lock */ | 49 | /* must be called under mdev tx lock */ |
57 | static void ieee80211_configure_filter(struct ieee80211_local *local) | 50 | void ieee80211_configure_filter(struct ieee80211_local *local) |
58 | { | 51 | { |
59 | unsigned int changed_flags; | 52 | unsigned int changed_flags; |
60 | unsigned int new_flags = 0; | 53 | unsigned int new_flags = 0; |
@@ -97,6 +90,20 @@ static void ieee80211_configure_filter(struct ieee80211_local *local) | |||
97 | 90 | ||
98 | /* master interface */ | 91 | /* master interface */ |
99 | 92 | ||
93 | static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) | ||
94 | { | ||
95 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
96 | return ETH_ALEN; | ||
97 | } | ||
98 | |||
99 | static const struct header_ops ieee80211_header_ops = { | ||
100 | .create = eth_header, | ||
101 | .parse = header_parse_80211, | ||
102 | .rebuild = eth_rebuild_header, | ||
103 | .cache = eth_header_cache, | ||
104 | .cache_update = eth_header_cache_update, | ||
105 | }; | ||
106 | |||
100 | static int ieee80211_master_open(struct net_device *dev) | 107 | static int ieee80211_master_open(struct net_device *dev) |
101 | { | 108 | { |
102 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 109 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -139,519 +146,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev) | |||
139 | ieee80211_configure_filter(local); | 146 | ieee80211_configure_filter(local); |
140 | } | 147 | } |
141 | 148 | ||
142 | /* regular interfaces */ | ||
143 | |||
144 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | ||
145 | { | ||
146 | int meshhdrlen; | ||
147 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
148 | |||
149 | meshhdrlen = (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) ? 5 : 0; | ||
150 | |||
151 | /* FIX: what would be proper limits for MTU? | ||
152 | * This interface uses 802.3 frames. */ | ||
153 | if (new_mtu < 256 || | ||
154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
159 | printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); | ||
160 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
161 | dev->mtu = new_mtu; | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static inline int identical_mac_addr_allowed(int type1, int type2) | ||
166 | { | ||
167 | return (type1 == IEEE80211_IF_TYPE_MNTR || | ||
168 | type2 == IEEE80211_IF_TYPE_MNTR || | ||
169 | (type1 == IEEE80211_IF_TYPE_AP && | ||
170 | type2 == IEEE80211_IF_TYPE_WDS) || | ||
171 | (type1 == IEEE80211_IF_TYPE_WDS && | ||
172 | (type2 == IEEE80211_IF_TYPE_WDS || | ||
173 | type2 == IEEE80211_IF_TYPE_AP)) || | ||
174 | (type1 == IEEE80211_IF_TYPE_AP && | ||
175 | type2 == IEEE80211_IF_TYPE_VLAN) || | ||
176 | (type1 == IEEE80211_IF_TYPE_VLAN && | ||
177 | (type2 == IEEE80211_IF_TYPE_AP || | ||
178 | type2 == IEEE80211_IF_TYPE_VLAN))); | ||
179 | } | ||
180 | |||
181 | static int ieee80211_open(struct net_device *dev) | ||
182 | { | ||
183 | struct ieee80211_sub_if_data *sdata, *nsdata; | ||
184 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
185 | struct sta_info *sta; | ||
186 | struct ieee80211_if_init_conf conf; | ||
187 | u32 changed = 0; | ||
188 | int res; | ||
189 | bool need_hw_reconfig = 0; | ||
190 | u8 null_addr[ETH_ALEN] = {0}; | ||
191 | |||
192 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
193 | |||
194 | /* fail early if user set an invalid address */ | ||
195 | if (compare_ether_addr(dev->dev_addr, null_addr) && | ||
196 | !is_valid_ether_addr(dev->dev_addr)) | ||
197 | return -EADDRNOTAVAIL; | ||
198 | |||
199 | /* we hold the RTNL here so can safely walk the list */ | ||
200 | list_for_each_entry(nsdata, &local->interfaces, list) { | ||
201 | struct net_device *ndev = nsdata->dev; | ||
202 | |||
203 | if (ndev != dev && netif_running(ndev)) { | ||
204 | /* | ||
205 | * Allow only a single IBSS interface to be up at any | ||
206 | * time. This is restricted because beacon distribution | ||
207 | * cannot work properly if both are in the same IBSS. | ||
208 | * | ||
209 | * To remove this restriction we'd have to disallow them | ||
210 | * from setting the same SSID on different IBSS interfaces | ||
211 | * belonging to the same hardware. Then, however, we're | ||
212 | * faced with having to adopt two different TSF timers... | ||
213 | */ | ||
214 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | ||
215 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS) | ||
216 | return -EBUSY; | ||
217 | |||
218 | /* | ||
219 | * The remaining checks are only performed for interfaces | ||
220 | * with the same MAC address. | ||
221 | */ | ||
222 | if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) | ||
223 | continue; | ||
224 | |||
225 | /* | ||
226 | * check whether it may have the same address | ||
227 | */ | ||
228 | if (!identical_mac_addr_allowed(sdata->vif.type, | ||
229 | nsdata->vif.type)) | ||
230 | return -ENOTUNIQ; | ||
231 | |||
232 | /* | ||
233 | * can only add VLANs to enabled APs | ||
234 | */ | ||
235 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | ||
236 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) | ||
237 | sdata->bss = &nsdata->u.ap; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | switch (sdata->vif.type) { | ||
242 | case IEEE80211_IF_TYPE_WDS: | ||
243 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) | ||
244 | return -ENOLINK; | ||
245 | break; | ||
246 | case IEEE80211_IF_TYPE_VLAN: | ||
247 | if (!sdata->bss) | ||
248 | return -ENOLINK; | ||
249 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | ||
250 | break; | ||
251 | case IEEE80211_IF_TYPE_AP: | ||
252 | sdata->bss = &sdata->u.ap; | ||
253 | break; | ||
254 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
255 | /* mesh ifaces must set allmulti to forward mcast traffic */ | ||
256 | atomic_inc(&local->iff_allmultis); | ||
257 | break; | ||
258 | case IEEE80211_IF_TYPE_STA: | ||
259 | case IEEE80211_IF_TYPE_MNTR: | ||
260 | case IEEE80211_IF_TYPE_IBSS: | ||
261 | /* no special treatment */ | ||
262 | break; | ||
263 | case IEEE80211_IF_TYPE_INVALID: | ||
264 | /* cannot happen */ | ||
265 | WARN_ON(1); | ||
266 | break; | ||
267 | } | ||
268 | |||
269 | if (local->open_count == 0) { | ||
270 | res = 0; | ||
271 | if (local->ops->start) | ||
272 | res = local->ops->start(local_to_hw(local)); | ||
273 | if (res) | ||
274 | goto err_del_bss; | ||
275 | need_hw_reconfig = 1; | ||
276 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Check all interfaces and copy the hopefully now-present | ||
281 | * MAC address to those that have the special null one. | ||
282 | */ | ||
283 | list_for_each_entry(nsdata, &local->interfaces, list) { | ||
284 | struct net_device *ndev = nsdata->dev; | ||
285 | |||
286 | /* | ||
287 | * No need to check netif_running since we do not allow | ||
288 | * it to start up with this invalid address. | ||
289 | */ | ||
290 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) | ||
291 | memcpy(ndev->dev_addr, | ||
292 | local->hw.wiphy->perm_addr, | ||
293 | ETH_ALEN); | ||
294 | } | ||
295 | |||
296 | if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0) | ||
297 | memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, | ||
298 | ETH_ALEN); | ||
299 | |||
300 | /* | ||
301 | * Validate the MAC address for this device. | ||
302 | */ | ||
303 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
304 | if (!local->open_count && local->ops->stop) | ||
305 | local->ops->stop(local_to_hw(local)); | ||
306 | return -EADDRNOTAVAIL; | ||
307 | } | ||
308 | |||
309 | switch (sdata->vif.type) { | ||
310 | case IEEE80211_IF_TYPE_VLAN: | ||
311 | /* no need to tell driver */ | ||
312 | break; | ||
313 | case IEEE80211_IF_TYPE_MNTR: | ||
314 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
315 | local->cooked_mntrs++; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | /* must be before the call to ieee80211_configure_filter */ | ||
320 | local->monitors++; | ||
321 | if (local->monitors == 1) | ||
322 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | ||
323 | |||
324 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
325 | local->fif_fcsfail++; | ||
326 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
327 | local->fif_plcpfail++; | ||
328 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
329 | local->fif_control++; | ||
330 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
331 | local->fif_other_bss++; | ||
332 | |||
333 | netif_addr_lock_bh(local->mdev); | ||
334 | ieee80211_configure_filter(local); | ||
335 | netif_addr_unlock_bh(local->mdev); | ||
336 | break; | ||
337 | case IEEE80211_IF_TYPE_STA: | ||
338 | case IEEE80211_IF_TYPE_IBSS: | ||
339 | sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
340 | /* fall through */ | ||
341 | default: | ||
342 | conf.vif = &sdata->vif; | ||
343 | conf.type = sdata->vif.type; | ||
344 | conf.mac_addr = dev->dev_addr; | ||
345 | res = local->ops->add_interface(local_to_hw(local), &conf); | ||
346 | if (res) | ||
347 | goto err_stop; | ||
348 | |||
349 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
350 | ieee80211_start_mesh(sdata); | ||
351 | changed |= ieee80211_reset_erp_info(sdata); | ||
352 | ieee80211_bss_info_change_notify(sdata, changed); | ||
353 | ieee80211_enable_keys(sdata); | ||
354 | |||
355 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | ||
356 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) | ||
357 | netif_carrier_off(dev); | ||
358 | else | ||
359 | netif_carrier_on(dev); | ||
360 | } | ||
361 | |||
362 | if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { | ||
363 | /* Create STA entry for the WDS peer */ | ||
364 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | ||
365 | GFP_KERNEL); | ||
366 | if (!sta) { | ||
367 | res = -ENOMEM; | ||
368 | goto err_del_interface; | ||
369 | } | ||
370 | |||
371 | /* no locking required since STA is not live yet */ | ||
372 | sta->flags |= WLAN_STA_AUTHORIZED; | ||
373 | |||
374 | res = sta_info_insert(sta); | ||
375 | if (res) { | ||
376 | /* STA has been freed */ | ||
377 | goto err_del_interface; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | if (local->open_count == 0) { | ||
382 | res = dev_open(local->mdev); | ||
383 | WARN_ON(res); | ||
384 | if (res) | ||
385 | goto err_del_interface; | ||
386 | tasklet_enable(&local->tx_pending_tasklet); | ||
387 | tasklet_enable(&local->tasklet); | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * set_multicast_list will be invoked by the networking core | ||
392 | * which will check whether any increments here were done in | ||
393 | * error and sync them down to the hardware as filter flags. | ||
394 | */ | ||
395 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | ||
396 | atomic_inc(&local->iff_allmultis); | ||
397 | |||
398 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
399 | atomic_inc(&local->iff_promiscs); | ||
400 | |||
401 | local->open_count++; | ||
402 | if (need_hw_reconfig) { | ||
403 | ieee80211_hw_config(local); | ||
404 | /* | ||
405 | * set default queue parameters so drivers don't | ||
406 | * need to initialise the hardware if the hardware | ||
407 | * doesn't start up with sane defaults | ||
408 | */ | ||
409 | ieee80211_set_wmm_default(sdata); | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * ieee80211_sta_work is disabled while network interface | ||
414 | * is down. Therefore, some configuration changes may not | ||
415 | * yet be effective. Trigger execution of ieee80211_sta_work | ||
416 | * to fix this. | ||
417 | */ | ||
418 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
419 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | ||
420 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
421 | queue_work(local->hw.workqueue, &ifsta->work); | ||
422 | } | ||
423 | |||
424 | netif_tx_start_all_queues(dev); | ||
425 | |||
426 | return 0; | ||
427 | err_del_interface: | ||
428 | local->ops->remove_interface(local_to_hw(local), &conf); | ||
429 | err_stop: | ||
430 | if (!local->open_count && local->ops->stop) | ||
431 | local->ops->stop(local_to_hw(local)); | ||
432 | err_del_bss: | ||
433 | sdata->bss = NULL; | ||
434 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | ||
435 | list_del(&sdata->u.vlan.list); | ||
436 | return res; | ||
437 | } | ||
438 | |||
439 | static int ieee80211_stop(struct net_device *dev) | ||
440 | { | ||
441 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
442 | struct ieee80211_local *local = sdata->local; | ||
443 | struct ieee80211_if_init_conf conf; | ||
444 | struct sta_info *sta; | ||
445 | |||
446 | /* | ||
447 | * Stop TX on this interface first. | ||
448 | */ | ||
449 | netif_tx_stop_all_queues(dev); | ||
450 | |||
451 | /* | ||
452 | * Now delete all active aggregation sessions. | ||
453 | */ | ||
454 | rcu_read_lock(); | ||
455 | |||
456 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||
457 | if (sta->sdata == sdata) | ||
458 | ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr); | ||
459 | } | ||
460 | |||
461 | rcu_read_unlock(); | ||
462 | |||
463 | /* | ||
464 | * Remove all stations associated with this interface. | ||
465 | * | ||
466 | * This must be done before calling ops->remove_interface() | ||
467 | * because otherwise we can later invoke ops->sta_notify() | ||
468 | * whenever the STAs are removed, and that invalidates driver | ||
469 | * assumptions about always getting a vif pointer that is valid | ||
470 | * (because if we remove a STA after ops->remove_interface() | ||
471 | * the driver will have removed the vif info already!) | ||
472 | * | ||
473 | * We could relax this and only unlink the stations from the | ||
474 | * hash table and list but keep them on a per-sdata list that | ||
475 | * will be inserted back again when the interface is brought | ||
476 | * up again, but I don't currently see a use case for that, | ||
477 | * except with WDS which gets a STA entry created when it is | ||
478 | * brought up. | ||
479 | */ | ||
480 | sta_info_flush(local, sdata); | ||
481 | |||
482 | /* | ||
483 | * Don't count this interface for promisc/allmulti while it | ||
484 | * is down. dev_mc_unsync() will invoke set_multicast_list | ||
485 | * on the master interface which will sync these down to the | ||
486 | * hardware as filter flags. | ||
487 | */ | ||
488 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | ||
489 | atomic_dec(&local->iff_allmultis); | ||
490 | |||
491 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
492 | atomic_dec(&local->iff_promiscs); | ||
493 | |||
494 | dev_mc_unsync(local->mdev, dev); | ||
495 | |||
496 | /* APs need special treatment */ | ||
497 | if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | ||
498 | struct ieee80211_sub_if_data *vlan, *tmp; | ||
499 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | ||
500 | |||
501 | /* remove beacon */ | ||
502 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
503 | synchronize_rcu(); | ||
504 | kfree(old_beacon); | ||
505 | |||
506 | /* down all dependent devices, that is VLANs */ | ||
507 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, | ||
508 | u.vlan.list) | ||
509 | dev_close(vlan->dev); | ||
510 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | ||
511 | } | ||
512 | |||
513 | local->open_count--; | ||
514 | |||
515 | switch (sdata->vif.type) { | ||
516 | case IEEE80211_IF_TYPE_VLAN: | ||
517 | list_del(&sdata->u.vlan.list); | ||
518 | /* no need to tell driver */ | ||
519 | break; | ||
520 | case IEEE80211_IF_TYPE_MNTR: | ||
521 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
522 | local->cooked_mntrs--; | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | local->monitors--; | ||
527 | if (local->monitors == 0) | ||
528 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | ||
529 | |||
530 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
531 | local->fif_fcsfail--; | ||
532 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
533 | local->fif_plcpfail--; | ||
534 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
535 | local->fif_control--; | ||
536 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
537 | local->fif_other_bss--; | ||
538 | |||
539 | netif_addr_lock_bh(local->mdev); | ||
540 | ieee80211_configure_filter(local); | ||
541 | netif_addr_unlock_bh(local->mdev); | ||
542 | break; | ||
543 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
544 | /* allmulti is always set on mesh ifaces */ | ||
545 | atomic_dec(&local->iff_allmultis); | ||
546 | /* fall through */ | ||
547 | case IEEE80211_IF_TYPE_STA: | ||
548 | case IEEE80211_IF_TYPE_IBSS: | ||
549 | sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED; | ||
550 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); | ||
551 | del_timer_sync(&sdata->u.sta.timer); | ||
552 | /* | ||
553 | * When we get here, the interface is marked down. | ||
554 | * Call synchronize_rcu() to wait for the RX path | ||
555 | * should it be using the interface and enqueuing | ||
556 | * frames at this very time on another CPU. | ||
557 | */ | ||
558 | synchronize_rcu(); | ||
559 | skb_queue_purge(&sdata->u.sta.skb_queue); | ||
560 | |||
561 | if (local->scan_sdata == sdata) { | ||
562 | if (!local->ops->hw_scan) { | ||
563 | local->sta_sw_scanning = 0; | ||
564 | cancel_delayed_work(&local->scan_work); | ||
565 | } else | ||
566 | local->sta_hw_scanning = 0; | ||
567 | } | ||
568 | |||
569 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | ||
570 | kfree(sdata->u.sta.extra_ie); | ||
571 | sdata->u.sta.extra_ie = NULL; | ||
572 | sdata->u.sta.extra_ie_len = 0; | ||
573 | /* fall through */ | ||
574 | default: | ||
575 | conf.vif = &sdata->vif; | ||
576 | conf.type = sdata->vif.type; | ||
577 | conf.mac_addr = dev->dev_addr; | ||
578 | /* disable all keys for as long as this netdev is down */ | ||
579 | ieee80211_disable_keys(sdata); | ||
580 | local->ops->remove_interface(local_to_hw(local), &conf); | ||
581 | } | ||
582 | |||
583 | sdata->bss = NULL; | ||
584 | |||
585 | if (local->open_count == 0) { | ||
586 | if (netif_running(local->mdev)) | ||
587 | dev_close(local->mdev); | ||
588 | |||
589 | if (local->ops->stop) | ||
590 | local->ops->stop(local_to_hw(local)); | ||
591 | |||
592 | ieee80211_led_radio(local, 0); | ||
593 | |||
594 | flush_workqueue(local->hw.workqueue); | ||
595 | |||
596 | tasklet_disable(&local->tx_pending_tasklet); | ||
597 | tasklet_disable(&local->tasklet); | ||
598 | } | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static void ieee80211_set_multicast_list(struct net_device *dev) | ||
604 | { | ||
605 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
606 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
607 | int allmulti, promisc, sdata_allmulti, sdata_promisc; | ||
608 | |||
609 | allmulti = !!(dev->flags & IFF_ALLMULTI); | ||
610 | promisc = !!(dev->flags & IFF_PROMISC); | ||
611 | sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); | ||
612 | sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC); | ||
613 | |||
614 | if (allmulti != sdata_allmulti) { | ||
615 | if (dev->flags & IFF_ALLMULTI) | ||
616 | atomic_inc(&local->iff_allmultis); | ||
617 | else | ||
618 | atomic_dec(&local->iff_allmultis); | ||
619 | sdata->flags ^= IEEE80211_SDATA_ALLMULTI; | ||
620 | } | ||
621 | |||
622 | if (promisc != sdata_promisc) { | ||
623 | if (dev->flags & IFF_PROMISC) | ||
624 | atomic_inc(&local->iff_promiscs); | ||
625 | else | ||
626 | atomic_dec(&local->iff_promiscs); | ||
627 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | ||
628 | } | ||
629 | |||
630 | dev_mc_sync(local->mdev, dev); | ||
631 | } | ||
632 | |||
633 | static const struct header_ops ieee80211_header_ops = { | ||
634 | .create = eth_header, | ||
635 | .parse = header_parse_80211, | ||
636 | .rebuild = eth_rebuild_header, | ||
637 | .cache = eth_header_cache, | ||
638 | .cache_update = eth_header_cache_update, | ||
639 | }; | ||
640 | |||
641 | void ieee80211_if_setup(struct net_device *dev) | ||
642 | { | ||
643 | ether_setup(dev); | ||
644 | dev->hard_start_xmit = ieee80211_subif_start_xmit; | ||
645 | dev->wireless_handlers = &ieee80211_iw_handler_def; | ||
646 | dev->set_multicast_list = ieee80211_set_multicast_list; | ||
647 | dev->change_mtu = ieee80211_change_mtu; | ||
648 | dev->open = ieee80211_open; | ||
649 | dev->stop = ieee80211_stop; | ||
650 | dev->destructor = free_netdev; | ||
651 | /* we will validate the address ourselves in ->open */ | ||
652 | dev->validate_addr = NULL; | ||
653 | } | ||
654 | |||
655 | /* everything else */ | 149 | /* everything else */ |
656 | 150 | ||
657 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | 151 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) |
@@ -662,18 +156,21 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
662 | if (WARN_ON(!netif_running(sdata->dev))) | 156 | if (WARN_ON(!netif_running(sdata->dev))) |
663 | return 0; | 157 | return 0; |
664 | 158 | ||
159 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
160 | return -EINVAL; | ||
161 | |||
665 | if (!local->ops->config_interface) | 162 | if (!local->ops->config_interface) |
666 | return 0; | 163 | return 0; |
667 | 164 | ||
668 | memset(&conf, 0, sizeof(conf)); | 165 | memset(&conf, 0, sizeof(conf)); |
669 | conf.changed = changed; | 166 | conf.changed = changed; |
670 | 167 | ||
671 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | 168 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
672 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 169 | sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
673 | conf.bssid = sdata->u.sta.bssid; | 170 | conf.bssid = sdata->u.sta.bssid; |
674 | conf.ssid = sdata->u.sta.ssid; | 171 | conf.ssid = sdata->u.sta.ssid; |
675 | conf.ssid_len = sdata->u.sta.ssid_len; | 172 | conf.ssid_len = sdata->u.sta.ssid_len; |
676 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 173 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { |
677 | conf.bssid = sdata->dev->dev_addr; | 174 | conf.bssid = sdata->dev->dev_addr; |
678 | conf.ssid = sdata->u.ap.ssid; | 175 | conf.ssid = sdata->u.ap.ssid; |
679 | conf.ssid_len = sdata->u.ap.ssid_len; | 176 | conf.ssid_len = sdata->u.ap.ssid_len; |
@@ -702,7 +199,7 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
702 | struct ieee80211_channel *chan; | 199 | struct ieee80211_channel *chan; |
703 | int ret = 0; | 200 | int ret = 0; |
704 | 201 | ||
705 | if (local->sta_sw_scanning) | 202 | if (local->sw_scanning) |
706 | chan = local->scan_channel; | 203 | chan = local->scan_channel; |
707 | else | 204 | else |
708 | chan = local->oper_channel; | 205 | chan = local->oper_channel; |
@@ -827,6 +324,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
827 | { | 324 | { |
828 | struct ieee80211_local *local = sdata->local; | 325 | struct ieee80211_local *local = sdata->local; |
829 | 326 | ||
327 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
328 | return; | ||
329 | |||
830 | if (!changed) | 330 | if (!changed) |
831 | return; | 331 | return; |
832 | 332 | ||
@@ -1046,29 +546,27 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1046 | 546 | ||
1047 | rcu_read_lock(); | 547 | rcu_read_lock(); |
1048 | 548 | ||
1049 | if (info->status.excessive_retries) { | 549 | sta = sta_info_get(local, hdr->addr1); |
1050 | sta = sta_info_get(local, hdr->addr1); | 550 | |
1051 | if (sta) { | 551 | if (sta) { |
1052 | if (test_sta_flags(sta, WLAN_STA_PS)) { | 552 | if (info->status.excessive_retries && |
1053 | /* | 553 | test_sta_flags(sta, WLAN_STA_PS)) { |
1054 | * The STA is in power save mode, so assume | 554 | /* |
1055 | * that this TX packet failed because of that. | 555 | * The STA is in power save mode, so assume |
1056 | */ | 556 | * that this TX packet failed because of that. |
1057 | ieee80211_handle_filtered_frame(local, sta, skb); | 557 | */ |
1058 | rcu_read_unlock(); | 558 | ieee80211_handle_filtered_frame(local, sta, skb); |
1059 | return; | 559 | rcu_read_unlock(); |
1060 | } | 560 | return; |
1061 | } | 561 | } |
1062 | } | ||
1063 | 562 | ||
1064 | fc = hdr->frame_control; | 563 | fc = hdr->frame_control; |
564 | |||
565 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
566 | (ieee80211_is_data_qos(fc))) { | ||
567 | u16 tid, ssn; | ||
568 | u8 *qc; | ||
1065 | 569 | ||
1066 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
1067 | (ieee80211_is_data_qos(fc))) { | ||
1068 | u16 tid, ssn; | ||
1069 | u8 *qc; | ||
1070 | sta = sta_info_get(local, hdr->addr1); | ||
1071 | if (sta) { | ||
1072 | qc = ieee80211_get_qos_ctl(hdr); | 570 | qc = ieee80211_get_qos_ctl(hdr); |
1073 | tid = qc[0] & 0xf; | 571 | tid = qc[0] & 0xf; |
1074 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | 572 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) |
@@ -1076,17 +574,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1076 | ieee80211_send_bar(sta->sdata, hdr->addr1, | 574 | ieee80211_send_bar(sta->sdata, hdr->addr1, |
1077 | tid, ssn); | 575 | tid, ssn); |
1078 | } | 576 | } |
1079 | } | ||
1080 | 577 | ||
1081 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | 578 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
1082 | sta = sta_info_get(local, hdr->addr1); | ||
1083 | if (sta) { | ||
1084 | ieee80211_handle_filtered_frame(local, sta, skb); | 579 | ieee80211_handle_filtered_frame(local, sta, skb); |
1085 | rcu_read_unlock(); | 580 | rcu_read_unlock(); |
1086 | return; | 581 | return; |
582 | } else { | ||
583 | if (info->status.excessive_retries) | ||
584 | sta->tx_retry_failed++; | ||
585 | sta->tx_retry_count += info->status.retry_count; | ||
1087 | } | 586 | } |
1088 | } else | 587 | |
1089 | rate_control_tx_status(local->mdev, skb); | 588 | rate_control_tx_status(local->mdev, skb); |
589 | } | ||
1090 | 590 | ||
1091 | rcu_read_unlock(); | 591 | rcu_read_unlock(); |
1092 | 592 | ||
@@ -1174,7 +674,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1174 | 674 | ||
1175 | rcu_read_lock(); | 675 | rcu_read_lock(); |
1176 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 676 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
1177 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { | 677 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { |
1178 | if (!netif_running(sdata->dev)) | 678 | if (!netif_running(sdata->dev)) |
1179 | continue; | 679 | continue; |
1180 | 680 | ||
@@ -1250,8 +750,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1250 | 750 | ||
1251 | local->hw.queues = 1; /* default */ | 751 | local->hw.queues = 1; /* default */ |
1252 | 752 | ||
1253 | local->bridge_packets = 1; | ||
1254 | |||
1255 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 753 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
1256 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 754 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
1257 | local->short_retry_limit = 7; | 755 | local->short_retry_limit = 7; |
@@ -1262,7 +760,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1262 | 760 | ||
1263 | spin_lock_init(&local->key_lock); | 761 | spin_lock_init(&local->key_lock); |
1264 | 762 | ||
1265 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 763 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
1266 | 764 | ||
1267 | sta_info_init(local); | 765 | sta_info_init(local); |
1268 | 766 | ||
@@ -1422,7 +920,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1422 | 920 | ||
1423 | /* add one default STA interface */ | 921 | /* add one default STA interface */ |
1424 | result = ieee80211_if_add(local, "wlan%d", NULL, | 922 | result = ieee80211_if_add(local, "wlan%d", NULL, |
1425 | IEEE80211_IF_TYPE_STA, NULL); | 923 | NL80211_IFTYPE_STATION, NULL); |
1426 | if (result) | 924 | if (result) |
1427 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 925 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
1428 | wiphy_name(local->hw.wiphy)); | 926 | wiphy_name(local->hw.wiphy)); |