aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2013-07-08 10:55:56 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-07-16 02:58:09 -0400
commit7ca15a0ae865067aac8d36e27e0acbe4a8f1e70a (patch)
tree0e1fb6ea9187626b3f9d2f806f26942e571d93c6 /net/mac80211
parent0430c883470d0c9a23661ea9f02c56b1d91cf93c (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')
-rw-r--r--net/mac80211/ibss.c16
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c13
-rw-r--r--net/mac80211/scan.c45
4 files changed, 56 insertions, 23 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 299603e4939f..8fa1c27bdfe3 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -51,6 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
51 u32 bss_change, rate_flags, rates = 0, rates_added = 0; 51 u32 bss_change, rate_flags, rates = 0, rates_added = 0;
52 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 52 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
53 struct cfg80211_chan_def chandef; 53 struct cfg80211_chan_def chandef;
54 enum nl80211_bss_scan_width scan_width;
54 struct beacon_data *presp; 55 struct beacon_data *presp;
55 int frame_len; 56 int frame_len;
56 int shift; 57 int shift;
@@ -271,8 +272,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
271 mod_timer(&ifibss->timer, 272 mod_timer(&ifibss->timer,
272 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 273 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
273 274
274 bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, 275 scan_width = cfg80211_chandef_to_scan_width(&chandef);
275 mgmt, presp->head_len, 0, GFP_KERNEL); 276 bss = cfg80211_inform_bss_width_frame(local->hw.wiphy, chan,
277 scan_width, mgmt,
278 presp->head_len, 0, GFP_KERNEL);
276 cfg80211_put_bss(local->hw.wiphy, bss); 279 cfg80211_put_bss(local->hw.wiphy, bss);
277 netif_carrier_on(sdata->dev); 280 netif_carrier_on(sdata->dev);
278 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); 281 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
@@ -726,6 +729,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
726static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) 729static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
727{ 730{
728 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 731 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
732 enum nl80211_bss_scan_width scan_width;
729 733
730 sdata_assert_lock(sdata); 734 sdata_assert_lock(sdata);
731 735
@@ -747,8 +751,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
747 sdata_info(sdata, 751 sdata_info(sdata,
748 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); 752 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
749 753
754 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
750 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, 755 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
751 NULL); 756 NULL, scan_width);
752} 757}
753 758
754static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 759static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -798,6 +803,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
798 struct cfg80211_bss *cbss; 803 struct cfg80211_bss *cbss;
799 struct ieee80211_channel *chan = NULL; 804 struct ieee80211_channel *chan = NULL;
800 const u8 *bssid = NULL; 805 const u8 *bssid = NULL;
806 enum nl80211_bss_scan_width scan_width;
801 int active_ibss; 807 int active_ibss;
802 u16 capability; 808 u16 capability;
803 809
@@ -846,8 +852,10 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
846 IEEE80211_SCAN_INTERVAL)) { 852 IEEE80211_SCAN_INTERVAL)) {
847 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); 853 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
848 854
855 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
849 ieee80211_request_ibss_scan(sdata, ifibss->ssid, 856 ieee80211_request_ibss_scan(sdata, ifibss->ssid,
850 ifibss->ssid_len, chan); 857 ifibss->ssid_len, chan,
858 scan_width);
851 } else { 859 } else {
852 int interval = IEEE80211_SCAN_INTERVAL; 860 int interval = IEEE80211_SCAN_INTERVAL;
853 861
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6596da66bfaf..23a191b03bbf 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1057,7 +1057,7 @@ struct ieee80211_local {
1057 struct cfg80211_ssid scan_ssid; 1057 struct cfg80211_ssid scan_ssid;
1058 struct cfg80211_scan_request *int_scan_req; 1058 struct cfg80211_scan_request *int_scan_req;
1059 struct cfg80211_scan_request *scan_req, *hw_scan_req; 1059 struct cfg80211_scan_request *scan_req, *hw_scan_req;
1060 struct ieee80211_channel *scan_channel; 1060 struct cfg80211_chan_def scan_chandef;
1061 enum ieee80211_band hw_scan_band; 1061 enum ieee80211_band hw_scan_band;
1062 int scan_channel_idx; 1062 int scan_channel_idx;
1063 int scan_ies_len; 1063 int scan_ies_len;
@@ -1337,7 +1337,8 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1337void ieee80211_scan_work(struct work_struct *work); 1337void ieee80211_scan_work(struct work_struct *work);
1338int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, 1338int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
1339 const u8 *ssid, u8 ssid_len, 1339 const u8 *ssid, u8 ssid_len,
1340 struct ieee80211_channel *chan); 1340 struct ieee80211_channel *chan,
1341 enum nl80211_bss_scan_width scan_width);
1341int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 1342int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
1342 struct cfg80211_scan_request *req); 1343 struct cfg80211_scan_request *req);
1343void ieee80211_scan_cancel(struct ieee80211_local *local); 1344void ieee80211_scan_cancel(struct ieee80211_local *local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 6da98c77496b..25eb35b01938 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -102,17 +102,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
102 102
103 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 103 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
104 104
105 if (local->scan_channel) { 105 if (local->scan_chandef.chan) {
106 chandef.chan = local->scan_channel; 106 chandef = local->scan_chandef;
107 /* If scanning on oper channel, use whatever channel-type
108 * is currently in use.
109 */
110 if (chandef.chan == local->_oper_chandef.chan) {
111 chandef = local->_oper_chandef;
112 } else {
113 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
114 chandef.center_freq1 = chandef.chan->center_freq;
115 }
116 } else if (local->tmp_channel) { 107 } else if (local->tmp_channel) {
117 chandef.chan = local->tmp_channel; 108 chandef.chan = local->tmp_channel;
118 chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 109 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
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
822int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, 853int 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