Re: [PATCH rtw-next v8 5/7] wifi: rtw88: 8723b: add the RTL8723B chip driver

From: Bitterblue Smith

Date: Fri Oct 09 2026 - 09:27:04 EST


On 06/10/2026 16:06, Luka Gejak wrote:
> Add the Realtek RTL8723B 802.11n chip driver: the chip operations, the
> power sequences, the efuse layout, the RF and IQ calibration, and the
> chip specific coexistence handling.
>
> The RTL8723B chip support is based on the initial work by
> Michael Straube <straube.linux@xxxxxxxxx>.
> Link: https://github.com/mistraube/rtw88/tree/rtl8723bs
>
> Co-developed-by: Michael Straube <straube.linux@xxxxxxxxx>
> Signed-off-by: Michael Straube <straube.linux@xxxxxxxxx>
> Signed-off-by: Luka Gejak <luka.gejak@xxxxxxxxx>
> Reviewed-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
> drivers/net/wireless/realtek/rtw88/rtw8723b.c | 2534 +++++++++++++++++
> drivers/net/wireless/realtek/rtw88/rtw8723b.h | 14 +
> 2 files changed, 2548 insertions(+)
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723b.c
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723b.h
>
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723b.c b/drivers/net/wireless/realtek/rtw88/rtw8723b.c
> new file mode 100644
> index 000000000000..8bb9c03d769c
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723b.c

[...]

> +static s8 rtw8723b_cck_rx_power(u8 lna_idx, u8 vga_idx)
> +{
> + s8 rx_power = 0;
> +
> + switch (lna_idx) {
> + case 6:
> + rx_power = -40 - (2 * vga_idx);
> + break;
> + case 4:
> + rx_power = -20 - (2 * vga_idx);
> + break;
> + case 1:
> + rx_power = 0 - (2 * vga_idx);
> + break;
> + case 0:
> + rx_power = 10 - (2 * vga_idx);
> + break;
> + default:
> + break;
> + }
> +
> + return rx_power;
> +}
> +
> +static void rtw8723b_query_phy_status_cck(struct rtw_dev *rtwdev, void *phy_raw,
> + struct rtw_rx_pkt_stat *pkt_stat)
> +{
> + struct phy_status_8723x *phy_status = phy_raw;
> + u8 lna_idx = u8_get_bits(phy_status->cck_agc_rpt_ofdm_cfosho_a, 0xE0);
> + u8 vga_idx = u8_get_bits(phy_status->cck_agc_rpt_ofdm_cfosho_a, 0x1F);
> + s8 rx_power = rtw8723b_cck_rx_power(lna_idx, vga_idx);
> + s8 min_rx_power = -120;
> +
> + pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
> +
> + pkt_stat->rx_power[RF_PATH_A] = rx_power;
> + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
> + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
> + min_rx_power);
> + rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi;
> +}
> +
> +static void rtw8723b_query_phy_status_ofdm(struct rtw_dev *rtwdev, void *phy_raw,
> + struct rtw_rx_pkt_stat *pkt_stat)
> +{
> + struct phy_status_8723x *phy_status = phy_raw;
> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> + s8 val_s8;
> +
> + /* pkt_stat->bw comes from the RX descriptor, not the PHY status. */
> +
> + val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F;
> + pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110;
> +
> + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
> + pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2);
> +
> + /* signal power reported by HW */
> + val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1;
> + pkt_stat->signal_power = (val_s8 & 0x7f) - 110;
> +
> + pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A];
> + pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A];
> +
> + dm_info->curr_rx_rate = pkt_stat->rate;
> + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
> + dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1;
> + dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1;
> +
> + val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A];
> + val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64);
> + val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */
> + dm_info->rx_evm_dbm[RF_PATH_A] = val_s8;
> +}
> +
> +static void rtw8723b_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
> + struct rtw_rx_pkt_stat *pkt_stat)
> +{
> + /*
> + * The 8723B PHY status does not report the channel, so we must
> + * mark it invalid to allow mac80211/rtw88 to parse it from the IE
> + * during scanning.
> + */
> + pkt_stat->channel_invalid = true;

After testing RTL8723BU for a bit, I think this is wrong.

mac80211 thinks there is massive beacon loss when connected to a network
with 40 MHz channel width, but phy_info in debugfs shows that beacons are
being received. The beacons are handed over to mac80211 with a wrong
frequency in struct ieee80211_rx_status. In my case, the correct frequency
is 2472 MHz, but after rtw_update_rx_freq_from_ie() the frequency is set
to 2462 MHz. mac80211 is probably discarding the beacons because of this.
Removing this line fixes the problem.

I think channel_invalid is only for chips which do hardware scan offload
(RTL8822C). With the chips that only do software scanning the driver
should always know what channel it's on and rtw_update_rx_freq_from_ie()
is not needed.

> +
> + if (pkt_stat->rate <= DESC_RATE11M)
> + rtw8723b_query_phy_status_cck(rtwdev, phy_status, pkt_stat);
> + else
> + rtw8723b_query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
> +}