diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-09-02 13:30:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-09-02 13:30:07 -0400 |
commit | 78ab952717b62c0ba6ca7f7a27eaa0486685e45f (patch) | |
tree | a4ab2bfc578f279fc6847031f501d84c75057531 /net/mac80211/main.c | |
parent | 3e502e63586920f219ed2590f69c1f5a8888cfa4 (diff) | |
parent | 85f72bc839705294b32b6c16b491c0422f0a71b3 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 82 |
1 files changed, 64 insertions, 18 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a53feac4618c..a06b6ee63c07 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -305,7 +305,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
305 | 305 | ||
306 | trace_api_restart_hw(local); | 306 | trace_api_restart_hw(local); |
307 | 307 | ||
308 | /* use this reason, __ieee80211_resume will unblock it */ | 308 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), |
309 | "%s called with hardware scan in progress\n", __func__); | ||
310 | |||
311 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) | ||
312 | ieee80211_scan_cancel(local); | ||
313 | |||
314 | /* use this reason, ieee80211_reconfig will unblock it */ | ||
309 | ieee80211_stop_queues_by_reason(hw, | 315 | ieee80211_stop_queues_by_reason(hw, |
310 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 316 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
311 | 317 | ||
@@ -339,9 +345,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
339 | struct ieee80211_if_managed *ifmgd; | 345 | struct ieee80211_if_managed *ifmgd; |
340 | int c = 0; | 346 | int c = 0; |
341 | 347 | ||
342 | if (!netif_running(ndev)) | ||
343 | return NOTIFY_DONE; | ||
344 | |||
345 | /* Make sure it's our interface that got changed */ | 348 | /* Make sure it's our interface that got changed */ |
346 | if (!wdev) | 349 | if (!wdev) |
347 | return NOTIFY_DONE; | 350 | return NOTIFY_DONE; |
@@ -352,6 +355,9 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
352 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); | 355 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); |
353 | bss_conf = &sdata->vif.bss_conf; | 356 | bss_conf = &sdata->vif.bss_conf; |
354 | 357 | ||
358 | if (!ieee80211_sdata_running(sdata)) | ||
359 | return NOTIFY_DONE; | ||
360 | |||
355 | /* ARP filtering is only supported in managed mode */ | 361 | /* ARP filtering is only supported in managed mode */ |
356 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 362 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
357 | return NOTIFY_DONE; | 363 | return NOTIFY_DONE; |
@@ -622,6 +628,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
622 | /* mac80211 always supports monitor */ | 628 | /* mac80211 always supports monitor */ |
623 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | 629 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); |
624 | 630 | ||
631 | #ifndef CONFIG_MAC80211_MESH | ||
632 | /* mesh depends on Kconfig, but drivers should set it if they want */ | ||
633 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | ||
634 | #endif | ||
635 | |||
636 | /* mac80211 supports control port protocol changing */ | ||
637 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | ||
638 | |||
625 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 639 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
626 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 640 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
627 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 641 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
@@ -657,13 +671,40 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
657 | if (local->hw.wiphy->max_scan_ie_len) | 671 | if (local->hw.wiphy->max_scan_ie_len) |
658 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; | 672 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; |
659 | 673 | ||
660 | local->hw.wiphy->cipher_suites = cipher_suites; | 674 | /* Set up cipher suites unless driver already did */ |
661 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 675 | if (!local->hw.wiphy->cipher_suites) { |
662 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | 676 | local->hw.wiphy->cipher_suites = cipher_suites; |
663 | local->hw.wiphy->n_cipher_suites--; | 677 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
678 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | ||
679 | local->hw.wiphy->n_cipher_suites--; | ||
680 | } | ||
664 | if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { | 681 | if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { |
665 | local->hw.wiphy->cipher_suites += 2; | 682 | if (local->hw.wiphy->cipher_suites == cipher_suites) { |
666 | local->hw.wiphy->n_cipher_suites -= 2; | 683 | local->hw.wiphy->cipher_suites += 2; |
684 | local->hw.wiphy->n_cipher_suites -= 2; | ||
685 | } else { | ||
686 | u32 *suites; | ||
687 | int r, w = 0; | ||
688 | |||
689 | /* Filter out WEP */ | ||
690 | |||
691 | suites = kmemdup( | ||
692 | local->hw.wiphy->cipher_suites, | ||
693 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | ||
694 | GFP_KERNEL); | ||
695 | if (!suites) | ||
696 | return -ENOMEM; | ||
697 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { | ||
698 | u32 suite = local->hw.wiphy->cipher_suites[r]; | ||
699 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | ||
700 | suite == WLAN_CIPHER_SUITE_WEP104) | ||
701 | continue; | ||
702 | suites[w++] = suite; | ||
703 | } | ||
704 | local->hw.wiphy->cipher_suites = suites; | ||
705 | local->hw.wiphy->n_cipher_suites = w; | ||
706 | local->wiphy_ciphers_allocated = true; | ||
707 | } | ||
667 | } | 708 | } |
668 | 709 | ||
669 | result = wiphy_register(local->hw.wiphy); | 710 | result = wiphy_register(local->hw.wiphy); |
@@ -713,16 +754,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
713 | 754 | ||
714 | result = ieee80211_wep_init(local); | 755 | result = ieee80211_wep_init(local); |
715 | if (result < 0) | 756 | if (result < 0) |
716 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", | 757 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
717 | wiphy_name(local->hw.wiphy), result); | 758 | result); |
718 | 759 | ||
719 | rtnl_lock(); | 760 | rtnl_lock(); |
720 | 761 | ||
721 | result = ieee80211_init_rate_ctrl_alg(local, | 762 | result = ieee80211_init_rate_ctrl_alg(local, |
722 | hw->rate_control_algorithm); | 763 | hw->rate_control_algorithm); |
723 | if (result < 0) { | 764 | if (result < 0) { |
724 | printk(KERN_DEBUG "%s: Failed to initialize rate control " | 765 | wiphy_debug(local->hw.wiphy, |
725 | "algorithm\n", wiphy_name(local->hw.wiphy)); | 766 | "Failed to initialize rate control algorithm\n"); |
726 | goto fail_rate; | 767 | goto fail_rate; |
727 | } | 768 | } |
728 | 769 | ||
@@ -731,8 +772,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
731 | result = ieee80211_if_add(local, "wlan%d", NULL, | 772 | result = ieee80211_if_add(local, "wlan%d", NULL, |
732 | NL80211_IFTYPE_STATION, NULL); | 773 | NL80211_IFTYPE_STATION, NULL); |
733 | if (result) | 774 | if (result) |
734 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 775 | wiphy_warn(local->hw.wiphy, |
735 | wiphy_name(local->hw.wiphy)); | 776 | "Failed to add default virtual iface\n"); |
736 | } | 777 | } |
737 | 778 | ||
738 | rtnl_unlock(); | 779 | rtnl_unlock(); |
@@ -778,6 +819,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
778 | fail_workqueue: | 819 | fail_workqueue: |
779 | wiphy_unregister(local->hw.wiphy); | 820 | wiphy_unregister(local->hw.wiphy); |
780 | fail_wiphy_register: | 821 | fail_wiphy_register: |
822 | if (local->wiphy_ciphers_allocated) | ||
823 | kfree(local->hw.wiphy->cipher_suites); | ||
781 | kfree(local->int_scan_req); | 824 | kfree(local->int_scan_req); |
782 | return result; | 825 | return result; |
783 | } | 826 | } |
@@ -807,6 +850,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
807 | 850 | ||
808 | rtnl_unlock(); | 851 | rtnl_unlock(); |
809 | 852 | ||
853 | cancel_work_sync(&local->restart_work); | ||
810 | cancel_work_sync(&local->reconfig_filter); | 854 | cancel_work_sync(&local->reconfig_filter); |
811 | 855 | ||
812 | ieee80211_clear_tx_pending(local); | 856 | ieee80211_clear_tx_pending(local); |
@@ -815,8 +859,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
815 | 859 | ||
816 | if (skb_queue_len(&local->skb_queue) || | 860 | if (skb_queue_len(&local->skb_queue) || |
817 | skb_queue_len(&local->skb_queue_unreliable)) | 861 | skb_queue_len(&local->skb_queue_unreliable)) |
818 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 862 | wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); |
819 | wiphy_name(local->hw.wiphy)); | ||
820 | skb_queue_purge(&local->skb_queue); | 863 | skb_queue_purge(&local->skb_queue); |
821 | skb_queue_purge(&local->skb_queue_unreliable); | 864 | skb_queue_purge(&local->skb_queue_unreliable); |
822 | 865 | ||
@@ -835,6 +878,9 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
835 | mutex_destroy(&local->iflist_mtx); | 878 | mutex_destroy(&local->iflist_mtx); |
836 | mutex_destroy(&local->mtx); | 879 | mutex_destroy(&local->mtx); |
837 | 880 | ||
881 | if (local->wiphy_ciphers_allocated) | ||
882 | kfree(local->hw.wiphy->cipher_suites); | ||
883 | |||
838 | wiphy_free(local->hw.wiphy); | 884 | wiphy_free(local->hw.wiphy); |
839 | } | 885 | } |
840 | EXPORT_SYMBOL(ieee80211_free_hw); | 886 | EXPORT_SYMBOL(ieee80211_free_hw); |