diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-07-08 10:55:53 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-16 02:58:06 -0400 |
commit | 2103dec14792be2c2194a454630b01120d30e5cb (patch) | |
tree | 6bc0cd39eb2fe5317f0383ed7c4c238fb98ec114 /net/mac80211/cfg.c | |
parent | a5e70697d0c4836e69c60de92db27eac9ae71e05 (diff) |
mac80211: select and adjust bitrates according to channel mode
The various components accessing the bitrates table must use consider
the used channel bandwidth to select only available rates or calculate
the bitrate correctly.
There are some rates in reduced bandwidth modes which can't be
represented as multiples of 500kbps, like 2.25 MBit/s in 5 MHz mode. The
standard suggests to round up to the next multiple of 500kbps, just do
that in mac80211 as well.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
[make rate unsigned in ieee80211_add_tx_radiotap_header(), squash fix]
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 45 |
1 files changed, 18 insertions, 27 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 | ||