diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-07-08 10:55:56 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-16 02:58:09 -0400 |
commit | 7ca15a0ae865067aac8d36e27e0acbe4a8f1e70a (patch) | |
tree | 0e1fb6ea9187626b3f9d2f806f26942e571d93c6 /net/mac80211/scan.c | |
parent | 0430c883470d0c9a23661ea9f02c56b1d91cf93c (diff) |
mac80211: allow scanning for 5/10 MHz channels in IBSS
Use a chandef instead of just the channel for scanning, and enable
5/10 Mhz scanning for IBSS mode. Also reporting is changed to the new
inform_bss functions.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 819d0956eb3b..08afe74b98f4 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -66,6 +66,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
66 | struct cfg80211_bss *cbss; | 66 | struct cfg80211_bss *cbss; |
67 | struct ieee80211_bss *bss; | 67 | struct ieee80211_bss *bss; |
68 | int clen, srlen; | 68 | int clen, srlen; |
69 | enum nl80211_bss_scan_width scan_width; | ||
69 | s32 signal = 0; | 70 | s32 signal = 0; |
70 | 71 | ||
71 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 72 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
@@ -73,8 +74,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
73 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 74 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
74 | signal = (rx_status->signal * 100) / local->hw.max_signal; | 75 | signal = (rx_status->signal * 100) / local->hw.max_signal; |
75 | 76 | ||
76 | cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, | 77 | scan_width = NL80211_BSS_CHAN_WIDTH_20; |
77 | mgmt, len, signal, GFP_ATOMIC); | 78 | if (rx_status->flag & RX_FLAG_5MHZ) |
79 | scan_width = NL80211_BSS_CHAN_WIDTH_5; | ||
80 | if (rx_status->flag & RX_FLAG_10MHZ) | ||
81 | scan_width = NL80211_BSS_CHAN_WIDTH_10; | ||
82 | |||
83 | cbss = cfg80211_inform_bss_width_frame(local->hw.wiphy, channel, | ||
84 | scan_width, mgmt, len, signal, | ||
85 | GFP_ATOMIC); | ||
78 | if (!cbss) | 86 | if (!cbss) |
79 | return NULL; | 87 | return NULL; |
80 | 88 | ||
@@ -300,7 +308,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
300 | rcu_assign_pointer(local->scan_sdata, NULL); | 308 | rcu_assign_pointer(local->scan_sdata, NULL); |
301 | 309 | ||
302 | local->scanning = 0; | 310 | local->scanning = 0; |
303 | local->scan_channel = NULL; | 311 | local->scan_chandef.chan = NULL; |
304 | 312 | ||
305 | /* Set power back to normal operating levels. */ | 313 | /* Set power back to normal operating levels. */ |
306 | ieee80211_hw_config(local, 0); | 314 | ieee80211_hw_config(local, 0); |
@@ -635,11 +643,34 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
635 | { | 643 | { |
636 | int skip; | 644 | int skip; |
637 | struct ieee80211_channel *chan; | 645 | struct ieee80211_channel *chan; |
646 | enum nl80211_bss_scan_width oper_scan_width; | ||
638 | 647 | ||
639 | skip = 0; | 648 | skip = 0; |
640 | chan = local->scan_req->channels[local->scan_channel_idx]; | 649 | chan = local->scan_req->channels[local->scan_channel_idx]; |
641 | 650 | ||
642 | local->scan_channel = chan; | 651 | local->scan_chandef.chan = chan; |
652 | local->scan_chandef.center_freq1 = chan->center_freq; | ||
653 | local->scan_chandef.center_freq2 = 0; | ||
654 | switch (local->scan_req->scan_width) { | ||
655 | case NL80211_BSS_CHAN_WIDTH_5: | ||
656 | local->scan_chandef.width = NL80211_CHAN_WIDTH_5; | ||
657 | break; | ||
658 | case NL80211_BSS_CHAN_WIDTH_10: | ||
659 | local->scan_chandef.width = NL80211_CHAN_WIDTH_10; | ||
660 | break; | ||
661 | case NL80211_BSS_CHAN_WIDTH_20: | ||
662 | /* If scanning on oper channel, use whatever channel-type | ||
663 | * is currently in use. | ||
664 | */ | ||
665 | oper_scan_width = cfg80211_chandef_to_scan_width( | ||
666 | &local->_oper_chandef); | ||
667 | if (chan == local->_oper_chandef.chan && | ||
668 | oper_scan_width == local->scan_req->scan_width) | ||
669 | local->scan_chandef = local->_oper_chandef; | ||
670 | else | ||
671 | local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | ||
672 | break; | ||
673 | } | ||
643 | 674 | ||
644 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) | 675 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
645 | skip = 1; | 676 | skip = 1; |
@@ -679,7 +710,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
679 | unsigned long *next_delay) | 710 | unsigned long *next_delay) |
680 | { | 711 | { |
681 | /* switch back to the operating channel */ | 712 | /* switch back to the operating channel */ |
682 | local->scan_channel = NULL; | 713 | local->scan_chandef.chan = NULL; |
683 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 714 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
684 | 715 | ||
685 | /* disable PS */ | 716 | /* disable PS */ |
@@ -821,7 +852,8 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
821 | 852 | ||
822 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | 853 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, |
823 | const u8 *ssid, u8 ssid_len, | 854 | const u8 *ssid, u8 ssid_len, |
824 | struct ieee80211_channel *chan) | 855 | struct ieee80211_channel *chan, |
856 | enum nl80211_bss_scan_width scan_width) | ||
825 | { | 857 | { |
826 | struct ieee80211_local *local = sdata->local; | 858 | struct ieee80211_local *local = sdata->local; |
827 | int ret = -EBUSY; | 859 | int ret = -EBUSY; |
@@ -871,6 +903,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | |||
871 | 903 | ||
872 | local->int_scan_req->ssids = &local->scan_ssid; | 904 | local->int_scan_req->ssids = &local->scan_ssid; |
873 | local->int_scan_req->n_ssids = 1; | 905 | local->int_scan_req->n_ssids = 1; |
906 | local->int_scan_req->scan_width = scan_width; | ||
874 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); | 907 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); |
875 | local->int_scan_req->ssids[0].ssid_len = ssid_len; | 908 | local->int_scan_req->ssids[0].ssid_len = ssid_len; |
876 | 909 | ||