Loading include/net/mac80211.h +11 −1 Original line number Diff line number Diff line Loading @@ -717,7 +717,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * (including FCS) was received. * @RX_FLAG_SHORTPRE: Short preamble was used for this frame * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_80MHZ: 80 MHz was used * @RX_FLAG_80P80MHZ: 80+80 MHz was used * @RX_FLAG_160MHZ: 160 MHz was used * @RX_FLAG_SHORT_GI: Short guard interval was used * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. * Valid only for data frames (mainly A-MPDU) Loading Loading @@ -760,6 +764,10 @@ enum mac80211_rx_flags { RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19), RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20), RX_FLAG_MACTIME_END = BIT(21), RX_FLAG_VHT = BIT(22), RX_FLAG_80MHZ = BIT(23), RX_FLAG_80P80MHZ = BIT(24), RX_FLAG_160MHZ = BIT(25), }; /** Loading @@ -780,7 +788,8 @@ enum mac80211_rx_flags { * @IEEE80211_HW_SIGNAL_* * @antenna: antenna used * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) * @vht_nss: number of streams (VHT only) * @flag: %RX_FLAG_* * @rx_flags: internal RX flags for mac80211 * @ampdu_reference: A-MPDU reference number, must be a different value for Loading @@ -803,6 +812,7 @@ struct ieee80211_rx_status { u16 vendor_radiotap_len; u16 freq; u8 rate_idx; u8 vht_nss; u8 rx_flags; u8 band; u8 antenna; Loading net/mac80211/cfg.c +23 −3 Original line number Diff line number Diff line Loading @@ -374,7 +374,8 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in { enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata); if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { if (!(rate->flags & RATE_INFO_FLAGS_MCS) && !(rate->flags & RATE_INFO_FLAGS_VHT_MCS)) { struct ieee80211_supported_band *sband; sband = sta->local->hw.wiphy->bands[band]; rate->legacy = sband->bitrates[idx].bitrate; Loading Loading @@ -444,13 +445,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); sinfo->rxrate.flags = 0; if (sta->last_rx_rate_flag & RX_FLAG_HT) if (sta->last_rx_rate_flag & RX_FLAG_HT) { sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS; sinfo->rxrate.mcs = sta->last_rx_rate_idx; } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) { sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS; sinfo->rxrate.nss = sta->last_rx_rate_vht_nss; sinfo->rxrate.mcs = sta->last_rx_rate_idx; } else { struct ieee80211_supported_band *sband; sband = sta->local->hw.wiphy->bands[ ieee80211_get_sdata_band(sta->sdata)]; sinfo->rxrate.legacy = sband->bitrates[sta->last_rx_rate_idx].bitrate; } if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx); if (sta->last_rx_rate_flag & RX_FLAG_80MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_160MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH Loading net/mac80211/rx.c +15 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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) Loading Loading @@ -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)) { Loading @@ -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; } } Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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; Loading net/mac80211/sta_info.h +3 −1 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ struct sta_ampdu_mlme { * "the" transmit rate * @last_rx_rate_idx: rx status rate index of the last data packet * @last_rx_rate_flag: rx status flag of the last data packet * @last_rx_rate_vht_nss: rx status nss of last data packet * @lock: used for locking all fields that require locking, see comments * in the header file. * @drv_unblock_wk: used for driver PS unblocking Loading Loading @@ -343,7 +344,8 @@ struct sta_info { unsigned long tx_fragments; struct ieee80211_tx_rate last_tx_rate; int last_rx_rate_idx; int last_rx_rate_flag; u32 last_rx_rate_flag; u8 last_rx_rate_vht_nss; u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; /* Loading net/mac80211/util.c +14 −0 Original line number Diff line number Diff line Loading @@ -2069,6 +2069,20 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (status->flag & RX_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; } else if (status->flag & RX_FLAG_VHT) { ri.flags |= RATE_INFO_FLAGS_VHT_MCS; ri.mcs = status->rate_idx; ri.nss = status->vht_nss; if (status->flag & RX_FLAG_40MHZ) ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (status->flag & RX_FLAG_80MHZ) ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; if (status->flag & RX_FLAG_80P80MHZ) ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; if (status->flag & RX_FLAG_160MHZ) ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; if (status->flag & RX_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; } else { struct ieee80211_supported_band *sband; Loading Loading
include/net/mac80211.h +11 −1 Original line number Diff line number Diff line Loading @@ -717,7 +717,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * (including FCS) was received. * @RX_FLAG_SHORTPRE: Short preamble was used for this frame * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_80MHZ: 80 MHz was used * @RX_FLAG_80P80MHZ: 80+80 MHz was used * @RX_FLAG_160MHZ: 160 MHz was used * @RX_FLAG_SHORT_GI: Short guard interval was used * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. * Valid only for data frames (mainly A-MPDU) Loading Loading @@ -760,6 +764,10 @@ enum mac80211_rx_flags { RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19), RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20), RX_FLAG_MACTIME_END = BIT(21), RX_FLAG_VHT = BIT(22), RX_FLAG_80MHZ = BIT(23), RX_FLAG_80P80MHZ = BIT(24), RX_FLAG_160MHZ = BIT(25), }; /** Loading @@ -780,7 +788,8 @@ enum mac80211_rx_flags { * @IEEE80211_HW_SIGNAL_* * @antenna: antenna used * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) * @vht_nss: number of streams (VHT only) * @flag: %RX_FLAG_* * @rx_flags: internal RX flags for mac80211 * @ampdu_reference: A-MPDU reference number, must be a different value for Loading @@ -803,6 +812,7 @@ struct ieee80211_rx_status { u16 vendor_radiotap_len; u16 freq; u8 rate_idx; u8 vht_nss; u8 rx_flags; u8 band; u8 antenna; Loading
net/mac80211/cfg.c +23 −3 Original line number Diff line number Diff line Loading @@ -374,7 +374,8 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in { enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata); if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { if (!(rate->flags & RATE_INFO_FLAGS_MCS) && !(rate->flags & RATE_INFO_FLAGS_VHT_MCS)) { struct ieee80211_supported_band *sband; sband = sta->local->hw.wiphy->bands[band]; rate->legacy = sband->bitrates[idx].bitrate; Loading Loading @@ -444,13 +445,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); sinfo->rxrate.flags = 0; if (sta->last_rx_rate_flag & RX_FLAG_HT) if (sta->last_rx_rate_flag & RX_FLAG_HT) { sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS; sinfo->rxrate.mcs = sta->last_rx_rate_idx; } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) { sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS; sinfo->rxrate.nss = sta->last_rx_rate_vht_nss; sinfo->rxrate.mcs = sta->last_rx_rate_idx; } else { struct ieee80211_supported_band *sband; sband = sta->local->hw.wiphy->bands[ ieee80211_get_sdata_band(sta->sdata)]; sinfo->rxrate.legacy = sband->bitrates[sta->last_rx_rate_idx].bitrate; } if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx); if (sta->last_rx_rate_flag & RX_FLAG_80MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; if (sta->last_rx_rate_flag & RX_FLAG_160MHZ) sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH Loading
net/mac80211/rx.c +15 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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) Loading Loading @@ -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)) { Loading @@ -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; } } Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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; Loading
net/mac80211/sta_info.h +3 −1 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ struct sta_ampdu_mlme { * "the" transmit rate * @last_rx_rate_idx: rx status rate index of the last data packet * @last_rx_rate_flag: rx status flag of the last data packet * @last_rx_rate_vht_nss: rx status nss of last data packet * @lock: used for locking all fields that require locking, see comments * in the header file. * @drv_unblock_wk: used for driver PS unblocking Loading Loading @@ -343,7 +344,8 @@ struct sta_info { unsigned long tx_fragments; struct ieee80211_tx_rate last_tx_rate; int last_rx_rate_idx; int last_rx_rate_flag; u32 last_rx_rate_flag; u8 last_rx_rate_vht_nss; u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; /* Loading
net/mac80211/util.c +14 −0 Original line number Diff line number Diff line Loading @@ -2069,6 +2069,20 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (status->flag & RX_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; } else if (status->flag & RX_FLAG_VHT) { ri.flags |= RATE_INFO_FLAGS_VHT_MCS; ri.mcs = status->rate_idx; ri.nss = status->vht_nss; if (status->flag & RX_FLAG_40MHZ) ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; if (status->flag & RX_FLAG_80MHZ) ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; if (status->flag & RX_FLAG_80P80MHZ) ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; if (status->flag & RX_FLAG_160MHZ) ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; if (status->flag & RX_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; } else { struct ieee80211_supported_band *sband; Loading