diff options
-rw-r--r-- | include/net/mac80211.h | 36 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 41 |
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 | */ |
561 | struct ieee80211_tx_rate { | 569 | struct 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 | |||
577 | static 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 | |||
585 | static inline u8 | ||
586 | ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate) | ||
587 | { | ||
588 | return rate->idx & 0xF; | ||
589 | } | ||
590 | |||
591 | static inline u8 | ||
592 | ieee80211_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 | ||
373 | static 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 | |||
386 | void sta_set_rate_info_tx(struct sta_info *sta, | 373 | void 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 | ||
400 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 401 | static 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); |