diff options
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r-- | net/mac80211/ieee80211.c | 199 |
1 files changed, 143 insertions, 56 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 6378850d8580..5dcc2d61551f 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "debugfs.h" | 34 | #include "debugfs.h" |
35 | #include "debugfs_netdev.h" | 35 | #include "debugfs_netdev.h" |
36 | 36 | ||
37 | #define SUPP_MCS_SET_LEN 16 | ||
38 | |||
37 | /* | 39 | /* |
38 | * For seeing transmitted packets on monitor interfaces | 40 | * For seeing transmitted packets on monitor interfaces |
39 | * we have a radiotap header too. | 41 | * we have a radiotap header too. |
@@ -175,21 +177,21 @@ static int ieee80211_open(struct net_device *dev) | |||
175 | /* | 177 | /* |
176 | * check whether it may have the same address | 178 | * check whether it may have the same address |
177 | */ | 179 | */ |
178 | if (!identical_mac_addr_allowed(sdata->type, | 180 | if (!identical_mac_addr_allowed(sdata->vif.type, |
179 | nsdata->type)) | 181 | nsdata->vif.type)) |
180 | return -ENOTUNIQ; | 182 | return -ENOTUNIQ; |
181 | 183 | ||
182 | /* | 184 | /* |
183 | * can only add VLANs to enabled APs | 185 | * can only add VLANs to enabled APs |
184 | */ | 186 | */ |
185 | if (sdata->type == IEEE80211_IF_TYPE_VLAN && | 187 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
186 | nsdata->type == IEEE80211_IF_TYPE_AP && | 188 | nsdata->vif.type == IEEE80211_IF_TYPE_AP && |
187 | netif_running(nsdata->dev)) | 189 | netif_running(nsdata->dev)) |
188 | sdata->u.vlan.ap = nsdata; | 190 | sdata->u.vlan.ap = nsdata; |
189 | } | 191 | } |
190 | } | 192 | } |
191 | 193 | ||
192 | switch (sdata->type) { | 194 | switch (sdata->vif.type) { |
193 | case IEEE80211_IF_TYPE_WDS: | 195 | case IEEE80211_IF_TYPE_WDS: |
194 | if (is_zero_ether_addr(sdata->u.wds.remote_addr)) | 196 | if (is_zero_ether_addr(sdata->u.wds.remote_addr)) |
195 | return -ENOLINK; | 197 | return -ENOLINK; |
@@ -217,9 +219,10 @@ static int ieee80211_open(struct net_device *dev) | |||
217 | if (res) | 219 | if (res) |
218 | return res; | 220 | return res; |
219 | ieee80211_hw_config(local); | 221 | ieee80211_hw_config(local); |
222 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | ||
220 | } | 223 | } |
221 | 224 | ||
222 | switch (sdata->type) { | 225 | switch (sdata->vif.type) { |
223 | case IEEE80211_IF_TYPE_VLAN: | 226 | case IEEE80211_IF_TYPE_VLAN: |
224 | list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans); | 227 | list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans); |
225 | /* no need to tell driver */ | 228 | /* no need to tell driver */ |
@@ -240,8 +243,8 @@ static int ieee80211_open(struct net_device *dev) | |||
240 | sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 243 | sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
241 | /* fall through */ | 244 | /* fall through */ |
242 | default: | 245 | default: |
243 | conf.if_id = dev->ifindex; | 246 | conf.vif = &sdata->vif; |
244 | conf.type = sdata->type; | 247 | conf.type = sdata->vif.type; |
245 | conf.mac_addr = dev->dev_addr; | 248 | conf.mac_addr = dev->dev_addr; |
246 | res = local->ops->add_interface(local_to_hw(local), &conf); | 249 | res = local->ops->add_interface(local_to_hw(local), &conf); |
247 | if (res && !local->open_count && local->ops->stop) | 250 | if (res && !local->open_count && local->ops->stop) |
@@ -253,7 +256,7 @@ static int ieee80211_open(struct net_device *dev) | |||
253 | ieee80211_reset_erp_info(dev); | 256 | ieee80211_reset_erp_info(dev); |
254 | ieee80211_enable_keys(sdata); | 257 | ieee80211_enable_keys(sdata); |
255 | 258 | ||
256 | if (sdata->type == IEEE80211_IF_TYPE_STA && | 259 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
257 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) | 260 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) |
258 | netif_carrier_off(dev); | 261 | netif_carrier_off(dev); |
259 | else | 262 | else |
@@ -290,9 +293,20 @@ static int ieee80211_stop(struct net_device *dev) | |||
290 | struct ieee80211_sub_if_data *sdata; | 293 | struct ieee80211_sub_if_data *sdata; |
291 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 294 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
292 | struct ieee80211_if_init_conf conf; | 295 | struct ieee80211_if_init_conf conf; |
296 | struct sta_info *sta; | ||
297 | int i; | ||
293 | 298 | ||
294 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 299 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
295 | 300 | ||
301 | list_for_each_entry(sta, &local->sta_list, list) { | ||
302 | if (sta->dev == dev) | ||
303 | for (i = 0; i < STA_TID_NUM; i++) | ||
304 | ieee80211_sta_stop_rx_ba_session(sta->dev, | ||
305 | sta->addr, i, | ||
306 | WLAN_BACK_RECIPIENT, | ||
307 | WLAN_REASON_QSTA_LEAVE_QBSS); | ||
308 | } | ||
309 | |||
296 | netif_stop_queue(dev); | 310 | netif_stop_queue(dev); |
297 | 311 | ||
298 | /* | 312 | /* |
@@ -309,10 +323,17 @@ static int ieee80211_stop(struct net_device *dev) | |||
309 | 323 | ||
310 | dev_mc_unsync(local->mdev, dev); | 324 | dev_mc_unsync(local->mdev, dev); |
311 | 325 | ||
312 | /* down all dependent devices, that is VLANs */ | 326 | /* APs need special treatment */ |
313 | if (sdata->type == IEEE80211_IF_TYPE_AP) { | 327 | if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
314 | struct ieee80211_sub_if_data *vlan, *tmp; | 328 | struct ieee80211_sub_if_data *vlan, *tmp; |
329 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | ||
315 | 330 | ||
331 | /* remove beacon */ | ||
332 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
333 | synchronize_rcu(); | ||
334 | kfree(old_beacon); | ||
335 | |||
336 | /* down all dependent devices, that is VLANs */ | ||
316 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, | 337 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, |
317 | u.vlan.list) | 338 | u.vlan.list) |
318 | dev_close(vlan->dev); | 339 | dev_close(vlan->dev); |
@@ -321,7 +342,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
321 | 342 | ||
322 | local->open_count--; | 343 | local->open_count--; |
323 | 344 | ||
324 | switch (sdata->type) { | 345 | switch (sdata->vif.type) { |
325 | case IEEE80211_IF_TYPE_VLAN: | 346 | case IEEE80211_IF_TYPE_VLAN: |
326 | list_del(&sdata->u.vlan.list); | 347 | list_del(&sdata->u.vlan.list); |
327 | sdata->u.vlan.ap = NULL; | 348 | sdata->u.vlan.ap = NULL; |
@@ -350,11 +371,14 @@ static int ieee80211_stop(struct net_device *dev) | |||
350 | synchronize_rcu(); | 371 | synchronize_rcu(); |
351 | skb_queue_purge(&sdata->u.sta.skb_queue); | 372 | skb_queue_purge(&sdata->u.sta.skb_queue); |
352 | 373 | ||
353 | if (!local->ops->hw_scan && | 374 | if (local->scan_dev == sdata->dev) { |
354 | local->scan_dev == sdata->dev) { | 375 | if (!local->ops->hw_scan) { |
355 | local->sta_scanning = 0; | 376 | local->sta_sw_scanning = 0; |
356 | cancel_delayed_work(&local->scan_work); | 377 | cancel_delayed_work(&local->scan_work); |
378 | } else | ||
379 | local->sta_hw_scanning = 0; | ||
357 | } | 380 | } |
381 | |||
358 | flush_workqueue(local->hw.workqueue); | 382 | flush_workqueue(local->hw.workqueue); |
359 | 383 | ||
360 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | 384 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; |
@@ -363,8 +387,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
363 | sdata->u.sta.extra_ie_len = 0; | 387 | sdata->u.sta.extra_ie_len = 0; |
364 | /* fall through */ | 388 | /* fall through */ |
365 | default: | 389 | default: |
366 | conf.if_id = dev->ifindex; | 390 | conf.vif = &sdata->vif; |
367 | conf.type = sdata->type; | 391 | conf.type = sdata->vif.type; |
368 | conf.mac_addr = dev->dev_addr; | 392 | conf.mac_addr = dev->dev_addr; |
369 | /* disable all keys for as long as this netdev is down */ | 393 | /* disable all keys for as long as this netdev is down */ |
370 | ieee80211_disable_keys(sdata); | 394 | ieee80211_disable_keys(sdata); |
@@ -378,6 +402,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
378 | if (local->ops->stop) | 402 | if (local->ops->stop) |
379 | local->ops->stop(local_to_hw(local)); | 403 | local->ops->stop(local_to_hw(local)); |
380 | 404 | ||
405 | ieee80211_led_radio(local, 0); | ||
406 | |||
381 | tasklet_disable(&local->tx_pending_tasklet); | 407 | tasklet_disable(&local->tx_pending_tasklet); |
382 | tasklet_disable(&local->tasklet); | 408 | tasklet_disable(&local->tasklet); |
383 | } | 409 | } |
@@ -485,20 +511,20 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
485 | return 0; | 511 | return 0; |
486 | 512 | ||
487 | memset(&conf, 0, sizeof(conf)); | 513 | memset(&conf, 0, sizeof(conf)); |
488 | conf.type = sdata->type; | 514 | conf.type = sdata->vif.type; |
489 | if (sdata->type == IEEE80211_IF_TYPE_STA || | 515 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
490 | sdata->type == IEEE80211_IF_TYPE_IBSS) { | 516 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
491 | conf.bssid = sdata->u.sta.bssid; | 517 | conf.bssid = sdata->u.sta.bssid; |
492 | conf.ssid = sdata->u.sta.ssid; | 518 | conf.ssid = sdata->u.sta.ssid; |
493 | conf.ssid_len = sdata->u.sta.ssid_len; | 519 | conf.ssid_len = sdata->u.sta.ssid_len; |
494 | } else if (sdata->type == IEEE80211_IF_TYPE_AP) { | 520 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
495 | conf.ssid = sdata->u.ap.ssid; | 521 | conf.ssid = sdata->u.ap.ssid; |
496 | conf.ssid_len = sdata->u.ap.ssid_len; | 522 | conf.ssid_len = sdata->u.ap.ssid_len; |
497 | conf.beacon = beacon; | 523 | conf.beacon = beacon; |
498 | conf.beacon_control = control; | 524 | conf.beacon_control = control; |
499 | } | 525 | } |
500 | return local->ops->config_interface(local_to_hw(local), | 526 | return local->ops->config_interface(local_to_hw(local), |
501 | dev->ifindex, &conf); | 527 | &sdata->vif, &conf); |
502 | } | 528 | } |
503 | 529 | ||
504 | int ieee80211_if_config(struct net_device *dev) | 530 | int ieee80211_if_config(struct net_device *dev) |
@@ -510,11 +536,13 @@ int ieee80211_if_config_beacon(struct net_device *dev) | |||
510 | { | 536 | { |
511 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 537 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
512 | struct ieee80211_tx_control control; | 538 | struct ieee80211_tx_control control; |
539 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
513 | struct sk_buff *skb; | 540 | struct sk_buff *skb; |
514 | 541 | ||
515 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 542 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
516 | return 0; | 543 | return 0; |
517 | skb = ieee80211_beacon_get(local_to_hw(local), dev->ifindex, &control); | 544 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, |
545 | &control); | ||
518 | if (!skb) | 546 | if (!skb) |
519 | return -ENOMEM; | 547 | return -ENOMEM; |
520 | return __ieee80211_if_config(dev, skb, &control); | 548 | return __ieee80211_if_config(dev, skb, &control); |
@@ -526,7 +554,7 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
526 | struct ieee80211_channel *chan; | 554 | struct ieee80211_channel *chan; |
527 | int ret = 0; | 555 | int ret = 0; |
528 | 556 | ||
529 | if (local->sta_scanning) { | 557 | if (local->sta_sw_scanning) { |
530 | chan = local->scan_channel; | 558 | chan = local->scan_channel; |
531 | mode = local->scan_hw_mode; | 559 | mode = local->scan_hw_mode; |
532 | } else { | 560 | } else { |
@@ -560,25 +588,79 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
560 | return ret; | 588 | return ret; |
561 | } | 589 | } |
562 | 590 | ||
563 | void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes) | 591 | /** |
592 | * ieee80211_hw_config_ht should be used only after legacy configuration | ||
593 | * has been determined, as ht configuration depends upon the hardware's | ||
594 | * HT abilities for a _specific_ band. | ||
595 | */ | ||
596 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | ||
597 | struct ieee80211_ht_info *req_ht_cap, | ||
598 | struct ieee80211_ht_bss_info *req_bss_cap) | ||
564 | { | 599 | { |
565 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 600 | struct ieee80211_conf *conf = &local->hw.conf; |
566 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 601 | struct ieee80211_hw_mode *mode = conf->mode; |
567 | if (local->ops->erp_ie_changed) | 602 | int i; |
568 | local->ops->erp_ie_changed(local_to_hw(local), changes, | 603 | |
569 | !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION), | 604 | /* HT is not supported */ |
570 | !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE)); | 605 | if (!mode->ht_info.ht_supported) { |
606 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
607 | return -EOPNOTSUPP; | ||
608 | } | ||
609 | |||
610 | /* disable HT */ | ||
611 | if (!enable_ht) { | ||
612 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
613 | } else { | ||
614 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
615 | conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap; | ||
616 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | ||
617 | conf->ht_conf.cap |= | ||
618 | mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | ||
619 | conf->ht_bss_conf.primary_channel = | ||
620 | req_bss_cap->primary_channel; | ||
621 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
622 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
623 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | ||
624 | conf->ht_conf.supp_mcs_set[i] = | ||
625 | mode->ht_info.supp_mcs_set[i] & | ||
626 | req_ht_cap->supp_mcs_set[i]; | ||
627 | |||
628 | /* In STA mode, this gives us indication | ||
629 | * to the AP's mode of operation */ | ||
630 | conf->ht_conf.ht_supported = 1; | ||
631 | conf->ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | ||
632 | conf->ht_conf.ampdu_density = req_ht_cap->ampdu_density; | ||
633 | } | ||
634 | |||
635 | local->ops->conf_ht(local_to_hw(local), &local->hw.conf); | ||
636 | |||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | ||
641 | u32 changed) | ||
642 | { | ||
643 | struct ieee80211_local *local = sdata->local; | ||
644 | |||
645 | if (!changed) | ||
646 | return; | ||
647 | |||
648 | if (local->ops->bss_info_changed) | ||
649 | local->ops->bss_info_changed(local_to_hw(local), | ||
650 | &sdata->vif, | ||
651 | &sdata->bss_conf, | ||
652 | changed); | ||
571 | } | 653 | } |
572 | 654 | ||
573 | void ieee80211_reset_erp_info(struct net_device *dev) | 655 | void ieee80211_reset_erp_info(struct net_device *dev) |
574 | { | 656 | { |
575 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 657 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
576 | 658 | ||
577 | sdata->flags &= ~(IEEE80211_SDATA_USE_PROTECTION | | 659 | sdata->bss_conf.use_cts_prot = 0; |
578 | IEEE80211_SDATA_SHORT_PREAMBLE); | 660 | sdata->bss_conf.use_short_preamble = 0; |
579 | ieee80211_erp_info_change_notify(dev, | 661 | ieee80211_bss_info_change_notify(sdata, |
580 | IEEE80211_ERP_CHANGE_PROTECTION | | 662 | BSS_CHANGED_ERP_CTS_PROT | |
581 | IEEE80211_ERP_CHANGE_PREAMBLE); | 663 | BSS_CHANGED_ERP_PREAMBLE); |
582 | } | 664 | } |
583 | 665 | ||
584 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 666 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
@@ -635,7 +717,7 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
635 | case IEEE80211_RX_MSG: | 717 | case IEEE80211_RX_MSG: |
636 | /* status is in skb->cb */ | 718 | /* status is in skb->cb */ |
637 | memcpy(&rx_status, skb->cb, sizeof(rx_status)); | 719 | memcpy(&rx_status, skb->cb, sizeof(rx_status)); |
638 | /* Clear skb->type in order to not confuse kernel | 720 | /* Clear skb->pkt_type in order to not confuse kernel |
639 | * netstack. */ | 721 | * netstack. */ |
640 | skb->pkt_type = 0; | 722 | skb->pkt_type = 0; |
641 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 723 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
@@ -670,7 +752,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | |||
670 | struct ieee80211_tx_packet_data *pkt_data; | 752 | struct ieee80211_tx_packet_data *pkt_data; |
671 | 753 | ||
672 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 754 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; |
673 | pkt_data->ifindex = control->ifindex; | 755 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; |
674 | pkt_data->flags = 0; | 756 | pkt_data->flags = 0; |
675 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 757 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) |
676 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | 758 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; |
@@ -678,6 +760,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | |||
678 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 760 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; |
679 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | 761 | if (control->flags & IEEE80211_TXCTL_REQUEUE) |
680 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | 762 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; |
763 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
764 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
681 | pkt_data->queue = control->queue; | 765 | pkt_data->queue = control->queue; |
682 | 766 | ||
683 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 767 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
@@ -805,10 +889,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
805 | sta_info_put(sta); | 889 | sta_info_put(sta); |
806 | return; | 890 | return; |
807 | } | 891 | } |
808 | } else { | 892 | } else |
809 | /* FIXME: STUPID to call this with both local and local->mdev */ | 893 | rate_control_tx_status(local->mdev, skb, status); |
810 | rate_control_tx_status(local, local->mdev, skb, status); | ||
811 | } | ||
812 | 894 | ||
813 | ieee80211_led_tx(local, 0); | 895 | ieee80211_led_tx(local, 0); |
814 | 896 | ||
@@ -894,7 +976,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
894 | if (!monitors || !skb) | 976 | if (!monitors || !skb) |
895 | goto out; | 977 | goto out; |
896 | 978 | ||
897 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) { | 979 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { |
898 | if (!netif_running(sdata->dev)) | 980 | if (!netif_running(sdata->dev)) |
899 | continue; | 981 | continue; |
900 | monitors--; | 982 | monitors--; |
@@ -1016,7 +1098,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1016 | mdev->header_ops = &ieee80211_header_ops; | 1098 | mdev->header_ops = &ieee80211_header_ops; |
1017 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 1099 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
1018 | 1100 | ||
1019 | sdata->type = IEEE80211_IF_TYPE_AP; | 1101 | sdata->vif.type = IEEE80211_IF_TYPE_AP; |
1020 | sdata->dev = mdev; | 1102 | sdata->dev = mdev; |
1021 | sdata->local = local; | 1103 | sdata->local = local; |
1022 | sdata->u.ap.force_unicast_rateidx = -1; | 1104 | sdata->u.ap.force_unicast_rateidx = -1; |
@@ -1260,33 +1342,38 @@ static int __init ieee80211_init(void) | |||
1260 | 1342 | ||
1261 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1343 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); |
1262 | 1344 | ||
1263 | #ifdef CONFIG_MAC80211_RCSIMPLE | 1345 | ret = rc80211_simple_init(); |
1264 | ret = ieee80211_rate_control_register(&mac80211_rcsimple); | ||
1265 | if (ret) | 1346 | if (ret) |
1266 | return ret; | 1347 | goto fail; |
1267 | #endif | 1348 | |
1349 | ret = rc80211_pid_init(); | ||
1350 | if (ret) | ||
1351 | goto fail_simple; | ||
1268 | 1352 | ||
1269 | ret = ieee80211_wme_register(); | 1353 | ret = ieee80211_wme_register(); |
1270 | if (ret) { | 1354 | if (ret) { |
1271 | #ifdef CONFIG_MAC80211_RCSIMPLE | ||
1272 | ieee80211_rate_control_unregister(&mac80211_rcsimple); | ||
1273 | #endif | ||
1274 | printk(KERN_DEBUG "ieee80211_init: failed to " | 1355 | printk(KERN_DEBUG "ieee80211_init: failed to " |
1275 | "initialize WME (err=%d)\n", ret); | 1356 | "initialize WME (err=%d)\n", ret); |
1276 | return ret; | 1357 | goto fail_pid; |
1277 | } | 1358 | } |
1278 | 1359 | ||
1279 | ieee80211_debugfs_netdev_init(); | 1360 | ieee80211_debugfs_netdev_init(); |
1280 | ieee80211_regdomain_init(); | 1361 | ieee80211_regdomain_init(); |
1281 | 1362 | ||
1282 | return 0; | 1363 | return 0; |
1364 | |||
1365 | fail_pid: | ||
1366 | rc80211_simple_exit(); | ||
1367 | fail_simple: | ||
1368 | rc80211_pid_exit(); | ||
1369 | fail: | ||
1370 | return ret; | ||
1283 | } | 1371 | } |
1284 | 1372 | ||
1285 | static void __exit ieee80211_exit(void) | 1373 | static void __exit ieee80211_exit(void) |
1286 | { | 1374 | { |
1287 | #ifdef CONFIG_MAC80211_RCSIMPLE | 1375 | rc80211_simple_exit(); |
1288 | ieee80211_rate_control_unregister(&mac80211_rcsimple); | 1376 | rc80211_pid_exit(); |
1289 | #endif | ||
1290 | 1377 | ||
1291 | ieee80211_wme_unregister(); | 1378 | ieee80211_wme_unregister(); |
1292 | ieee80211_debugfs_netdev_exit(); | 1379 | ieee80211_debugfs_netdev_exit(); |