diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/rx.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rx.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c index 84aedabdf285..66f9419588cf 100644 --- a/drivers/net/wireless/realtek/rtw88/rx.c +++ b/drivers/net/wireless/realtek/rtw88/rx.c @@ -146,6 +146,47 @@ static void rtw_set_rx_freq_by_pktstat(struct rtw_rx_pkt_stat *pkt_stat, rx_status->band = pkt_stat->band; } +void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + int channel = rtwdev->hal.current_channel; + size_t hdr_len, ielen; + int channel_number; + u8 *variable; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + goto fill_rx_status; + + if (ieee80211_is_beacon(mgmt->frame_control)) { + variable = mgmt->u.beacon.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { + variable = mgmt->u.probe_resp.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + } else { + goto fill_rx_status; + } + + if (skb->len > hdr_len) + ielen = skb->len - hdr_len; + else + goto fill_rx_status; + + channel_number = cfg80211_get_ies_channel_number(variable, ielen, + NL80211_BAND_2GHZ); + if (channel_number != -1) + channel = channel_number; + +fill_rx_status: + rtw_set_rx_freq_band(pkt_stat, channel); + rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); +} +EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); + void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, struct rtw_rx_pkt_stat *pkt_stat, struct ieee80211_hdr *hdr, |