aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-09 12:38:32 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-26 06:43:00 -0500
commit8bc83c24638b72421e783b96b5a05c1f4109a51d (patch)
tree883e8d2a22889f3394a44b9e34a713a752198ed0
parent5614618ec498320e3b686fea246e50b833865c34 (diff)
mac80211: support VHT rates in TX info
To achieve this, limit the number of retries to 31 (instead of 255) and use the three bits that are then free for VHT flags. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h36
-rw-r--r--net/mac80211/cfg.c41
2 files changed, 57 insertions, 20 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 598ea215fc3..db7680acd0d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -499,9 +499,14 @@ enum mac80211_tx_control_flags {
499 * This is set if the current BSS requires ERP protection. 499 * This is set if the current BSS requires ERP protection.
500 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. 500 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
501 * @IEEE80211_TX_RC_MCS: HT rate. 501 * @IEEE80211_TX_RC_MCS: HT rate.
502 * @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split
503 * into a higher 4 bits (Nss) and lower 4 bits (MCS number)
502 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in 504 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in
503 * Greenfield mode. 505 * Greenfield mode.
504 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz. 506 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz.
507 * @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
508 * @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
509 * (80+80 isn't supported yet)
505 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the 510 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the
506 * adjacent 20 MHz channels, if the current channel type is 511 * adjacent 20 MHz channels, if the current channel type is
507 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. 512 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
@@ -512,12 +517,15 @@ enum mac80211_rate_control_flags {
512 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), 517 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1),
513 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), 518 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
514 519
515 /* rate index is an MCS rate number instead of an index */ 520 /* rate index is an HT/VHT MCS instead of an index */
516 IEEE80211_TX_RC_MCS = BIT(3), 521 IEEE80211_TX_RC_MCS = BIT(3),
517 IEEE80211_TX_RC_GREEN_FIELD = BIT(4), 522 IEEE80211_TX_RC_GREEN_FIELD = BIT(4),
518 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), 523 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5),
519 IEEE80211_TX_RC_DUP_DATA = BIT(6), 524 IEEE80211_TX_RC_DUP_DATA = BIT(6),
520 IEEE80211_TX_RC_SHORT_GI = BIT(7), 525 IEEE80211_TX_RC_SHORT_GI = BIT(7),
526 IEEE80211_TX_RC_VHT_MCS = BIT(8),
527 IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9),
528 IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10),
521}; 529};
522 530
523 531
@@ -560,10 +568,32 @@ enum mac80211_rate_control_flags {
560 */ 568 */
561struct ieee80211_tx_rate { 569struct ieee80211_tx_rate {
562 s8 idx; 570 s8 idx;
563 u8 count; 571 u16 count:5,
564 u8 flags; 572 flags:11;
565} __packed; 573} __packed;
566 574
575#define IEEE80211_MAX_TX_RETRY 31
576
577static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate,
578 u8 mcs, u8 nss)
579{
580 WARN_ON(mcs & ~0xF);
581 WARN_ON(nss & ~0x7);
582 rate->idx = (nss << 4) | mcs;
583}
584
585static inline u8
586ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate)
587{
588 return rate->idx & 0xF;
589}
590
591static inline u8
592ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
593{
594 return rate->idx >> 4;
595}
596
567/** 597/**
568 * struct ieee80211_tx_info - skb transmit information 598 * struct ieee80211_tx_info - skb transmit information
569 * 599 *
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 0b9de4fa54a..5d30e5f57ff 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -370,31 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
370 return 0; 370 return 0;
371} 371}
372 372
373static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
374{
375 enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
376
377 if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
378 !(rate->flags & RATE_INFO_FLAGS_VHT_MCS)) {
379 struct ieee80211_supported_band *sband;
380 sband = sta->local->hw.wiphy->bands[band];
381 rate->legacy = sband->bitrates[idx].bitrate;
382 } else
383 rate->mcs = idx;
384}
385
386void sta_set_rate_info_tx(struct sta_info *sta, 373void sta_set_rate_info_tx(struct sta_info *sta,
387 const struct ieee80211_tx_rate *rate, 374 const struct ieee80211_tx_rate *rate,
388 struct rate_info *rinfo) 375 struct rate_info *rinfo)
389{ 376{
390 rinfo->flags = 0; 377 rinfo->flags = 0;
391 if (rate->flags & IEEE80211_TX_RC_MCS) 378 if (rate->flags & IEEE80211_TX_RC_MCS) {
392 rinfo->flags |= RATE_INFO_FLAGS_MCS; 379 rinfo->flags |= RATE_INFO_FLAGS_MCS;
380 rinfo->mcs = rate->idx;
381 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
382 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
383 rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
384 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
385 } else {
386 struct ieee80211_supported_band *sband;
387 sband = sta->local->hw.wiphy->bands[
388 ieee80211_get_sdata_band(sta->sdata)];
389 rinfo->legacy = sband->bitrates[rate->idx].bitrate;
390 }
393 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 391 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
394 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 392 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
393 if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
394 rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
395 if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
396 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
395 if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 397 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
396 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; 398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
397 rate_idx_to_bitrate(rinfo, sta, rate->idx);
398} 399}
399 400
400static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 401static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
@@ -2003,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2003 return err; 2004 return err;
2004 } 2005 }
2005 2006
2006 if (changed & WIPHY_PARAM_RETRY_SHORT) 2007 if (changed & WIPHY_PARAM_RETRY_SHORT) {
2008 if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
2009 return -EINVAL;
2007 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 2010 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
2008 if (changed & WIPHY_PARAM_RETRY_LONG) 2011 }
2012 if (changed & WIPHY_PARAM_RETRY_LONG) {
2013 if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
2014 return -EINVAL;
2009 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 2015 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
2016 }
2010 if (changed & 2017 if (changed &
2011 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) 2018 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
2012 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 2019 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);