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.c236
1 files changed, 181 insertions, 55 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0d2d94881f1f..ded5c3843e06 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -17,10 +17,10 @@
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/if_arp.h> 19#include <linux/if_arp.h>
20#include <linux/wireless.h>
21#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
22#include <linux/bitmap.h> 21#include <linux/bitmap.h>
23#include <linux/pm_qos_params.h> 22#include <linux/pm_qos_params.h>
23#include <linux/inetdevice.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/cfg80211.h> 25#include <net/cfg80211.h>
26 26
@@ -32,7 +32,12 @@
32#include "led.h" 32#include "led.h"
33#include "cfg.h" 33#include "cfg.h"
34#include "debugfs.h" 34#include "debugfs.h"
35#include "debugfs_netdev.h" 35
36
37bool ieee80211_disable_40mhz_24ghz;
38module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
39MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
40 "Disable 40MHz support in the 2.4GHz band");
36 41
37void ieee80211_configure_filter(struct ieee80211_local *local) 42void ieee80211_configure_filter(struct ieee80211_local *local)
38{ 43{
@@ -67,7 +72,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
67 spin_lock_bh(&local->filter_lock); 72 spin_lock_bh(&local->filter_lock);
68 changed_flags = local->filter_flags ^ new_flags; 73 changed_flags = local->filter_flags ^ new_flags;
69 74
70 mc = drv_prepare_multicast(local, local->mc_count, local->mc_list); 75 mc = drv_prepare_multicast(local, &local->mc_list);
71 spin_unlock_bh(&local->filter_lock); 76 spin_unlock_bh(&local->filter_lock);
72 77
73 /* be a bit nasty */ 78 /* be a bit nasty */
@@ -102,9 +107,15 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
102 if (scan_chan) { 107 if (scan_chan) {
103 chan = scan_chan; 108 chan = scan_chan;
104 channel_type = NL80211_CHAN_NO_HT; 109 channel_type = NL80211_CHAN_NO_HT;
110 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
111 } else if (local->tmp_channel) {
112 chan = scan_chan = local->tmp_channel;
113 channel_type = local->tmp_channel_type;
114 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
105 } else { 115 } else {
106 chan = local->oper_channel; 116 chan = local->oper_channel;
107 channel_type = local->oper_channel_type; 117 channel_type = local->_oper_channel_type;
118 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
108 } 119 }
109 120
110 if (chan != local->hw.conf.channel || 121 if (chan != local->hw.conf.channel ||
@@ -114,6 +125,18 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
114 changed |= IEEE80211_CONF_CHANGE_CHANNEL; 125 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
115 } 126 }
116 127
128 if (!conf_is_ht(&local->hw.conf)) {
129 /*
130 * mac80211.h documents that this is only valid
131 * when the channel is set to an HT type, and
132 * that otherwise STATIC is used.
133 */
134 local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC;
135 } else if (local->hw.conf.smps_mode != local->smps_mode) {
136 local->hw.conf.smps_mode = local->smps_mode;
137 changed |= IEEE80211_CONF_CHANGE_SMPS;
138 }
139
117 if (scan_chan) 140 if (scan_chan)
118 power = chan->max_power; 141 power = chan->max_power;
119 else 142 else
@@ -173,7 +196,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
173 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 196 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
174 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 197 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
175 else if (sdata->vif.type == NL80211_IFTYPE_AP) 198 else if (sdata->vif.type == NL80211_IFTYPE_AP)
176 sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; 199 sdata->vif.bss_conf.bssid = sdata->vif.addr;
177 else if (ieee80211_vif_is_mesh(&sdata->vif)) { 200 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
178 sdata->vif.bss_conf.bssid = zero; 201 sdata->vif.bss_conf.bssid = zero;
179 } else { 202 } else {
@@ -195,7 +218,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
195 } 218 }
196 219
197 if (changed & BSS_CHANGED_BEACON_ENABLED) { 220 if (changed & BSS_CHANGED_BEACON_ENABLED) {
198 if (local->quiescing || !netif_running(sdata->dev) || 221 if (local->quiescing || !ieee80211_sdata_running(sdata) ||
199 test_bit(SCAN_SW_SCANNING, &local->scanning)) { 222 test_bit(SCAN_SW_SCANNING, &local->scanning)) {
200 sdata->vif.bss_conf.enable_beacon = false; 223 sdata->vif.bss_conf.enable_beacon = false;
201 } else { 224 } else {
@@ -206,11 +229,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
206 switch (sdata->vif.type) { 229 switch (sdata->vif.type) {
207 case NL80211_IFTYPE_AP: 230 case NL80211_IFTYPE_AP:
208 sdata->vif.bss_conf.enable_beacon = 231 sdata->vif.bss_conf.enable_beacon =
209 !!rcu_dereference(sdata->u.ap.beacon); 232 !!sdata->u.ap.beacon;
210 break; 233 break;
211 case NL80211_IFTYPE_ADHOC: 234 case NL80211_IFTYPE_ADHOC:
212 sdata->vif.bss_conf.enable_beacon = 235 sdata->vif.bss_conf.enable_beacon =
213 !!rcu_dereference(sdata->u.ibss.presp); 236 !!sdata->u.ibss.presp;
214 break; 237 break;
215 case NL80211_IFTYPE_MESH_POINT: 238 case NL80211_IFTYPE_MESH_POINT:
216 sdata->vif.bss_conf.enable_beacon = true; 239 sdata->vif.bss_conf.enable_beacon = true;
@@ -223,8 +246,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
223 } 246 }
224 } 247 }
225 248
226 drv_bss_info_changed(local, &sdata->vif, 249 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
227 &sdata->vif.bss_conf, changed);
228} 250}
229 251
230u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 252u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -241,7 +263,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
241{ 263{
242 struct ieee80211_local *local = (struct ieee80211_local *) data; 264 struct ieee80211_local *local = (struct ieee80211_local *) data;
243 struct sk_buff *skb; 265 struct sk_buff *skb;
244 struct ieee80211_ra_tid *ra_tid;
245 266
246 while ((skb = skb_dequeue(&local->skb_queue)) || 267 while ((skb = skb_dequeue(&local->skb_queue)) ||
247 (skb = skb_dequeue(&local->skb_queue_unreliable))) { 268 (skb = skb_dequeue(&local->skb_queue_unreliable))) {
@@ -256,18 +277,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
256 skb->pkt_type = 0; 277 skb->pkt_type = 0;
257 ieee80211_tx_status(local_to_hw(local), skb); 278 ieee80211_tx_status(local_to_hw(local), skb);
258 break; 279 break;
259 case IEEE80211_DELBA_MSG:
260 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
261 ieee80211_stop_tx_ba_cb(ra_tid->vif, ra_tid->ra,
262 ra_tid->tid);
263 dev_kfree_skb(skb);
264 break;
265 case IEEE80211_ADDBA_MSG:
266 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
267 ieee80211_start_tx_ba_cb(ra_tid->vif, ra_tid->ra,
268 ra_tid->tid);
269 dev_kfree_skb(skb);
270 break ;
271 default: 280 default:
272 WARN(1, "mac80211: Packet is of unknown type %d\n", 281 WARN(1, "mac80211: Packet is of unknown type %d\n",
273 skb->pkt_type); 282 skb->pkt_type);
@@ -291,6 +300,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
291{ 300{
292 struct ieee80211_local *local = hw_to_local(hw); 301 struct ieee80211_local *local = hw_to_local(hw);
293 302
303 trace_api_restart_hw(local);
304
294 /* use this reason, __ieee80211_resume will unblock it */ 305 /* use this reason, __ieee80211_resume will unblock it */
295 ieee80211_stop_queues_by_reason(hw, 306 ieee80211_stop_queues_by_reason(hw,
296 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 307 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -299,6 +310,86 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
299} 310}
300EXPORT_SYMBOL(ieee80211_restart_hw); 311EXPORT_SYMBOL(ieee80211_restart_hw);
301 312
313static void ieee80211_recalc_smps_work(struct work_struct *work)
314{
315 struct ieee80211_local *local =
316 container_of(work, struct ieee80211_local, recalc_smps);
317
318 mutex_lock(&local->iflist_mtx);
319 ieee80211_recalc_smps(local, NULL);
320 mutex_unlock(&local->iflist_mtx);
321}
322
323#ifdef CONFIG_INET
324static int ieee80211_ifa_changed(struct notifier_block *nb,
325 unsigned long data, void *arg)
326{
327 struct in_ifaddr *ifa = arg;
328 struct ieee80211_local *local =
329 container_of(nb, struct ieee80211_local,
330 ifa_notifier);
331 struct net_device *ndev = ifa->ifa_dev->dev;
332 struct wireless_dev *wdev = ndev->ieee80211_ptr;
333 struct in_device *idev;
334 struct ieee80211_sub_if_data *sdata;
335 struct ieee80211_bss_conf *bss_conf;
336 struct ieee80211_if_managed *ifmgd;
337 int c = 0;
338
339 if (!netif_running(ndev))
340 return NOTIFY_DONE;
341
342 /* Make sure it's our interface that got changed */
343 if (!wdev)
344 return NOTIFY_DONE;
345
346 if (wdev->wiphy != local->hw.wiphy)
347 return NOTIFY_DONE;
348
349 sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
350 bss_conf = &sdata->vif.bss_conf;
351
352 /* ARP filtering is only supported in managed mode */
353 if (sdata->vif.type != NL80211_IFTYPE_STATION)
354 return NOTIFY_DONE;
355
356 idev = sdata->dev->ip_ptr;
357 if (!idev)
358 return NOTIFY_DONE;
359
360 ifmgd = &sdata->u.mgd;
361 mutex_lock(&ifmgd->mtx);
362
363 /* Copy the addresses to the bss_conf list */
364 ifa = idev->ifa_list;
365 while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) {
366 bss_conf->arp_addr_list[c] = ifa->ifa_address;
367 ifa = ifa->ifa_next;
368 c++;
369 }
370
371 /* If not all addresses fit the list, disable filtering */
372 if (ifa) {
373 sdata->arp_filter_state = false;
374 c = 0;
375 } else {
376 sdata->arp_filter_state = true;
377 }
378 bss_conf->arp_addr_cnt = c;
379
380 /* Configure driver only if associated */
381 if (ifmgd->associated) {
382 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
383 ieee80211_bss_info_change_notify(sdata,
384 BSS_CHANGED_ARP_FILTER);
385 }
386
387 mutex_unlock(&ifmgd->mtx);
388
389 return NOTIFY_DONE;
390}
391#endif
392
302struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 393struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
303 const struct ieee80211_ops *ops) 394 const struct ieee80211_ops *ops)
304{ 395{
@@ -333,9 +424,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
333 WIPHY_FLAG_4ADDR_STATION; 424 WIPHY_FLAG_4ADDR_STATION;
334 wiphy->privid = mac80211_wiphy_privid; 425 wiphy->privid = mac80211_wiphy_privid;
335 426
336 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 427 wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
337 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
338 sizeof(struct cfg80211_bss);
339 428
340 local = wiphy_priv(wiphy); 429 local = wiphy_priv(wiphy);
341 430
@@ -358,20 +447,29 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
358 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 447 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
359 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 448 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
360 local->user_power_level = -1; 449 local->user_power_level = -1;
450 local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
451 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
361 452
362 INIT_LIST_HEAD(&local->interfaces); 453 INIT_LIST_HEAD(&local->interfaces);
454
455 __hw_addr_init(&local->mc_list);
456
363 mutex_init(&local->iflist_mtx); 457 mutex_init(&local->iflist_mtx);
364 mutex_init(&local->scan_mtx); 458 mutex_init(&local->scan_mtx);
365 459
366 spin_lock_init(&local->key_lock); 460 mutex_init(&local->key_mtx);
367 spin_lock_init(&local->filter_lock); 461 spin_lock_init(&local->filter_lock);
368 spin_lock_init(&local->queue_stop_reason_lock); 462 spin_lock_init(&local->queue_stop_reason_lock);
369 463
370 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 464 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
371 465
466 ieee80211_work_init(local);
467
372 INIT_WORK(&local->restart_work, ieee80211_restart_work); 468 INIT_WORK(&local->restart_work, ieee80211_restart_work);
373 469
374 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); 470 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
471 INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work);
472 local->smps_mode = IEEE80211_SMPS_OFF;
375 473
376 INIT_WORK(&local->dynamic_ps_enable_work, 474 INIT_WORK(&local->dynamic_ps_enable_work,
377 ieee80211_dynamic_ps_enable_work); 475 ieee80211_dynamic_ps_enable_work);
@@ -382,8 +480,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
382 480
383 sta_info_init(local); 481 sta_info_init(local);
384 482
385 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) 483 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
386 skb_queue_head_init(&local->pending[i]); 484 skb_queue_head_init(&local->pending[i]);
485 atomic_set(&local->agg_queue_stop[i], 0);
486 }
387 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, 487 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
388 (unsigned long)local); 488 (unsigned long)local);
389 489
@@ -394,8 +494,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
394 skb_queue_head_init(&local->skb_queue); 494 skb_queue_head_init(&local->skb_queue);
395 skb_queue_head_init(&local->skb_queue_unreliable); 495 skb_queue_head_init(&local->skb_queue_unreliable);
396 496
397 spin_lock_init(&local->ampdu_lock);
398
399 return local_to_hw(local); 497 return local_to_hw(local);
400} 498}
401EXPORT_SYMBOL(ieee80211_alloc_hw); 499EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -405,7 +503,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
405 struct ieee80211_local *local = hw_to_local(hw); 503 struct ieee80211_local *local = hw_to_local(hw);
406 int result; 504 int result;
407 enum ieee80211_band band; 505 enum ieee80211_band band;
408 int channels, i, j, max_bitrates; 506 int channels, max_bitrates;
409 bool supp_ht; 507 bool supp_ht;
410 static const u32 cipher_suites[] = { 508 static const u32 cipher_suites[] = {
411 WLAN_CIPHER_SUITE_WEP40, 509 WLAN_CIPHER_SUITE_WEP40,
@@ -461,6 +559,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
461 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 559 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
462 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; 560 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
463 561
562 WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
563 && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK),
564 "U-APSD not supported with HW_PS_NULLFUNC_STACK\n");
565
464 /* 566 /*
465 * Calculate scan IE length -- we need this to alloc 567 * Calculate scan IE length -- we need this to alloc
466 * memory and to subtract from the driver limit. It 568 * memory and to subtract from the driver limit. It
@@ -522,21 +624,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
522 624
523 debugfs_hw_add(local); 625 debugfs_hw_add(local);
524 626
627 /*
628 * if the driver doesn't specify a max listen interval we
629 * use 5 which should be a safe default
630 */
525 if (local->hw.max_listen_interval == 0) 631 if (local->hw.max_listen_interval == 0)
526 local->hw.max_listen_interval = 1; 632 local->hw.max_listen_interval = 5;
527 633
528 local->hw.conf.listen_interval = local->hw.max_listen_interval; 634 local->hw.conf.listen_interval = local->hw.max_listen_interval;
529 635
636 local->dynamic_ps_forced_timeout = -1;
637
530 result = sta_info_start(local); 638 result = sta_info_start(local);
531 if (result < 0) 639 if (result < 0)
532 goto fail_sta_info; 640 goto fail_sta_info;
533 641
534 result = ieee80211_wep_init(local); 642 result = ieee80211_wep_init(local);
535 if (result < 0) { 643 if (result < 0)
536 printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", 644 printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
537 wiphy_name(local->hw.wiphy), result); 645 wiphy_name(local->hw.wiphy), result);
538 goto fail_wep;
539 }
540 646
541 rtnl_lock(); 647 rtnl_lock();
542 648
@@ -561,40 +667,36 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
561 667
562 ieee80211_led_init(local); 668 ieee80211_led_init(local);
563 669
564 /* alloc internal scan request */
565 i = 0;
566 local->int_scan_req->ssids = &local->scan_ssid;
567 local->int_scan_req->n_ssids = 1;
568 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
569 if (!hw->wiphy->bands[band])
570 continue;
571 for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
572 local->int_scan_req->channels[i] =
573 &hw->wiphy->bands[band]->channels[j];
574 i++;
575 }
576 }
577 local->int_scan_req->n_channels = i;
578
579 local->network_latency_notifier.notifier_call = 670 local->network_latency_notifier.notifier_call =
580 ieee80211_max_network_latency; 671 ieee80211_max_network_latency;
581 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, 672 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
582 &local->network_latency_notifier); 673 &local->network_latency_notifier);
583
584 if (result) { 674 if (result) {
585 rtnl_lock(); 675 rtnl_lock();
586 goto fail_pm_qos; 676 goto fail_pm_qos;
587 } 677 }
588 678
679#ifdef CONFIG_INET
680 local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
681 result = register_inetaddr_notifier(&local->ifa_notifier);
682 if (result)
683 goto fail_ifa;
684#endif
685
589 return 0; 686 return 0;
590 687
688#ifdef CONFIG_INET
689 fail_ifa:
690 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
691 &local->network_latency_notifier);
692 rtnl_lock();
693#endif
591 fail_pm_qos: 694 fail_pm_qos:
592 ieee80211_led_exit(local); 695 ieee80211_led_exit(local);
593 ieee80211_remove_interfaces(local); 696 ieee80211_remove_interfaces(local);
594 fail_rate: 697 fail_rate:
595 rtnl_unlock(); 698 rtnl_unlock();
596 ieee80211_wep_free(local); 699 ieee80211_wep_free(local);
597 fail_wep:
598 sta_info_stop(local); 700 sta_info_stop(local);
599 fail_sta_info: 701 fail_sta_info:
600 destroy_workqueue(local->workqueue); 702 destroy_workqueue(local->workqueue);
@@ -615,6 +717,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
615 717
616 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 718 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
617 &local->network_latency_notifier); 719 &local->network_latency_notifier);
720#ifdef CONFIG_INET
721 unregister_inetaddr_notifier(&local->ifa_notifier);
722#endif
618 723
619 rtnl_lock(); 724 rtnl_lock();
620 725
@@ -627,6 +732,12 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
627 732
628 rtnl_unlock(); 733 rtnl_unlock();
629 734
735 /*
736 * Now all work items will be gone, but the
737 * timer might still be armed, so delete it
738 */
739 del_timer_sync(&local->work_timer);
740
630 cancel_work_sync(&local->reconfig_filter); 741 cancel_work_sync(&local->reconfig_filter);
631 742
632 ieee80211_clear_tx_pending(local); 743 ieee80211_clear_tx_pending(local);
@@ -672,18 +783,33 @@ static int __init ieee80211_init(void)
672 if (ret) 783 if (ret)
673 return ret; 784 return ret;
674 785
786 ret = rc80211_minstrel_ht_init();
787 if (ret)
788 goto err_minstrel;
789
675 ret = rc80211_pid_init(); 790 ret = rc80211_pid_init();
676 if (ret) 791 if (ret)
677 return ret; 792 goto err_pid;
678 793
679 ieee80211_debugfs_netdev_init(); 794 ret = ieee80211_iface_init();
795 if (ret)
796 goto err_netdev;
680 797
681 return 0; 798 return 0;
799 err_netdev:
800 rc80211_pid_exit();
801 err_pid:
802 rc80211_minstrel_ht_exit();
803 err_minstrel:
804 rc80211_minstrel_exit();
805
806 return ret;
682} 807}
683 808
684static void __exit ieee80211_exit(void) 809static void __exit ieee80211_exit(void)
685{ 810{
686 rc80211_pid_exit(); 811 rc80211_pid_exit();
812 rc80211_minstrel_ht_exit();
687 rc80211_minstrel_exit(); 813 rc80211_minstrel_exit();
688 814
689 /* 815 /*
@@ -695,7 +821,7 @@ static void __exit ieee80211_exit(void)
695 if (mesh_allocated) 821 if (mesh_allocated)
696 ieee80211s_stop(); 822 ieee80211s_stop();
697 823
698 ieee80211_debugfs_netdev_exit(); 824 ieee80211_iface_exit();
699} 825}
700 826
701 827