summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorKuan-Chung Chen <damon.chen@realtek.com>2022-09-22 04:27:19 +0300
committerKalle Valo <kvalo@kernel.org>2022-09-24 15:37:02 +0300
commit8d540f9d29162e273797bef36686a010724f0f8a (patch)
tree8a9ff0206e86877455c3968a312540651304e4ab /drivers/net/wireless
parentf4a43c3b95a0c422cea5dea2e0377728e8ea4475 (diff)
downloadlinux-8d540f9d29162e273797bef36686a010724f0f8a.tar.xz
wifi: rtw89: disable 26-tone RU HE TB PPDU transmissions
Align with the spec of 802.11ax, follow the conditions for not responding with an HE TB PPDU. When there are OBSS that cannot interpret 26-tone RU transmissions, we should disable such transmissions. Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220922012719.15037-1-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c44
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c1
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index d5a2e30a4ba0..6f2fba6c32bf 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3703,6 +3703,50 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
return 0;
}
+static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
+ struct cfg80211_bss *bss,
+ void *data)
+{
+ const struct cfg80211_bss_ies *ies;
+ const struct element *elem;
+ bool *tolerated = data;
+
+ rcu_read_lock();
+ ies = rcu_dereference(bss->ies);
+ elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
+ ies->len);
+
+ if (!elem || elem->datalen < 10 ||
+ !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
+ *tolerated = false;
+ rcu_read_unlock();
+}
+
+void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif)
+{
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_hw *hw = rtwdev->hw;
+ bool tolerated = true;
+ u32 reg;
+
+ if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION)
+ return;
+
+ if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR))
+ return;
+
+ cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
+ rtw89_mac_check_he_obss_narrow_bw_ru_iter,
+ &tolerated);
+
+ reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, rtwvif->mac_idx);
+ if (tolerated)
+ rtw89_write32_clr(rtwdev, reg, B_AX_RXTRIG_RU26_DIS);
+ else
+ rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_RU26_DIS);
+}
+
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
int ret;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 9cb5d20e6e33..5d1bb00a0fd2 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -801,6 +801,8 @@ int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val);
int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val);
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index cf70570087bf..a296bfa8188f 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -379,6 +379,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif);
+ rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
rtw89_store_op_chan(rtwdev, true);
} else {
/* Abort ongoing scan if cancel_scan isn't issued