aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r--net/mac80211/ieee80211.c199
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
504int ieee80211_if_config(struct net_device *dev) 530int 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
563void 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 */
596int 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
640void 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
573void ieee80211_reset_erp_info(struct net_device *dev) 655void 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
584void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 666void 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
1285static void __exit ieee80211_exit(void) 1373static 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();