aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c45
-rw-r--r--net/mac80211/ibss.c81
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/mesh.c3
-rw-r--r--net/mac80211/mesh_plink.c2
-rw-r--r--net/mac80211/mlme.c95
-rw-r--r--net/mac80211/rate.c46
-rw-r--r--net/mac80211/rx.c7
-rw-r--r--net/mac80211/scan.c27
-rw-r--r--net/mac80211/status.c18
-rw-r--r--net/mac80211/tx.c21
-rw-r--r--net/mac80211/util.c159
12 files changed, 352 insertions, 159 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 8184d121ff09..b82fff6c0b30 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -395,9 +395,13 @@ void sta_set_rate_info_tx(struct sta_info *sta,
395 rinfo->nss = ieee80211_rate_get_vht_nss(rate); 395 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
396 } else { 396 } else {
397 struct ieee80211_supported_band *sband; 397 struct ieee80211_supported_band *sband;
398 int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
399 u16 brate;
400
398 sband = sta->local->hw.wiphy->bands[ 401 sband = sta->local->hw.wiphy->bands[
399 ieee80211_get_sdata_band(sta->sdata)]; 402 ieee80211_get_sdata_band(sta->sdata)];
400 rinfo->legacy = sband->bitrates[rate->idx].bitrate; 403 brate = sband->bitrates[rate->idx].bitrate;
404 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
401 } 405 }
402 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 406 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
403 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 407 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
@@ -422,11 +426,13 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
422 rinfo->mcs = sta->last_rx_rate_idx; 426 rinfo->mcs = sta->last_rx_rate_idx;
423 } else { 427 } else {
424 struct ieee80211_supported_band *sband; 428 struct ieee80211_supported_band *sband;
429 int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
430 u16 brate;
425 431
426 sband = sta->local->hw.wiphy->bands[ 432 sband = sta->local->hw.wiphy->bands[
427 ieee80211_get_sdata_band(sta->sdata)]; 433 ieee80211_get_sdata_band(sta->sdata)];
428 rinfo->legacy = 434 brate = sband->bitrates[sta->last_rx_rate_idx].bitrate;
429 sband->bitrates[sta->last_rx_rate_idx].bitrate; 435 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
430 } 436 }
431 437
432 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) 438 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
@@ -1190,8 +1196,6 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1190 struct station_parameters *params) 1196 struct station_parameters *params)
1191{ 1197{
1192 int ret = 0; 1198 int ret = 0;
1193 u32 rates;
1194 int i, j;
1195 struct ieee80211_supported_band *sband; 1199 struct ieee80211_supported_band *sband;
1196 struct ieee80211_sub_if_data *sdata = sta->sdata; 1200 struct ieee80211_sub_if_data *sdata = sta->sdata;
1197 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 1201 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
@@ -1284,16 +1288,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1284 sta->listen_interval = params->listen_interval; 1288 sta->listen_interval = params->listen_interval;
1285 1289
1286 if (params->supported_rates) { 1290 if (params->supported_rates) {
1287 rates = 0; 1291 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
1288 1292 sband, params->supported_rates,
1289 for (i = 0; i < params->supported_rates_len; i++) { 1293 params->supported_rates_len,
1290 int rate = (params->supported_rates[i] & 0x7f) * 5; 1294 &sta->sta.supp_rates[band]);
1291 for (j = 0; j < sband->n_bitrates; j++) {
1292 if (sband->bitrates[j].bitrate == rate)
1293 rates |= BIT(j);
1294 }
1295 }
1296 sta->sta.supp_rates[band] = rates;
1297 } 1295 }
1298 1296
1299 if (params->ht_capa) 1297 if (params->ht_capa)
@@ -1956,18 +1954,11 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1956 } 1954 }
1957 1955
1958 if (params->basic_rates) { 1956 if (params->basic_rates) {
1959 int i, j; 1957 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
1960 u32 rates = 0; 1958 wiphy->bands[band],
1961 struct ieee80211_supported_band *sband = wiphy->bands[band]; 1959 params->basic_rates,
1962 1960 params->basic_rates_len,
1963 for (i = 0; i < params->basic_rates_len; i++) { 1961 &sdata->vif.bss_conf.basic_rates);
1964 int rate = (params->basic_rates[i] & 0x7f) * 5;
1965 for (j = 0; j < sband->n_bitrates; j++) {
1966 if (sband->bitrates[j].bitrate == rate)
1967 rates |= BIT(j);
1968 }
1969 }
1970 sdata->vif.bss_conf.basic_rates = rates;
1971 changed |= BSS_CHANGED_BASIC_RATES; 1962 changed |= BSS_CHANGED_BASIC_RATES;
1972 } 1963 }
1973 1964
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 7f290a8562ef..272a3b37615c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -43,16 +43,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
43{ 43{
44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
45 struct ieee80211_local *local = sdata->local; 45 struct ieee80211_local *local = sdata->local;
46 int rates, i; 46 int rates_n = 0, i, ri;
47 struct ieee80211_mgmt *mgmt; 47 struct ieee80211_mgmt *mgmt;
48 u8 *pos; 48 u8 *pos;
49 struct ieee80211_supported_band *sband; 49 struct ieee80211_supported_band *sband;
50 struct cfg80211_bss *bss; 50 struct cfg80211_bss *bss;
51 u32 bss_change; 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 struct beacon_data *presp; 54 struct beacon_data *presp;
55 int frame_len; 55 int frame_len;
56 int shift;
56 57
57 sdata_assert_lock(sdata); 58 sdata_assert_lock(sdata);
58 59
@@ -99,6 +100,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 100 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 101
101 sband = local->hw.wiphy->bands[chan->band]; 102 sband = local->hw.wiphy->bands[chan->band];
103 shift = ieee80211_vif_get_shift(&sdata->vif);
102 104
103 /* Build IBSS probe response */ 105 /* Build IBSS probe response */
104 frame_len = sizeof(struct ieee80211_hdr_3addr) + 106 frame_len = sizeof(struct ieee80211_hdr_3addr) +
@@ -134,15 +136,29 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
134 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 136 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
135 pos += ifibss->ssid_len; 137 pos += ifibss->ssid_len;
136 138
137 rates = min_t(int, 8, sband->n_bitrates); 139 rate_flags = ieee80211_chandef_rate_flags(&chandef);
140 for (i = 0; i < sband->n_bitrates; i++) {
141 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
142 continue;
143
144 rates |= BIT(i);
145 rates_n++;
146 }
147
138 *pos++ = WLAN_EID_SUPP_RATES; 148 *pos++ = WLAN_EID_SUPP_RATES;
139 *pos++ = rates; 149 *pos++ = min_t(int, 8, rates_n);
140 for (i = 0; i < rates; i++) { 150 for (ri = 0; ri < sband->n_bitrates; ri++) {
141 int rate = sband->bitrates[i].bitrate; 151 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
152 5 * (1 << shift));
142 u8 basic = 0; 153 u8 basic = 0;
143 if (basic_rates & BIT(i)) 154 if (!(rates & BIT(ri)))
155 continue;
156
157 if (basic_rates & BIT(ri))
144 basic = 0x80; 158 basic = 0x80;
145 *pos++ = basic | (u8) (rate / 5); 159 *pos++ = basic | (u8) rate;
160 if (++rates_added == 8)
161 break;
146 } 162 }
147 163
148 if (sband->band == IEEE80211_BAND_2GHZ) { 164 if (sband->band == IEEE80211_BAND_2GHZ) {
@@ -157,15 +173,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
157 *pos++ = 0; 173 *pos++ = 0;
158 *pos++ = 0; 174 *pos++ = 0;
159 175
160 if (sband->n_bitrates > 8) { 176 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
177 if (rates_n > 8) {
161 *pos++ = WLAN_EID_EXT_SUPP_RATES; 178 *pos++ = WLAN_EID_EXT_SUPP_RATES;
162 *pos++ = sband->n_bitrates - 8; 179 *pos++ = rates_n - 8;
163 for (i = 8; i < sband->n_bitrates; i++) { 180 for (; ri < sband->n_bitrates; ri++) {
164 int rate = sband->bitrates[i].bitrate; 181 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
182 5 * (1 << shift));
165 u8 basic = 0; 183 u8 basic = 0;
166 if (basic_rates & BIT(i)) 184 if (!(rates & BIT(ri)))
185 continue;
186
187 if (basic_rates & BIT(ri))
167 basic = 0x80; 188 basic = 0x80;
168 *pos++ = basic | (u8) (rate / 5); 189 *pos++ = basic | (u8) rate;
169 } 190 }
170 } 191 }
171 192
@@ -244,7 +265,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
244 sdata->vif.bss_conf.ibss_creator = creator; 265 sdata->vif.bss_conf.ibss_creator = creator;
245 ieee80211_bss_info_change_notify(sdata, bss_change); 266 ieee80211_bss_info_change_notify(sdata, bss_change);
246 267
247 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); 268 ieee80211_sta_def_wmm_params(sdata, rates, supp_rates);
248 269
249 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 270 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
250 mod_timer(&ifibss->timer, 271 mod_timer(&ifibss->timer,
@@ -268,6 +289,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
268 u16 beacon_int = cbss->beacon_interval; 289 u16 beacon_int = cbss->beacon_interval;
269 const struct cfg80211_bss_ies *ies; 290 const struct cfg80211_bss_ies *ies;
270 u64 tsf; 291 u64 tsf;
292 u32 rate_flags;
293 int shift;
271 294
272 sdata_assert_lock(sdata); 295 sdata_assert_lock(sdata);
273 296
@@ -275,15 +298,24 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
275 beacon_int = 10; 298 beacon_int = 10;
276 299
277 sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; 300 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
301 rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef);
302 shift = ieee80211_vif_get_shift(&sdata->vif);
278 303
279 basic_rates = 0; 304 basic_rates = 0;
280 305
281 for (i = 0; i < bss->supp_rates_len; i++) { 306 for (i = 0; i < bss->supp_rates_len; i++) {
282 int rate = (bss->supp_rates[i] & 0x7f) * 5; 307 int rate = bss->supp_rates[i] & 0x7f;
283 bool is_basic = !!(bss->supp_rates[i] & 0x80); 308 bool is_basic = !!(bss->supp_rates[i] & 0x80);
284 309
285 for (j = 0; j < sband->n_bitrates; j++) { 310 for (j = 0; j < sband->n_bitrates; j++) {
286 if (sband->bitrates[j].bitrate == rate) { 311 int brate;
312 if ((rate_flags & sband->bitrates[j].flags)
313 != rate_flags)
314 continue;
315
316 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
317 5 * (1 << shift));
318 if (brate == rate) {
287 if (is_basic) 319 if (is_basic)
288 basic_rates |= BIT(j); 320 basic_rates |= BIT(j);
289 break; 321 break;
@@ -465,7 +497,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
465 sta = sta_info_get(sdata, mgmt->sa); 497 sta = sta_info_get(sdata, mgmt->sa);
466 498
467 if (elems->supp_rates) { 499 if (elems->supp_rates) {
468 supp_rates = ieee80211_sta_get_rates(local, elems, 500 supp_rates = ieee80211_sta_get_rates(sdata, elems,
469 band, NULL); 501 band, NULL);
470 if (sta) { 502 if (sta) {
471 u32 prev_rates; 503 u32 prev_rates;
@@ -589,7 +621,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
589 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", 621 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n",
590 mgmt->bssid); 622 mgmt->bssid);
591 ieee80211_sta_join_ibss(sdata, bss); 623 ieee80211_sta_join_ibss(sdata, bss);
592 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); 624 supp_rates = ieee80211_sta_get_rates(sdata, elems, band, NULL);
593 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 625 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
594 supp_rates); 626 supp_rates);
595 rcu_read_unlock(); 627 rcu_read_unlock();
@@ -1024,6 +1056,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1024 struct cfg80211_ibss_params *params) 1056 struct cfg80211_ibss_params *params)
1025{ 1057{
1026 u32 changed = 0; 1058 u32 changed = 0;
1059 u32 rate_flags;
1060 struct ieee80211_supported_band *sband;
1061 int i;
1027 1062
1028 if (params->bssid) { 1063 if (params->bssid) {
1029 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 1064 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
@@ -1034,6 +1069,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1034 sdata->u.ibss.privacy = params->privacy; 1069 sdata->u.ibss.privacy = params->privacy;
1035 sdata->u.ibss.control_port = params->control_port; 1070 sdata->u.ibss.control_port = params->control_port;
1036 sdata->u.ibss.basic_rates = params->basic_rates; 1071 sdata->u.ibss.basic_rates = params->basic_rates;
1072
1073 /* fix basic_rates if channel does not support these rates */
1074 rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
1075 sband = sdata->local->hw.wiphy->bands[params->chandef.chan->band];
1076 for (i = 0; i < sband->n_bitrates; i++) {
1077 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1078 sdata->u.ibss.basic_rates &= ~BIT(i);
1079 }
1037 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, 1080 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
1038 sizeof(params->mcast_rate)); 1081 sizeof(params->mcast_rate));
1039 1082
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 338e7ca21ea5..6596da66bfaf 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1601,7 +1601,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1601int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1601int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1602 size_t buffer_len, const u8 *ie, size_t ie_len, 1602 size_t buffer_len, const u8 *ie, size_t ie_len,
1603 enum ieee80211_band band, u32 rate_mask, 1603 enum ieee80211_band band, u32 rate_mask,
1604 u8 channel); 1604 struct cfg80211_chan_def *chandef);
1605struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1605struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1606 u8 *dst, u32 ratemask, 1606 u8 *dst, u32 ratemask,
1607 struct ieee80211_channel *chan, 1607 struct ieee80211_channel *chan,
@@ -1617,7 +1617,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1617void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1617void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1618 const size_t supp_rates_len, 1618 const size_t supp_rates_len,
1619 const u8 *supp_rates); 1619 const u8 *supp_rates);
1620u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1620u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
1621 struct ieee802_11_elems *elems, 1621 struct ieee802_11_elems *elems,
1622 enum ieee80211_band band, u32 *basic_rates); 1622 enum ieee80211_band band, u32 *basic_rates);
1623int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, 1623int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
@@ -1634,6 +1634,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1634 u16 prot_mode); 1634 u16 prot_mode);
1635u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1635u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1636 u32 cap); 1636 u32 cap);
1637int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
1638 const struct ieee80211_supported_band *sband,
1639 const u8 *srates, int srates_len, u32 *rates);
1637int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1640int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1638 struct sk_buff *skb, bool need_basic, 1641 struct sk_buff *skb, bool need_basic,
1639 enum ieee80211_band band); 1642 enum ieee80211_band band);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 447f41bbe744..e536f22fbeca 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -62,7 +62,6 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
62 struct ieee802_11_elems *ie) 62 struct ieee802_11_elems *ie)
63{ 63{
64 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 64 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
65 struct ieee80211_local *local = sdata->local;
66 u32 basic_rates = 0; 65 u32 basic_rates = 0;
67 struct cfg80211_chan_def sta_chan_def; 66 struct cfg80211_chan_def sta_chan_def;
68 67
@@ -85,7 +84,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
85 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) 84 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
86 return false; 85 return false;
87 86
88 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), 87 ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
89 &basic_rates); 88 &basic_rates);
90 89
91 if (sdata->vif.bss_conf.basic_rates != basic_rates) 90 if (sdata->vif.bss_conf.basic_rates != basic_rates)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 02c05fa15c20..6b65d5055f5b 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -379,7 +379,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
379 u32 rates, basic_rates = 0, changed = 0; 379 u32 rates, basic_rates = 0, changed = 0;
380 380
381 sband = local->hw.wiphy->bands[band]; 381 sband = local->hw.wiphy->bands[band];
382 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates); 382 rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
383 383
384 spin_lock_bh(&sta->lock); 384 spin_lock_bh(&sta->lock);
385 sta->last_rx = jiffies; 385 sta->last_rx = jiffies;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ae31968d42d3..f7552c2b74eb 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -478,27 +478,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
478 478
479/* frame sending functions */ 479/* frame sending functions */
480 480
481static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
482 struct ieee80211_supported_band *sband,
483 u32 *rates)
484{
485 int i, j, count;
486 *rates = 0;
487 count = 0;
488 for (i = 0; i < supp_rates_len; i++) {
489 int rate = (supp_rates[i] & 0x7F) * 5;
490
491 for (j = 0; j < sband->n_bitrates; j++)
492 if (sband->bitrates[j].bitrate == rate) {
493 *rates |= BIT(j);
494 count++;
495 break;
496 }
497 }
498
499 return count;
500}
501
502static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, 481static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
503 struct sk_buff *skb, u8 ap_ht_param, 482 struct sk_buff *skb, u8 ap_ht_param,
504 struct ieee80211_supported_band *sband, 483 struct ieee80211_supported_band *sband,
@@ -617,12 +596,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
617 struct ieee80211_mgmt *mgmt; 596 struct ieee80211_mgmt *mgmt;
618 u8 *pos, qos_info; 597 u8 *pos, qos_info;
619 size_t offset = 0, noffset; 598 size_t offset = 0, noffset;
620 int i, count, rates_len, supp_rates_len; 599 int i, count, rates_len, supp_rates_len, shift;
621 u16 capab; 600 u16 capab;
622 struct ieee80211_supported_band *sband; 601 struct ieee80211_supported_band *sband;
623 struct ieee80211_chanctx_conf *chanctx_conf; 602 struct ieee80211_chanctx_conf *chanctx_conf;
624 struct ieee80211_channel *chan; 603 struct ieee80211_channel *chan;
625 u32 rates = 0; 604 u32 rate_flags, rates = 0;
626 605
627 sdata_assert_lock(sdata); 606 sdata_assert_lock(sdata);
628 607
@@ -633,8 +612,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
633 return; 612 return;
634 } 613 }
635 chan = chanctx_conf->def.chan; 614 chan = chanctx_conf->def.chan;
615 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
636 rcu_read_unlock(); 616 rcu_read_unlock();
637 sband = local->hw.wiphy->bands[chan->band]; 617 sband = local->hw.wiphy->bands[chan->band];
618 shift = ieee80211_vif_get_shift(&sdata->vif);
638 619
639 if (assoc_data->supp_rates_len) { 620 if (assoc_data->supp_rates_len) {
640 /* 621 /*
@@ -643,17 +624,24 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
643 * in the association request (e.g. D-Link DAP 1353 in 624 * in the association request (e.g. D-Link DAP 1353 in
644 * b-only mode)... 625 * b-only mode)...
645 */ 626 */
646 rates_len = ieee80211_compatible_rates(assoc_data->supp_rates, 627 rates_len = ieee80211_parse_bitrates(&chanctx_conf->def, sband,
647 assoc_data->supp_rates_len, 628 assoc_data->supp_rates,
648 sband, &rates); 629 assoc_data->supp_rates_len,
630 &rates);
649 } else { 631 } else {
650 /* 632 /*
651 * In case AP not provide any supported rates information 633 * In case AP not provide any supported rates information
652 * before association, we send information element(s) with 634 * before association, we send information element(s) with
653 * all rates that we support. 635 * all rates that we support.
654 */ 636 */
655 rates = ~0; 637 rates_len = 0;
656 rates_len = sband->n_bitrates; 638 for (i = 0; i < sband->n_bitrates; i++) {
639 if ((rate_flags & sband->bitrates[i].flags)
640 != rate_flags)
641 continue;
642 rates |= BIT(i);
643 rates_len++;
644 }
657 } 645 }
658 646
659 skb = alloc_skb(local->hw.extra_tx_headroom + 647 skb = alloc_skb(local->hw.extra_tx_headroom +
@@ -730,8 +718,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
730 count = 0; 718 count = 0;
731 for (i = 0; i < sband->n_bitrates; i++) { 719 for (i = 0; i < sband->n_bitrates; i++) {
732 if (BIT(i) & rates) { 720 if (BIT(i) & rates) {
733 int rate = sband->bitrates[i].bitrate; 721 int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
734 *pos++ = (u8) (rate / 5); 722 5 * (1 << shift));
723 *pos++ = (u8) rate;
735 if (++count == 8) 724 if (++count == 8)
736 break; 725 break;
737 } 726 }
@@ -744,8 +733,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
744 733
745 for (i++; i < sband->n_bitrates; i++) { 734 for (i++; i < sband->n_bitrates; i++) {
746 if (BIT(i) & rates) { 735 if (BIT(i) & rates) {
747 int rate = sband->bitrates[i].bitrate; 736 int rate;
748 *pos++ = (u8) (rate / 5); 737 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
738 5 * (1 << shift));
739 *pos++ = (u8) rate;
749 } 740 }
750 } 741 }
751 } 742 }
@@ -2432,15 +2423,16 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2432 u8 *supp_rates, unsigned int supp_rates_len, 2423 u8 *supp_rates, unsigned int supp_rates_len,
2433 u32 *rates, u32 *basic_rates, 2424 u32 *rates, u32 *basic_rates,
2434 bool *have_higher_than_11mbit, 2425 bool *have_higher_than_11mbit,
2435 int *min_rate, int *min_rate_index) 2426 int *min_rate, int *min_rate_index,
2427 int shift, u32 rate_flags)
2436{ 2428{
2437 int i, j; 2429 int i, j;
2438 2430
2439 for (i = 0; i < supp_rates_len; i++) { 2431 for (i = 0; i < supp_rates_len; i++) {
2440 int rate = (supp_rates[i] & 0x7f) * 5; 2432 int rate = supp_rates[i] & 0x7f;
2441 bool is_basic = !!(supp_rates[i] & 0x80); 2433 bool is_basic = !!(supp_rates[i] & 0x80);
2442 2434
2443 if (rate > 110) 2435 if ((rate * 5 * (1 << shift)) > 110)
2444 *have_higher_than_11mbit = true; 2436 *have_higher_than_11mbit = true;
2445 2437
2446 /* 2438 /*
@@ -2456,12 +2448,20 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2456 continue; 2448 continue;
2457 2449
2458 for (j = 0; j < sband->n_bitrates; j++) { 2450 for (j = 0; j < sband->n_bitrates; j++) {
2459 if (sband->bitrates[j].bitrate == rate) { 2451 struct ieee80211_rate *br;
2452 int brate;
2453
2454 br = &sband->bitrates[j];
2455 if ((rate_flags & br->flags) != rate_flags)
2456 continue;
2457
2458 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
2459 if (brate == rate) {
2460 *rates |= BIT(j); 2460 *rates |= BIT(j);
2461 if (is_basic) 2461 if (is_basic)
2462 *basic_rates |= BIT(j); 2462 *basic_rates |= BIT(j);
2463 if (rate < *min_rate) { 2463 if ((rate * 5) < *min_rate) {
2464 *min_rate = rate; 2464 *min_rate = rate * 5;
2465 *min_rate_index = j; 2465 *min_rate_index = j;
2466 } 2466 }
2467 break; 2467 break;
@@ -3884,27 +3884,40 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3884 if (!new_sta) 3884 if (!new_sta)
3885 return -ENOMEM; 3885 return -ENOMEM;
3886 } 3886 }
3887
3888 if (new_sta) { 3887 if (new_sta) {
3889 u32 rates = 0, basic_rates = 0; 3888 u32 rates = 0, basic_rates = 0;
3890 bool have_higher_than_11mbit; 3889 bool have_higher_than_11mbit;
3891 int min_rate = INT_MAX, min_rate_index = -1; 3890 int min_rate = INT_MAX, min_rate_index = -1;
3891 struct ieee80211_chanctx_conf *chanctx_conf;
3892 struct ieee80211_supported_band *sband; 3892 struct ieee80211_supported_band *sband;
3893 const struct cfg80211_bss_ies *ies; 3893 const struct cfg80211_bss_ies *ies;
3894 int shift;
3895 u32 rate_flags;
3894 3896
3895 sband = local->hw.wiphy->bands[cbss->channel->band]; 3897 sband = local->hw.wiphy->bands[cbss->channel->band];
3896 3898
3897 err = ieee80211_prep_channel(sdata, cbss); 3899 err = ieee80211_prep_channel(sdata, cbss);
3898 if (err) { 3900 if (err) {
3899 sta_info_free(local, new_sta); 3901 sta_info_free(local, new_sta);
3900 return err; 3902 return -EINVAL;
3901 } 3903 }
3904 shift = ieee80211_vif_get_shift(&sdata->vif);
3905
3906 rcu_read_lock();
3907 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3908 if (WARN_ON(!chanctx_conf)) {
3909 rcu_read_unlock();
3910 return -EINVAL;
3911 }
3912 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
3913 rcu_read_unlock();
3902 3914
3903 ieee80211_get_rates(sband, bss->supp_rates, 3915 ieee80211_get_rates(sband, bss->supp_rates,
3904 bss->supp_rates_len, 3916 bss->supp_rates_len,
3905 &rates, &basic_rates, 3917 &rates, &basic_rates,
3906 &have_higher_than_11mbit, 3918 &have_higher_than_11mbit,
3907 &min_rate, &min_rate_index); 3919 &min_rate, &min_rate_index,
3920 shift, rate_flags);
3908 3921
3909 /* 3922 /*
3910 * This used to be a workaround for basic rates missing 3923 * This used to be a workaround for basic rates missing
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 30d58d2d13e2..ba63ac851c2b 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -232,37 +232,28 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
232 /* could not find a basic rate; use original selection */ 232 /* could not find a basic rate; use original selection */
233} 233}
234 234
235static inline s8 235static void __rate_control_send_low(struct ieee80211_hw *hw,
236rate_lowest_non_cck_index(struct ieee80211_supported_band *sband, 236 struct ieee80211_supported_band *sband,
237 struct ieee80211_sta *sta) 237 struct ieee80211_sta *sta,
238 struct ieee80211_tx_info *info)
238{ 239{
239 int i; 240 int i;
241 u32 rate_flags =
242 ieee80211_chandef_rate_flags(&hw->conf.chandef);
240 243
244 if ((sband->band == IEEE80211_BAND_2GHZ) &&
245 (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
246 rate_flags |= IEEE80211_RATE_ERP_G;
247
248 info->control.rates[0].idx = 0;
241 for (i = 0; i < sband->n_bitrates; i++) { 249 for (i = 0; i < sband->n_bitrates; i++) {
242 struct ieee80211_rate *srate = &sband->bitrates[i]; 250 if (!rate_supported(sta, sband->band, i))
243 if ((srate->bitrate == 10) || (srate->bitrate == 20) ||
244 (srate->bitrate == 55) || (srate->bitrate == 110))
245 continue; 251 continue;
246 252
247 if (rate_supported(sta, sband->band, i)) 253 info->control.rates[0].idx = i;
248 return i; 254 break;
249 } 255 }
250 256 WARN_ON_ONCE(i == sband->n_bitrates);
251 /* No matching rate found */
252 return 0;
253}
254
255static void __rate_control_send_low(struct ieee80211_hw *hw,
256 struct ieee80211_supported_band *sband,
257 struct ieee80211_sta *sta,
258 struct ieee80211_tx_info *info)
259{
260 if ((sband->band != IEEE80211_BAND_2GHZ) ||
261 !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
262 info->control.rates[0].idx = rate_lowest_index(sband, sta);
263 else
264 info->control.rates[0].idx =
265 rate_lowest_non_cck_index(sband, sta);
266 257
267 info->control.rates[0].count = 258 info->control.rates[0].count =
268 (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 259 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
@@ -585,6 +576,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
585 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; 576 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
586 bool has_mcs_mask; 577 bool has_mcs_mask;
587 u32 mask; 578 u32 mask;
579 u32 rate_flags;
588 int i; 580 int i;
589 581
590 /* 582 /*
@@ -594,6 +586,12 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
594 */ 586 */
595 mask = sdata->rc_rateidx_mask[info->band]; 587 mask = sdata->rc_rateidx_mask[info->band];
596 has_mcs_mask = sdata->rc_has_mcs_mask[info->band]; 588 has_mcs_mask = sdata->rc_has_mcs_mask[info->band];
589 rate_flags =
590 ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
591 for (i = 0; i < sband->n_bitrates; i++)
592 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
593 mask &= ~BIT(i);
594
597 if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask) 595 if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask)
598 return; 596 return;
599 597
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index deeeca1299bd..0ac75127b7d2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -236,8 +236,13 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
236 */ 236 */
237 *pos = 0; 237 *pos = 0;
238 } else { 238 } else {
239 int shift = 0;
239 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 240 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
240 *pos = rate->bitrate / 5; 241 if (status->flag & RX_FLAG_10MHZ)
242 shift = 1;
243 else if (status->flag & RX_FLAG_5MHZ)
244 shift = 2;
245 *pos = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
241 } 246 }
242 pos++; 247 pos++;
243 248
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1b122a79b0d8..819d0956eb3b 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -204,10 +204,29 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
204 ieee80211_rx_bss_put(local, bss); 204 ieee80211_rx_bss_put(local, bss);
205} 205}
206 206
207static void
208ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef,
209 enum nl80211_bss_scan_width scan_width)
210{
211 memset(chandef, 0, sizeof(*chandef));
212 switch (scan_width) {
213 case NL80211_BSS_CHAN_WIDTH_5:
214 chandef->width = NL80211_CHAN_WIDTH_5;
215 break;
216 case NL80211_BSS_CHAN_WIDTH_10:
217 chandef->width = NL80211_CHAN_WIDTH_10;
218 break;
219 default:
220 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
221 break;
222 }
223}
224
207/* return false if no more work */ 225/* return false if no more work */
208static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) 226static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
209{ 227{
210 struct cfg80211_scan_request *req = local->scan_req; 228 struct cfg80211_scan_request *req = local->scan_req;
229 struct cfg80211_chan_def chandef;
211 enum ieee80211_band band; 230 enum ieee80211_band band;
212 int i, ielen, n_chans; 231 int i, ielen, n_chans;
213 232
@@ -229,11 +248,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
229 } while (!n_chans); 248 } while (!n_chans);
230 249
231 local->hw_scan_req->n_channels = n_chans; 250 local->hw_scan_req->n_channels = n_chans;
251 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
232 252
233 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, 253 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
234 local->hw_scan_ies_bufsize, 254 local->hw_scan_ies_bufsize,
235 req->ie, req->ie_len, band, 255 req->ie, req->ie_len, band,
236 req->rates[band], 0); 256 req->rates[band], &chandef);
237 local->hw_scan_req->ie_len = ielen; 257 local->hw_scan_req->ie_len = ielen;
238 local->hw_scan_req->no_cck = req->no_cck; 258 local->hw_scan_req->no_cck = req->no_cck;
239 259
@@ -912,6 +932,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
912{ 932{
913 struct ieee80211_local *local = sdata->local; 933 struct ieee80211_local *local = sdata->local;
914 struct ieee80211_sched_scan_ies sched_scan_ies = {}; 934 struct ieee80211_sched_scan_ies sched_scan_ies = {};
935 struct cfg80211_chan_def chandef;
915 int ret, i, iebufsz; 936 int ret, i, iebufsz;
916 937
917 iebufsz = 2 + IEEE80211_MAX_SSID_LEN + 938 iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
@@ -939,10 +960,12 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
939 goto out_free; 960 goto out_free;
940 } 961 }
941 962
963 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
964
942 sched_scan_ies.len[i] = 965 sched_scan_ies.len[i] =
943 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], 966 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
944 iebufsz, req->ie, req->ie_len, 967 iebufsz, req->ie, req->ie_len,
945 i, (u32) -1, 0); 968 i, (u32) -1, &chandef);
946 } 969 }
947 970
948 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 971 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 43439203f4e4..6ad4c14385ef 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -252,9 +252,10 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
252 return len; 252 return len;
253} 253}
254 254
255static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band 255static void
256 *sband, struct sk_buff *skb, 256ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
257 int retry_count, int rtap_len) 257 struct sk_buff *skb, int retry_count,
258 int rtap_len, int shift)
258{ 259{
259 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 260 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
260 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 261 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -280,8 +281,11 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
280 /* IEEE80211_RADIOTAP_RATE */ 281 /* IEEE80211_RADIOTAP_RATE */
281 if (info->status.rates[0].idx >= 0 && 282 if (info->status.rates[0].idx >= 0 &&
282 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) { 283 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
284 u16 rate;
285
283 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 286 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
284 *pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5; 287 rate = sband->bitrates[info->status.rates[0].idx].bitrate;
288 *pos = DIV_ROUND_UP(rate, 5 * (1 << shift));
285 /* padding for tx flags */ 289 /* padding for tx flags */
286 pos += 2; 290 pos += 2;
287 } 291 }
@@ -424,6 +428,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
424 bool acked; 428 bool acked;
425 struct ieee80211_bar *bar; 429 struct ieee80211_bar *bar;
426 int rtap_len; 430 int rtap_len;
431 int shift = 0;
427 432
428 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 433 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
429 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 434 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -458,6 +463,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
458 if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr)) 463 if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
459 continue; 464 continue;
460 465
466 shift = ieee80211_vif_get_shift(&sta->sdata->vif);
467
461 if (info->flags & IEEE80211_TX_STATUS_EOSP) 468 if (info->flags & IEEE80211_TX_STATUS_EOSP)
462 clear_sta_flag(sta, WLAN_STA_SP); 469 clear_sta_flag(sta, WLAN_STA_SP);
463 470
@@ -624,7 +631,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
624 dev_kfree_skb(skb); 631 dev_kfree_skb(skb);
625 return; 632 return;
626 } 633 }
627 ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len); 634 ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len,
635 shift);
628 636
629 /* XXX: is this sufficient for BPF? */ 637 /* XXX: is this sufficient for BPF? */
630 skb_set_mac_header(skb, 0); 638 skb_set_mac_header(skb, 0);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3523daa0b15c..f82301b6cef2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -40,12 +40,22 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
40 struct sk_buff *skb, int group_addr, 40 struct sk_buff *skb, int group_addr,
41 int next_frag_len) 41 int next_frag_len)
42{ 42{
43 int rate, mrate, erp, dur, i, shift; 43 int rate, mrate, erp, dur, i, shift = 0;
44 struct ieee80211_rate *txrate; 44 struct ieee80211_rate *txrate;
45 struct ieee80211_local *local = tx->local; 45 struct ieee80211_local *local = tx->local;
46 struct ieee80211_supported_band *sband; 46 struct ieee80211_supported_band *sband;
47 struct ieee80211_hdr *hdr; 47 struct ieee80211_hdr *hdr;
48 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 48 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
49 struct ieee80211_chanctx_conf *chanctx_conf;
50 u32 rate_flags = 0;
51
52 rcu_read_lock();
53 chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
54 if (chanctx_conf) {
55 shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
56 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
57 }
58 rcu_read_unlock();
49 59
50 /* assume HW handles this */ 60 /* assume HW handles this */
51 if (tx->rate.flags & IEEE80211_TX_RC_MCS) 61 if (tx->rate.flags & IEEE80211_TX_RC_MCS)
@@ -122,8 +132,11 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
122 if (r->bitrate > txrate->bitrate) 132 if (r->bitrate > txrate->bitrate)
123 break; 133 break;
124 134
135 if ((rate_flags & r->flags) != rate_flags)
136 continue;
137
125 if (tx->sdata->vif.bss_conf.basic_rates & BIT(i)) 138 if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
126 rate = r->bitrate; 139 rate = DIV_ROUND_UP(r->bitrate, 1 << shift);
127 140
128 switch (sband->band) { 141 switch (sband->band) {
129 case IEEE80211_BAND_2GHZ: { 142 case IEEE80211_BAND_2GHZ: {
@@ -150,11 +163,9 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
150 if (rate == -1) { 163 if (rate == -1) {
151 /* No matching basic rate found; use highest suitable mandatory 164 /* No matching basic rate found; use highest suitable mandatory
152 * PHY rate */ 165 * PHY rate */
153 rate = mrate; 166 rate = DIV_ROUND_UP(mrate, 1 << shift);
154 } 167 }
155 168
156 shift = ieee80211_vif_get_shift(&tx->sdata->vif);
157
158 /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ 169 /* Don't calculate ACKs for QoS Frames with NoAck Policy set */
159 if (ieee80211_is_data_qos(hdr->frame_control) && 170 if (ieee80211_is_data_qos(hdr->frame_control) &&
160 *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK) 171 *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 61856e17a1e4..1e45891ca219 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -141,14 +141,18 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
141 dur = 16; /* SIFS + signal ext */ 141 dur = 16; /* SIFS + signal ext */
142 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */ 142 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
143 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */ 143 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
144 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
145 4 * rate); /* T_SYM x N_SYM */
146 144
147 /* IEEE 802.11-2012 18.3.2.4: all values above are: 145 /* IEEE 802.11-2012 18.3.2.4: all values above are:
148 * * times 4 for 5 MHz 146 * * times 4 for 5 MHz
149 * * times 2 for 10 MHz 147 * * times 2 for 10 MHz
150 */ 148 */
151 dur *= 1 << shift; 149 dur *= 1 << shift;
150
151 /* rates should already consider the channel bandwidth,
152 * don't apply divisor again.
153 */
154 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
155 4 * rate); /* T_SYM x N_SYM */
152 } else { 156 } else {
153 /* 157 /*
154 * 802.11b or 802.11g with 802.11b compatibility: 158 * 802.11b or 802.11g with 802.11b compatibility:
@@ -205,7 +209,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
205 struct ieee80211_rate *rate; 209 struct ieee80211_rate *rate;
206 struct ieee80211_sub_if_data *sdata; 210 struct ieee80211_sub_if_data *sdata;
207 bool short_preamble; 211 bool short_preamble;
208 int erp, shift = 0; 212 int erp, shift = 0, bitrate;
209 u16 dur; 213 u16 dur;
210 struct ieee80211_supported_band *sband; 214 struct ieee80211_supported_band *sband;
211 215
@@ -224,14 +228,16 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
224 shift = ieee80211_vif_get_shift(vif); 228 shift = ieee80211_vif_get_shift(vif);
225 } 229 }
226 230
231 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
232
227 /* CTS duration */ 233 /* CTS duration */
228 dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate, 234 dur = ieee80211_frame_duration(sband->band, 10, bitrate,
229 erp, short_preamble, shift); 235 erp, short_preamble, shift);
230 /* Data frame duration */ 236 /* Data frame duration */
231 dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 237 dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
232 erp, short_preamble, shift); 238 erp, short_preamble, shift);
233 /* ACK duration */ 239 /* ACK duration */
234 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 240 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
235 erp, short_preamble, shift); 241 erp, short_preamble, shift);
236 242
237 return cpu_to_le16(dur); 243 return cpu_to_le16(dur);
@@ -247,7 +253,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
247 struct ieee80211_rate *rate; 253 struct ieee80211_rate *rate;
248 struct ieee80211_sub_if_data *sdata; 254 struct ieee80211_sub_if_data *sdata;
249 bool short_preamble; 255 bool short_preamble;
250 int erp, shift = 0; 256 int erp, shift = 0, bitrate;
251 u16 dur; 257 u16 dur;
252 struct ieee80211_supported_band *sband; 258 struct ieee80211_supported_band *sband;
253 259
@@ -265,12 +271,14 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
265 shift = ieee80211_vif_get_shift(vif); 271 shift = ieee80211_vif_get_shift(vif);
266 } 272 }
267 273
274 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
275
268 /* Data frame duration */ 276 /* Data frame duration */
269 dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 277 dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
270 erp, short_preamble, shift); 278 erp, short_preamble, shift);
271 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { 279 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
272 /* ACK duration */ 280 /* ACK duration */
273 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 281 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
274 erp, short_preamble, shift); 282 erp, short_preamble, shift);
275 } 283 }
276 284
@@ -1175,7 +1183,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1175int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1183int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1176 size_t buffer_len, const u8 *ie, size_t ie_len, 1184 size_t buffer_len, const u8 *ie, size_t ie_len,
1177 enum ieee80211_band band, u32 rate_mask, 1185 enum ieee80211_band band, u32 rate_mask,
1178 u8 channel) 1186 struct cfg80211_chan_def *chandef)
1179{ 1187{
1180 struct ieee80211_supported_band *sband; 1188 struct ieee80211_supported_band *sband;
1181 u8 *pos = buffer, *end = buffer + buffer_len; 1189 u8 *pos = buffer, *end = buffer + buffer_len;
@@ -1184,16 +1192,26 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1184 u8 rates[32]; 1192 u8 rates[32];
1185 int num_rates; 1193 int num_rates;
1186 int ext_rates_len; 1194 int ext_rates_len;
1195 int shift;
1196 u32 rate_flags;
1187 1197
1188 sband = local->hw.wiphy->bands[band]; 1198 sband = local->hw.wiphy->bands[band];
1189 if (WARN_ON_ONCE(!sband)) 1199 if (WARN_ON_ONCE(!sband))
1190 return 0; 1200 return 0;
1191 1201
1202 rate_flags = ieee80211_chandef_rate_flags(chandef);
1203 shift = ieee80211_chandef_get_shift(chandef);
1204
1192 num_rates = 0; 1205 num_rates = 0;
1193 for (i = 0; i < sband->n_bitrates; i++) { 1206 for (i = 0; i < sband->n_bitrates; i++) {
1194 if ((BIT(i) & rate_mask) == 0) 1207 if ((BIT(i) & rate_mask) == 0)
1195 continue; /* skip rate */ 1208 continue; /* skip rate */
1196 rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); 1209 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1210 continue;
1211
1212 rates[num_rates++] =
1213 (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate,
1214 (1 << shift) * 5);
1197 } 1215 }
1198 1216
1199 supp_rates_len = min_t(int, num_rates, 8); 1217 supp_rates_len = min_t(int, num_rates, 8);
@@ -1233,12 +1251,13 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1233 pos += ext_rates_len; 1251 pos += ext_rates_len;
1234 } 1252 }
1235 1253
1236 if (channel && sband->band == IEEE80211_BAND_2GHZ) { 1254 if (chandef->chan && sband->band == IEEE80211_BAND_2GHZ) {
1237 if (end - pos < 3) 1255 if (end - pos < 3)
1238 goto out_err; 1256 goto out_err;
1239 *pos++ = WLAN_EID_DS_PARAMS; 1257 *pos++ = WLAN_EID_DS_PARAMS;
1240 *pos++ = 1; 1258 *pos++ = 1;
1241 *pos++ = channel; 1259 *pos++ = ieee80211_frequency_to_channel(
1260 chandef->chan->center_freq);
1242 } 1261 }
1243 1262
1244 /* insert custom IEs that go before HT */ 1263 /* insert custom IEs that go before HT */
@@ -1303,9 +1322,9 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1303 bool directed) 1322 bool directed)
1304{ 1323{
1305 struct ieee80211_local *local = sdata->local; 1324 struct ieee80211_local *local = sdata->local;
1325 struct cfg80211_chan_def chandef;
1306 struct sk_buff *skb; 1326 struct sk_buff *skb;
1307 struct ieee80211_mgmt *mgmt; 1327 struct ieee80211_mgmt *mgmt;
1308 u8 chan_no;
1309 int ies_len; 1328 int ies_len;
1310 1329
1311 /* 1330 /*
@@ -1313,10 +1332,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1313 * in order to maximize the chance that we get a response. Some 1332 * in order to maximize the chance that we get a response. Some
1314 * badly-behaved APs don't respond when this parameter is included. 1333 * badly-behaved APs don't respond when this parameter is included.
1315 */ 1334 */
1335 chandef.width = sdata->vif.bss_conf.chandef.width;
1316 if (directed) 1336 if (directed)
1317 chan_no = 0; 1337 chandef.chan = NULL;
1318 else 1338 else
1319 chan_no = ieee80211_frequency_to_channel(chan->center_freq); 1339 chandef.chan = chan;
1320 1340
1321 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1341 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1322 ssid, ssid_len, 100 + ie_len); 1342 ssid, ssid_len, 100 + ie_len);
@@ -1326,7 +1346,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1326 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1346 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1327 skb_tailroom(skb), 1347 skb_tailroom(skb),
1328 ie, ie_len, chan->band, 1348 ie, ie_len, chan->band,
1329 ratemask, chan_no); 1349 ratemask, &chandef);
1330 skb_put(skb, ies_len); 1350 skb_put(skb, ies_len);
1331 1351
1332 if (dst) { 1352 if (dst) {
@@ -1360,16 +1380,19 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1360 } 1380 }
1361} 1381}
1362 1382
1363u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1383u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
1364 struct ieee802_11_elems *elems, 1384 struct ieee802_11_elems *elems,
1365 enum ieee80211_band band, u32 *basic_rates) 1385 enum ieee80211_band band, u32 *basic_rates)
1366{ 1386{
1367 struct ieee80211_supported_band *sband; 1387 struct ieee80211_supported_band *sband;
1368 struct ieee80211_rate *bitrates; 1388 struct ieee80211_rate *bitrates;
1369 size_t num_rates; 1389 size_t num_rates;
1370 u32 supp_rates; 1390 u32 supp_rates, rate_flags;
1371 int i, j; 1391 int i, j, shift;
1372 sband = local->hw.wiphy->bands[band]; 1392 sband = sdata->local->hw.wiphy->bands[band];
1393
1394 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
1395 shift = ieee80211_vif_get_shift(&sdata->vif);
1373 1396
1374 if (WARN_ON(!sband)) 1397 if (WARN_ON(!sband))
1375 return 1; 1398 return 1;
@@ -1394,7 +1417,15 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1394 continue; 1417 continue;
1395 1418
1396 for (j = 0; j < num_rates; j++) { 1419 for (j = 0; j < num_rates; j++) {
1397 if (bitrates[j].bitrate == own_rate) { 1420 int brate;
1421 if ((rate_flags & sband->bitrates[j].flags)
1422 != rate_flags)
1423 continue;
1424
1425 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
1426 1 << shift);
1427
1428 if (brate == own_rate) {
1398 supp_rates |= BIT(j); 1429 supp_rates |= BIT(j);
1399 if (basic_rates && is_basic) 1430 if (basic_rates && is_basic)
1400 *basic_rates |= BIT(j); 1431 *basic_rates |= BIT(j);
@@ -2017,18 +2048,56 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
2017 cfg80211_chandef_create(chandef, control_chan, channel_type); 2048 cfg80211_chandef_create(chandef, control_chan, channel_type);
2018} 2049}
2019 2050
2051int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
2052 const struct ieee80211_supported_band *sband,
2053 const u8 *srates, int srates_len, u32 *rates)
2054{
2055 u32 rate_flags = ieee80211_chandef_rate_flags(chandef);
2056 int shift = ieee80211_chandef_get_shift(chandef);
2057 struct ieee80211_rate *br;
2058 int brate, rate, i, j, count = 0;
2059
2060 *rates = 0;
2061
2062 for (i = 0; i < srates_len; i++) {
2063 rate = srates[i] & 0x7f;
2064
2065 for (j = 0; j < sband->n_bitrates; j++) {
2066 br = &sband->bitrates[j];
2067 if ((rate_flags & br->flags) != rate_flags)
2068 continue;
2069
2070 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
2071 if (brate == rate) {
2072 *rates |= BIT(j);
2073 count++;
2074 break;
2075 }
2076 }
2077 }
2078 return count;
2079}
2080
2020int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 2081int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2021 struct sk_buff *skb, bool need_basic, 2082 struct sk_buff *skb, bool need_basic,
2022 enum ieee80211_band band) 2083 enum ieee80211_band band)
2023{ 2084{
2024 struct ieee80211_local *local = sdata->local; 2085 struct ieee80211_local *local = sdata->local;
2025 struct ieee80211_supported_band *sband; 2086 struct ieee80211_supported_band *sband;
2026 int rate; 2087 int rate, shift;
2027 u8 i, rates, *pos; 2088 u8 i, rates, *pos;
2028 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2089 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2090 u32 rate_flags;
2029 2091
2092 shift = ieee80211_vif_get_shift(&sdata->vif);
2093 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2030 sband = local->hw.wiphy->bands[band]; 2094 sband = local->hw.wiphy->bands[band];
2031 rates = sband->n_bitrates; 2095 rates = 0;
2096 for (i = 0; i < sband->n_bitrates; i++) {
2097 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2098 continue;
2099 rates++;
2100 }
2032 if (rates > 8) 2101 if (rates > 8)
2033 rates = 8; 2102 rates = 8;
2034 2103
@@ -2040,10 +2109,15 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2040 *pos++ = rates; 2109 *pos++ = rates;
2041 for (i = 0; i < rates; i++) { 2110 for (i = 0; i < rates; i++) {
2042 u8 basic = 0; 2111 u8 basic = 0;
2112 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2113 continue;
2114
2043 if (need_basic && basic_rates & BIT(i)) 2115 if (need_basic && basic_rates & BIT(i))
2044 basic = 0x80; 2116 basic = 0x80;
2045 rate = sband->bitrates[i].bitrate; 2117 rate = sband->bitrates[i].bitrate;
2046 *pos++ = basic | (u8) (rate / 5); 2118 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2119 5 * (1 << shift));
2120 *pos++ = basic | (u8) rate;
2047 } 2121 }
2048 2122
2049 return 0; 2123 return 0;
@@ -2055,12 +2129,22 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2055{ 2129{
2056 struct ieee80211_local *local = sdata->local; 2130 struct ieee80211_local *local = sdata->local;
2057 struct ieee80211_supported_band *sband; 2131 struct ieee80211_supported_band *sband;
2058 int rate; 2132 int rate, skip, shift;
2059 u8 i, exrates, *pos; 2133 u8 i, exrates, *pos;
2060 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2134 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2135 u32 rate_flags;
2136
2137 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2138 shift = ieee80211_vif_get_shift(&sdata->vif);
2061 2139
2062 sband = local->hw.wiphy->bands[band]; 2140 sband = local->hw.wiphy->bands[band];
2063 exrates = sband->n_bitrates; 2141 exrates = 0;
2142 for (i = 0; i < sband->n_bitrates; i++) {
2143 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2144 continue;
2145 exrates++;
2146 }
2147
2064 if (exrates > 8) 2148 if (exrates > 8)
2065 exrates -= 8; 2149 exrates -= 8;
2066 else 2150 else
@@ -2073,12 +2157,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2073 pos = skb_put(skb, exrates + 2); 2157 pos = skb_put(skb, exrates + 2);
2074 *pos++ = WLAN_EID_EXT_SUPP_RATES; 2158 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2075 *pos++ = exrates; 2159 *pos++ = exrates;
2160 skip = 0;
2076 for (i = 8; i < sband->n_bitrates; i++) { 2161 for (i = 8; i < sband->n_bitrates; i++) {
2077 u8 basic = 0; 2162 u8 basic = 0;
2163 if ((rate_flags & sband->bitrates[i].flags)
2164 != rate_flags)
2165 continue;
2166 if (skip++ < 8)
2167 continue;
2078 if (need_basic && basic_rates & BIT(i)) 2168 if (need_basic && basic_rates & BIT(i))
2079 basic = 0x80; 2169 basic = 0x80;
2080 rate = sband->bitrates[i].bitrate; 2170 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2081 *pos++ = basic | (u8) (rate / 5); 2171 5 * (1 << shift));
2172 *pos++ = basic | (u8) rate;
2082 } 2173 }
2083 } 2174 }
2084 return 0; 2175 return 0;
@@ -2162,9 +2253,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2162 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2253 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2163 } else { 2254 } else {
2164 struct ieee80211_supported_band *sband; 2255 struct ieee80211_supported_band *sband;
2256 int shift = 0;
2257 int bitrate;
2258
2259 if (status->flag & RX_FLAG_10MHZ)
2260 shift = 1;
2261 if (status->flag & RX_FLAG_5MHZ)
2262 shift = 2;
2165 2263
2166 sband = local->hw.wiphy->bands[status->band]; 2264 sband = local->hw.wiphy->bands[status->band];
2167 ri.legacy = sband->bitrates[status->rate_idx].bitrate; 2265 bitrate = sband->bitrates[status->rate_idx].bitrate;
2266 ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
2168 } 2267 }
2169 2268
2170 rate = cfg80211_calculate_bitrate(&ri); 2269 rate = cfg80211_calculate_bitrate(&ri);