aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 598ea215fc3b..db7680acd0da 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 0b9de4fa54a6..5d30e5f57ff0 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);