Re: [PATCH 19/19] wifi: rtw88: advertise the correct receive capabilities on RTL8723BS
From: Bitterblue Smith
Date: Fri Jul 24 2026 - 18:29:23 EST
On 24/07/2026 21:33, luka.gejak@xxxxxxxxx wrote:
> From: Luka Gejak <luka.gejak@xxxxxxxxx>
>
> This chip has neither a firmware feature report nor an efuse hardware
> capability parser, so the capability struct is left at zero. A zero
> stream count builds an HT capability with no usable RX MCS rates, and
> APs drop the station immediately after an otherwise successful
> association. Fill in the stream and antenna counts from the RF path
> count, and advertise the 20 and 40 MHz support the chip has.
>
> RTL8723BS also leaves BIT_APP_FCS clear, so received frames do not carry
> the FCS. Advertising RX_INCLUDES_FCS would make mac80211 trim four bytes
> of real frame data and corrupt the trailing element of beacons and probe
> responses, so leave it unset for this chip.
>
> Signed-off-by: Luka Gejak <luka.gejak@xxxxxxxxx>
> ---
> drivers/net/wireless/realtek/rtw88/main.c | 61 +++++++++++++++--------
> 1 file changed, 40 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index 63d1fb4bc87e..e2f0fd367beb 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -126,6 +126,25 @@ static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)
> rtwdev->initial_rfk_done = true;
> }
>
> +static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,
> + struct ieee80211_sta *sta,
> + struct ieee80211_vif *vif)
> +{
> + return rtw_is_8723bs(rtwdev) &&
> + vif->type == NL80211_IFTYPE_STATION && !sta->tdls;
> +}
> +
> +/* 8723BS SDIO: defer the connect MEDIA_STATUS_RPT until the STA is actually
> + * associated (the vendor firmware sends it at assoc completion, not sta-add).
> + */
> +static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,
> + struct ieee80211_sta *sta,
> + struct ieee80211_vif *vif)
> +{
> + return rtw8723bs_station_media_status(rtwdev, sta, vif) &&
> + !vif->cfg.assoc;
> +}
> +
> static struct ieee80211_channel rtw_channeltable_2g[] = {
> {.center_freq = 2412, .hw_value = 1,},
> {.center_freq = 2417, .hw_value = 2,},
> @@ -304,25 +323,6 @@ static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev,
> /* process TX/RX statistics periodically for hardware,
> * the information helps hardware to enhance performance
> */
> -static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,
> - struct ieee80211_sta *sta,
> - struct ieee80211_vif *vif)
> -{
> - return rtw_is_8723bs(rtwdev) &&
> - vif->type == NL80211_IFTYPE_STATION && !sta->tdls;
> -}
> -
> -/* 8723BS SDIO: defer the connect MEDIA_STATUS_RPT until the STA is actually
> - * associated (the vendor firmware sends it at assoc completion, not sta-add).
> - */
> -static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,
> - struct ieee80211_sta *sta,
> - struct ieee80211_vif *vif)
> -{
> - return rtw8723bs_station_media_status(rtwdev, sta, vif) &&
> - !vif->cfg.assoc;
> -}
> -
> static void rtw_watch_dog_work(struct work_struct *work)
> {
> struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
> @@ -401,6 +401,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
> * get that vif and check if device is having traffic more than the
> * threshold.
> */
> +
> /* On 8723BS SDIO the firmware's per-packet wake latency out of LPS
> * throttles bursty traffic hard. The stock check enters LPS after a
> * single quiet 2s window, which a normal bursty session hits
> @@ -2122,8 +2123,21 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
> u8 bw;
> int i;
>
> - if (!rtwdev->chip->hw_feature_report)
> + if (!rtwdev->chip->hw_feature_report) {
> + /* 8723BS has neither a firmware feature report nor an efuse hw_cap
> + * parser, so hw_cap is otherwise left at zero. A zero stream count
> + * produces an HT capability with no usable RX MCS rates, which makes
> + * APs drop the station immediately after a successful association.
> + * Other report-less chips fill hw_cap in when parsing the efuse.
You can do that too instead of adding special code here. You can
make your own rtw8723b_read_efuse() which calls rtw8723x_read_efuse()
and also fills hw_cap.
> + */
> + if (rtw_is_8723bs(rtwdev)) {
> + efuse->hw_cap.nss = rtwdev->hal.rf_path_num ? : 1;
> + efuse->hw_cap.ant_num = rtwdev->hal.rf_path_num ? : 1;
> + efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) |
> + BIT(RTW_CHANNEL_WIDTH_40);
> + }
> return 0;
> + }
>
> id = rtw_read8(rtwdev, REG_C2HEVT);
> if (id != C2H_HW_FEATURE_REPORT) {
> @@ -2429,7 +2443,12 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
> hw->vif_data_size = sizeof(struct rtw_vif);
>
> ieee80211_hw_set(hw, SIGNAL_DBM);
> - ieee80211_hw_set(hw, RX_INCLUDES_FCS);
> + /* RTL8723BS keeps BIT_APP_FCS clear, so received frames do not contain
> + * the FCS. Advertising RX_INCLUDES_FCS would make mac80211 trim four
> + * bytes of frame data and corrupt the tail IE in beacons/probe responses.
> + */
The driver is supposed to set that bit. The default value of
rtwdev->hal.rcr includes it. I think that should work for this
chip too.
> + if (!rtw_is_8723bs(rtwdev))
> + ieee80211_hw_set(hw, RX_INCLUDES_FCS);
> ieee80211_hw_set(hw, AMPDU_AGGREGATION);
> ieee80211_hw_set(hw, MFP_CAPABLE);
> ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);