* [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support
@ 2026-11-15 11:43 Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
` (6 more replies)
0 siblings, 7 replies; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
This series enables HT STBC transmission, VHT SU beamformed reception
and carrier-frequency-offset correction on supported 88xxA devices.
Tested on RTL8812AU:
TX went from 136.0 to 144.2.
RX went from 215.5 to 249.2.
Changelog v4:
- Restore "wifi: rtw88: correctly expose beamformee capabilities"
- Add a patch to skip the dynamic CSI rate on chips without a
cfg_csi_rate op.
- Describe magic numbers
- Link to v3: https://lore.kernel.org/linux-wireless/20261112173246.3201729-1-hjf3108@gmail.com/
Changelog v3:
- Remove EDCCA commits since it causes problems in some situations
- Beamformee: gate on spatial streams instead of the RX antennas,
in case an antenna is disabled
- Beamformee: writes RTL8814A use rtw_write32_mask() instead of
an unaligned 16-bit write
- Beamformee: drop the chip ID from the debug message, style fixes
- CFO: add RTW_XCAP_MASK to phy.h
- CFO: use 0x20 as the RTL8814A crystal cap when the efuse is empty,
following the vendor driver
- CFO: add comment on why min(...,2) is needed for rtl8814
- A-MPDU: set BIT(31) of REG_AMPDU_MAX_LENGTH, like the vendor driver
- A-MPDU: limit RTL8821A with IEEE80211_VHT_MAX_AMPDU_64K
- Link to v2: https://lore.kernel.org/linux-wireless/20261031070950.425176-1-hjf3108@gmail.com/
Changelog v2:
- Split correcting beamform caps into its own commit
- Adjust EDCCA threshold on scan to avoid high latency
- Link to v1: https://lore.kernel.org/linux-wireless/20261029055212.84711-1-hjf3108@gmail.com/
Ho Jie Feng (7):
wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions
wifi: rtw88: skip the dynamic CSI rate without a cfg_csi_rate op
wifi: rtw88: correctly expose beamformee capabilities
wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions
wifi: rtw88: prepare frequency-offset correction for more chips
wifi: rtw88: 88xxa: correct carrier-frequency offset
wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits
drivers/net/wireless/realtek/rtw88/bf.h | 7 +
drivers/net/wireless/realtek/rtw88/main.c | 17 ++-
drivers/net/wireless/realtek/rtw88/phy.c | 109 +++++++++++++++-
drivers/net/wireless/realtek/rtw88/phy.h | 8 ++
drivers/net/wireless/realtek/rtw88/reg.h | 1 +
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 17 ++-
drivers/net/wireless/realtek/rtw88/rtw8814a.c | 75 ++++++++++-
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 16 ++-
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 100 +--------------
drivers/net/wireless/realtek/rtw88/rtw8822c.h | 3 -
drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 120 ++++++++++++++++--
drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 3 +
12 files changed, 353 insertions(+), 123 deletions(-)
base-commit: 61a5eb87b2d9b4d5e353780b781cf691f39ba9e1
--
2.53.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 13:35 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 2/7] wifi: rtw88: skip the dynamic CSI rate without a cfg_csi_rate op Ho Jie Feng
` (5 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
8812a and 8814a support STBC, enable it.
8822c will lose reporting TX STBC capability if efuse reports
only 1 path, but this is correct, since in that case it doesn't
actually support STBC.
Tested on RTL8812AU, STBC packets were captured in monitor mode.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8814a.c | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index f7708ad17b..e243738809 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1583,7 +1583,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
if (rtw_chip_has_rx_ldpc(rtwdev))
ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
- if (rtw_chip_has_tx_stbc(rtwdev))
+ if (rtw_chip_has_tx_stbc(rtwdev) && rtwdev->hal.rf_path_num > 1)
ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40))
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
index 781b66ccde..55f1d3d324 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -1077,6 +1077,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = {
.rfe_defs = rtw8812a_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs),
.rx_ldpc = false,
+ .tx_stbc = true,
.amsdu_in_ampdu = true,
.hw_feature_report = false,
.c2h_ra_report_size = 4,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
index b6916d3dc6..e35c57c9d1 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8814a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
@@ -2200,6 +2200,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = {
.txgi_factor = 1,
.is_pwr_by_rate_dec = true,
.rx_ldpc = true,
+ .tx_stbc = true,
.max_power_index = 0x3f,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
.amsdu_in_ampdu = false, /* RX speed is better without AMSDU */
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 2/7] wifi: rtw88: skip the dynamic CSI rate without a cfg_csi_rate op
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
` (4 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
rtw_dynamic_csi_rate() runs from the watchdog for each vif that is a
SU or MU beamformee. new_csi_rate_idx is only written by the
cfg_csi_rate chip op, so on a chip without that op such as 88xxa,
an uninitialized value is compared with cur_csi_rpt_rate.
Return early when the chip has no cfg_csi_rate op.
Suggested-by: Luka Gejak <luka.gejak@linux.dev>
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index e243738809..a8a603aaee 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -174,6 +174,9 @@ static void rtw_dynamic_csi_rate(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
u8 fix_rate_enable = 0;
u8 new_csi_rate_idx;
+ if (!rtwdev->chip->ops->cfg_csi_rate)
+ return;
+
if (rtwvif->bfee.role != RTW_BFEE_SU &&
rtwvif->bfee.role != RTW_BFEE_MU)
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 2/7] wifi: rtw88: skip the dynamic CSI rate without a cfg_csi_rate op Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
` (2 more replies)
2026-11-15 11:43 ` [PATCH rtw-next v4 4/7] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions Ho Jie Feng
` (3 subsequent siblings)
6 siblings, 3 replies; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
Make MU and SU capability flags each depend on the chip declared
maximum instead of setting both flags together.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index a8a603aaee..b0c338954b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1606,6 +1606,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
struct ieee80211_sta_vht_cap *vht_cap)
{
+ const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_efuse *efuse = &rtwdev->efuse;
u16 mcs_map = 0;
__le16 highest;
@@ -1624,10 +1625,13 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
0;
if (rtwdev->hal.rf_path_num > 1)
vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
- vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
- IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
- vht_cap->cap |= (rtwdev->hal.bfee_sts_cap <<
- IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
+ if (rtw_bf_support && chip->bfer_su_max_num) {
+ vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+ vht_cap->cap |= rtwdev->hal.bfee_sts_cap <<
+ IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
+ }
+ if (rtw_bf_support && chip->bfer_mu_max_num)
+ vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
if (rtw_chip_has_rx_ldpc(rtwdev))
vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 4/7] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
` (2 preceding siblings ...)
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips Ho Jie Feng
` (2 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
Implement beamformee support for 88xxa since they have
support for it.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/bf.h | 7 ++
drivers/net/wireless/realtek/rtw88/reg.h | 1 +
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 3 +-
drivers/net/wireless/realtek/rtw88/rtw8814a.c | 42 ++++++++++-
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 3 +-
drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 73 +++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 2 +
7 files changed, 126 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/bf.h b/drivers/net/wireless/realtek/rtw88/bf.h
index a5d3010e6b..3a53e69d01 100644
--- a/drivers/net/wireless/realtek/rtw88/bf.h
+++ b/drivers/net/wireless/realtek/rtw88/bf.h
@@ -12,9 +12,16 @@
#define REG_ASSOCIATED_BFMER0_INFO 0x06E4
#define REG_ASSOCIATED_BFMER1_INFO 0x06EC
#define REG_TX_CSI_RPT_PARAM_BW20 0x06F4
+#define REG_TX_CSI_RPT_PARAM_BW40 0x06F8
+#define REG_TX_CSI_RPT_PARAM_BW80 0x06FC
#define REG_SND_PTCL_CTRL 0x0718
+#define BIT_USE_NSTS BIT(7)
#define BIT_DIS_CHK_VHTSIGB_CRC BIT(6)
#define BIT_DIS_CHK_VHTSIGA_CRC BIT(5)
+#define BIT_BFPARAM_SEL BIT(4)
+#define BIT_CSISEQ_SEL BIT(3)
+#define BIT_HT_NDPA_EN BIT(1)
+#define BIT_VHT_NDPA_EN BIT(0)
#define BIT_MASK_BEAMFORM (GENMASK(4, 0) | BIT(7))
#define REG_MU_TX_CTL 0x14C0
#define REG_MU_STA_GID_VLD 0x14C4
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index afcdb66fdb..f8ec1e2931 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -671,6 +671,7 @@
#define REG_IQK_COM96 0x0984
#define REG_FAS 0x09a4
+#define REG_CSI_CONTENT_VALUE 0x09b4
#define REG_RXSB 0x0a00
#define BIT_RXSB_ANA_DIV BIT(15)
#define REG_CCK_RX 0x0a04
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
index 55f1d3d324..5d58dff4fc 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -931,7 +931,7 @@ static const struct rtw_chip_ops rtw8812a_ops = {
.phy_calibration = rtw8812a_phy_calibration,
.cck_pd_set = rtw_phy_cck_pd_set,
.pwr_track = rtw8812a_pwr_track,
- .config_bfee = NULL,
+ .config_bfee = rtw88xxa_bf_config_bfee,
.set_gid_table = NULL,
.cfg_csi_rate = NULL,
.led_set = rtw8812a_led_set,
@@ -1084,6 +1084,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = {
.old_datarate_fb_limit = true,
.usb_tx_agg_desc_num = 1,
.iqk_threshold = 8,
+ .bfer_su_max_num = 2,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
index e35c57c9d1..13c22d2e50 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8814a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
@@ -4,6 +4,7 @@
#include <linux/usb.h>
#include "main.h"
+#include "bf.h"
#include "coex.h"
#include "tx.h"
#include "phy.h"
@@ -115,10 +116,13 @@ static void rtw8814a_init_hwcap(struct rtw_dev *rtwdev)
BIT(RTW_CHANNEL_WIDTH_80);
efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT;
- if (hal->rf_type == RF_3T3R)
+ if (hal->rf_type == RF_3T3R) {
efuse->hw_cap.nss = 3;
- else
+ hal->bfee_sts_cap = 2;
+ } else {
efuse->hw_cap.nss = 2;
+ hal->bfee_sts_cap = 1;
+ }
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
"hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n",
@@ -2039,6 +2043,37 @@ static void rtw8814a_led_set(struct led_classdev *led,
rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, led_gpio_cfg);
}
+#define RTW_NDP_RX_STANDBY_TIME_8814A 0x40
+#define RTW_SND_CTRL_SOUNDING_8814A (BIT_USE_NSTS | \
+ BIT_DIS_CHK_VHTSIGB_CRC | \
+ BIT_BFPARAM_SEL | BIT_CSISEQ_SEL | \
+ BIT_HT_NDPA_EN | BIT_VHT_NDPA_EN)
+#define RTW_CSI_RPT_OFFSET_VHT_8814A 2
+#define RTW_CSI_RPT_OFFSET_HT_8814A 2
+
+static void rtw8814a_bf_enable_bfee_su(struct rtw_dev *rtwdev,
+ struct rtw_vif *vif,
+ struct rtw_bfee *bfee)
+{
+ rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
+
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 1, RTW_CSI_RPT_OFFSET_VHT_8814A);
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 2, RTW_CSI_RPT_OFFSET_HT_8814A);
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING_8814A);
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3,
+ RTW_NDP_RX_STANDBY_TIME_8814A);
+}
+
+static void rtw8814a_bf_config_bfee(struct rtw_dev *rtwdev,
+ struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable)
+{
+ if (enable)
+ rtw8814a_bf_enable_bfee_su(rtwdev, vif, bfee);
+ else
+ rtw_bf_remove_bfee_su(rtwdev, bfee);
+}
+
static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *txdesc)
@@ -2068,7 +2103,7 @@ static const struct rtw_chip_ops rtw8814a_ops = {
.phy_calibration = rtw8814a_phy_calibration,
.cck_pd_set = rtw8814a_phy_cck_pd_set,
.pwr_track = rtw8814a_pwr_track,
- .config_bfee = NULL,
+ .config_bfee = rtw8814a_bf_config_bfee,
.set_gid_table = NULL,
.cfg_csi_rate = NULL,
.led_set = rtw8814a_led_set,
@@ -2231,6 +2266,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = {
.rfe_defs = rtw8814a_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8814a_rfe_defs),
.iqk_threshold = 8,
+ .bfer_su_max_num = 2,
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
.coex_para_ver = 0,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
index 6096d3b8e4..6d106ae70d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -877,7 +877,7 @@ static const struct rtw_chip_ops rtw8821a_ops = {
.phy_calibration = rtw8821a_phy_calibration,
.cck_pd_set = rtw_phy_cck_pd_set,
.pwr_track = rtw8821a_pwr_track,
- .config_bfee = NULL,
+ .config_bfee = rtw88xxa_bf_config_bfee,
.set_gid_table = NULL,
.cfg_csi_rate = NULL,
.led_set = rtw8821a_led_set,
@@ -1188,6 +1188,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = {
.old_datarate_fb_limit = true,
.usb_tx_agg_desc_num = 6,
.iqk_threshold = 8,
+ .bfer_su_max_num = 2,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
index 5ffa29d181..9780999a9b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
@@ -138,6 +138,7 @@ static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev)
efuse->hw_cap.nss = 1;
else
efuse->hw_cap.nss = 2;
+ hal->bfee_sts_cap = 1;
if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
goto print_hw_cap;
@@ -197,6 +198,78 @@ static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev)
efuse->hw_cap.ant_num, efuse->hw_cap.nss);
}
+#define RTW_NDP_RX_STANDBY_TIME_88XXA 0x50
+#define RTW_SND_CTRL_REMOVE_88XXA (BIT_USE_NSTS | \
+ BIT_DIS_CHK_VHTSIGB_CRC | \
+ BIT_CSISEQ_SEL)
+#define RTW_SND_CTRL_SOUNDING_88XXA (RTW_SND_CTRL_REMOVE_88XXA | \
+ BIT_HT_NDPA_EN | BIT_VHT_NDPA_EN)
+/* REG_CSI_CONTENT_VALUE from the 8812a (2T2R) and 8821a (1T1R) bb tables */
+#define RTW_CSI_CONTENT_2T2R_88XXA 0x00000000
+#define RTW_CSI_CONTENT_1T1R_88XXA 0x01081008
+
+void rtw88xxa_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable)
+{
+ static const u32 csi_rpt_regs[] = {
+ REG_TX_CSI_RPT_PARAM_BW20,
+ REG_TX_CSI_RPT_PARAM_BW40,
+ REG_TX_CSI_RPT_PARAM_BW80,
+ };
+ struct rtw_bf_info *bf_info = &rtwdev->bf_info;
+ u8 nc_index = rtwdev->efuse.hw_cap.nss - 1;
+ u8 nr_index = 1, grouping = 0, codebookinfo = 1, coefficientsize = 0;
+ u8 slot = bfee->su_reg_index;
+ u32 addr_bfer_info;
+ u32 csi_param;
+ int i;
+
+ if (bfee->role != RTW_BFEE_SU || slot >= 2)
+ return;
+
+ addr_bfer_info = slot ? REG_ASSOCIATED_BFMER1_INFO :
+ REG_ASSOCIATED_BFMER0_INFO;
+
+ rtw_dbg(rtwdev, RTW_DBG_BF, "SU beamformee %s slot %u\n",
+ enable ? "enable" : "disable", slot);
+
+ if (!enable) {
+ rtw_write32(rtwdev, addr_bfer_info, 0);
+ rtw_write16(rtwdev, addr_bfer_info + 4, 0);
+
+ clear_bit(slot, bf_info->bfer_su_reg_maping);
+ bfee->su_reg_index = 0xff;
+
+ if (!bf_info->bfer_su_cnt)
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL,
+ RTW_SND_CTRL_REMOVE_88XXA);
+ return;
+ }
+
+ if (rtwdev->efuse.hw_cap.nss == 2)
+ rtw_write32(rtwdev, REG_CSI_CONTENT_VALUE,
+ RTW_CSI_CONTENT_2T2R_88XXA);
+ else
+ rtw_write32(rtwdev, REG_CSI_CONTENT_VALUE,
+ RTW_CSI_CONTENT_1T1R_88XXA);
+
+ csi_param = (coefficientsize << 10) | (codebookinfo << 8) |
+ (grouping << 6) | (nr_index << 3) | nc_index;
+ /* same parameters for both beamformer slots */
+ csi_param |= csi_param << 16;
+
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING_88XXA);
+ for (i = 0; i < ETH_ALEN; i++)
+ rtw_write8(rtwdev, addr_bfer_info + i, bfee->mac_addr[i]);
+
+ for (i = 0; i < ARRAY_SIZE(csi_rpt_regs); i++)
+ rtw_write32(rtwdev, csi_rpt_regs[i], csi_param);
+
+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3,
+ RTW_NDP_RX_STANDBY_TIME_88XXA);
+}
+EXPORT_SYMBOL(rtw88xxa_bf_config_bfee);
+
int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map)
{
const struct rtw_chip_info *chip = rtwdev->chip;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
index 6597ca0dfc..150e86ea74 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
@@ -170,5 +170,7 @@ bool rtw88xxa_iqk_finish(int average, int threshold,
void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
void (*do_lck)(struct rtw_dev *rtwdev),
void (*do_iqk)(struct rtw_dev *rtwdev));
+void rtw88xxa_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable);
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
` (3 preceding siblings ...)
2026-11-15 11:43 ` [PATCH rtw-next v4 4/7] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 13:41 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
6 siblings, 1 reply; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
Promote chip specific functions into the common core for cfo tracking.
These become helpers which can be used by the other drivers.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/phy.c | 106 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/phy.h | 2 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 100 +----------------
drivers/net/wireless/realtek/rtw88/rtw8822c.h | 3 -
4 files changed, 113 insertions(+), 98 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index e2515a662b..d0c1fb65be 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -720,6 +720,112 @@ void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
}
EXPORT_SYMBOL(rtw_phy_parsing_cfo);
+#define CFO_TRK_ENABLE_TH 20
+#define CFO_TRK_STOP_TH 10
+#define CFO_TRK_ADJ_TH 10
+
+static u8 rtw_phy_cfo_tracking_reset(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ cfo->is_adjust = true;
+
+ if (cfo->crystal_cap > rtwdev->efuse.crystal_cap)
+ return cfo->crystal_cap - 1;
+ else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap)
+ return cfo->crystal_cap + 1;
+
+ return cfo->crystal_cap;
+}
+
+void rtw_phy_cfo_xcap_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ cfo->crystal_cap = rtwdev->efuse.crystal_cap;
+ cfo->is_adjust = true;
+}
+EXPORT_SYMBOL(rtw_phy_cfo_xcap_init);
+
+#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); })
+static s32 rtw_phy_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+ s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum;
+ u8 i;
+
+ for (i = 0; i < path_num; i++) {
+ cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]);
+
+ if (cfo->cfo_cnt[i])
+ cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i];
+ else
+ cfo_avg = 0;
+
+ cfo_path_sum += cfo_avg;
+ }
+
+ for (i = 0; i < path_num; i++) {
+ cfo->cfo_tail[i] = 0;
+ cfo->cfo_cnt[i] = 0;
+ }
+
+ return cfo_path_sum / path_num;
+}
+
+static void rtw_phy_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ if (!cfo->is_adjust) {
+ if (abs(cfo_avg) > CFO_TRK_ENABLE_TH)
+ cfo->is_adjust = true;
+ } else {
+ if (abs(cfo_avg) <= CFO_TRK_STOP_TH)
+ cfo->is_adjust = false;
+ }
+}
+
+u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+ u8 path_num = rtwdev->hal.rf_path_num;
+ s8 crystal_cap = cfo->crystal_cap;
+ s32 cfo_avg = 0;
+
+ if (rtwdev->sta_cnt != 1)
+ return rtw_phy_cfo_tracking_reset(rtwdev);
+
+ if (cfo->packet_count == cfo->packet_count_pre)
+ return cfo->crystal_cap;
+
+ cfo->packet_count_pre = cfo->packet_count;
+ cfo_avg = rtw_phy_cfo_calc_avg(rtwdev, path_num);
+ rtw_phy_cfo_need_adjust(rtwdev, cfo_avg);
+
+ if (bt_hold) {
+ cfo->is_adjust = false;
+ return rtwdev->efuse.crystal_cap;
+ }
+
+ if (cfo->is_adjust) {
+ if (cfo_avg > CFO_TRK_ADJ_TH)
+ crystal_cap++;
+ else if (cfo_avg < -CFO_TRK_ADJ_TH)
+ crystal_cap--;
+
+ crystal_cap = clamp_t(s8, crystal_cap, 0, xcap_max);
+ }
+
+ return (u8)crystal_cap;
+}
+EXPORT_SYMBOL(rtw_phy_cfo_xcap_track);
+
static void rtw_phy_cfo_track(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h
index 8a843aac73..b551cb860d 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.h
+++ b/drivers/net/wireless/realtek/rtw88/phy.h
@@ -68,6 +68,8 @@ void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev);
void rtw_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl);
void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat);
+void rtw_phy_cfo_xcap_init(struct rtw_dev *rtwdev);
+u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold);
void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev);
struct rtw_txpwr_lmt_cfg_pair {
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 09315d23e2..d7b0204e6d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4243,103 +4243,13 @@ static void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap)
rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap);
}
-static void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- cfo->is_adjust = true;
-
- if (cfo->crystal_cap > rtwdev->efuse.crystal_cap)
- rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1);
- else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap)
- rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1);
-}
-
-static void rtw8822c_cfo_init(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- cfo->crystal_cap = rtwdev->efuse.crystal_cap;
- cfo->is_adjust = true;
-}
-
-#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); })
-static s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
- s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum;
- u8 i;
-
- for (i = 0; i < path_num; i++) {
- cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]);
-
- if (cfo->cfo_cnt[i])
- cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i];
- else
- cfo_avg = 0;
-
- cfo_path_sum += cfo_avg;
- }
-
- for (i = 0; i < path_num; i++) {
- cfo->cfo_tail[i] = 0;
- cfo->cfo_cnt[i] = 0;
- }
-
- return cfo_path_sum / path_num;
-}
-
-static void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- if (!cfo->is_adjust) {
- if (abs(cfo_avg) > CFO_TRK_ENABLE_TH)
- cfo->is_adjust = true;
- } else {
- if (abs(cfo_avg) <= CFO_TRK_STOP_TH)
- cfo->is_adjust = false;
- }
-
- if (!rtw_coex_disabled(rtwdev)) {
- cfo->is_adjust = false;
- rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap);
- }
-}
-
static void rtw8822c_cfo_track(struct rtw_dev *rtwdev)
{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
- u8 path_num = rtwdev->hal.rf_path_num;
- s8 crystal_cap = cfo->crystal_cap;
- s32 cfo_avg = 0;
-
- if (rtwdev->sta_cnt != 1) {
- rtw8822c_cfo_tracking_reset(rtwdev);
- return;
- }
-
- if (cfo->packet_count == cfo->packet_count_pre)
- return;
-
- cfo->packet_count_pre = cfo->packet_count;
- cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num);
- rtw8822c_cfo_need_adjust(rtwdev, cfo_avg);
-
- if (cfo->is_adjust) {
- if (cfo_avg > CFO_TRK_ADJ_TH)
- crystal_cap++;
- else if (cfo_avg < -CFO_TRK_ADJ_TH)
- crystal_cap--;
+ u8 crystal_cap;
- crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK);
- rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap);
- }
+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, XCAP_MASK,
+ !rtw_coex_disabled(rtwdev));
+ rtw8822c_set_crystal_cap(rtwdev, crystal_cap);
}
static const struct rtw_phy_cck_pd_reg
@@ -4985,7 +4895,7 @@ static const struct rtw_chip_ops rtw8822c_ops = {
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
.adaptivity_init = rtw8822c_adaptivity_init,
.adaptivity = rtw8822c_adaptivity,
- .cfo_init = rtw8822c_cfo_init,
+ .cfo_init = rtw_phy_cfo_xcap_init,
.cfo_track = rtw8822c_cfo_track,
.config_tx_path = rtw8822c_config_tx_path,
.config_txrx_mode = rtw8822c_config_trx_mode,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
index fc62b67a15..c27e4c394a 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
@@ -181,9 +181,6 @@ const struct rtw_table name ## _tbl = { \
#define REG_ANAPARLDO_POW_MAC 0x0029
#define BIT_LDOE25_PON BIT(0)
#define XCAP_MASK GENMASK(6, 0)
-#define CFO_TRK_ENABLE_TH 20
-#define CFO_TRK_STOP_TH 10
-#define CFO_TRK_ADJ_TH 10
#define REG_TXDFIR0 0x808
#define REG_DFIRBW 0x810
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
` (4 preceding siblings ...)
2026-11-15 11:43 ` [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:42 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
6 siblings, 2 replies; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
Use the newly promoted helpers to implement support for 88xxa
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/phy.c | 5 +-
drivers/net/wireless/realtek/rtw88/phy.h | 6 +++
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 2 +
drivers/net/wireless/realtek/rtw88/rtw8814a.c | 32 +++++++++++--
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 2 +
drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 47 +++++++++++++++----
drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 1 +
7 files changed, 81 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index d0c1fb65be..b01601d707 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -687,13 +687,14 @@ static void rtw_phy_parsing_cfo_iter(void *data, u8 *mac,
struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat;
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+ u8 path_num = min_t(u8, rtwdev->hal.rf_path_num, RTW_CFO_PATH_NUM_MAX);
u8 *bssid = iter_data->bssid;
u8 i;
if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
return;
- for (i = 0; i < rtwdev->hal.rf_path_num; i++) {
+ for (i = 0; i < path_num; i++) {
cfo->cfo_tail[i] += pkt_stat->cfo_tail[i];
cfo->cfo_cnt[i]++;
}
@@ -794,7 +795,7 @@ u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
struct rtw_cfo_track *cfo = &dm_info->cfo_track;
- u8 path_num = rtwdev->hal.rf_path_num;
+ u8 path_num = min_t(u8, rtwdev->hal.rf_path_num, RTW_CFO_PATH_NUM_MAX);
s8 crystal_cap = cfo->crystal_cap;
s32 cfo_avg = 0;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h
index b551cb860d..52e6546b52 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.h
+++ b/drivers/net/wireless/realtek/rtw88/phy.h
@@ -204,4 +204,10 @@ enum rtw_phy_cck_pd_lv {
#define RRSR_RATE_ORDER_MAX 0xfffff
#define RRSR_RATE_ORDER_CCK_LEN 4
+/* crystal cap width of all chips except RTL8822C */
+#define RTW_XCAP_MASK GENMASK(5, 0)
+
+/* RTL8814A has 4 paths, but only paths A and B report CFO */
+#define RTW_CFO_PATH_NUM_MAX 2
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
index 5d58dff4fc..c8008cf43d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -943,6 +943,8 @@ static const struct rtw_chip_ops rtw8812a_ops = {
.coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type,
.coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power,
.coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
+ .cfo_init = rtw_phy_cfo_xcap_init,
+ .cfo_track = rtw88xxa_cfo_track,
};
static const struct rtw_page_table page_table_8812a[] = {
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
index 13c22d2e50..74c548cb5c 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8814a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
@@ -146,6 +146,9 @@ static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map)
efuse->rfe_option = map->rfe_option;
efuse->rf_board_option = map->rf_board_option;
efuse->crystal_cap = map->xtal_k;
+ if (efuse->crystal_cap == 0xff)
+ efuse->crystal_cap = 0x20;
+ efuse->crystal_cap &= RTW_XCAP_MASK;
efuse->channel_plan = map->channel_plan;
efuse->country_code[0] = map->country_code[0];
efuse->country_code[1] = map->country_code[1];
@@ -284,9 +287,15 @@ static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev)
rtw_write32_mask(rtwdev, REG_CCKTX, BIT_CMB_CCA_2R, 1);
}
+static void rtw8814a_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap)
+{
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000,
+ crystal_cap | (crystal_cap << 6));
+}
+
static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev)
{
- u32 crystal_cap, val32;
+ u32 val32;
u8 val8, rf_path;
/* power on BB/RF domain */
@@ -308,9 +317,7 @@ static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev)
rtw_load_table(rtwdev, rtwdev->chip->bb_tbl);
rtw_load_table(rtwdev, rtwdev->chip->agc_tbl);
- crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
- crystal_cap |= crystal_cap << 6;
- rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000, crystal_cap);
+ rtw8814a_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap);
rtw8814a_config_trx_path(rtwdev);
@@ -1269,6 +1276,8 @@ static void rtw8814a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
pkt_stat->cfo_tail[i] = cfo[i];
dm_info->cfo_tail[i] = (cfo[i] * 5) >> 1;
}
+
+ rtw_phy_parsing_cfo(rtwdev, pkt_stat);
}
}
@@ -2074,6 +2083,19 @@ static void rtw8814a_bf_config_bfee(struct rtw_dev *rtwdev,
rtw_bf_remove_bfee_su(rtwdev, bfee);
}
+static void rtw8814a_cfo_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_cfo_track *cfo = &rtwdev->dm_info.cfo_track;
+ u8 crystal_cap;
+
+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, false);
+ if (crystal_cap == cfo->crystal_cap)
+ return;
+
+ cfo->crystal_cap = crystal_cap;
+ rtw8814a_set_crystal_cap(rtwdev, crystal_cap);
+}
+
static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *txdesc)
@@ -2108,6 +2130,8 @@ static const struct rtw_chip_ops rtw8814a_ops = {
.cfg_csi_rate = NULL,
.led_set = rtw8814a_led_set,
.fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum,
+ .cfo_init = rtw_phy_cfo_xcap_init,
+ .cfo_track = rtw8814a_cfo_track,
.coex_set_init = rtw8814a_coex_cfg_init,
.coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
index 6d106ae70d..17d3677ca4 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -889,6 +889,8 @@ static const struct rtw_chip_ops rtw8821a_ops = {
.coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type,
.coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power,
.coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
+ .cfo_init = rtw_phy_cfo_xcap_init,
+ .cfo_track = rtw88xxa_cfo_track,
};
static const struct rtw_page_table page_table_8821a[] = {
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
index 9780999a9b..68a4ca8069 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
@@ -290,6 +290,7 @@ int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map)
efuse->crystal_cap = map->xtal_k;
if (efuse->crystal_cap == 0xff)
efuse->crystal_cap = 0x20;
+ efuse->crystal_cap &= RTW_XCAP_MASK;
efuse->pa_type_2g = map->pa_type;
efuse->pa_type_5g = map->pa_type;
efuse->lna_type_2g = map->lna_type_2g;
@@ -643,9 +644,19 @@ static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev)
rtw_write16(rtwdev, REG_BCNTCFG, 0x4413);
}
+static void rtw88xxa_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap)
+{
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000,
+ crystal_cap | (crystal_cap << 6));
+ else
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000,
+ crystal_cap | (crystal_cap << 6));
+}
+
static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev)
{
- u8 val8, crystal_cap;
+ u8 val8;
/* power on BB/RF domain */
val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
@@ -664,13 +675,7 @@ static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev)
rtw_load_table(rtwdev, rtwdev->chip->bb_tbl);
rtw_load_table(rtwdev, rtwdev->chip->agc_tbl);
- crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
- rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000,
- crystal_cap | (crystal_cap << 6));
- else
- rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000,
- crystal_cap | (crystal_cap << 6));
+ rtw88xxa_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap);
}
static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev)
@@ -1632,6 +1637,17 @@ void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
power_b = power_a;
pkt_stat->signal_power = max3(power_a, power_b, min_rx_power);
+
+ pkt_stat->cfo_tail[RF_PATH_A] =
+ (s8)le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_A);
+ pkt_stat->cfo_tail[RF_PATH_B] =
+ (s8)le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_B);
+
+ /* convert to kHz (used only for debugfs) */
+ for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++)
+ dm_info->cfo_tail[i] = (pkt_stat->cfo_tail[i] * 5) >> 1;
+
+ rtw_phy_parsing_cfo(rtwdev, pkt_stat);
}
}
EXPORT_SYMBOL(rtw88xxa_query_phy_status);
@@ -2020,6 +2036,21 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
}
EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack);
+void rtw88xxa_cfo_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_cfo_track *cfo = &rtwdev->dm_info.cfo_track;
+ bool bt_hold = rtwdev->efuse.btcoex && !rtw_coex_disabled(rtwdev);
+ u8 crystal_cap;
+
+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, bt_hold);
+ if (crystal_cap == cfo->crystal_cap)
+ return;
+
+ cfo->crystal_cap = crystal_cap;
+ rtw88xxa_set_crystal_cap(rtwdev, crystal_cap);
+}
+EXPORT_SYMBOL(rtw88xxa_cfo_track);
+
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
index 150e86ea74..188b8f3a4b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
@@ -172,5 +172,6 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
void (*do_iqk)(struct rtw_dev *rtwdev));
void rtw88xxa_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
struct rtw_bfee *bfee, bool enable);
+void rtw88xxa_cfo_track(struct rtw_dev *rtwdev);
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
` (5 preceding siblings ...)
2026-11-15 11:43 ` [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
@ 2026-11-15 11:43 ` Ho Jie Feng
2026-11-15 13:43 ` Luka Gejak
6 siblings, 1 reply; 17+ messages in thread
From: Ho Jie Feng @ 2026-11-15 11:43 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: linux-wireless, linux-kernel, Bitterblue Smith, Luka Gejak,
Ho Jie Feng
Honor the peer-advertised receive limit for transmitted A-MPDUs.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 11 ++++++++++-
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 11 ++++++++++-
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
index c8008cf43d..7e3c86160f 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -78,6 +78,15 @@ static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
{
}
+static void rtw8812a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor)
+{
+ factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_128K);
+
+ /* the vendor driver sets the undocumented BIT(31) */
+ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH,
+ ((8192 << factor) - 1) | BIT(31));
+}
+
static void rtw8812a_do_lck(struct rtw_dev *rtwdev)
{
u32 cont_tx, lc_cal, i;
@@ -926,7 +935,7 @@ static const struct rtw_chip_ops rtw8812a_ops = {
.set_tx_power_index = rtw88xxa_set_tx_power_index,
.cfg_ldo25 = rtw8812a_cfg_ldo25,
.efuse_grant = rtw88xxa_efuse_grant,
- .set_ampdu_factor = NULL,
+ .set_ampdu_factor = rtw8812a_set_ampdu_factor,
.false_alarm_statistics = rtw88xxa_false_alarm_statistics,
.phy_calibration = rtw8812a_phy_calibration,
.cck_pd_set = rtw_phy_cck_pd_set,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
index 17d3677ca4..408b5ecdc5 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -49,6 +49,15 @@ static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
{
}
+static void rtw8821a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor)
+{
+ factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_64K);
+
+ /* the vendor driver sets the undocumented BIT(31) */
+ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH,
+ ((8192 << factor) - 1) | BIT(31));
+}
+
#define CAL_NUM_8821A 3
#define MACBB_REG_NUM_8821A 8
#define AFE_REG_NUM_8821A 4
@@ -872,7 +881,7 @@ static const struct rtw_chip_ops rtw8821a_ops = {
.set_tx_power_index = rtw88xxa_set_tx_power_index,
.cfg_ldo25 = rtw8821a_cfg_ldo25,
.efuse_grant = rtw88xxa_efuse_grant,
- .set_ampdu_factor = NULL,
+ .set_ampdu_factor = rtw8821a_set_ampdu_factor,
.false_alarm_statistics = rtw88xxa_false_alarm_statistics,
.phy_calibration = rtw8821a_phy_calibration,
.cck_pd_set = rtw_phy_cck_pd_set,
--
2.53.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
@ 2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:36 ` Luka Gejak
2026-11-15 13:37 ` Luka Gejak
2 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:20 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
Thanks for the update. One comment below.
On November 15, 2026 12:43:29 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
[ ... ]
> @@ -1624,10 +1625,13 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
[ ... ]
> + if (rtw_bf_support && chip->bfer_su_max_num) {
> + vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
> + vht_cap->cap |= rtwdev->hal.bfee_sts_cap <<
> + IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
> + }
> + if (rtw_bf_support && chip->bfer_mu_max_num)
> + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
As far as I can see, this also changes whether support_bf can be enabled
at runtime. It is still writable, but if it is false when the adapter
probes, writing Y later and reconnecting leaves these capabilities clear.
rtw_set_supported_band() only runs from rtw_register_hw(), and the bool
setter does not update the bands.
rtw_bf_assoc() checks these cached capabilities too, so neither SU nor MU
setup can run. Before this patch, enabling the parameter before the next
association worked on chips that already supported beamforming.
Could we keep that runtime enable working? If the setting now needs to be
fixed at probe, maybe the parameter should be read only instead.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset
2026-11-15 11:43 ` [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
@ 2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:42 ` Luka Gejak
1 sibling, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:20 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
Thanks for the patch. One comment below.
On November 15, 2026 12:43:32 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
> --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
[ ... ]
> @@ -1632,6 +1637,17 @@ void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
[ ... ]
> + rtw_phy_parsing_cfo(rtwdev, pkt_stat);
[ ... ]
> @@ -2020,6 +2036,21 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
[ ... ]
> + crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, bt_hold);
> + if (crystal_cap == cfo->crystal_cap)
> + return;
> +
> + cfo->crystal_cap = crystal_cap;
> + rtw88xxa_set_crystal_cap(rtwdev, crystal_cap);
Could the shared helper discard the samples while sta_cnt != 1? In AP
mode, frames from both clients match the interface BSSID, so these new
calls keep adding their CFO samples. But rtw_phy_cfo_xcap_track() returns
through rtw_phy_cfo_tracking_reset() before clearing the sums or counts.
So if I read it right, when one client leaves, the first adjustment still
includes samples from that client. For example, on each reporting path,
a +12 sample from the remaining client and a -48 sample from the other,
followed by another +12, give an average of -20 kHz. The remaining client
alone gives +30 kHz, so the first correction goes the wrong way.
This was already present on 8822c, and this patch makes it reachable on
88xxa too. I think the fix belongs in rtw_phy_cfo_xcap_track(), before
these new callers start using it. Could the sums and counts be reset
there when there is no single peer to track?
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions
2026-11-15 11:43 ` [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
@ 2026-11-15 13:35 ` Luka Gejak
0 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:35 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
Thanks for the update. Two comments below.
On November 15, 2026 12:43:27 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> 8812a and 8814a support STBC, enable it.
Could you mention here that this enables HT TX STBC on these chips? As
far as I can see, VHT TX STBC was already advertised when more than one RF
path is available, so that would make the scope clearer.
[ ... ]
> Tested on RTL8812AU, STBC packets were captured in monitor mode.
Were these HT transmissions from the RTL8812AU, for example on 2.4 GHz
or with an HT only AP? As far as I can see, we already advertise VHT TX
STBC on this chip, so a VHT capture would not confirm the change here.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
@ 2026-11-15 13:36 ` Luka Gejak
2026-11-15 13:37 ` Luka Gejak
2 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:36 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
One more thing for this patch.
On November 15, 2026 12:43:29 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> Make MU and SU capability flags each depend on the chip declared
> maximum instead of setting both flags together.
Could you also describe the problem with the old advertisement? As far
as I can see, both SU and MU beamformee flags were set regardless of the
chip limits. Explaining why they need separate checks would make the
reason for the change clearer.
I think the new support_bf check is worth mentioning too, once the
runtime behavior from my earlier reply is settled.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:36 ` Luka Gejak
@ 2026-11-15 13:37 ` Luka Gejak
2026-11-15 13:39 ` Luka Gejak
2 siblings, 1 reply; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:37 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
Thanks for the patch. One comment on the description below.
On November 15, 2026 12:43:29 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> Implement beamformee support for 88xxa since they have
> support for it.
Could you expand this a little to explain what was missing? As far as I
can see, the chips had no config_bfee callback, and this adds the SU
beamformee setup for RTL8812A, RTL8821A and RTL8814A.
I think a short explanation of the sounding and CSI report setup would
make the change easier to follow.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities
2026-11-15 13:37 ` Luka Gejak
@ 2026-11-15 13:39 ` Luka Gejak
0 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:39 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
On November 15, 2026 2:37:46 PM GMT+01:00, Luka Gejak
<luka.gejak@linux.dev> wrote:
>Hi Jie Feng,
>
>Thanks for the patch. One comment on the description below.
>
>On November 15, 2026 12:43:29 PM GMT+01:00, Ho Jie Feng
><hjf3108@gmail.com>
>wrote:
>
>> Implement beamformee support for 88xxa since they have
>> support for it.
>
>Could you expand this a little to explain what was missing? As far as I
>can see, the chips had no config_bfee callback, and this adds the SU
>beamformee setup for RTL8812A, RTL8821A and RTL8814A.
>
>I think a short explanation of the sounding and CSI report setup would
>make the change easier to follow.
>
>Best regards,
>Luka Gejak
>
This is supposed to be for patch 4. I have used a wrong message id.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips
2026-11-15 11:43 ` [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips Ho Jie Feng
@ 2026-11-15 13:41 ` Luka Gejak
0 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:41 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
Thanks for the patch. One small suggestion below.
On November 15, 2026 12:43:31 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> Promote chip specific functions into the common core for cfo tracking.
> These become helpers which can be used by the other drivers.
Could you name RTL8822C as the source of these helpers and mention that
the crystal register writes stay in the chip code? I think that would
make the split between the common tracking logic and the hardware
specific part clearer.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset
2026-11-15 11:43 ` [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
@ 2026-11-15 13:42 ` Luka Gejak
1 sibling, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:42 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
One more thing in addition to the other patch 6 reply.
On November 15, 2026 12:43:32 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> Use the newly promoted helpers to implement support for 88xxa
Could you expand this to describe how the CFO samples are collected and
used to adjust the crystal cap? I think the two path reporting limit on
RTL8814A and the handling of the efuse crystal value are worth explaining
too.
This adds more than the callbacks, and a short description would help
explain the changes to the shared parser and chip initialization.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits
2026-11-15 11:43 ` [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
@ 2026-11-15 13:43 ` Luka Gejak
0 siblings, 0 replies; 17+ messages in thread
From: Luka Gejak @ 2026-11-15 13:43 UTC (permalink / raw)
To: Ho Jie Feng, Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Bitterblue Smith
Hi Jie Feng,
I have one comment on this description as well.
On November 15, 2026 12:43:33 PM GMT+01:00, Ho Jie Feng <hjf3108@gmail.com>
wrote:
> Honor the peer-advertised receive limit for transmitted A-MPDUs.
Could you mention that these chips had no set_ampdu_factor callback, so
rtw_set_ampdu_factor() returned before programming the peer's limit?
I think it would also help to explain that the new setters clamp the
factor to the chip limit before updating REG_AMPDU_MAX_LENGTH.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-11-15 13:43 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-15 11:43 [PATCH rtw-next v4 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
2026-11-15 13:35 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 2/7] wifi: rtw88: skip the dynamic CSI rate without a cfg_csi_rate op Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:36 ` Luka Gejak
2026-11-15 13:37 ` Luka Gejak
2026-11-15 13:39 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 4/7] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions Ho Jie Feng
2026-11-15 11:43 ` [PATCH rtw-next v4 5/7] wifi: rtw88: prepare frequency-offset correction for more chips Ho Jie Feng
2026-11-15 13:41 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 6/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
2026-11-15 13:20 ` Luka Gejak
2026-11-15 13:42 ` Luka Gejak
2026-11-15 11:43 ` [PATCH rtw-next v4 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
2026-11-15 13:43 ` Luka Gejak
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.