diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 194 |
1 files changed, 172 insertions, 22 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ded5c3843e06..22bc42b18991 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
54 | if (local->monitors || local->scanning) | 54 | if (local->monitors || local->scanning) |
55 | new_flags |= FIF_BCN_PRBRESP_PROMISC; | 55 | new_flags |= FIF_BCN_PRBRESP_PROMISC; |
56 | 56 | ||
57 | if (local->fif_probe_req || local->probe_req_reg) | ||
58 | new_flags |= FIF_PROBE_REQ; | ||
59 | |||
57 | if (local->fif_fcsfail) | 60 | if (local->fif_fcsfail) |
58 | new_flags |= FIF_FCSFAIL; | 61 | new_flags |= FIF_FCSFAIL; |
59 | 62 | ||
@@ -99,16 +102,19 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
99 | int ret = 0; | 102 | int ret = 0; |
100 | int power; | 103 | int power; |
101 | enum nl80211_channel_type channel_type; | 104 | enum nl80211_channel_type channel_type; |
105 | u32 offchannel_flag; | ||
102 | 106 | ||
103 | might_sleep(); | 107 | might_sleep(); |
104 | 108 | ||
105 | scan_chan = local->scan_channel; | 109 | scan_chan = local->scan_channel; |
106 | 110 | ||
111 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | ||
107 | if (scan_chan) { | 112 | if (scan_chan) { |
108 | chan = scan_chan; | 113 | chan = scan_chan; |
109 | channel_type = NL80211_CHAN_NO_HT; | 114 | channel_type = NL80211_CHAN_NO_HT; |
110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 115 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
111 | } else if (local->tmp_channel) { | 116 | } else if (local->tmp_channel && |
117 | local->oper_channel != local->tmp_channel) { | ||
112 | chan = scan_chan = local->tmp_channel; | 118 | chan = scan_chan = local->tmp_channel; |
113 | channel_type = local->tmp_channel_type; | 119 | channel_type = local->tmp_channel_type; |
114 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 120 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
@@ -117,8 +123,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
117 | channel_type = local->_oper_channel_type; | 123 | channel_type = local->_oper_channel_type; |
118 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | 124 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; |
119 | } | 125 | } |
126 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | ||
120 | 127 | ||
121 | if (chan != local->hw.conf.channel || | 128 | if (offchannel_flag || chan != local->hw.conf.channel || |
122 | channel_type != local->hw.conf.channel_type) { | 129 | channel_type != local->hw.conf.channel_type) { |
123 | local->hw.conf.channel = chan; | 130 | local->hw.conf.channel = chan; |
124 | local->hw.conf.channel_type = channel_type; | 131 | local->hw.conf.channel_type = channel_type; |
@@ -197,6 +204,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
197 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | 204 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; |
198 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | 205 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
199 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 206 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
207 | else if (sdata->vif.type == NL80211_IFTYPE_WDS) | ||
208 | sdata->vif.bss_conf.bssid = NULL; | ||
200 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 209 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
201 | sdata->vif.bss_conf.bssid = zero; | 210 | sdata->vif.bss_conf.bssid = zero; |
202 | } else { | 211 | } else { |
@@ -207,6 +216,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
207 | switch (sdata->vif.type) { | 216 | switch (sdata->vif.type) { |
208 | case NL80211_IFTYPE_AP: | 217 | case NL80211_IFTYPE_AP: |
209 | case NL80211_IFTYPE_ADHOC: | 218 | case NL80211_IFTYPE_ADHOC: |
219 | case NL80211_IFTYPE_WDS: | ||
210 | case NL80211_IFTYPE_MESH_POINT: | 220 | case NL80211_IFTYPE_MESH_POINT: |
211 | break; | 221 | break; |
212 | default: | 222 | default: |
@@ -291,7 +301,16 @@ static void ieee80211_restart_work(struct work_struct *work) | |||
291 | struct ieee80211_local *local = | 301 | struct ieee80211_local *local = |
292 | container_of(work, struct ieee80211_local, restart_work); | 302 | container_of(work, struct ieee80211_local, restart_work); |
293 | 303 | ||
304 | /* wait for scan work complete */ | ||
305 | flush_workqueue(local->workqueue); | ||
306 | |||
307 | mutex_lock(&local->mtx); | ||
308 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), | ||
309 | "%s called with hardware scan in progress\n", __func__); | ||
310 | mutex_unlock(&local->mtx); | ||
311 | |||
294 | rtnl_lock(); | 312 | rtnl_lock(); |
313 | ieee80211_scan_cancel(local); | ||
295 | ieee80211_reconfig(local); | 314 | ieee80211_reconfig(local); |
296 | rtnl_unlock(); | 315 | rtnl_unlock(); |
297 | } | 316 | } |
@@ -302,7 +321,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
302 | 321 | ||
303 | trace_api_restart_hw(local); | 322 | trace_api_restart_hw(local); |
304 | 323 | ||
305 | /* use this reason, __ieee80211_resume will unblock it */ | 324 | /* use this reason, ieee80211_reconfig will unblock it */ |
306 | ieee80211_stop_queues_by_reason(hw, | 325 | ieee80211_stop_queues_by_reason(hw, |
307 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 326 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
308 | 327 | ||
@@ -316,7 +335,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) | |||
316 | container_of(work, struct ieee80211_local, recalc_smps); | 335 | container_of(work, struct ieee80211_local, recalc_smps); |
317 | 336 | ||
318 | mutex_lock(&local->iflist_mtx); | 337 | mutex_lock(&local->iflist_mtx); |
319 | ieee80211_recalc_smps(local, NULL); | 338 | ieee80211_recalc_smps(local); |
320 | mutex_unlock(&local->iflist_mtx); | 339 | mutex_unlock(&local->iflist_mtx); |
321 | } | 340 | } |
322 | 341 | ||
@@ -336,9 +355,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
336 | struct ieee80211_if_managed *ifmgd; | 355 | struct ieee80211_if_managed *ifmgd; |
337 | int c = 0; | 356 | int c = 0; |
338 | 357 | ||
339 | if (!netif_running(ndev)) | ||
340 | return NOTIFY_DONE; | ||
341 | |||
342 | /* Make sure it's our interface that got changed */ | 358 | /* Make sure it's our interface that got changed */ |
343 | if (!wdev) | 359 | if (!wdev) |
344 | return NOTIFY_DONE; | 360 | return NOTIFY_DONE; |
@@ -349,11 +365,14 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
349 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); | 365 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); |
350 | bss_conf = &sdata->vif.bss_conf; | 366 | bss_conf = &sdata->vif.bss_conf; |
351 | 367 | ||
368 | if (!ieee80211_sdata_running(sdata)) | ||
369 | return NOTIFY_DONE; | ||
370 | |||
352 | /* ARP filtering is only supported in managed mode */ | 371 | /* ARP filtering is only supported in managed mode */ |
353 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 372 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
354 | return NOTIFY_DONE; | 373 | return NOTIFY_DONE; |
355 | 374 | ||
356 | idev = sdata->dev->ip_ptr; | 375 | idev = __in_dev_get_rtnl(sdata->dev); |
357 | if (!idev) | 376 | if (!idev) |
358 | return NOTIFY_DONE; | 377 | return NOTIFY_DONE; |
359 | 378 | ||
@@ -390,6 +409,80 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
390 | } | 409 | } |
391 | #endif | 410 | #endif |
392 | 411 | ||
412 | static int ieee80211_napi_poll(struct napi_struct *napi, int budget) | ||
413 | { | ||
414 | struct ieee80211_local *local = | ||
415 | container_of(napi, struct ieee80211_local, napi); | ||
416 | |||
417 | return local->ops->napi_poll(&local->hw, budget); | ||
418 | } | ||
419 | |||
420 | void ieee80211_napi_schedule(struct ieee80211_hw *hw) | ||
421 | { | ||
422 | struct ieee80211_local *local = hw_to_local(hw); | ||
423 | |||
424 | napi_schedule(&local->napi); | ||
425 | } | ||
426 | EXPORT_SYMBOL(ieee80211_napi_schedule); | ||
427 | |||
428 | void ieee80211_napi_complete(struct ieee80211_hw *hw) | ||
429 | { | ||
430 | struct ieee80211_local *local = hw_to_local(hw); | ||
431 | |||
432 | napi_complete(&local->napi); | ||
433 | } | ||
434 | EXPORT_SYMBOL(ieee80211_napi_complete); | ||
435 | |||
436 | /* There isn't a lot of sense in it, but you can transmit anything you like */ | ||
437 | static const struct ieee80211_txrx_stypes | ||
438 | ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | ||
439 | [NL80211_IFTYPE_ADHOC] = { | ||
440 | .tx = 0xffff, | ||
441 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4), | ||
442 | }, | ||
443 | [NL80211_IFTYPE_STATION] = { | ||
444 | .tx = 0xffff, | ||
445 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||
446 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), | ||
447 | }, | ||
448 | [NL80211_IFTYPE_AP] = { | ||
449 | .tx = 0xffff, | ||
450 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
451 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
452 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
453 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
454 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
455 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
456 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
457 | }, | ||
458 | [NL80211_IFTYPE_AP_VLAN] = { | ||
459 | /* copy AP */ | ||
460 | .tx = 0xffff, | ||
461 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
462 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
463 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
464 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
465 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
466 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
467 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
468 | }, | ||
469 | [NL80211_IFTYPE_P2P_CLIENT] = { | ||
470 | .tx = 0xffff, | ||
471 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||
472 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), | ||
473 | }, | ||
474 | [NL80211_IFTYPE_P2P_GO] = { | ||
475 | .tx = 0xffff, | ||
476 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
477 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
478 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
479 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
480 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
481 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
482 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
483 | }, | ||
484 | }; | ||
485 | |||
393 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 486 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
394 | const struct ieee80211_ops *ops) | 487 | const struct ieee80211_ops *ops) |
395 | { | 488 | { |
@@ -419,6 +512,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
419 | if (!wiphy) | 512 | if (!wiphy) |
420 | return NULL; | 513 | return NULL; |
421 | 514 | ||
515 | wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; | ||
516 | |||
422 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | | 517 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
423 | WIPHY_FLAG_4ADDR_AP | | 518 | WIPHY_FLAG_4ADDR_AP | |
424 | WIPHY_FLAG_4ADDR_STATION; | 519 | WIPHY_FLAG_4ADDR_STATION; |
@@ -444,6 +539,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
444 | /* set up some defaults */ | 539 | /* set up some defaults */ |
445 | local->hw.queues = 1; | 540 | local->hw.queues = 1; |
446 | local->hw.max_rates = 1; | 541 | local->hw.max_rates = 1; |
542 | local->hw.max_report_rates = 0; | ||
447 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 543 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
448 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 544 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
449 | local->user_power_level = -1; | 545 | local->user_power_level = -1; |
@@ -455,7 +551,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
455 | __hw_addr_init(&local->mc_list); | 551 | __hw_addr_init(&local->mc_list); |
456 | 552 | ||
457 | mutex_init(&local->iflist_mtx); | 553 | mutex_init(&local->iflist_mtx); |
458 | mutex_init(&local->scan_mtx); | 554 | mutex_init(&local->mtx); |
459 | 555 | ||
460 | mutex_init(&local->key_mtx); | 556 | mutex_init(&local->key_mtx); |
461 | spin_lock_init(&local->filter_lock); | 557 | spin_lock_init(&local->filter_lock); |
@@ -494,6 +590,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
494 | skb_queue_head_init(&local->skb_queue); | 590 | skb_queue_head_init(&local->skb_queue); |
495 | skb_queue_head_init(&local->skb_queue_unreliable); | 591 | skb_queue_head_init(&local->skb_queue_unreliable); |
496 | 592 | ||
593 | /* init dummy netdev for use w/ NAPI */ | ||
594 | init_dummy_netdev(&local->napi_dev); | ||
595 | |||
497 | return local_to_hw(local); | 596 | return local_to_hw(local); |
498 | } | 597 | } |
499 | EXPORT_SYMBOL(ieee80211_alloc_hw); | 598 | EXPORT_SYMBOL(ieee80211_alloc_hw); |
@@ -506,6 +605,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
506 | int channels, max_bitrates; | 605 | int channels, max_bitrates; |
507 | bool supp_ht; | 606 | bool supp_ht; |
508 | static const u32 cipher_suites[] = { | 607 | static const u32 cipher_suites[] = { |
608 | /* keep WEP first, it may be removed below */ | ||
509 | WLAN_CIPHER_SUITE_WEP40, | 609 | WLAN_CIPHER_SUITE_WEP40, |
510 | WLAN_CIPHER_SUITE_WEP104, | 610 | WLAN_CIPHER_SUITE_WEP104, |
511 | WLAN_CIPHER_SUITE_TKIP, | 611 | WLAN_CIPHER_SUITE_TKIP, |
@@ -515,6 +615,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
515 | WLAN_CIPHER_SUITE_AES_CMAC | 615 | WLAN_CIPHER_SUITE_AES_CMAC |
516 | }; | 616 | }; |
517 | 617 | ||
618 | if (hw->max_report_rates == 0) | ||
619 | hw->max_report_rates = hw->max_rates; | ||
620 | |||
518 | /* | 621 | /* |
519 | * generic code guarantees at least one band, | 622 | * generic code guarantees at least one band, |
520 | * set this very early because much code assumes | 623 | * set this very early because much code assumes |
@@ -554,6 +657,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
554 | /* mac80211 always supports monitor */ | 657 | /* mac80211 always supports monitor */ |
555 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | 658 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); |
556 | 659 | ||
660 | #ifndef CONFIG_MAC80211_MESH | ||
661 | /* mesh depends on Kconfig, but drivers should set it if they want */ | ||
662 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | ||
663 | #endif | ||
664 | |||
665 | /* mac80211 supports control port protocol changing */ | ||
666 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | ||
667 | |||
557 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 668 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
558 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 669 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
559 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 670 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
@@ -589,10 +700,41 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
589 | if (local->hw.wiphy->max_scan_ie_len) | 700 | if (local->hw.wiphy->max_scan_ie_len) |
590 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; | 701 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; |
591 | 702 | ||
592 | local->hw.wiphy->cipher_suites = cipher_suites; | 703 | /* Set up cipher suites unless driver already did */ |
593 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 704 | if (!local->hw.wiphy->cipher_suites) { |
594 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | 705 | local->hw.wiphy->cipher_suites = cipher_suites; |
595 | local->hw.wiphy->n_cipher_suites--; | 706 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
707 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | ||
708 | local->hw.wiphy->n_cipher_suites--; | ||
709 | } | ||
710 | if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { | ||
711 | if (local->hw.wiphy->cipher_suites == cipher_suites) { | ||
712 | local->hw.wiphy->cipher_suites += 2; | ||
713 | local->hw.wiphy->n_cipher_suites -= 2; | ||
714 | } else { | ||
715 | u32 *suites; | ||
716 | int r, w = 0; | ||
717 | |||
718 | /* Filter out WEP */ | ||
719 | |||
720 | suites = kmemdup( | ||
721 | local->hw.wiphy->cipher_suites, | ||
722 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | ||
723 | GFP_KERNEL); | ||
724 | if (!suites) | ||
725 | return -ENOMEM; | ||
726 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { | ||
727 | u32 suite = local->hw.wiphy->cipher_suites[r]; | ||
728 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | ||
729 | suite == WLAN_CIPHER_SUITE_WEP104) | ||
730 | continue; | ||
731 | suites[w++] = suite; | ||
732 | } | ||
733 | local->hw.wiphy->cipher_suites = suites; | ||
734 | local->hw.wiphy->n_cipher_suites = w; | ||
735 | local->wiphy_ciphers_allocated = true; | ||
736 | } | ||
737 | } | ||
596 | 738 | ||
597 | result = wiphy_register(local->hw.wiphy); | 739 | result = wiphy_register(local->hw.wiphy); |
598 | if (result < 0) | 740 | if (result < 0) |
@@ -641,16 +783,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
641 | 783 | ||
642 | result = ieee80211_wep_init(local); | 784 | result = ieee80211_wep_init(local); |
643 | if (result < 0) | 785 | if (result < 0) |
644 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", | 786 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
645 | wiphy_name(local->hw.wiphy), result); | 787 | result); |
646 | 788 | ||
647 | rtnl_lock(); | 789 | rtnl_lock(); |
648 | 790 | ||
649 | result = ieee80211_init_rate_ctrl_alg(local, | 791 | result = ieee80211_init_rate_ctrl_alg(local, |
650 | hw->rate_control_algorithm); | 792 | hw->rate_control_algorithm); |
651 | if (result < 0) { | 793 | if (result < 0) { |
652 | printk(KERN_DEBUG "%s: Failed to initialize rate control " | 794 | wiphy_debug(local->hw.wiphy, |
653 | "algorithm\n", wiphy_name(local->hw.wiphy)); | 795 | "Failed to initialize rate control algorithm\n"); |
654 | goto fail_rate; | 796 | goto fail_rate; |
655 | } | 797 | } |
656 | 798 | ||
@@ -659,8 +801,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
659 | result = ieee80211_if_add(local, "wlan%d", NULL, | 801 | result = ieee80211_if_add(local, "wlan%d", NULL, |
660 | NL80211_IFTYPE_STATION, NULL); | 802 | NL80211_IFTYPE_STATION, NULL); |
661 | if (result) | 803 | if (result) |
662 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 804 | wiphy_warn(local->hw.wiphy, |
663 | wiphy_name(local->hw.wiphy)); | 805 | "Failed to add default virtual iface\n"); |
664 | } | 806 | } |
665 | 807 | ||
666 | rtnl_unlock(); | 808 | rtnl_unlock(); |
@@ -683,6 +825,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
683 | goto fail_ifa; | 825 | goto fail_ifa; |
684 | #endif | 826 | #endif |
685 | 827 | ||
828 | netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, | ||
829 | local->hw.napi_weight); | ||
830 | |||
686 | return 0; | 831 | return 0; |
687 | 832 | ||
688 | #ifdef CONFIG_INET | 833 | #ifdef CONFIG_INET |
@@ -703,6 +848,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
703 | fail_workqueue: | 848 | fail_workqueue: |
704 | wiphy_unregister(local->hw.wiphy); | 849 | wiphy_unregister(local->hw.wiphy); |
705 | fail_wiphy_register: | 850 | fail_wiphy_register: |
851 | if (local->wiphy_ciphers_allocated) | ||
852 | kfree(local->hw.wiphy->cipher_suites); | ||
706 | kfree(local->int_scan_req); | 853 | kfree(local->int_scan_req); |
707 | return result; | 854 | return result; |
708 | } | 855 | } |
@@ -738,6 +885,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
738 | */ | 885 | */ |
739 | del_timer_sync(&local->work_timer); | 886 | del_timer_sync(&local->work_timer); |
740 | 887 | ||
888 | cancel_work_sync(&local->restart_work); | ||
741 | cancel_work_sync(&local->reconfig_filter); | 889 | cancel_work_sync(&local->reconfig_filter); |
742 | 890 | ||
743 | ieee80211_clear_tx_pending(local); | 891 | ieee80211_clear_tx_pending(local); |
@@ -746,8 +894,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
746 | 894 | ||
747 | if (skb_queue_len(&local->skb_queue) || | 895 | if (skb_queue_len(&local->skb_queue) || |
748 | skb_queue_len(&local->skb_queue_unreliable)) | 896 | skb_queue_len(&local->skb_queue_unreliable)) |
749 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 897 | wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); |
750 | wiphy_name(local->hw.wiphy)); | ||
751 | skb_queue_purge(&local->skb_queue); | 898 | skb_queue_purge(&local->skb_queue); |
752 | skb_queue_purge(&local->skb_queue_unreliable); | 899 | skb_queue_purge(&local->skb_queue_unreliable); |
753 | 900 | ||
@@ -764,7 +911,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
764 | struct ieee80211_local *local = hw_to_local(hw); | 911 | struct ieee80211_local *local = hw_to_local(hw); |
765 | 912 | ||
766 | mutex_destroy(&local->iflist_mtx); | 913 | mutex_destroy(&local->iflist_mtx); |
767 | mutex_destroy(&local->scan_mtx); | 914 | mutex_destroy(&local->mtx); |
915 | |||
916 | if (local->wiphy_ciphers_allocated) | ||
917 | kfree(local->hw.wiphy->cipher_suites); | ||
768 | 918 | ||
769 | wiphy_free(local->hw.wiphy); | 919 | wiphy_free(local->hw.wiphy); |
770 | } | 920 | } |