You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmod-redhat-rtw89/SOURCES/0064-wifi-rtw89-add-HE-radi...

125 lines
4.6 KiB

From 77e1e15e7e995bfe5a34df7831f8772e4cd2a178 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
Date: Wed, 24 May 2023 15:00:30 +0200
Subject: [PATCH 064/142] wifi: rtw89: add HE radiotap for monitor mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bugzilla: https://bugzilla.redhat.com/2207499
commit 51e8ed4e44b5efcf8da2c1f3478e52120a12cdf8
Author: Ping-Ke Shih <pkshih@realtek.com>
Date: Fri Nov 25 15:24:15 2022 +0800
wifi: rtw89: add HE radiotap for monitor mode
With basic HE radiotap, we can check data rate in sniffer data. To store
the radiotap data, we reserve headroom of aligned 64 bytes, and then
update HE radiotap in monitor mode, so it doesn't affect performance in
normal mode.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221125072416.94752-3-pkshih@realtek.com
Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 22 ++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/core.h | 18 ++++++++++++++++++
drivers/net/wireless/realtek/rtw89/pci.c | 2 +-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 2db9eb6556565..3647998014408 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1480,6 +1480,27 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status)
rx_status->rate_idx -= 4;
}
+static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev,
+ struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status)
+{
+ static const struct ieee80211_radiotap_he known_he = {
+ .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
+ .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
+ };
+ struct ieee80211_radiotap_he *he;
+
+ if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR))
+ return;
+
+ if (rx_status->encoding == RX_ENC_HE) {
+ rx_status->flag |= RX_FLAG_RADIOTAP_HE;
+ he = skb_push(skb, sizeof(*he));
+ *he = known_he;
+ }
+}
+
static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct rtw89_rx_desc_info *desc_info,
@@ -1494,6 +1515,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
rtw89_core_hw_to_sband_rate(rx_status);
rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu);
+ rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
/* In low power mode, it does RX in thread context. */
local_bh_disable();
ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, napi);
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 1b0acb1c5450e..0be8f7bd3ca2d 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -35,6 +35,7 @@ extern const struct ieee80211_ops rtw89_ops;
#define RSSI_FACTOR 1
#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI)
#define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR)
+#define RTW89_RADIOTAP_ROOM ALIGN(sizeof(struct ieee80211_radiotap_he), 64)
#define RTW89_HTC_MASK_VARIANT GENMASK(1, 0)
#define RTW89_HTC_VARIANT_HE 3
@@ -4383,6 +4384,23 @@ static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev,
return &fw_info->normal;
}
+static inline struct sk_buff *rtw89_alloc_skb_for_rx(struct rtw89_dev *rtwdev,
+ unsigned int length)
+{
+ struct sk_buff *skb;
+
+ if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) {
+ skb = dev_alloc_skb(length + RTW89_RADIOTAP_ROOM);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, RTW89_RADIOTAP_ROOM);
+ return skb;
+ }
+
+ return dev_alloc_skb(length);
+}
+
int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel);
int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 7aa0af18cdd50..1c4500ba777c6 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -267,7 +267,7 @@ static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev,
rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size);
- new = dev_alloc_skb(desc_info->pkt_size);
+ new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size);
if (!new)
goto err_sync_device;
--
2.13.6