aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c218
1 files changed, 152 insertions, 66 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22654452a561..e1b34a18b243 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -107,7 +107,8 @@ void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
107} 107}
108 108
109int ieee80211_frame_duration(enum ieee80211_band band, size_t len, 109int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
110 int rate, int erp, int short_preamble) 110 int rate, int erp, int short_preamble,
111 int shift)
111{ 112{
112 int dur; 113 int dur;
113 114
@@ -118,6 +119,9 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
118 * 119 *
119 * rate is in 100 kbps, so divident is multiplied by 10 in the 120 * rate is in 100 kbps, so divident is multiplied by 10 in the
120 * DIV_ROUND_UP() operations. 121 * DIV_ROUND_UP() operations.
122 *
123 * shift may be 2 for 5 MHz channels or 1 for 10 MHz channels, and
124 * is assumed to be 0 otherwise.
121 */ 125 */
122 126
123 if (band == IEEE80211_BAND_5GHZ || erp) { 127 if (band == IEEE80211_BAND_5GHZ || erp) {
@@ -130,13 +134,23 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
130 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext 134 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
131 * 135 *
132 * T_SYM = 4 usec 136 * T_SYM = 4 usec
133 * 802.11a - 17.5.2: aSIFSTime = 16 usec 137 * 802.11a - 18.5.2: aSIFSTime = 16 usec
134 * 802.11g - 19.8.4: aSIFSTime = 10 usec + 138 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
135 * signal ext = 6 usec 139 * signal ext = 6 usec
136 */ 140 */
137 dur = 16; /* SIFS + signal ext */ 141 dur = 16; /* SIFS + signal ext */
138 dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ 142 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
139 dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ 143 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
144
145 /* IEEE 802.11-2012 18.3.2.4: all values above are:
146 * * times 4 for 5 MHz
147 * * times 2 for 10 MHz
148 */
149 dur *= 1 << shift;
150
151 /* rates should already consider the channel bandwidth,
152 * don't apply divisor again.
153 */
140 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, 154 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
141 4 * rate); /* T_SYM x N_SYM */ 155 4 * rate); /* T_SYM x N_SYM */
142 } else { 156 } else {
@@ -168,7 +182,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
168{ 182{
169 struct ieee80211_sub_if_data *sdata; 183 struct ieee80211_sub_if_data *sdata;
170 u16 dur; 184 u16 dur;
171 int erp; 185 int erp, shift = 0;
172 bool short_preamble = false; 186 bool short_preamble = false;
173 187
174 erp = 0; 188 erp = 0;
@@ -177,10 +191,11 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
177 short_preamble = sdata->vif.bss_conf.use_short_preamble; 191 short_preamble = sdata->vif.bss_conf.use_short_preamble;
178 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 192 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
179 erp = rate->flags & IEEE80211_RATE_ERP_G; 193 erp = rate->flags & IEEE80211_RATE_ERP_G;
194 shift = ieee80211_vif_get_shift(vif);
180 } 195 }
181 196
182 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp, 197 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
183 short_preamble); 198 short_preamble, shift);
184 199
185 return cpu_to_le16(dur); 200 return cpu_to_le16(dur);
186} 201}
@@ -194,7 +209,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
194 struct ieee80211_rate *rate; 209 struct ieee80211_rate *rate;
195 struct ieee80211_sub_if_data *sdata; 210 struct ieee80211_sub_if_data *sdata;
196 bool short_preamble; 211 bool short_preamble;
197 int erp; 212 int erp, shift = 0, bitrate;
198 u16 dur; 213 u16 dur;
199 struct ieee80211_supported_band *sband; 214 struct ieee80211_supported_band *sband;
200 215
@@ -210,17 +225,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
210 short_preamble = sdata->vif.bss_conf.use_short_preamble; 225 short_preamble = sdata->vif.bss_conf.use_short_preamble;
211 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 226 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
212 erp = rate->flags & IEEE80211_RATE_ERP_G; 227 erp = rate->flags & IEEE80211_RATE_ERP_G;
228 shift = ieee80211_vif_get_shift(vif);
213 } 229 }
214 230
231 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
232
215 /* CTS duration */ 233 /* CTS duration */
216 dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate, 234 dur = ieee80211_frame_duration(sband->band, 10, bitrate,
217 erp, short_preamble); 235 erp, short_preamble, shift);
218 /* Data frame duration */ 236 /* Data frame duration */
219 dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 237 dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
220 erp, short_preamble); 238 erp, short_preamble, shift);
221 /* ACK duration */ 239 /* ACK duration */
222 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 240 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
223 erp, short_preamble); 241 erp, short_preamble, shift);
224 242
225 return cpu_to_le16(dur); 243 return cpu_to_le16(dur);
226} 244}
@@ -235,7 +253,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
235 struct ieee80211_rate *rate; 253 struct ieee80211_rate *rate;
236 struct ieee80211_sub_if_data *sdata; 254 struct ieee80211_sub_if_data *sdata;
237 bool short_preamble; 255 bool short_preamble;
238 int erp; 256 int erp, shift = 0, bitrate;
239 u16 dur; 257 u16 dur;
240 struct ieee80211_supported_band *sband; 258 struct ieee80211_supported_band *sband;
241 259
@@ -250,15 +268,18 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
250 short_preamble = sdata->vif.bss_conf.use_short_preamble; 268 short_preamble = sdata->vif.bss_conf.use_short_preamble;
251 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 269 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
252 erp = rate->flags & IEEE80211_RATE_ERP_G; 270 erp = rate->flags & IEEE80211_RATE_ERP_G;
271 shift = ieee80211_vif_get_shift(vif);
253 } 272 }
254 273
274 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
275
255 /* Data frame duration */ 276 /* Data frame duration */
256 dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 277 dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
257 erp, short_preamble); 278 erp, short_preamble, shift);
258 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { 279 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
259 /* ACK duration */ 280 /* ACK duration */
260 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 281 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
261 erp, short_preamble); 282 erp, short_preamble, shift);
262 } 283 }
263 284
264 return cpu_to_le16(dur); 285 return cpu_to_le16(dur);
@@ -1052,32 +1073,6 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1052 } 1073 }
1053} 1074}
1054 1075
1055void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1056 const size_t supp_rates_len,
1057 const u8 *supp_rates)
1058{
1059 struct ieee80211_chanctx_conf *chanctx_conf;
1060 int i, have_higher_than_11mbit = 0;
1061
1062 /* cf. IEEE 802.11 9.2.12 */
1063 for (i = 0; i < supp_rates_len; i++)
1064 if ((supp_rates[i] & 0x7f) * 5 > 110)
1065 have_higher_than_11mbit = 1;
1066
1067 rcu_read_lock();
1068 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1069
1070 if (chanctx_conf &&
1071 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ &&
1072 have_higher_than_11mbit)
1073 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1074 else
1075 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
1076 rcu_read_unlock();
1077
1078 ieee80211_set_wmm_default(sdata, true);
1079}
1080
1081void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1076void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1082 u16 transaction, u16 auth_alg, u16 status, 1077 u16 transaction, u16 auth_alg, u16 status,
1083 const u8 *extra, size_t extra_len, const u8 *da, 1078 const u8 *extra, size_t extra_len, const u8 *da,
@@ -1162,7 +1157,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1162int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1157int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1163 size_t buffer_len, const u8 *ie, size_t ie_len, 1158 size_t buffer_len, const u8 *ie, size_t ie_len,
1164 enum ieee80211_band band, u32 rate_mask, 1159 enum ieee80211_band band, u32 rate_mask,
1165 u8 channel) 1160 struct cfg80211_chan_def *chandef)
1166{ 1161{
1167 struct ieee80211_supported_band *sband; 1162 struct ieee80211_supported_band *sband;
1168 u8 *pos = buffer, *end = buffer + buffer_len; 1163 u8 *pos = buffer, *end = buffer + buffer_len;
@@ -1171,16 +1166,26 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1171 u8 rates[32]; 1166 u8 rates[32];
1172 int num_rates; 1167 int num_rates;
1173 int ext_rates_len; 1168 int ext_rates_len;
1169 int shift;
1170 u32 rate_flags;
1174 1171
1175 sband = local->hw.wiphy->bands[band]; 1172 sband = local->hw.wiphy->bands[band];
1176 if (WARN_ON_ONCE(!sband)) 1173 if (WARN_ON_ONCE(!sband))
1177 return 0; 1174 return 0;
1178 1175
1176 rate_flags = ieee80211_chandef_rate_flags(chandef);
1177 shift = ieee80211_chandef_get_shift(chandef);
1178
1179 num_rates = 0; 1179 num_rates = 0;
1180 for (i = 0; i < sband->n_bitrates; i++) { 1180 for (i = 0; i < sband->n_bitrates; i++) {
1181 if ((BIT(i) & rate_mask) == 0) 1181 if ((BIT(i) & rate_mask) == 0)
1182 continue; /* skip rate */ 1182 continue; /* skip rate */
1183 rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); 1183 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1184 continue;
1185
1186 rates[num_rates++] =
1187 (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate,
1188 (1 << shift) * 5);
1184 } 1189 }
1185 1190
1186 supp_rates_len = min_t(int, num_rates, 8); 1191 supp_rates_len = min_t(int, num_rates, 8);
@@ -1220,12 +1225,13 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1220 pos += ext_rates_len; 1225 pos += ext_rates_len;
1221 } 1226 }
1222 1227
1223 if (channel && sband->band == IEEE80211_BAND_2GHZ) { 1228 if (chandef->chan && sband->band == IEEE80211_BAND_2GHZ) {
1224 if (end - pos < 3) 1229 if (end - pos < 3)
1225 goto out_err; 1230 goto out_err;
1226 *pos++ = WLAN_EID_DS_PARAMS; 1231 *pos++ = WLAN_EID_DS_PARAMS;
1227 *pos++ = 1; 1232 *pos++ = 1;
1228 *pos++ = channel; 1233 *pos++ = ieee80211_frequency_to_channel(
1234 chandef->chan->center_freq);
1229 } 1235 }
1230 1236
1231 /* insert custom IEs that go before HT */ 1237 /* insert custom IEs that go before HT */
@@ -1290,9 +1296,9 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1290 bool directed) 1296 bool directed)
1291{ 1297{
1292 struct ieee80211_local *local = sdata->local; 1298 struct ieee80211_local *local = sdata->local;
1299 struct cfg80211_chan_def chandef;
1293 struct sk_buff *skb; 1300 struct sk_buff *skb;
1294 struct ieee80211_mgmt *mgmt; 1301 struct ieee80211_mgmt *mgmt;
1295 u8 chan_no;
1296 int ies_len; 1302 int ies_len;
1297 1303
1298 /* 1304 /*
@@ -1300,10 +1306,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1300 * in order to maximize the chance that we get a response. Some 1306 * in order to maximize the chance that we get a response. Some
1301 * badly-behaved APs don't respond when this parameter is included. 1307 * badly-behaved APs don't respond when this parameter is included.
1302 */ 1308 */
1309 chandef.width = sdata->vif.bss_conf.chandef.width;
1303 if (directed) 1310 if (directed)
1304 chan_no = 0; 1311 chandef.chan = NULL;
1305 else 1312 else
1306 chan_no = ieee80211_frequency_to_channel(chan->center_freq); 1313 chandef.chan = chan;
1307 1314
1308 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1315 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1309 ssid, ssid_len, 100 + ie_len); 1316 ssid, ssid_len, 100 + ie_len);
@@ -1313,7 +1320,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1313 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1320 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1314 skb_tailroom(skb), 1321 skb_tailroom(skb),
1315 ie, ie_len, chan->band, 1322 ie, ie_len, chan->band,
1316 ratemask, chan_no); 1323 ratemask, &chandef);
1317 skb_put(skb, ies_len); 1324 skb_put(skb, ies_len);
1318 1325
1319 if (dst) { 1326 if (dst) {
@@ -1347,16 +1354,19 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1347 } 1354 }
1348} 1355}
1349 1356
1350u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1357u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
1351 struct ieee802_11_elems *elems, 1358 struct ieee802_11_elems *elems,
1352 enum ieee80211_band band, u32 *basic_rates) 1359 enum ieee80211_band band, u32 *basic_rates)
1353{ 1360{
1354 struct ieee80211_supported_band *sband; 1361 struct ieee80211_supported_band *sband;
1355 struct ieee80211_rate *bitrates; 1362 struct ieee80211_rate *bitrates;
1356 size_t num_rates; 1363 size_t num_rates;
1357 u32 supp_rates; 1364 u32 supp_rates, rate_flags;
1358 int i, j; 1365 int i, j, shift;
1359 sband = local->hw.wiphy->bands[band]; 1366 sband = sdata->local->hw.wiphy->bands[band];
1367
1368 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
1369 shift = ieee80211_vif_get_shift(&sdata->vif);
1360 1370
1361 if (WARN_ON(!sband)) 1371 if (WARN_ON(!sband))
1362 return 1; 1372 return 1;
@@ -1381,7 +1391,15 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1381 continue; 1391 continue;
1382 1392
1383 for (j = 0; j < num_rates; j++) { 1393 for (j = 0; j < num_rates; j++) {
1384 if (bitrates[j].bitrate == own_rate) { 1394 int brate;
1395 if ((rate_flags & sband->bitrates[j].flags)
1396 != rate_flags)
1397 continue;
1398
1399 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
1400 1 << shift);
1401
1402 if (brate == own_rate) {
1385 supp_rates |= BIT(j); 1403 supp_rates |= BIT(j);
1386 if (basic_rates && is_basic) 1404 if (basic_rates && is_basic)
1387 *basic_rates |= BIT(j); 1405 *basic_rates |= BIT(j);
@@ -1435,8 +1453,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1435 local->resuming = true; 1453 local->resuming = true;
1436 1454
1437 if (local->wowlan) { 1455 if (local->wowlan) {
1438 local->wowlan = false;
1439 res = drv_resume(local); 1456 res = drv_resume(local);
1457 local->wowlan = false;
1440 if (res < 0) { 1458 if (res < 0) {
1441 local->resuming = false; 1459 local->resuming = false;
1442 return res; 1460 return res;
@@ -2004,18 +2022,56 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
2004 cfg80211_chandef_create(chandef, control_chan, channel_type); 2022 cfg80211_chandef_create(chandef, control_chan, channel_type);
2005} 2023}
2006 2024
2025int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
2026 const struct ieee80211_supported_band *sband,
2027 const u8 *srates, int srates_len, u32 *rates)
2028{
2029 u32 rate_flags = ieee80211_chandef_rate_flags(chandef);
2030 int shift = ieee80211_chandef_get_shift(chandef);
2031 struct ieee80211_rate *br;
2032 int brate, rate, i, j, count = 0;
2033
2034 *rates = 0;
2035
2036 for (i = 0; i < srates_len; i++) {
2037 rate = srates[i] & 0x7f;
2038
2039 for (j = 0; j < sband->n_bitrates; j++) {
2040 br = &sband->bitrates[j];
2041 if ((rate_flags & br->flags) != rate_flags)
2042 continue;
2043
2044 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
2045 if (brate == rate) {
2046 *rates |= BIT(j);
2047 count++;
2048 break;
2049 }
2050 }
2051 }
2052 return count;
2053}
2054
2007int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 2055int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2008 struct sk_buff *skb, bool need_basic, 2056 struct sk_buff *skb, bool need_basic,
2009 enum ieee80211_band band) 2057 enum ieee80211_band band)
2010{ 2058{
2011 struct ieee80211_local *local = sdata->local; 2059 struct ieee80211_local *local = sdata->local;
2012 struct ieee80211_supported_band *sband; 2060 struct ieee80211_supported_band *sband;
2013 int rate; 2061 int rate, shift;
2014 u8 i, rates, *pos; 2062 u8 i, rates, *pos;
2015 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2063 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2064 u32 rate_flags;
2016 2065
2066 shift = ieee80211_vif_get_shift(&sdata->vif);
2067 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2017 sband = local->hw.wiphy->bands[band]; 2068 sband = local->hw.wiphy->bands[band];
2018 rates = sband->n_bitrates; 2069 rates = 0;
2070 for (i = 0; i < sband->n_bitrates; i++) {
2071 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2072 continue;
2073 rates++;
2074 }
2019 if (rates > 8) 2075 if (rates > 8)
2020 rates = 8; 2076 rates = 8;
2021 2077
@@ -2027,10 +2083,15 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2027 *pos++ = rates; 2083 *pos++ = rates;
2028 for (i = 0; i < rates; i++) { 2084 for (i = 0; i < rates; i++) {
2029 u8 basic = 0; 2085 u8 basic = 0;
2086 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2087 continue;
2088
2030 if (need_basic && basic_rates & BIT(i)) 2089 if (need_basic && basic_rates & BIT(i))
2031 basic = 0x80; 2090 basic = 0x80;
2032 rate = sband->bitrates[i].bitrate; 2091 rate = sband->bitrates[i].bitrate;
2033 *pos++ = basic | (u8) (rate / 5); 2092 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2093 5 * (1 << shift));
2094 *pos++ = basic | (u8) rate;
2034 } 2095 }
2035 2096
2036 return 0; 2097 return 0;
@@ -2042,12 +2103,22 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2042{ 2103{
2043 struct ieee80211_local *local = sdata->local; 2104 struct ieee80211_local *local = sdata->local;
2044 struct ieee80211_supported_band *sband; 2105 struct ieee80211_supported_band *sband;
2045 int rate; 2106 int rate, skip, shift;
2046 u8 i, exrates, *pos; 2107 u8 i, exrates, *pos;
2047 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2108 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2109 u32 rate_flags;
2110
2111 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2112 shift = ieee80211_vif_get_shift(&sdata->vif);
2048 2113
2049 sband = local->hw.wiphy->bands[band]; 2114 sband = local->hw.wiphy->bands[band];
2050 exrates = sband->n_bitrates; 2115 exrates = 0;
2116 for (i = 0; i < sband->n_bitrates; i++) {
2117 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2118 continue;
2119 exrates++;
2120 }
2121
2051 if (exrates > 8) 2122 if (exrates > 8)
2052 exrates -= 8; 2123 exrates -= 8;
2053 else 2124 else
@@ -2060,12 +2131,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2060 pos = skb_put(skb, exrates + 2); 2131 pos = skb_put(skb, exrates + 2);
2061 *pos++ = WLAN_EID_EXT_SUPP_RATES; 2132 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2062 *pos++ = exrates; 2133 *pos++ = exrates;
2134 skip = 0;
2063 for (i = 8; i < sband->n_bitrates; i++) { 2135 for (i = 8; i < sband->n_bitrates; i++) {
2064 u8 basic = 0; 2136 u8 basic = 0;
2137 if ((rate_flags & sband->bitrates[i].flags)
2138 != rate_flags)
2139 continue;
2140 if (skip++ < 8)
2141 continue;
2065 if (need_basic && basic_rates & BIT(i)) 2142 if (need_basic && basic_rates & BIT(i))
2066 basic = 0x80; 2143 basic = 0x80;
2067 rate = sband->bitrates[i].bitrate; 2144 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2068 *pos++ = basic | (u8) (rate / 5); 2145 5 * (1 << shift));
2146 *pos++ = basic | (u8) rate;
2069 } 2147 }
2070 } 2148 }
2071 return 0; 2149 return 0;
@@ -2149,9 +2227,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2149 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2227 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2150 } else { 2228 } else {
2151 struct ieee80211_supported_band *sband; 2229 struct ieee80211_supported_band *sband;
2230 int shift = 0;
2231 int bitrate;
2232
2233 if (status->flag & RX_FLAG_10MHZ)
2234 shift = 1;
2235 if (status->flag & RX_FLAG_5MHZ)
2236 shift = 2;
2152 2237
2153 sband = local->hw.wiphy->bands[status->band]; 2238 sband = local->hw.wiphy->bands[status->band];
2154 ri.legacy = sband->bitrates[status->rate_idx].bitrate; 2239 bitrate = sband->bitrates[status->rate_idx].bitrate;
2240 ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
2155 } 2241 }
2156 2242
2157 rate = cfg80211_calculate_bitrate(&ri); 2243 rate = cfg80211_calculate_bitrate(&ri);