aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/status.c
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2013-07-08 10:55:53 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-07-16 02:58:06 -0400
commit2103dec14792be2c2194a454630b01120d30e5cb (patch)
tree6bc0cd39eb2fe5317f0383ed7c4c238fb98ec114 /net/mac80211/status.c
parenta5e70697d0c4836e69c60de92db27eac9ae71e05 (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/status.c')
-rw-r--r--net/mac80211/status.c18
1 files changed, 13 insertions, 5 deletions
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);