diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/scan.c | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 37 |
3 files changed, 24 insertions, 17 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9346a6b0f400..3641563d90f8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1256,7 +1256,7 @@ 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); | 1259 | enum ieee80211_band band, u32 rate_mask); |
1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1261 | const u8 *ssid, size_t ssid_len, | 1261 | const u8 *ssid, size_t ssid_len, |
1262 | const u8 *ie, size_t ie_len); | 1262 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d60389ba9b95..1623e9d2086e 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -242,7 +242,7 @@ 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); | 245 | req->ie, req->ie_len, band, (u32) -1); |
246 | local->hw_scan_req->ie_len = ielen; | 246 | local->hw_scan_req->ie_len = ielen; |
247 | 247 | ||
248 | return true; | 248 | return true; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 737f4267c335..bfd19d76667a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -895,26 +895,33 @@ 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) | 898 | enum ieee80211_band band, u32 rate_mask) |
899 | { | 899 | { |
900 | struct ieee80211_supported_band *sband; | 900 | struct ieee80211_supported_band *sband; |
901 | u8 *pos; | 901 | u8 *pos; |
902 | size_t offset = 0, noffset; | 902 | size_t offset = 0, noffset; |
903 | int supp_rates_len, i; | 903 | int supp_rates_len, i; |
904 | u8 rates[32]; | ||
905 | int num_rates; | ||
906 | int ext_rates_len; | ||
904 | 907 | ||
905 | sband = local->hw.wiphy->bands[band]; | 908 | sband = local->hw.wiphy->bands[band]; |
906 | 909 | ||
907 | pos = buffer; | 910 | pos = buffer; |
908 | 911 | ||
909 | supp_rates_len = min_t(int, sband->n_bitrates, 8); | 912 | num_rates = 0; |
913 | for (i = 0; i < sband->n_bitrates; i++) { | ||
914 | if ((BIT(i) & rate_mask) == 0) | ||
915 | continue; /* skip rate */ | ||
916 | rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); | ||
917 | } | ||
918 | |||
919 | supp_rates_len = min_t(int, num_rates, 8); | ||
910 | 920 | ||
911 | *pos++ = WLAN_EID_SUPP_RATES; | 921 | *pos++ = WLAN_EID_SUPP_RATES; |
912 | *pos++ = supp_rates_len; | 922 | *pos++ = supp_rates_len; |
913 | 923 | memcpy(pos, rates, supp_rates_len); | |
914 | for (i = 0; i < supp_rates_len; i++) { | 924 | pos += supp_rates_len; |
915 | int rate = sband->bitrates[i].bitrate; | ||
916 | *pos++ = (u8) (rate / 5); | ||
917 | } | ||
918 | 925 | ||
919 | /* insert "request information" if in custom IEs */ | 926 | /* insert "request information" if in custom IEs */ |
920 | if (ie && ie_len) { | 927 | if (ie && ie_len) { |
@@ -932,14 +939,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
932 | offset = noffset; | 939 | offset = noffset; |
933 | } | 940 | } |
934 | 941 | ||
935 | if (sband->n_bitrates > i) { | 942 | ext_rates_len = num_rates - supp_rates_len; |
943 | if (ext_rates_len > 0) { | ||
936 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 944 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
937 | *pos++ = sband->n_bitrates - i; | 945 | *pos++ = ext_rates_len; |
938 | 946 | memcpy(pos, rates + supp_rates_len, ext_rates_len); | |
939 | for (; i < sband->n_bitrates; i++) { | 947 | pos += ext_rates_len; |
940 | int rate = sband->bitrates[i].bitrate; | ||
941 | *pos++ = (u8) (rate / 5); | ||
942 | } | ||
943 | } | 948 | } |
944 | 949 | ||
945 | /* insert custom IEs that go before HT */ | 950 | /* insert custom IEs that go before HT */ |
@@ -1018,7 +1023,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1018 | } | 1023 | } |
1019 | 1024 | ||
1020 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1025 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1021 | local->hw.conf.channel->band); | 1026 | local->hw.conf.channel->band, |
1027 | sdata->rc_rateidx_mask | ||
1028 | [local->hw.conf.channel->band]); | ||
1022 | 1029 | ||
1023 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1030 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1024 | ssid, ssid_len, | 1031 | ssid, ssid_len, |