|
@@ -193,7 +193,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|
|
pos++;
|
|
|
|
|
|
/* IEEE80211_RADIOTAP_RATE */
|
|
|
- if (!rate || status->flag & RX_FLAG_HT) {
|
|
|
+ if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
|
|
|
/*
|
|
|
* Without rate information don't add it. If we have,
|
|
|
* MCS information is a separate field in radiotap,
|
|
@@ -213,7 +213,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|
|
if (status->band == IEEE80211_BAND_5GHZ)
|
|
|
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
|
|
|
pos);
|
|
|
- else if (status->flag & RX_FLAG_HT)
|
|
|
+ else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
|
|
put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
|
|
|
pos);
|
|
|
else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
|
|
@@ -1356,6 +1356,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|
|
if (ieee80211_is_data(hdr->frame_control)) {
|
|
|
sta->last_rx_rate_idx = status->rate_idx;
|
|
|
sta->last_rx_rate_flag = status->flag;
|
|
|
+ sta->last_rx_rate_vht_nss = status->vht_nss;
|
|
|
}
|
|
|
}
|
|
|
} else if (!is_multicast_ether_addr(hdr->addr1)) {
|
|
@@ -1367,6 +1368,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|
|
if (ieee80211_is_data(hdr->frame_control)) {
|
|
|
sta->last_rx_rate_idx = status->rate_idx;
|
|
|
sta->last_rx_rate_flag = status->flag;
|
|
|
+ sta->last_rx_rate_vht_nss = status->vht_nss;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2710,7 +2712,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
|
|
status = IEEE80211_SKB_RXCB((rx->skb));
|
|
|
|
|
|
sband = rx->local->hw.wiphy->bands[status->band];
|
|
|
- if (!(status->flag & RX_FLAG_HT))
|
|
|
+ if (!(status->flag & RX_FLAG_HT) &&
|
|
|
+ !(status->flag & RX_FLAG_VHT))
|
|
|
rate = &sband->bitrates[status->rate_idx];
|
|
|
|
|
|
ieee80211_rx_cooked_monitor(rx, rate);
|
|
@@ -2877,8 +2880,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
|
|
status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
} else if (!rx->sta) {
|
|
|
int rate_idx;
|
|
|
- if (status->flag & RX_FLAG_HT)
|
|
|
- rate_idx = 0; /* TODO: HT rates */
|
|
|
+ if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
|
|
+ rate_idx = 0; /* TODO: HT/VHT rates */
|
|
|
else
|
|
|
rate_idx = status->rate_idx;
|
|
|
ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2,
|
|
@@ -3154,6 +3157,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
|
status->rate_idx,
|
|
|
status->rate_idx))
|
|
|
goto drop;
|
|
|
+ } else if (status->flag & RX_FLAG_VHT) {
|
|
|
+ if (WARN_ONCE(status->rate_idx > 9 ||
|
|
|
+ !status->vht_nss ||
|
|
|
+ status->vht_nss > 8,
|
|
|
+ "Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
|
|
|
+ status->rate_idx, status->vht_nss))
|
|
|
+ goto drop;
|
|
|
} else {
|
|
|
if (WARN_ON(status->rate_idx >= sband->n_bitrates))
|
|
|
goto drop;
|