aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl Beldan <karl.beldan@rivierawaves.com>2013-04-15 12:28:21 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-04-16 09:59:08 -0400
commitfbd647b17689d584748bad62395cd1161d42d37c (patch)
treebd513410018d31ec19d764aa8a22ca147512edcb
parent7a7da6ee0ea3443cd5111adffa80a3daba4bb8df (diff)
mac80211: fix rate control tx handler for VHT rates
Handle VHT rates like HT ones, otherwise we easily trigger the pre-HT rates WARN_ON(rc_rate->idx >= sband->n_bitrates) which will set rc_rate->idx to -1. Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/tx.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c93483fd477e..bb82c873f774 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -742,16 +742,18 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
742 } 742 }
743 743
744 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 744 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
745 struct ieee80211_tx_rate *rc_rate = &info->control.rates[i];
746
745 /* 747 /*
746 * make sure there's no valid rate following 748 * make sure there's no valid rate following
747 * an invalid one, just in case drivers don't 749 * an invalid one, just in case drivers don't
748 * take the API seriously to stop at -1. 750 * take the API seriously to stop at -1.
749 */ 751 */
750 if (inval) { 752 if (inval) {
751 info->control.rates[i].idx = -1; 753 rc_rate->idx = -1;
752 continue; 754 continue;
753 } 755 }
754 if (info->control.rates[i].idx < 0) { 756 if (rc_rate->idx < 0) {
755 inval = true; 757 inval = true;
756 continue; 758 continue;
757 } 759 }
@@ -760,36 +762,37 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
760 * For now assume MCS is already set up correctly, this 762 * For now assume MCS is already set up correctly, this
761 * needs to be fixed. 763 * needs to be fixed.
762 */ 764 */
763 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) { 765 if (rc_rate->flags & IEEE80211_TX_RC_MCS) {
764 WARN_ON(info->control.rates[i].idx > 76); 766 WARN_ON(rc_rate->idx > 76);
767 continue;
768 }
769
770 if (rc_rate->flags & IEEE80211_TX_RC_VHT_MCS) {
771 WARN_ON(ieee80211_rate_get_vht_mcs(rc_rate) > 9);
765 continue; 772 continue;
766 } 773 }
767 774
768 /* set up RTS protection if desired */ 775 /* set up RTS protection if desired */
769 if (rts) 776 if (rts)
770 info->control.rates[i].flags |= 777 rc_rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
771 IEEE80211_TX_RC_USE_RTS_CTS;
772 778
773 /* RC is busted */ 779 /* RC is busted */
774 if (WARN_ON_ONCE(info->control.rates[i].idx >= 780 if (WARN_ON_ONCE(rc_rate->idx >= sband->n_bitrates)) {
775 sband->n_bitrates)) { 781 rc_rate->idx = -1;
776 info->control.rates[i].idx = -1;
777 continue; 782 continue;
778 } 783 }
779 784
780 rate = &sband->bitrates[info->control.rates[i].idx]; 785 rate = &sband->bitrates[rc_rate->idx];
781 786
782 /* set up short preamble */ 787 /* set up short preamble */
783 if (short_preamble && 788 if (short_preamble &&
784 rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 789 rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
785 info->control.rates[i].flags |= 790 rc_rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
786 IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
787 791
788 /* set up G protection */ 792 /* set up G protection */
789 if (!rts && tx->sdata->vif.bss_conf.use_cts_prot && 793 if (!rts && tx->sdata->vif.bss_conf.use_cts_prot &&
790 rate->flags & IEEE80211_RATE_ERP_G) 794 rate->flags & IEEE80211_RATE_ERP_G)
791 info->control.rates[i].flags |= 795 rc_rate->flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
792 IEEE80211_TX_RC_USE_CTS_PROTECT;
793 } 796 }
794 797
795 return TX_CONTINUE; 798 return TX_CONTINUE;