diff options
author | Jouni Malinen <j@w1.fi> | 2010-08-28 12:37:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-09-24 15:54:28 -0400 |
commit | 651b52254fc061f02d965524e71de4333a009a5a (patch) | |
tree | 5eb085461cc417ca32fe7a8a13f52b231030be86 /net/mac80211 | |
parent | 8dcb20038ade81f9a87c024e7f12ec74f0e95f33 (diff) |
mac80211: Add DS Parameter Set into Probe Request on 2.4 GHz
IEEE Std 802.11k-2008 added DS Parameter Set information element into
Probe Request frames as an optional information on 2.4 GHz band (and
mandatory, if radio measurements are enabled). This allows APs to
filter out Probe Request frames that may be received from neighboring
overlapping channels and by doing so, reduce the number of unnecessary
frames in the air. Make mac80211 add this IE into Probe Request frames
whenever the channel is known (i.e., whenever hwscan is not used).
Signed-off-by: Jouni Malinen <j@w1.fi>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/scan.c | 3 | ||||
-rw-r--r-- | net/mac80211/util.c | 16 |
3 files changed, 18 insertions, 4 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3641563d90f8..78a8d9208cec 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1256,7 +1256,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1256 | const u8 *key, u8 key_len, u8 key_idx); | 1256 | const u8 *key, u8 key_len, u8 key_idx); |
1257 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1257 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1258 | const u8 *ie, size_t ie_len, | 1258 | const u8 *ie, size_t ie_len, |
1259 | enum ieee80211_band band, u32 rate_mask); | 1259 | enum ieee80211_band band, u32 rate_mask, |
1260 | u8 channel); | ||
1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1261 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1261 | const u8 *ssid, size_t ssid_len, | 1262 | const u8 *ssid, size_t ssid_len, |
1262 | const u8 *ie, size_t ie_len); | 1263 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 1623e9d2086e..5171a9581631 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -242,7 +242,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
242 | local->hw_scan_req->n_channels = n_chans; | 242 | local->hw_scan_req->n_channels = n_chans; |
243 | 243 | ||
244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
245 | req->ie, req->ie_len, band, (u32) -1); | 245 | req->ie, req->ie_len, band, (u32) -1, |
246 | 0); | ||
246 | local->hw_scan_req->ie_len = ielen; | 247 | local->hw_scan_req->ie_len = ielen; |
247 | 248 | ||
248 | return true; | 249 | return true; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bfd19d76667a..aba025d748e9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -895,7 +895,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
895 | 895 | ||
896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
897 | const u8 *ie, size_t ie_len, | 897 | const u8 *ie, size_t ie_len, |
898 | enum ieee80211_band band, u32 rate_mask) | 898 | enum ieee80211_band band, u32 rate_mask, |
899 | u8 channel) | ||
899 | { | 900 | { |
900 | struct ieee80211_supported_band *sband; | 901 | struct ieee80211_supported_band *sband; |
901 | u8 *pos; | 902 | u8 *pos; |
@@ -947,6 +948,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
947 | pos += ext_rates_len; | 948 | pos += ext_rates_len; |
948 | } | 949 | } |
949 | 950 | ||
951 | if (channel && sband->band == IEEE80211_BAND_2GHZ) { | ||
952 | *pos++ = WLAN_EID_DS_PARAMS; | ||
953 | *pos++ = 1; | ||
954 | *pos++ = channel; | ||
955 | } | ||
956 | |||
950 | /* insert custom IEs that go before HT */ | 957 | /* insert custom IEs that go before HT */ |
951 | if (ie && ie_len) { | 958 | if (ie && ie_len) { |
952 | static const u8 before_ht[] = { | 959 | static const u8 before_ht[] = { |
@@ -1013,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1013 | struct ieee80211_mgmt *mgmt; | 1020 | struct ieee80211_mgmt *mgmt; |
1014 | size_t buf_len; | 1021 | size_t buf_len; |
1015 | u8 *buf; | 1022 | u8 *buf; |
1023 | u8 chan; | ||
1016 | 1024 | ||
1017 | /* FIXME: come up with a proper value */ | 1025 | /* FIXME: come up with a proper value */ |
1018 | buf = kmalloc(200 + ie_len, GFP_KERNEL); | 1026 | buf = kmalloc(200 + ie_len, GFP_KERNEL); |
@@ -1022,10 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1022 | return; | 1030 | return; |
1023 | } | 1031 | } |
1024 | 1032 | ||
1033 | chan = ieee80211_frequency_to_channel( | ||
1034 | local->hw.conf.channel->center_freq); | ||
1035 | |||
1025 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1036 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1026 | local->hw.conf.channel->band, | 1037 | local->hw.conf.channel->band, |
1027 | sdata->rc_rateidx_mask | 1038 | sdata->rc_rateidx_mask |
1028 | [local->hw.conf.channel->band]); | 1039 | [local->hw.conf.channel->band], |
1040 | chan); | ||
1029 | 1041 | ||
1030 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1042 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1031 | ssid, ssid_len, | 1043 | ssid, ssid_len, |