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.
125 lines
4.6 KiB
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
|
|
|