diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index caf92424c76d..5667f4e8067f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -210,6 +210,8 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
210 | !!rcu_dereference(sdata->u.ap.beacon); | 210 | !!rcu_dereference(sdata->u.ap.beacon); |
211 | break; | 211 | break; |
212 | case NL80211_IFTYPE_ADHOC: | 212 | case NL80211_IFTYPE_ADHOC: |
213 | conf.enable_beacon = !!sdata->u.sta.probe_resp; | ||
214 | break; | ||
213 | case NL80211_IFTYPE_MESH_POINT: | 215 | case NL80211_IFTYPE_MESH_POINT: |
214 | conf.enable_beacon = true; | 216 | conf.enable_beacon = true; |
215 | break; | 217 | break; |
@@ -731,6 +733,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
731 | return NULL; | 733 | return NULL; |
732 | 734 | ||
733 | wiphy->privid = mac80211_wiphy_privid; | 735 | wiphy->privid = mac80211_wiphy_privid; |
736 | wiphy->max_scan_ssids = 4; | ||
737 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | ||
738 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - | ||
739 | sizeof(struct cfg80211_bss); | ||
734 | 740 | ||
735 | local = wiphy_priv(wiphy); | 741 | local = wiphy_priv(wiphy); |
736 | local->hw.wiphy = wiphy; | 742 | local->hw.wiphy = wiphy; |
@@ -815,25 +821,33 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
815 | enum ieee80211_band band; | 821 | enum ieee80211_band band; |
816 | struct net_device *mdev; | 822 | struct net_device *mdev; |
817 | struct ieee80211_master_priv *mpriv; | 823 | struct ieee80211_master_priv *mpriv; |
824 | int channels, i, j; | ||
818 | 825 | ||
819 | /* | 826 | /* |
820 | * generic code guarantees at least one band, | 827 | * generic code guarantees at least one band, |
821 | * set this very early because much code assumes | 828 | * set this very early because much code assumes |
822 | * that hw.conf.channel is assigned | 829 | * that hw.conf.channel is assigned |
823 | */ | 830 | */ |
831 | channels = 0; | ||
824 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 832 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
825 | struct ieee80211_supported_band *sband; | 833 | struct ieee80211_supported_band *sband; |
826 | 834 | ||
827 | sband = local->hw.wiphy->bands[band]; | 835 | sband = local->hw.wiphy->bands[band]; |
828 | if (sband) { | 836 | if (sband && !local->oper_channel) { |
829 | /* init channel we're on */ | 837 | /* init channel we're on */ |
830 | local->hw.conf.channel = | 838 | local->hw.conf.channel = |
831 | local->oper_channel = | 839 | local->oper_channel = |
832 | local->scan_channel = &sband->channels[0]; | 840 | local->scan_channel = &sband->channels[0]; |
833 | break; | ||
834 | } | 841 | } |
842 | if (sband) | ||
843 | channels += sband->n_channels; | ||
835 | } | 844 | } |
836 | 845 | ||
846 | local->int_scan_req.n_channels = channels; | ||
847 | local->int_scan_req.channels = kzalloc(sizeof(void *) * channels, GFP_KERNEL); | ||
848 | if (!local->int_scan_req.channels) | ||
849 | return -ENOMEM; | ||
850 | |||
837 | /* if low-level driver supports AP, we also support VLAN */ | 851 | /* if low-level driver supports AP, we also support VLAN */ |
838 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) | 852 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) |
839 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | 853 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); |
@@ -843,7 +857,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
843 | 857 | ||
844 | result = wiphy_register(local->hw.wiphy); | 858 | result = wiphy_register(local->hw.wiphy); |
845 | if (result < 0) | 859 | if (result < 0) |
846 | return result; | 860 | goto fail_wiphy_register; |
847 | 861 | ||
848 | /* | 862 | /* |
849 | * We use the number of queues for feature tests (QoS, HT) internally | 863 | * We use the number of queues for feature tests (QoS, HT) internally |
@@ -866,8 +880,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
866 | mpriv->local = local; | 880 | mpriv->local = local; |
867 | local->mdev = mdev; | 881 | local->mdev = mdev; |
868 | 882 | ||
869 | ieee80211_rx_bss_list_init(local); | ||
870 | |||
871 | local->hw.workqueue = | 883 | local->hw.workqueue = |
872 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); | 884 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); |
873 | if (!local->hw.workqueue) { | 885 | if (!local->hw.workqueue) { |
@@ -893,14 +905,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
893 | 905 | ||
894 | local->hw.conf.listen_interval = local->hw.max_listen_interval; | 906 | local->hw.conf.listen_interval = local->hw.max_listen_interval; |
895 | 907 | ||
896 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | | ||
897 | IEEE80211_HW_SIGNAL_DBM) ? | ||
898 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | ||
899 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? | ||
900 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | ||
901 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
902 | local->wstats_flags |= IW_QUAL_DBM; | ||
903 | |||
904 | result = sta_info_start(local); | 908 | result = sta_info_start(local); |
905 | if (result < 0) | 909 | if (result < 0) |
906 | goto fail_sta_info; | 910 | goto fail_sta_info; |
@@ -946,6 +950,20 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
946 | 950 | ||
947 | ieee80211_led_init(local); | 951 | ieee80211_led_init(local); |
948 | 952 | ||
953 | /* alloc internal scan request */ | ||
954 | i = 0; | ||
955 | local->int_scan_req.ssids = &local->scan_ssid; | ||
956 | local->int_scan_req.n_ssids = 1; | ||
957 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
958 | if (!hw->wiphy->bands[band]) | ||
959 | continue; | ||
960 | for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) { | ||
961 | local->int_scan_req.channels[i] = | ||
962 | &hw->wiphy->bands[band]->channels[j]; | ||
963 | i++; | ||
964 | } | ||
965 | } | ||
966 | |||
949 | return 0; | 967 | return 0; |
950 | 968 | ||
951 | fail_wep: | 969 | fail_wep: |
@@ -964,6 +982,8 @@ fail_workqueue: | |||
964 | free_netdev(local->mdev); | 982 | free_netdev(local->mdev); |
965 | fail_mdev_alloc: | 983 | fail_mdev_alloc: |
966 | wiphy_unregister(local->hw.wiphy); | 984 | wiphy_unregister(local->hw.wiphy); |
985 | fail_wiphy_register: | ||
986 | kfree(local->int_scan_req.channels); | ||
967 | return result; | 987 | return result; |
968 | } | 988 | } |
969 | EXPORT_SYMBOL(ieee80211_register_hw); | 989 | EXPORT_SYMBOL(ieee80211_register_hw); |
@@ -991,7 +1011,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
991 | 1011 | ||
992 | rtnl_unlock(); | 1012 | rtnl_unlock(); |
993 | 1013 | ||
994 | ieee80211_rx_bss_list_deinit(local); | ||
995 | ieee80211_clear_tx_pending(local); | 1014 | ieee80211_clear_tx_pending(local); |
996 | sta_info_stop(local); | 1015 | sta_info_stop(local); |
997 | rate_control_deinitialize(local); | 1016 | rate_control_deinitialize(local); |
@@ -1009,6 +1028,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1009 | ieee80211_wep_free(local); | 1028 | ieee80211_wep_free(local); |
1010 | ieee80211_led_exit(local); | 1029 | ieee80211_led_exit(local); |
1011 | free_netdev(local->mdev); | 1030 | free_netdev(local->mdev); |
1031 | kfree(local->int_scan_req.channels); | ||
1012 | } | 1032 | } |
1013 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1033 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1014 | 1034 | ||