AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/26 07:18 flow patch-triage
5m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch adds support for the RTL8723BS SDIO WiFi/BT coexistence and related SDIO handling. However, the chip definition for RTL8723BS (which would set `chip-\u003eid = RTW_CHIP_TYPE_8723B`) is not present in the kernel tree, meaning `rtw_is_8723bs()` will always evaluate to false and the core logic is unreachable. Furthermore, the few generic SDIO changes in `sdio.c` are unreachable in virtualized environments because there is no software-emulated SDIO host controller (like `dummy_hcd` for USB) available for fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/07/26 07:18 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit d186f4a873ba6b92056bb5d3129a2c126320d6fe\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sun Jul 26 07:18:47 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c\nindex 37c336def41915..dc74e479351d8d 100644\n--- a/drivers/net/wireless/realtek/rtw88/coex.c\n+++ b/drivers/net/wireless/realtek/rtw88/coex.c\n@@ -1443,6 +1443,191 @@ static void rtw_coex_set_ant_path(struct rtw_dev *rtwdev, bool force, u8 phase)\n #define case_ALGO(src) \\\n \tcase COEX_ALGO_##src: return #src\n \n+/* 8723BS SDIO WiFi/BT coexistence antenna handling. On BT-disabled boards the\n+ * scan/auth window still routes through the PTA mux; these helpers force the\n+ * vendor-shaped WiFi-owned antenna path so directed management TX reaches air.\n+ */\n+#define REG_8723BS_BT_COEX_CTRL\t\t0x0039\n+#define REG_8723BS_BB_ANT_CFG\t\t0x0930\n+#define REG_8723BS_BB_ANT_CFG1\t\t0x0944\n+#define REG_8723BS_BB_ANT_BUF\t\t0x0974\n+#define RTW8723BS_COEX_H_WLAN_ACTIVE\t0x1800101b\n+\n+static bool rtw_coex_8723bs_ant_is_aux(struct rtw_dev *rtwdev)\n+{\n+\treturn !!(rtwdev-\u003eefuse.bt_setting \u0026 BIT(6));\n+}\n+\n+static bool rtw_coex_8723bs_bt_disabled(struct rtw_dev *rtwdev)\n+{\n+\treturn rtw_is_8723bs(rtwdev) \u0026\u0026 rtwdev-\u003ecoex.stat.bt_disabled;\n+}\n+\n+static u32 rtw_coex_8723bs_pta_ant_path(struct rtw_dev *rtwdev)\n+{\n+\treturn rtw_coex_8723bs_ant_is_aux(rtwdev) ? 0x80 : 0x200;\n+}\n+\n+/* Write BB_SEL_BTG (0x948), retrying once with SYS_FUNC BB reset if the first\n+ * write does not stick (RF/BB clock may have been gated).\n+ */\n+static u32 rtw_coex_8723bs_write_bb_sel_btg(struct rtw_dev *rtwdev, u32 value)\n+{\n+\tu8 sys_func_before;\n+\tu32 readback;\n+\n+\tsys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN);\n+\tif ((sys_func_before \u0026 (BIT(0) | BIT(1))) != (BIT(0) | BIT(1))) {\n+\t\trtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));\n+\t\tusleep_range(10, 11);\n+\t}\n+\n+\trtw_write32(rtwdev, 0x948, value);\n+\treadback = rtw_read32(rtwdev, 0x948);\n+\tif (readback == value)\n+\t\treturn readback;\n+\n+\tusleep_range(10, 11);\n+\trtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));\n+\trtw_write32(rtwdev, 0x948, value);\n+\n+\treturn rtw_read32(rtwdev, 0x948);\n+}\n+\n+static u32 rtw_coex_8723bs_reassert_pta_ant(struct rtw_dev *rtwdev)\n+{\n+\treturn rtw_coex_8723bs_write_bb_sel_btg(rtwdev,\n+\t\t\t\t\t\trtw_coex_8723bs_pta_ant_path(rtwdev));\n+}\n+\n+static void rtw_coex_8723bs_set_cck_pri(struct rtw_dev *rtwdev, bool high)\n+{\n+\tif (!rtw_coex_8723bs_bt_disabled(rtwdev))\n+\t\treturn;\n+\n+\tif (high) {\n+\t\trtw_write32(rtwdev, REG_BT_COEX_TABLE_H,\n+\t\t\t    RTW8723BS_COEX_H_WLAN_ACTIVE);\n+\t} else {\n+\t\trtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_CCK, false);\n+\t\trtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, false);\n+\t}\n+}\n+\n+static void rtw_coex_8723bs_restore_pad_ctrl(struct rtw_dev *rtwdev,\n+\t\t\t\t\t     bool keep_pta_owner)\n+{\n+\tu32 before, after;\n+\n+\tbefore = rtw_read32(rtwdev, REG_PAD_CTRL1);\n+\tafter = before \u0026 ~(BIT_LNAON_WLBT_SEL | BIT_SW_DPDT_SEL_DATA);\n+\tif (keep_pta_owner)\n+\t\tafter |= BIT_PAPE_WLBT_SEL;\n+\telse\n+\t\tafter \u0026= ~BIT_PAPE_WLBT_SEL;\n+\tif (after != before)\n+\t\trtw_write32(rtwdev, REG_PAD_CTRL1, after);\n+}\n+\n+static void rtw_coex_8723bs_fw_gnt_bt_low(struct rtw_dev *rtwdev)\n+{\n+\tif (!rtw_coex_8723bs_bt_disabled(rtwdev))\n+\t\treturn;\n+\n+\tif (rtw_read8(rtwdev, 0x765) == 0x00 \u0026\u0026\n+\t    rtw_read8(rtwdev, 0x76e) == 0x0c)\n+\t\treturn;\n+\n+\trtw_fw_set_gnt_bt(rtwdev, 0);\n+}\n+\n+static void rtw_coex_8723bs_force_assoc_pta_ant(struct rtw_dev *rtwdev)\n+{\n+\tu32 ant_target;\n+\n+\tif (!rtw_coex_8723bs_bt_disabled(rtwdev))\n+\t\treturn;\n+\n+\tant_target = rtw_coex_8723bs_pta_ant_path(rtwdev);\n+\n+\trtw_coex_8723bs_fw_gnt_bt_low(rtwdev);\n+\trtw_coex_set_ant_switch(rtwdev, COEX_SWITCH_CTRL_BY_PTA,\n+\t\t\t\tCOEX_SWITCH_TO_NOCARE);\n+\trtw_coex_8723bs_set_cck_pri(rtwdev, true);\n+\trtw_coex_8723bs_write_bb_sel_btg(rtwdev, ant_target);\n+\trtw_coex_8723bs_restore_pad_ctrl(rtwdev, true);\n+}\n+\n+static void rtw_coex_8723bs_reassert_ant_buffer(struct rtw_dev *rtwdev)\n+{\n+\tu8 sys_func_before;\n+\n+\tsys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN);\n+\tif ((sys_func_before \u0026 (BIT(0) | BIT(1))) != (BIT(0) | BIT(1))) {\n+\t\trtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));\n+\t\tusleep_range(10, 11);\n+\t}\n+\n+\trtw_write8_mask(rtwdev, REG_8723BS_BT_COEX_CTRL, BIT(3), 0x1);\n+\trtw_write8(rtwdev, REG_8723BS_BB_ANT_BUF, 0xff);\n+\trtw_write8_mask(rtwdev, REG_8723BS_BB_ANT_CFG1, 0x3, 0x3);\n+\trtw_write8(rtwdev, REG_8723BS_BB_ANT_CFG, 0x77);\n+}\n+\n+static void rtw_coex_8723bs_apply_scan_table(struct rtw_dev *rtwdev)\n+{\n+\trtwdev-\u003ecoex.dm.cur_table = 2;\n+\trtw_coex_set_table(rtwdev, true, 0x5a5a5a5a, 0x5a5a5a5a);\n+}\n+\n+/* Non-connected scan/auth workaround: PS-TDMA type 8 off, PTA antenna path,\n+ * coex table type 2 (matches the vendor non-connected arbitration).\n+ */\n+void rtw_coex_8723bs_scan_workaround(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_coex_dm *coex_dm = \u0026rtwdev-\u003ecoex.dm;\n+\tstruct rtw_coex_stat *coex_stat = \u0026rtwdev-\u003ecoex.stat;\n+\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\treturn;\n+\n+\tcoex_dm-\u003ecur_ps_tdma_on = false;\n+\tcoex_dm-\u003ecur_ps_tdma = 8;\n+\tcoex_dm-\u003eps_tdma_para[0] = 0x08;\n+\tcoex_dm-\u003eps_tdma_para[1] = 0x00;\n+\tcoex_dm-\u003eps_tdma_para[2] = 0x00;\n+\tcoex_dm-\u003eps_tdma_para[3] = 0x00;\n+\tcoex_dm-\u003eps_tdma_para[4] = 0x00;\n+\n+\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\trtw_coex_8723bs_fw_gnt_bt_low(rtwdev);\n+\trtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);\n+\trtw_coex_8723bs_reassert_ant_buffer(rtwdev);\n+\trtw_coex_8723bs_apply_scan_table(rtwdev);\n+\tif (coex_stat-\u003ebt_disabled)\n+\t\trtw_coex_8723bs_set_cck_pri(rtwdev, true);\n+\trtw_coex_8723bs_reassert_pta_ant(rtwdev);\n+\trtw_coex_8723bs_restore_pad_ctrl(rtwdev, true);\n+}\n+\n+/* Replayed immediately before start_clnt_join()/auth: BT_INFO + PS-TDMA type 8\n+ * then the forced WiFi PTA antenna path, so the auth window is clean.\n+ */\n+void rtw_coex_8723bs_pre_auth_h2c(struct rtw_dev *rtwdev)\n+{\n+\tlockdep_assert_held(\u0026rtwdev-\u003emutex);\n+\n+\tif (!rtw_coex_8723bs_bt_disabled(rtwdev))\n+\t\treturn;\n+\n+\trtw_fw_query_bt_info(rtwdev);\n+\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\trtw_coex_8723bs_fw_gnt_bt_low(rtwdev);\n+\trtw_coex_8723bs_force_assoc_pta_ant(rtwdev);\n+}\n+\n static const char *rtw_coex_get_algo_string(u8 algo)\n {\n \tswitch (algo) {\n@@ -2877,6 +3062,33 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type)\n \tcoex-\u003efreeze = false;\n \trtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);\n \n+\t/* 8723BS SDIO BT-disabled: keep the scan/auth PTA antenna state the\n+\t * vendor uses and skip the generic coex run. At scan start (firmware\n+\t * has been up long enough for stable RX DMA) replay the vendor BT_MP /\n+\t * BT_INFO queries, then re-establish the scan-path PTA setup.\n+\t */\n+\tif (rtw_coex_8723bs_bt_disabled(rtwdev)) {\n+\t\tif (type == COEX_SCAN_START_2G || type == COEX_SCAN_START) {\n+\t\t\tstruct rtw_coex_info_req req = {};\n+\n+\t\t\tcoex_stat-\u003ecnt_wl[COEX_CNT_WL_SCANAP] = 0;\n+\t\t\tcoex_stat-\u003ewl_hi_pri_task2 = true;\n+\n+\t\t\treq.seq = 0x0e;\n+\t\t\treq.op_code = BT_MP_INFO_OP_SUPP_VER;\n+\t\t\trtw_fw_query_bt_mp_info(rtwdev, \u0026req);\n+\t\t\treq.seq = 0x0f;\n+\t\t\treq.op_code = BT_MP_INFO_OP_PATCH_VER;\n+\t\t\trtw_fw_query_bt_mp_info(rtwdev, \u0026req);\n+\t\t\trtw_fw_query_bt_info(rtwdev);\n+\n+\t\t\trtw_coex_8723bs_scan_workaround(rtwdev);\n+\t\t} else {\n+\t\t\tcoex_stat-\u003ewl_hi_pri_task2 = false;\n+\t\t}\n+\t\treturn;\n+\t}\n+\n \tif (type == COEX_SCAN_START_5G) {\n \t\trtw_dbg(rtwdev, RTW_DBG_COEX,\n \t\t\t\"[BTCoex], SCAN START notify (5G)\\n\");\n@@ -2938,6 +3150,17 @@ void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type)\n \tif (coex-\u003emanual_control || coex-\u003estop_dm)\n \t\treturn;\n \n+\t/* 8723BS SDIO BT-disabled: the vendor ConnectNotify() early-returns\n+\t * without sending H2Cs; scan_workaround already established the PTA\n+\t * path / coex table / PS-TDMA. Keep only the register-level PTA\n+\t * reassertion at associate-start.\n+\t */\n+\tif (rtw_coex_8723bs_bt_disabled(rtwdev)) {\n+\t\tif (type == COEX_ASSOCIATE_START)\n+\t\t\trtw_coex_8723bs_force_assoc_pta_ant(rtwdev);\n+\t\treturn;\n+\t}\n+\n \trtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);\n \n \tif (type == COEX_ASSOCIATE_5G_START) {\ndiff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h\nindex c398be8391f7b0..c58ae0a50b30b1 100644\n--- a/drivers/net/wireless/realtek/rtw88/coex.h\n+++ b/drivers/net/wireless/realtek/rtw88/coex.h\n@@ -430,4 +430,7 @@ static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)\n \t\trtw_coex_query_bt_info(rtwdev);\n }\n \n+void rtw_coex_8723bs_scan_workaround(struct rtw_dev *rtwdev);\n+void rtw_coex_8723bs_pre_auth_h2c(struct rtw_dev *rtwdev);\n+\n #endif\ndiff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c\nindex 945fedcd375b62..20f19675238147 100644\n--- a/drivers/net/wireless/realtek/rtw88/fw.c\n+++ b/drivers/net/wireless/realtek/rtw88/fw.c\n@@ -317,6 +317,15 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)\n \tcase C2H_CCX_TX_RPT:\n \t\trtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);\n \t\tbreak;\n+\tcase C2H_VENDOR_TX_RPT:\n+\tcase C2H_WLAN_RFON:\n+\t\t/*\n+\t\t * The RTL8723BS firmware reports management TX through these\n+\t\t * two events instead, using the same payload layout.\n+\t\t */\n+\t\tif (rtw_is_8723bs(rtwdev))\n+\t\t\trtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);\n+\t\tbreak;\n \tcase C2H_BT_INFO:\n \t\trtw_coex_bt_info_notify(rtwdev, c2h-\u003epayload, len);\n \t\tbreak;\n@@ -365,6 +374,15 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,\n \t\trtw_coex_info_response(rtwdev, skb);\n \t\tbreak;\n \tcase C2H_WLAN_RFON:\n+\t\t/* On 8723BS SDIO with v41 firmware, C2H 0x32 carries a scan TX\n+\t\t * report, not a WLAN_RFON event: defer it to rtw_fw_c2h_cmd_handle().\n+\t\t */\n+\t\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t\t*((u32 *)skb-\u003ecb) = pkt_offset;\n+\t\t\tskb_queue_tail(\u0026rtwdev-\u003ec2h_queue, skb);\n+\t\t\tieee80211_queue_work(rtwdev-\u003ehw, \u0026rtwdev-\u003ec2h_work);\n+\t\t\tbreak;\n+\t\t}\n \t\tcomplete(\u0026rtwdev-\u003elps_leave_check);\n \t\tdev_kfree_skb_any(skb);\n \t\tbreak;\n@@ -726,9 +744,19 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)\n \n \tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSSI_MONITOR);\n \n-\tSET_RSSI_INFO_MACID(h2c_pkt, si-\u003emac_id);\n-\tSET_RSSI_INFO_RSSI(h2c_pkt, rssi);\n-\tSET_RSSI_INFO_STBC(h2c_pkt, stbc_en);\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t/* Vendor v5.2.17 RA_INFO byte layout (H2C 0x42):\n+\t\t * [1] mac_id, [2] 0x00, [3] rssi, [4] stbc?0x04:0x00.\n+\t\t */\n+\t\th2c_pkt[1] = si-\u003emac_id \u0026 0x7f;\n+\t\th2c_pkt[2] = 0x00;\n+\t\th2c_pkt[3] = rssi;\n+\t\th2c_pkt[4] = stbc_en ? 0x04 : 0x00;\n+\t} else {\n+\t\tSET_RSSI_INFO_MACID(h2c_pkt, si-\u003emac_id);\n+\t\tSET_RSSI_INFO_RSSI(h2c_pkt, rssi);\n+\t\tSET_RSSI_INFO_STBC(h2c_pkt, stbc_en);\n+\t}\n \n \trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n }\n@@ -742,6 +770,37 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,\n \n \tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);\n \n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t/* The v41 firmware parses the vendor v5.2.17 MACID_CFG (0x40)\n+\t\t * byte layout, not the bit-packed rtw88 RA_INFO below:\n+\t\t * [1] mac_id, [2] rate_id | sgi_en(bit7),\n+\t\t * [3] bw(bits 1-0) | no_update(bit3), [4..7] 4-byte mask.\n+\t\t *\n+\t\t * no_update(bit3)=1 tells the firmware to keep its existing\n+\t\t * rate mask, so a mask that changes under no_update is dropped.\n+\t\t * Force no_update=0 whenever the mask actually changes so the\n+\t\t * update is applied, and keep no_update=1 for identical\n+\t\t * refreshes so the firmware retains the rate it has learned.\n+\t\t */\n+\t\tbool apply = reset_ra_mask || si-\u003era_mask != si-\u003era_mask_last;\n+\n+\t\th2c_pkt[1] = si-\u003emac_id \u0026 0x7f;\n+\t\th2c_pkt[2] = (si-\u003erate_id \u0026 0x1f) |\n+\t\t\t     (si-\u003esgi_enable ? BIT(7) : 0);\n+\t\th2c_pkt[3] = ((si-\u003ebw_mode ? 3 : 1) \u0026 0x3) |\n+\t\t\t     (apply ? 0 : BIT(3));\n+\t\th2c_pkt[4] = si-\u003era_mask \u0026 0xff;\n+\t\th2c_pkt[5] = (si-\u003era_mask \u003e\u003e 8) \u0026 0xff;\n+\t\th2c_pkt[6] = (si-\u003era_mask \u003e\u003e 16) \u0026 0xff;\n+\t\th2c_pkt[7] = (si-\u003era_mask \u003e\u003e 24) \u0026 0xff;\n+\n+\t\tsi-\u003era_mask_last = si-\u003era_mask;\n+\t\tsi-\u003einit_ra_lv = 0;\n+\n+\t\trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n+\t\treturn;\n+\t}\n+\n \tSET_RA_INFO_MACID(h2c_pkt, si-\u003emac_id);\n \tSET_RA_INFO_RATE_ID(h2c_pkt, si-\u003erate_id);\n \tSET_RA_INFO_INIT_RA_LVL(h2c_pkt, si-\u003einit_ra_lv);\n@@ -780,8 +839,78 @@ void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect)\n \tu8 h2c_pkt[H2C_PKT_SIZE] = {0};\n \n \tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_MEDIA_STATUS_RPT);\n-\tMEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect);\n-\tMEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id);\n+\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t/* Vendor v5.2.17 MEDIA_STATUS_RPT: connect = 21 00 00,\n+\t\t * disconnect = 00 00 00. Byte1[0]=OPMODE, [5]=ROLE(STA=0),\n+\t\t * [1]=MACID_IND; byte2=MACID; byte3=MACID_END.\n+\t\t */\n+\t\th2c_pkt[1] = connect ? 0x21 : 0x00;\n+\t\th2c_pkt[2] = mac_id \u0026 0x7f;\n+\t\th2c_pkt[3] = 0x00;\n+\t} else {\n+\t\tMEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect);\n+\t\tMEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id);\n+\t}\n+\n+\trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n+}\n+\n+/* 8723BS SDIO: post-assoc rate-adaptation config in the vendor v5.2.17\n+ * MACID_CFG byte layout. disra (bit7 of [2]) must stay 0 so the firmware keeps\n+ * running rate adaptation for this mac_id.\n+ */\n+void rtw_fw_macid_cfg(struct rtw_dev *rtwdev, u8 mac_id, u8 raid, u8 bw,\n+\t\t      u8 sgi, u32 rate_mask)\n+{\n+\tu8 h2c_pkt[H2C_PKT_SIZE] = {0};\n+\n+\tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);\n+\n+\th2c_pkt[1] = mac_id \u0026 0x7f;\n+\th2c_pkt[2] = (raid \u0026 0x1f) | (sgi ? BIT(7) : 0) | 0x60;\n+\th2c_pkt[3] = (bw ? 3 : 1) \u0026 0x3;\n+\th2c_pkt[4] = rate_mask \u0026 0xff;\n+\th2c_pkt[5] = (rate_mask \u003e\u003e 8) \u0026 0xff;\n+\th2c_pkt[6] = (rate_mask \u003e\u003e 16) \u0026 0xff;\n+\th2c_pkt[7] = (rate_mask \u003e\u003e 24) \u0026 0xff;\n+\n+\trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n+}\n+\n+/* 8723BS SDIO: report the connected channel/bandwidth to the vendor firmware. */\n+void rtw_fw_send_wl_ch_info(struct rtw_dev *rtwdev, u8 ch, u8 bw)\n+{\n+\tu8 h2c_pkt[H2C_PKT_SIZE] = {0};\n+\tu8 bw_byte = bw == RTW_CHANNEL_WIDTH_40 ? 0x30 : 0x20;\n+\n+\tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_CH_INFO);\n+\th2c_pkt[1] = 0x00;\n+\th2c_pkt[2] = ch;\n+\th2c_pkt[3] = bw_byte;\n+\n+\trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n+}\n+\n+/* 8723BS SDIO: set the firmware GNT_BT state (0 = WiFi owns the antenna). */\n+void rtw_fw_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)\n+{\n+\tu8 h2c_pkt[H2C_PKT_SIZE] = {0};\n+\n+\tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_GNT_BT);\n+\tSET_GNT_BT_STATE(h2c_pkt, state);\n+\n+\trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n+}\n+\n+/* 8723BS SDIO: vendor coex antenna-select reserve H2C (part of the init toggle). */\n+void rtw_fw_coex_ant_sel_rsv(struct rtw_dev *rtwdev, u8 inverse, u8 type)\n+{\n+\tu8 h2c_pkt[H2C_PKT_SIZE] = {0};\n+\n+\tSET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_COEX_ANT_SEL_RSV);\n+\tSET_COEX_ANT_SEL_RSV_INVERSE(h2c_pkt, inverse);\n+\tSET_COEX_ANT_SEL_RSV_TYPE(h2c_pkt, type);\n \n \trtw_fw_send_h2c_command(rtwdev, h2c_pkt);\n }\n@@ -1466,10 +1595,14 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,\n \trtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_INFO, true);\n }\n \n+/* REG_DWBCN1_CTRL bit 20 (SW_BCN_SEL for port 0), relative to byte +2 */\n+#define BIT_OFFSET_DWBCN1_SW_BCN_SEL_PORT0\t(20 - 16)\n+\n int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,\n \t\t\t\tu8 *buf, u32 size)\n {\n-\tu8 bckp[3];\n+\tconst bool is_8723bs_sdio = rtw_is_8723bs(rtwdev);\n+\tu8 bckp[4];\n \tu8 val;\n \tu16 rsvd_pg_head;\n \tu32 bcn_valid_addr;\n@@ -1499,13 +1632,28 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,\n \trtw_write8(rtwdev, REG_BCN_CTRL,\n \t\t   (bckp[2] \u0026 ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT);\n \n-\tif (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {\n+\t/* Clear BIT_EN_BCNQ_DL so the chip does not treat the reserved-page\n+\t * upload as a real beacon; otherwise BIT_BCN_VALID never asserts. The\n+\t * vendor rtl8723bs driver does this unconditionally; rtw88 only did it\n+\t * for PCIe, which left 8723BS SDIO's BCN_VALID handshake failing.\n+\t */\n+\tif (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE || is_8723bs_sdio) {\n \t\tval = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);\n \t\tbckp[1] = val;\n \t\tval \u0026= ~(BIT_EN_BCNQ_DL \u003e\u003e 16);\n \t\trtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val);\n \t}\n \n+\t/* 8723BS SDIO: point the SW beacon download path at port 0, else\n+\t * BIT_BCN_VALID is never asserted after the SDIO upload completes.\n+\t */\n+\tif (is_8723bs_sdio) {\n+\t\tval = rtw_read8(rtwdev, REG_DWBCN1_CTRL + 2);\n+\t\tbckp[3] = val;\n+\t\tval \u0026= ~BIT(BIT_OFFSET_DWBCN1_SW_BCN_SEL_PORT0);\n+\t\trtw_write8(rtwdev, REG_DWBCN1_CTRL + 2, val);\n+\t}\n+\n \tret = rtw_hci_write_data_rsvd_page(rtwdev, buf, size);\n \tif (ret) {\n \t\trtw_err(rtwdev, \"failed to write data to rsvd page\\n\");\n@@ -1526,11 +1674,13 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,\n \t}\n \n restore:\n+\tif (is_8723bs_sdio)\n+\t\trtw_write8(rtwdev, REG_DWBCN1_CTRL + 2, bckp[3]);\n \trsvd_pg_head = rtwdev-\u003efifo.rsvd_boundary;\n \trtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,\n \t\t    rsvd_pg_head | BIT_BCN_VALID_V1);\n \trtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]);\n-\tif (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)\n+\tif (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE || is_8723bs_sdio)\n \t\trtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);\n \trtw_write8(rtwdev, REG_CR + 1, bckp[0]);\n \ndiff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h\nindex 48ad9ceab6ea12..8b238b41decfa2 100644\n--- a/drivers/net/wireless/realtek/rtw88/fw.h\n+++ b/drivers/net/wireless/realtek/rtw88/fw.h\n@@ -54,6 +54,10 @@ enum rtw_c2h_cmd_id {\n \tC2H_BT_MP_INFO = 0x0b,\n \tC2H_BT_HID_INFO = 0x45,\n \tC2H_RA_RPT = 0x0c,\n+\t/* 8723BS SDIO vendor v41 firmware management TX report (0x32 is\n+\t * reported as C2H_WLAN_RFON, handled per-chip in the C2H dispatch).\n+\t */\n+\tC2H_VENDOR_TX_RPT = 0x12,\n \tC2H_HW_FEATURE_REPORT = 0x19,\n \tC2H_WLAN_INFO = 0x27,\n \tC2H_WLAN_RFON = 0x32,\n@@ -568,10 +572,12 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)\n #define H2C_CMD_QUERY_BT_INFO\t\t0x61\n #define H2C_CMD_FORCE_BT_TX_POWER\t0x62\n #define H2C_CMD_IGNORE_WLAN_ACTION\t0x63\n+#define H2C_CMD_COEX_ANT_SEL_RSV\t0x65\n #define H2C_CMD_WL_CH_INFO\t\t0x66\n #define H2C_CMD_QUERY_BT_MP_INFO\t0x67\n #define H2C_CMD_BT_WIFI_CONTROL\t\t0x69\n #define H2C_CMD_WIFI_CALIBRATION\t0x6d\n+#define H2C_CMD_GNT_BT\t\t\t0x6e\n #define H2C_CMD_QUERY_BT_HID_INFO\t0x73\n \n #define H2C_CMD_KEEP_ALIVE\t\t0x03\n@@ -684,6 +690,12 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)\n \tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(31, 24))\n #define SET_QUERY_BT_INFO(h2c_pkt, value)                                      \\\n \tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))\n+#define SET_GNT_BT_STATE(h2c_pkt, value)                                       \\\n+\tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))\n+#define SET_COEX_ANT_SEL_RSV_INVERSE(h2c_pkt, value)                           \\\n+\tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))\n+#define SET_COEX_ANT_SEL_RSV_TYPE(h2c_pkt, value)                              \\\n+\tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))\n #define SET_WL_CH_INFO_LINK(h2c_pkt, value)                                    \\\n \tle32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))\n #define SET_WL_CH_INFO_CHNL(h2c_pkt, value)                                    \\\n@@ -849,6 +861,11 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);\n void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,\n \t\t\t bool reset_ra_mask);\n void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn);\n+void rtw_fw_macid_cfg(struct rtw_dev *rtwdev, u8 mac_id, u8 raid, u8 bw,\n+\t\t      u8 sgi, u32 rate_mask);\n+void rtw_fw_send_wl_ch_info(struct rtw_dev *rtwdev, u8 ch, u8 bw);\n+void rtw_fw_set_gnt_bt(struct rtw_dev *rtwdev, u8 state);\n+void rtw_fw_coex_ant_sel_rsv(struct rtw_dev *rtwdev, u8 inverse, u8 type);\n void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev);\n void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,\n \t\t\t\t struct ieee80211_vif *vif);\ndiff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c\nindex 766f22d31079ee..f920321b8874e5 100644\n--- a/drivers/net/wireless/realtek/rtw88/mac80211.c\n+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c\n@@ -15,6 +15,463 @@\n #include \"wow.h\"\n #include \"sar.h\"\n \n+/* 8723BS SDIO: record a beacon/probe-resp seen from the target BSSID during\n+ * the pre-auth window so the join sequence (mgd_prepare_tx) can wait for it,\n+ * mirroring the vendor start_clnt_join(). Called from the SDIO RX path.\n+ */\n+void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\n+\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n+\t\t\t    const struct rtw_rx_pkt_stat *pkt_stat,\n+\t\t\t    const struct ieee80211_rx_status *rx_status)\n+{\n+\tstruct rtw_auth_sync *sync = \u0026rtwdev-\u003eauth_sync;\n+\tunsigned long flags;\n+\t__le16 fc = hdr-\u003eframe_control;\n+\n+\tif (!rtw_is_8723bs(rtwdev) ||\n+\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags) ||\n+\t    pkt_stat-\u003ecrc_err || pkt_stat-\u003eicv_err)\n+\t\treturn;\n+\n+\tif (!ieee80211_is_beacon(fc) \u0026\u0026 !ieee80211_is_probe_resp(fc))\n+\t\treturn;\n+\n+\tspin_lock_irqsave(\u0026sync-\u003elock, flags);\n+\tif (sync-\u003eactive \u0026\u0026 ether_addr_equal(hdr-\u003eaddr3, sync-\u003ebssid)) {\n+\t\tsync-\u003eseen = true;\n+\t\tsync-\u003eseen_count++;\n+\t\twake_up(\u0026sync-\u003ewait);\n+\t}\n+\tspin_unlock_irqrestore(\u0026sync-\u003elock, flags);\n+}\n+EXPORT_SYMBOL(rtw8723bs_auth_sync_rx);\n+\n+/* ---- 8723BS SDIO association sequence (vendor start_clnt_join) ---- */\n+\n+#define RTW8723BS_JOIN_RETRY_LIMIT\t\t0x30\n+#define RTW8723BS_AUTH_SYNC_WAIT_FALLBACK_MS\t120\n+#define RTW8723BS_AUTH_SYNC_WAIT_MIN_MS\t\t80\n+#define RTW8723BS_AUTH_SYNC_WAIT_MAX_MS\t\t160\n+#define RTW8723BS_ACK_PREAMBLE_SHORT\t\tBIT(7)\n+#define RTW8723BS_SHORT_SLOT_TIME\t\t9\n+#define RTW8723BS_LONG_SLOT_TIME\t\t20\n+#define RTW8723BS_RRSR_1M\t\t\tBIT(0)\n+#define RTW8723BS_RRSR_2M\t\t\tBIT(1)\n+#define RTW8723BS_RRSR_5_5M\t\t\tBIT(2)\n+#define RTW8723BS_RRSR_11M\t\t\tBIT(3)\n+#define RTW8723BS_RRSR_6M\t\t\tBIT(4)\n+#define RTW8723BS_RRSR_9M\t\t\tBIT(5)\n+#define RTW8723BS_RRSR_12M\t\t\tBIT(6)\n+#define RTW8723BS_RRSR_18M\t\t\tBIT(7)\n+#define RTW8723BS_RRSR_24M\t\t\tBIT(8)\n+#define RTW8723BS_RRSR_36M\t\t\tBIT(9)\n+#define RTW8723BS_RRSR_48M\t\t\tBIT(10)\n+#define RTW8723BS_RRSR_54M\t\t\tBIT(11)\n+#define RTW8723BS_RRSR_CCK_RATES \\\n+\t(RTW8723BS_RRSR_1M | RTW8723BS_RRSR_2M | \\\n+\t RTW8723BS_RRSR_5_5M | RTW8723BS_RRSR_11M)\n+#define RTW8723BS_RRSR_2G_FORCE\t\t\tRTW8723BS_RRSR_CCK_RATES\n+#define RTW8723BS_RRSR_2G_ALLOW \\\n+\t(RTW8723BS_RRSR_CCK_RATES | RTW8723BS_RRSR_6M | \\\n+\t RTW8723BS_RRSR_12M | RTW8723BS_RRSR_24M)\n+\n+/* Keep the RCR at the vendor target-only state (AMF + CBSSID) across the whole\n+ * connect window, matching the vendor STA path. accept_all is kept only for the\n+ * caller's intent; both paths converge the filter to target-only.\n+ */\n+static void rtw8723bs_auth_rx_filter(struct rtw_dev *rtwdev, bool accept_all)\n+{\n+\trtwdev-\u003ehal.rcr |= BIT_AMF | BIT_CBSSID_DATA | BIT_CBSSID_BCN;\n+\trtwdev-\u003ehal.rcr \u0026= ~BIT_AAP;\n+\trtw_write32(rtwdev, REG_RCR, rtwdev-\u003ehal.rcr);\n+}\n+\n+static void rtw8723bs_config_sec_cfg(struct rtw_dev *rtwdev)\n+{\n+\tu16 sec = rtw_read16(rtwdev, RTW_SEC_CONFIG);\n+\n+\tsec |= RTW_SEC_CHK_KEYID | RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;\n+\trtw_write16(rtwdev, RTW_SEC_CONFIG, sec);\n+}\n+\n+static void rtw8723bs_config_default_key_search(struct rtw_dev *rtwdev,\n+\t\t\t\t\t\tbool enable)\n+{\n+\tu16 sec = rtw_read16(rtwdev, RTW_SEC_CONFIG);\n+\n+\tif (enable)\n+\t\tsec |= RTW_SEC_TX_BC_USE_DK | RTW_SEC_TX_UNI_USE_DK |\n+\t\t       RTW_SEC_RX_UNI_USE_DK;\n+\telse\n+\t\tsec \u0026= ~(RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |\n+\t\t\t RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK);\n+\trtw_write16(rtwdev, RTW_SEC_CONFIG, sec);\n+}\n+\n+static void rtw8723bs_enable_tsf_update(struct rtw_dev *rtwdev)\n+{\n+\trtw_write8_clr(rtwdev, REG_BCN_CTRL, BIT_DIS_TSF_UDT);\n+}\n+\n+static void rtw8723bs_set_ack_preamble(struct rtw_dev *rtwdev,\n+\t\t\t\t       bool short_preamble)\n+{\n+\tu8 val = rtw_read8(rtwdev, REG_RRSR + 2) \u0026 ~RTW8723BS_ACK_PREAMBLE_SHORT;\n+\n+\tif (short_preamble)\n+\t\tval |= RTW8723BS_ACK_PREAMBLE_SHORT;\n+\trtw_write8(rtwdev, REG_RRSR + 2, val);\n+}\n+\n+static void rtw8723bs_set_slot_time(struct rtw_dev *rtwdev, bool short_slot)\n+{\n+\trtw_write8(rtwdev, REG_SLOT,\n+\t\t   short_slot ? RTW8723BS_SHORT_SLOT_TIME :\n+\t\t\t\tRTW8723BS_LONG_SLOT_TIME);\n+}\n+\n+static u16 rtw8723bs_rrsr_from_ie_rate(u8 rate)\n+{\n+\tswitch (rate \u0026 0x7f) {\n+\tcase 2:   return RTW8723BS_RRSR_1M;\n+\tcase 4:   return RTW8723BS_RRSR_2M;\n+\tcase 11:  return RTW8723BS_RRSR_5_5M;\n+\tcase 22:  return RTW8723BS_RRSR_11M;\n+\tcase 12:  return RTW8723BS_RRSR_6M;\n+\tcase 18:  return RTW8723BS_RRSR_9M;\n+\tcase 24:  return RTW8723BS_RRSR_12M;\n+\tcase 36:  return RTW8723BS_RRSR_18M;\n+\tcase 48:  return RTW8723BS_RRSR_24M;\n+\tcase 72:  return RTW8723BS_RRSR_36M;\n+\tcase 96:  return RTW8723BS_RRSR_48M;\n+\tcase 108: return RTW8723BS_RRSR_54M;\n+\tdefault:  return 0;\n+\t}\n+}\n+\n+static void rtw8723bs_collect_basic_rates(const u8 *ie, u16 *basic_rates,\n+\t\t\t\t\t  bool *valid)\n+{\n+\tint i;\n+\n+\tif (!ie)\n+\t\treturn;\n+\n+\tfor (i = 0; i \u003c ie[1]; i++) {\n+\t\tu16 r;\n+\n+\t\tif (!(ie[i + 2] \u0026 0x80))\n+\t\t\tcontinue;\n+\t\tr = rtw8723bs_rrsr_from_ie_rate(ie[i + 2]);\n+\t\tif (!r)\n+\t\t\tcontinue;\n+\t\t*basic_rates |= r;\n+\t\t*valid = true;\n+\t}\n+}\n+\n+static void rtw8723bs_reset_response_rates(struct rtw_dev *rtwdev)\n+{\n+\trtw_write32(rtwdev, REG_RRSR, 0xffff1);\n+\trtwdev-\u003edm_info.rrsr_val_init = 0xffff1;\n+}\n+\n+static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,\n+\t\t\t\t\tstruct ieee80211_vif *vif,\n+\t\t\t\t\tconst u8 *bssid)\n+{\n+\tstruct ieee80211_bss_conf *conf = \u0026vif-\u003ebss_conf;\n+\tstruct cfg80211_bss *lookup_bss = NULL;\n+\tstruct cfg80211_bss *bss = NULL;\n+\tbool valid = false;\n+\tu16 basic_rates = 0;\n+\n+\tif (!rtw_is_8723bs(rtwdev) || vif-\u003etype != NL80211_IFTYPE_STATION)\n+\t\treturn;\n+\n+\tif (conf-\u003ebss) {\n+\t\tbss = conf-\u003ebss;\n+\t} else if (bssid \u0026\u0026 is_valid_ether_addr(bssid)) {\n+\t\tlookup_bss = cfg80211_get_bss(rtwdev-\u003ehw-\u003ewiphy, NULL,\n+\t\t\t\t\t      bssid, NULL, 0,\n+\t\t\t\t\t      IEEE80211_BSS_TYPE_ESS,\n+\t\t\t\t\t      IEEE80211_PRIVACY_ANY);\n+\t\tbss = lookup_bss;\n+\t}\n+\n+\tif (bss) {\n+\t\tconst u8 *rates, *ext;\n+\n+\t\trcu_read_lock();\n+\t\trates = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);\n+\t\text = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);\n+\t\trtw8723bs_collect_basic_rates(rates, \u0026basic_rates, \u0026valid);\n+\t\trtw8723bs_collect_basic_rates(ext, \u0026basic_rates, \u0026valid);\n+\t\trcu_read_unlock();\n+\t}\n+\n+\tif (valid) {\n+\t\tbasic_rates |= RTW8723BS_RRSR_2G_FORCE;\n+\t\tbasic_rates \u0026= RTW8723BS_RRSR_2G_ALLOW;\n+\t\trtw_write16(rtwdev, REG_RRSR, basic_rates);\n+\t\trtw_write8(rtwdev, REG_RRSR + 2,\n+\t\t\t   rtw_read8(rtwdev, REG_RRSR + 2) \u0026 0xf0);\n+\t\trtwdev-\u003edm_info.rrsr_val_init = basic_rates;\n+\t}\n+\n+\tif (lookup_bss)\n+\t\tcfg80211_put_bss(rtwdev-\u003ehw-\u003ewiphy, lookup_bss);\n+}\n+\n+/* Program response slot time (and, when set_preamble, the ACK preamble) from\n+ * the selected scan BSS capabilities; the AP capabilities are not yet in\n+ * bss_conf at mgd_prepare_tx() time.\n+ */\n+static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,\n+\t\t\t\t    struct ieee80211_vif *vif,\n+\t\t\t\t    const u8 *bssid, bool set_preamble)\n+{\n+\tstruct ieee80211_bss_conf *conf = \u0026vif-\u003ebss_conf;\n+\tstruct cfg80211_bss *lookup_bss = NULL;\n+\tstruct cfg80211_bss *bss = NULL;\n+\tbool short_preamble, short_slot;\n+\tu16 cap = 0;\n+\n+\tif (!rtw_is_8723bs(rtwdev) || vif-\u003etype != NL80211_IFTYPE_STATION)\n+\t\treturn;\n+\n+\tif (conf-\u003ebss) {\n+\t\tbss = conf-\u003ebss;\n+\t} else if (bssid \u0026\u0026 is_valid_ether_addr(bssid)) {\n+\t\tlookup_bss = cfg80211_get_bss(rtwdev-\u003ehw-\u003ewiphy, NULL,\n+\t\t\t\t\t      bssid, NULL, 0,\n+\t\t\t\t\t      IEEE80211_BSS_TYPE_ESS,\n+\t\t\t\t\t      IEEE80211_PRIVACY_ANY);\n+\t\tbss = lookup_bss;\n+\t}\n+\n+\tif (bss) {\n+\t\tcap = bss-\u003ecapability;\n+\t} else if (conf-\u003eassoc_capability) {\n+\t\tcap = conf-\u003eassoc_capability;\n+\t} else {\n+\t\tshort_preamble = conf-\u003euse_short_preamble;\n+\t\tshort_slot = conf-\u003euse_short_slot;\n+\t\tgoto program;\n+\t}\n+\tshort_preamble = !!(cap \u0026 WLAN_CAPABILITY_SHORT_PREAMBLE);\n+\tshort_slot = !!(cap \u0026 WLAN_CAPABILITY_SHORT_SLOT_TIME);\n+\n+program:\n+\tif (set_preamble)\n+\t\trtw8723bs_set_ack_preamble(rtwdev, short_preamble);\n+\trtw8723bs_set_slot_time(rtwdev, short_slot);\n+\n+\tif (lookup_bss)\n+\t\tcfg80211_put_bss(rtwdev-\u003ehw-\u003ewiphy, lookup_bss);\n+}\n+\n+static unsigned int rtw8723bs_auth_sync_wait_ms(struct ieee80211_vif *vif)\n+{\n+\tu16 beacon_int = vif-\u003ebss_conf.beacon_int;\n+\tunsigned int wait_ms;\n+\n+\tif (!beacon_int)\n+\t\treturn RTW8723BS_AUTH_SYNC_WAIT_FALLBACK_MS;\n+\n+\twait_ms = DIV_ROUND_UP(beacon_int * 1024, 1000) + 20;\n+\treturn clamp_t(unsigned int, wait_ms, RTW8723BS_AUTH_SYNC_WAIT_MIN_MS,\n+\t\t       RTW8723BS_AUTH_SYNC_WAIT_MAX_MS);\n+}\n+\n+static void rtw8723bs_auth_sync_start(struct rtw_dev *rtwdev, const u8 *bssid)\n+{\n+\tstruct rtw_auth_sync *sync = \u0026rtwdev-\u003eauth_sync;\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(\u0026sync-\u003elock, flags);\n+\tether_addr_copy(sync-\u003ebssid, bssid);\n+\tsync-\u003eseen = false;\n+\tsync-\u003eseen_count = 0;\n+\tsync-\u003eactive = true;\n+\tspin_unlock_irqrestore(\u0026sync-\u003elock, flags);\n+}\n+\n+static void rtw8723bs_auth_sync_stop(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_auth_sync *sync = \u0026rtwdev-\u003eauth_sync;\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(\u0026sync-\u003elock, flags);\n+\tsync-\u003eactive = false;\n+\tspin_unlock_irqrestore(\u0026sync-\u003elock, flags);\n+}\n+\n+static bool rtw8723bs_auth_sync_seen(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_auth_sync *sync = \u0026rtwdev-\u003eauth_sync;\n+\tunsigned long flags;\n+\tbool seen;\n+\n+\tspin_lock_irqsave(\u0026sync-\u003elock, flags);\n+\tseen = sync-\u003eseen;\n+\tspin_unlock_irqrestore(\u0026sync-\u003elock, flags);\n+\n+\treturn seen;\n+}\n+\n+static bool rtw8723bs_auth_sync_wait(struct rtw_dev *rtwdev,\n+\t\t\t\t     unsigned int wait_ms)\n+{\n+\tstruct rtw_auth_sync *sync = \u0026rtwdev-\u003eauth_sync;\n+\n+\treturn wait_event_timeout(sync-\u003ewait, rtw8723bs_auth_sync_seen(rtwdev),\n+\t\t\t\t  msecs_to_jiffies(wait_ms)) \u003e 0;\n+}\n+\n+static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,\n+\t\t\t\t\t  struct ieee80211_prep_tx_info *info)\n+{\n+\treturn rtw_is_8723bs(rtwdev) \u0026\u0026 info \u0026\u0026\n+\t       info-\u003esubtype == IEEE80211_STYPE_AUTH;\n+}\n+\n+/* Replicate the vendor start_clnt_join() register programming right before\n+ * auth. Returns true for a fresh join (BSSID changed).\n+ */\n+static bool rtw8723bs_mgd_prepare_join(struct rtw_dev *rtwdev,\n+\t\t\t\t       struct ieee80211_vif *vif,\n+\t\t\t\t       const u8 *bssid)\n+{\n+\tstruct rtw_vif *rtwvif = (struct rtw_vif *)vif-\u003edrv_priv;\n+\tbool fresh_join;\n+\tu16 retry_limit;\n+\n+\tif (!is_valid_ether_addr(bssid))\n+\t\treturn false;\n+\n+\tfresh_join = !ether_addr_equal(rtwvif-\u003ebssid, bssid);\n+\n+\tether_addr_copy(rtwvif-\u003ebssid, bssid);\n+\trtwvif-\u003eaid = 0;\n+\trtwvif-\u003enet_type = RTW_NET_MGD_LINKED;\n+\trtw_vif_port_config(rtwdev, rtwvif,\n+\t\t\t    PORT_SET_BSSID | PORT_SET_AID | PORT_SET_NET_TYPE);\n+\n+\t/* Do not narrow RRSR or switch to short-preamble responses before the\n+\t * exchange: the whole auth/assoc runs on the init response set\n+\t * (0xffff1, long preamble). Only slot time is programmed early.\n+\t */\n+\trtw8723bs_apply_bss_cap(rtwdev, vif, bssid, false);\n+\n+\trtw_fw_beacon_filter_config(rtwdev, false, vif);\n+\n+\t/* Match the vendor start_clnt_join() TX state (set_msr directly, keep\n+\t * BCN_CTRL / BCNQ_DL set, reassert TBTT/RESP_SIFS every join).\n+\t */\n+\trtw_write8(rtwdev, REG_BCN_CTRL,\n+\t\t   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);\n+\trtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT_EN_BCNQ_DL);\n+\trtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1, 0x64 \u0026 0xff);\n+\trtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2,\n+\t\t   (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) \u0026 0xf0) | (0x64 \u003e\u003e 8));\n+\trtw_write16(rtwdev, REG_RESP_SIFS_CCK, 0x0808);\n+\trtw_write16(rtwdev, REG_RESP_SIFS_OFDM, 0x0a0a);\n+\n+\trtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff);\n+\trtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);\n+\trtw8723bs_auth_rx_filter(rtwdev, true);\n+\n+\tretry_limit = (RTW8723BS_JOIN_RETRY_LIMIT \u003c\u003c 8) |\n+\t\t      RTW8723BS_JOIN_RETRY_LIMIT;\n+\trtw_write16(rtwdev, REG_RETRY_LIMIT, retry_limit);\n+\n+\trtw8723bs_config_sec_cfg(rtwdev);\n+\n+\treturn fresh_join;\n+}\n+\n+/* The vendor sends a deauth to the target before auth to clear stale AP-side\n+ * state; synthesize and TX one, then let the AP settle.\n+ */\n+static void rtw8723bs_tx_pre_auth_deauth(struct rtw_dev *rtwdev,\n+\t\t\t\t\t struct ieee80211_vif *vif,\n+\t\t\t\t\t const u8 *bssid)\n+{\n+\tstruct ieee80211_tx_control control = {};\n+\tstruct ieee80211_tx_info *info;\n+\tstruct ieee80211_mgmt *mgmt;\n+\tstruct sk_buff *skb;\n+\tunsigned int frame_len, headroom;\n+\n+\tframe_len = sizeof(struct ieee80211_hdr_3addr) + sizeof(mgmt-\u003eu.deauth);\n+\theadroom = rtwdev-\u003echip-\u003etx_pkt_desc_sz + 8;\n+\n+\tskb = dev_alloc_skb(headroom + frame_len);\n+\tif (!skb)\n+\t\treturn;\n+\n+\tskb_reserve(skb, headroom);\n+\tmgmt = skb_put_zero(skb, frame_len);\n+\tmgmt-\u003eframe_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |\n+\t\t\t\t\t  IEEE80211_STYPE_DEAUTH);\n+\tmemcpy(mgmt-\u003eda, bssid, ETH_ALEN);\n+\tmemcpy(mgmt-\u003esa, vif-\u003eaddr, ETH_ALEN);\n+\tmemcpy(mgmt-\u003ebssid, bssid, ETH_ALEN);\n+\tmgmt-\u003eu.deauth.reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);\n+\n+\tinfo = IEEE80211_SKB_CB(skb);\n+\tmemset(info, 0, sizeof(*info));\n+\tinfo-\u003econtrol.vif = vif;\n+\n+\trtw_tx(rtwdev, \u0026control, skb);\n+\tmsleep(100);\n+}\n+\n+/* Orchestrate the pre-auth join: program the vendor join state, send the\n+ * pre-auth deauth, wait for a beacon from the target, then replay the\n+ * pre-auth coex H2Cs - once per fresh BSSID.\n+ */\n+static void rtw8723bs_mgd_prepare_auth_join(struct rtw_dev *rtwdev,\n+\t\t\t\t\t    struct ieee80211_vif *vif,\n+\t\t\t\t\t    struct ieee80211_prep_tx_info *info)\n+{\n+\tstruct rtw_vif *rtwvif;\n+\tconst u8 *bssid = NULL;\n+\tbool fresh_join;\n+\n+\tif (!rtw8723bs_mgd_prepare_is_auth(rtwdev, info) || !vif ||\n+\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags))\n+\t\treturn;\n+\n+\trtwvif = (struct rtw_vif *)vif-\u003edrv_priv;\n+\n+\tif (!is_zero_ether_addr(vif-\u003ecfg.ap_addr))\n+\t\tbssid = vif-\u003ecfg.ap_addr;\n+\telse if (vif-\u003ebss_conf.bssid \u0026\u0026 !is_zero_ether_addr(vif-\u003ebss_conf.bssid))\n+\t\tbssid = vif-\u003ebss_conf.bssid;\n+\n+\tif (!bssid)\n+\t\treturn;\n+\n+\tfresh_join = rtw8723bs_mgd_prepare_join(rtwdev, vif, bssid);\n+\n+\tif (fresh_join || !rtwvif-\u003epre_auth_join_done) {\n+\t\tunsigned int wait_ms = rtw8723bs_auth_sync_wait_ms(vif);\n+\n+\t\trtw8723bs_auth_sync_start(rtwdev, bssid);\n+\t\trtw8723bs_tx_pre_auth_deauth(rtwdev, vif, bssid);\n+\t\trtw8723bs_auth_sync_wait(rtwdev, wait_ms);\n+\t\trtw8723bs_auth_sync_stop(rtwdev);\n+\t\trtwvif-\u003epre_auth_join_done = true;\n+\t}\n+\n+\tif (!rtwvif-\u003epre_auth_h2c_sent) {\n+\t\trtw_coex_8723bs_pre_auth_h2c(rtwdev);\n+\t\trtwvif-\u003epre_auth_h2c_sent = true;\n+\t}\n+}\n+\n static void rtw_ops_tx(struct ieee80211_hw *hw,\n \t\t       struct ieee80211_tx_control *control,\n \t\t       struct sk_buff *skb)\n@@ -387,6 +844,28 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n \tif (changed \u0026 BSS_CHANGED_ASSOC) {\n \t\trtw_vif_assoc_changed(rtwvif, conf);\n \t\tif (vif-\u003ecfg.assoc) {\n+\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\n+\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\n+\t\t\t\trtw8723bs_apply_bss_cap(rtwdev, vif, NULL, true);\n+\t\t\t\trtw8723bs_apply_basic_rates(rtwdev, vif, NULL);\n+\t\t\t\trtw8723bs_enable_tsf_update(rtwdev);\n+\t\t\t\t/* Vendor mlmeext_joinbss sends MACID_CFG before\n+\t\t\t\t * MEDIA_STATUS_RPT, then WL_CH_INFO.\n+\t\t\t\t */\n+\t\t\t\trtw_fw_macid_cfg(rtwdev, rtwvif-\u003emac_id,\n+\t\t\t\t\t\t 1, 0, 1, 0x0ff015);\n+\t\t\t\tif (!rtwvif-\u003efw_media_connected) {\n+\t\t\t\t\trtw_fw_media_status_report(rtwdev,\n+\t\t\t\t\t\t\t\t   rtwvif-\u003emac_id,\n+\t\t\t\t\t\t\t\t   true);\n+\t\t\t\t\trtwvif-\u003efw_media_connected = true;\n+\t\t\t\t}\n+\t\t\t\trtw_fw_send_wl_ch_info(rtwdev,\n+\t\t\t\t\t\t       rtwdev-\u003ehal.current_channel,\n+\t\t\t\t\t\t       rtwdev-\u003ehal.current_band_width);\n+\t\t\t}\n+\n \t\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH);\n \n \t\t\trtw_fw_download_rsvd_page(rtwdev);\n@@ -408,6 +887,13 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n \t\t\tif (test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags))\n \t\t\t\trtw_hw_scan_abort(rtwdev);\n \n+\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\n+\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\n+\t\t\t\trtw8723bs_reset_response_rates(rtwdev);\n+\t\t\t\trtwvif-\u003epre_auth_h2c_sent = false;\n+\t\t\t\trtwvif-\u003epre_auth_join_done = false;\n+\t\t\t}\n \t\t}\n \n \t\tconfig |= PORT_SET_NET_TYPE;\n@@ -415,8 +901,26 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n \t}\n \n \tif (changed \u0026 BSS_CHANGED_BSSID) {\n+\t\tbool bssid_cleared = is_zero_ether_addr(conf-\u003ebssid);\n+\t\tbool bssid_changed = !ether_addr_equal(rtwvif-\u003ebssid,\n+\t\t\t\t\t\t       conf-\u003ebssid);\n+\n+\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 bssid_changed) {\n+\t\t\trtwvif-\u003epre_auth_h2c_sent = false;\n+\t\t\trtwvif-\u003epre_auth_join_done = false;\n+\t\t}\n \t\tether_addr_copy(rtwvif-\u003ebssid, conf-\u003ebssid);\n \t\tconfig |= PORT_SET_BSSID;\n+\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 bssid_cleared) {\n+\t\t\trtwvif-\u003eaid = 0;\n+\t\t\trtwvif-\u003enet_type = RTW_NET_NO_LINK;\n+\t\t\tconfig |= PORT_SET_NET_TYPE | PORT_SET_AID;\n+\t\t\trtw_write8(rtwdev, REG_BCN_CTRL,\n+\t\t\t\t   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION |\n+\t\t\t\t   BIT_DIS_ATIM);\n+\t\t}\n \t\tif (!rtw_core_check_sta_active(rtwdev))\n \t\t\trtw_clear_op_chan(rtwdev);\n \t\telse\n@@ -448,8 +952,17 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n \tif (changed \u0026 BSS_CHANGED_MU_GROUPS)\n \t\trtw_chip_set_gid_table(rtwdev, vif, conf);\n \n-\tif (changed \u0026 BSS_CHANGED_ERP_SLOT)\n+\tif (changed \u0026 BSS_CHANGED_ERP_PREAMBLE \u0026\u0026\n+\t    rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t    vif-\u003etype == NL80211_IFTYPE_STATION)\n+\t\trtw8723bs_set_ack_preamble(rtwdev, conf-\u003euse_short_preamble);\n+\n+\tif (changed \u0026 BSS_CHANGED_ERP_SLOT) {\n+\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t    vif-\u003etype == NL80211_IFTYPE_STATION)\n+\t\t\trtw8723bs_set_slot_time(rtwdev, conf-\u003euse_short_slot);\n \t\trtw_conf_tx(rtwdev, rtwvif);\n+\t}\n \n \tif (changed \u0026 BSS_CHANGED_PS)\n \t\trtw_recalc_lps(rtwdev, NULL);\n@@ -609,11 +1122,19 @@ static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n \t\tkey-\u003ehw_key_idx = hw_key_idx;\n \t\trtw_sec_write_cam(rtwdev, sec, sta, key,\n \t\t\t\t  hw_key_type, hw_key_idx);\n+\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 vif \u0026\u0026\n+\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026\n+\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\n+\t\t\trtw8723bs_config_default_key_search(rtwdev, true);\n \t\tbreak;\n \tcase DISABLE_KEY:\n \t\trtw_hci_flush_all_queues(rtwdev, false);\n \t\trtw_mac_flush_all_queues(rtwdev, false);\n \t\trtw_sec_clear_cam(rtwdev, sec, key-\u003ehw_key_idx);\n+\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 vif \u0026\u0026\n+\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026\n+\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\n+\t\t\trtw8723bs_config_default_key_search(rtwdev, false);\n \t\tbreak;\n \t}\n \n@@ -703,8 +1224,23 @@ static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,\n \n \tmutex_lock(\u0026rtwdev-\u003emutex);\n \trtw_leave_lps_deep(rtwdev);\n-\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\n-\trtw_chip_prepare_tx(rtwdev);\n+\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t/* Wake from soft IPS and run the vendor join sequence. The RFK\n+\t\t * is handled by the once-only power-on IQK plus the ps.c\n+\t\t * post-IPS RF-bus recovery, not a fresh calibration here.\n+\t\t */\n+\t\tif (rtw_leave_ips(rtwdev)) {\n+\t\t\trtw_err(rtwdev, \"failed to leave idle state for mgd tx\\n\");\n+\t\t\tgoto out;\n+\t\t}\n+\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\n+\t\trtw8723bs_mgd_prepare_auth_join(rtwdev, vif, info);\n+\t} else {\n+\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\n+\t\trtw_chip_prepare_tx(rtwdev);\n+\t}\n+out:\n \tmutex_unlock(\u0026rtwdev-\u003emutex);\n }\n \ndiff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c\nindex cd9254370fcc72..e2f0fd367bebfa 100644\n--- a/drivers/net/wireless/realtek/rtw88/main.c\n+++ b/drivers/net/wireless/realtek/rtw88/main.c\n@@ -43,6 +43,108 @@ MODULE_PARM_DESC(disable_lps_deep, \"Set Y to disable Deep PS\");\n MODULE_PARM_DESC(support_bf, \"Set Y to enable beamformee support\");\n MODULE_PARM_DESC(debug_mask, \"Debugging mask\");\n \n+#define RTW8723BS_REG_BB_SEL_BTG\t0x0948\n+#define RTW8723BS_SCAN_IGI\t\t0x1e\n+\n+struct rtw8723bs_txagc_entry {\n+\tu8 rate;\n+\tu8 pwr_idx;\n+};\n+\n+/* Vendor/staging per-rate TXAGC PG bytes for 8723BS 2.4 GHz. */\n+static const struct rtw8723bs_txagc_entry rtw8723bs_pg_txagc[] = {\n+\t{ DESC_RATE1M, 0x38 }, { DESC_RATE2M, 0x36 },\n+\t{ DESC_RATE5_5M, 0x34 }, { DESC_RATE11M, 0x32 },\n+\t{ DESC_RATE6M, 0x44 }, { DESC_RATE9M, 0x44 },\n+\t{ DESC_RATE12M, 0x42 }, { DESC_RATE18M, 0x40 },\n+\t{ DESC_RATE24M, 0x38 }, { DESC_RATE36M, 0x36 },\n+\t{ DESC_RATE48M, 0x32 }, { DESC_RATE54M, 0x28 },\n+\t{ DESC_RATEMCS0, 0x44 }, { DESC_RATEMCS1, 0x42 },\n+\t{ DESC_RATEMCS2, 0x40 }, { DESC_RATEMCS3, 0x38 },\n+\t{ DESC_RATEMCS4, 0x36 }, { DESC_RATEMCS5, 0x34 },\n+\t{ DESC_RATEMCS6, 0x30 }, { DESC_RATEMCS7, 0x26 },\n+};\n+\n+/* Lower the scan-time initial gain so the 8723BS SDIO site-survey hears the AP. */\n+static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)\n+{\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\treturn;\n+\n+\trtw_write32_mask(rtwdev, REG_RXIGI_A, MASKBYTE0, RTW8723BS_SCAN_IGI);\n+}\n+\n+/* rtw_load_table() only populates the by-rate cache; restore the staging\n+ * 8723BS PG bytes after the generic channel power update and push them to the\n+ * chip TXAGC registers.\n+ */\n+static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_hal *hal = \u0026rtwdev-\u003ehal;\n+\tu8 path;\n+\tint i;\n+\n+\tif (!rtw_is_8723bs(rtwdev) || hal-\u003ecurrent_band_type != RTW_BAND_2G)\n+\t\treturn;\n+\n+\tmutex_lock(\u0026hal-\u003etx_power_mutex);\n+\tfor (path = 0; path \u003c hal-\u003erf_path_num \u0026\u0026 path \u003c RTW_RF_PATH_MAX; path++)\n+\t\tfor (i = 0; i \u003c ARRAY_SIZE(rtw8723bs_pg_txagc); i++)\n+\t\t\thal-\u003etx_pwr_tbl[path][rtw8723bs_pg_txagc[i].rate] =\n+\t\t\t\trtw8723bs_pg_txagc[i].pwr_idx;\n+\trtwdev-\u003echip-\u003eops-\u003eset_tx_power_index(rtwdev);\n+\tmutex_unlock(\u0026hal-\u003etx_power_mutex);\n+}\n+\n+/* Staging runs PHY_IQCalibrate_8723B() only during initial hal_init, never on\n+ * IPS leave. Match that: run IQK once on the first power-on, then on later\n+ * (IPS-leave) power-ons just restore the PTA antenna path and reset RF_WLINT.\n+ */\n+static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)\n+{\n+\tconst struct rtw_chip_info *chip = rtwdev-\u003echip;\n+\tstruct rtw_efuse *efuse = \u0026rtwdev-\u003eefuse;\n+\tu32 pta_path;\n+\tu32 saved_path;\n+\n+\tif (!rtw_is_8723bs(rtwdev) || !chip-\u003eops-\u003ephy_calibration)\n+\t\treturn;\n+\n+\tpta_path = (efuse-\u003ebt_setting \u0026 BIT(6)) ? 0x80 : 0x200;\n+\n+\tif (rtwdev-\u003einitial_rfk_done) {\n+\t\trtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, pta_path);\n+\t\trtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780);\n+\t\treturn;\n+\t}\n+\n+\tsaved_path = rtw_read32(rtwdev, RTW8723BS_REG_BB_SEL_BTG);\n+\trtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, pta_path);\n+\tchip-\u003eops-\u003ephy_calibration(rtwdev);\n+\trtwdev-\u003eneed_rfk = false;\n+\trtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, saved_path);\n+\trtwdev-\u003einitial_rfk_done = true;\n+}\n+\n+static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,\n+\t\t\t\t\t   struct ieee80211_sta *sta,\n+\t\t\t\t\t   struct ieee80211_vif *vif)\n+{\n+\treturn rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t       vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 !sta-\u003etdls;\n+}\n+\n+/* 8723BS SDIO: defer the connect MEDIA_STATUS_RPT until the STA is actually\n+ * associated (the vendor firmware sends it at assoc completion, not sta-add).\n+ */\n+static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,\n+\t\t\t\t\t     struct ieee80211_sta *sta,\n+\t\t\t\t\t     struct ieee80211_vif *vif)\n+{\n+\treturn rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\n+\t       !vif-\u003ecfg.assoc;\n+}\n+\n static struct ieee80211_channel rtw_channeltable_2g[] = {\n \t{.center_freq = 2412, .hw_value = 1,},\n \t{.center_freq = 2417, .hw_value = 2,},\n@@ -299,6 +401,18 @@ static void rtw_watch_dog_work(struct work_struct *work)\n \t * get that vif and check if device is having traffic more than the\n \t * threshold.\n \t */\n+\n+\t/* On 8723BS SDIO the firmware's per-packet wake latency out of LPS\n+\t * throttles bursty traffic hard. The stock check enters LPS after a\n+\t * single quiet 2s window, which a normal bursty session hits\n+\t * constantly. Gate LPS on the smoothed throughput instead so the chip\n+\t * only sleeps after sustained idle and stays awake through an active\n+\t * session. Other chips keep the normal behaviour.\n+\t */\n+\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t    (stats-\u003etx_throughput || stats-\u003erx_throughput))\n+\t\tps_active = true;\n+\n \tif (rtwdev-\u003eps_enabled \u0026\u0026 data.rtwvif \u0026\u0026 !ps_active \u0026\u0026\n \t    !rtwdev-\u003ebeacon_loss \u0026\u0026 !rtwdev-\u003eap_active)\n \t\trtw_enter_lps(rtwdev, data.rtwvif-\u003eport);\n@@ -367,7 +481,13 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n \tINIT_WORK(\u0026si-\u003erc_work, rtw_sta_rc_work);\n \n \trtw_update_sta_info(rtwdev, si, true);\n-\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, true);\n+\tif (rtw8723bs_defer_sta_media_status(rtwdev, sta, vif)) {\n+\t\trtwvif-\u003efw_media_connected = false;\n+\t} else {\n+\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, true);\n+\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\n+\t\t\trtwvif-\u003efw_media_connected = true;\n+\t}\n \n \trtwdev-\u003esta_cnt++;\n \trtwdev-\u003ebeacon_loss = false;\n@@ -382,14 +502,21 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n {\n \tstruct rtw_sta_info *si = (struct rtw_sta_info *)sta-\u003edrv_priv;\n \tstruct ieee80211_vif *vif = si-\u003evif;\n+\tstruct rtw_vif *rtwvif = (struct rtw_vif *)vif-\u003edrv_priv;\n \tint i;\n \n \tcancel_work_sync(\u0026si-\u003erc_work);\n \n \tif (vif-\u003etype != NL80211_IFTYPE_STATION || sta-\u003etdls)\n \t\trtw_release_macid(rtwdev, si-\u003emac_id);\n-\tif (fw_exist)\n+\tif (fw_exist \u0026\u0026 rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\n+\t    !rtwvif-\u003efw_media_connected) {\n+\t\t/* connect status was deferred and never sent; nothing to undo */\n+\t} else if (fw_exist) {\n \t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, false);\n+\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\n+\t\t\trtwvif-\u003efw_media_connected = false;\n+\t}\n \n \tfor (i = 0; i \u003c ARRAY_SIZE(sta-\u003etxq); i++)\n \t\trtw_txq_cleanup(rtwdev, sta-\u003etxq[i]);\n@@ -904,6 +1031,8 @@ void rtw_set_channel(struct rtw_dev *rtwdev)\n \n \trtw_phy_set_tx_power_level(rtwdev, center_chan);\n \n+\trtw8723bs_reapply_pg_txagc(rtwdev);\n+\n \t/* if the channel isn't set for scanning, we will do RF calibration\n \t * in ieee80211_ops::mgd_prepare_tx(). Performing the calibration\n \t * during scanning on each channel takes too long.\n@@ -1429,6 +1558,34 @@ int rtw_power_on(struct rtw_dev *rtwdev)\n \trtw_fw_send_phydm_info(rtwdev);\n \n \twifi_only = !rtwdev-\u003eefuse.btcoex;\n+\n+\t/* 8723BS SDIO: on an IPS-leave power-on (IQK already done once) skip the\n+\t * BT-path coex init entirely - scan_workaround re-establishes the PTA /\n+\t * coex state. Run the once-only IQK via the RFK helper; on the first\n+\t * power-on, finalise coex with the vendor init H2C toggle that enables\n+\t * the 8051 management TX scheduler.\n+\t */\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\tbool ips_wake = rtwdev-\u003einitial_rfk_done;\n+\n+\t\tif (!ips_wake)\n+\t\t\trtw_coex_power_on_setting(rtwdev);\n+\n+\t\trtw_power_on_8723bs_sdio_rfk(rtwdev);\n+\n+\t\tif (!ips_wake) {\n+\t\t\trtw_coex_init_hw_config(rtwdev, wifi_only);\n+\t\t\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\t\t\trtw_fw_set_gnt_bt(rtwdev, 1);\n+\t\t\trtw_fw_coex_ant_sel_rsv(rtwdev, 0, 0);\n+\t\t\trtw_fw_query_bt_info(rtwdev);\n+\t\t\trtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);\n+\t\t\trtw_fw_set_gnt_bt(rtwdev, 0);\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\n \trtw_coex_power_on_setting(rtwdev);\n \trtw_coex_init_hw_config(rtwdev, wifi_only);\n \n@@ -1485,6 +1642,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,\n \tset_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags);\n \n \trtw_phy_dig_set_max_coverage(rtwdev);\n+\trtw_scan_set_8723bs_igi(rtwdev);\n }\n \n void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\n@@ -1965,8 +2123,21 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)\n \tu8 bw;\n \tint i;\n \n-\tif (!rtwdev-\u003echip-\u003ehw_feature_report)\n+\tif (!rtwdev-\u003echip-\u003ehw_feature_report) {\n+\t\t/* 8723BS has neither a firmware feature report nor an efuse hw_cap\n+\t\t * parser, so hw_cap is otherwise left at zero. A zero stream count\n+\t\t * produces an HT capability with no usable RX MCS rates, which makes\n+\t\t * APs drop the station immediately after a successful association.\n+\t\t * Other report-less chips fill hw_cap in when parsing the efuse.\n+\t\t */\n+\t\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t\tefuse-\u003ehw_cap.nss = rtwdev-\u003ehal.rf_path_num ? : 1;\n+\t\t\tefuse-\u003ehw_cap.ant_num = rtwdev-\u003ehal.rf_path_num ? : 1;\n+\t\t\tefuse-\u003ehw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) |\n+\t\t\t\t\t   BIT(RTW_CHANNEL_WIDTH_40);\n+\t\t}\n \t\treturn 0;\n+\t}\n \n \tid = rtw_read8(rtwdev, REG_C2HEVT);\n \tif (id != C2H_HW_FEATURE_REPORT) {\n@@ -2174,11 +2345,13 @@ int rtw_core_init(struct rtw_dev *rtwdev)\n \n \tspin_lock_init(\u0026rtwdev-\u003etxq_lock);\n \tspin_lock_init(\u0026rtwdev-\u003etx_report.q_lock);\n+\tspin_lock_init(\u0026rtwdev-\u003eauth_sync.lock);\n \n \tmutex_init(\u0026rtwdev-\u003emutex);\n \tmutex_init(\u0026rtwdev-\u003ehal.tx_power_mutex);\n \n \tinit_waitqueue_head(\u0026rtwdev-\u003ecoex.wait);\n+\tinit_waitqueue_head(\u0026rtwdev-\u003eauth_sync.wait);\n \tinit_completion(\u0026rtwdev-\u003elps_leave_check);\n \tinit_completion(\u0026rtwdev-\u003efw_scan_density);\n \n@@ -2270,7 +2443,12 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)\n \thw-\u003evif_data_size = sizeof(struct rtw_vif);\n \n \tieee80211_hw_set(hw, SIGNAL_DBM);\n-\tieee80211_hw_set(hw, RX_INCLUDES_FCS);\n+\t/* RTL8723BS keeps BIT_APP_FCS clear, so received frames do not contain\n+\t * the FCS. Advertising RX_INCLUDES_FCS would make mac80211 trim four\n+\t * bytes of frame data and corrupt the tail IE in beacons/probe responses.\n+\t */\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\tieee80211_hw_set(hw, RX_INCLUDES_FCS);\n \tieee80211_hw_set(hw, AMPDU_AGGREGATION);\n \tieee80211_hw_set(hw, MFP_CAPABLE);\n \tieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);\ndiff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h\nindex 9c0b746540b0ee..5866c96c92723f 100644\n--- a/drivers/net/wireless/realtek/rtw88/main.h\n+++ b/drivers/net/wireless/realtek/rtw88/main.h\n@@ -194,6 +194,7 @@ enum rtw_chip_type {\n \tRTW_CHIP_TYPE_8723D,\n \tRTW_CHIP_TYPE_8821C,\n \tRTW_CHIP_TYPE_8703B,\n+\tRTW_CHIP_TYPE_8723B,\n \tRTW_CHIP_TYPE_8821A,\n \tRTW_CHIP_TYPE_8812A,\n \tRTW_CHIP_TYPE_8814A,\n@@ -781,6 +782,8 @@ struct rtw_sta_info {\n \tbool vht_enable;\n \tu8 init_ra_lv;\n \tu64 ra_mask;\n+\t/* Last rate mask sent to the firmware, to gate no_update. */\n+\tu64 ra_mask_last;\n \n \tDECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS);\n \n@@ -828,6 +831,10 @@ struct rtw_vif {\n \tu8 bssid[ETH_ALEN];\n \tu8 port;\n \tu8 bcn_ctrl;\n+\t/* Set once the firmware has been told the STA is connected. */\n+\tbool fw_media_connected;\n+\tbool pre_auth_h2c_sent;\n+\tbool pre_auth_join_done;\n \tstruct list_head rsvd_page_list;\n \tstruct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];\n \tconst struct rtw_vif_port *conf;\n@@ -2056,6 +2063,20 @@ struct rtw_hw_scan_info {\n \tu8 op_bw;\n };\n \n+/*\n+ * Synchronises the pre-auth wait on a beacon or probe response from the\n+ * target BSSID before the join sequence continues.\n+ */\n+struct rtw_auth_sync {\n+\twait_queue_head_t wait;\n+\t/* Protects the fields below. */\n+\tspinlock_t lock;\n+\tu8 bssid[ETH_ALEN];\n+\tbool active;\n+\tbool seen;\n+\tu32 seen_count;\n+};\n+\n struct rtw_dev {\n \tstruct ieee80211_hw *hw;\n \tstruct device *dev;\n@@ -2129,9 +2150,13 @@ struct rtw_dev {\n \tstruct rtw_wow_param wow;\n \n \tbool need_rfk;\n+\t/* Run the initial IQK once, not on every IPS leave. */\n+\tbool initial_rfk_done;\n \tstruct completion fw_scan_density;\n \tbool ap_active;\n \n+\tstruct rtw_auth_sync auth_sync;\n+\n \tbool led_registered;\n \tchar led_name[32];\n \tstruct led_classdev led_cdev;\n@@ -2193,6 +2218,12 @@ static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev)\n \treturn rtwdev-\u003echip-\u003etx_stbc;\n }\n \n+static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\n+{\n+\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\n+\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n+}\n+\n static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)\n {\n \tunsigned long mac_id;\n@@ -2283,4 +2314,8 @@ bool rtw_core_check_sta_active(struct rtw_dev *rtwdev);\n void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable);\n void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\n \t\t\t  struct ieee80211_bss_conf *bss_conf);\n+void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\n+\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n+\t\t\t    const struct rtw_rx_pkt_stat *pkt_stat,\n+\t\t\t    const struct ieee80211_rx_status *rx_status);\n #endif\ndiff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h\nindex 08e9494977e06a..455303bc28a954 100644\n--- a/drivers/net/wireless/realtek/rtw88/reg.h\n+++ b/drivers/net/wireless/realtek/rtw88/reg.h\n@@ -479,6 +479,7 @@\n #define BIT_DIS_TSF_UDT\t\tBIT(4)\n #define BIT_EN_BCN_FUNCTION\tBIT(3)\n #define BIT_EN_TXBCN_RPT\tBIT(2)\n+#define BIT_DIS_ATIM\t\tBIT(0)\n #define REG_BCN_CTRL_CLINT0\t0x0551\n #define REG_DRVERLYINT\t\t0x0558\n #define REG_BCNDMATIM\t\t0x0559\n@@ -518,6 +519,7 @@\n #define BIT_UC_MD_EN\t\tBIT(16)\n #define BIT_RXSK_PERPKT\t\tBIT(15)\n #define BIT_HTC_LOC_CTRL\tBIT(14)\n+#define BIT_AMF\t\t\tBIT(13)\n #define BIT_RPFM_CAM_ENABLE\tBIT(12)\n #define BIT_TA_BCN\t\tBIT(11)\n #define BIT_RCR_ADF\t\tBIT(11)\ndiff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c\nindex 01fd299abb7fe9..57facbc1b41f76 100644\n--- a/drivers/net/wireless/realtek/rtw88/rx.c\n+++ b/drivers/net/wireless/realtek/rtw88/rx.c\n@@ -253,10 +253,12 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n \n \trtw_rx_addr_match(rtwdev, pkt_stat, hdr);\n \n-\t/* Rtl8723cs driver checks for size \u003c 14 or size \u003e 8192 and\n-\t * simply drops the packet.\n+\t/* Rtl8723cs and rtl8723bs drivers check for size \u003c 14 or size \u003e 8192\n+\t * and simply drop the packet.\n \t */\n-\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B \u0026\u0026 pkt_stat-\u003epkt_len == 0) {\n+\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\n+\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\n+\t    pkt_stat-\u003epkt_len == 0) {\n \t\trx_status-\u003eflag |= RX_FLAG_NO_PSDU;\n \t\trtw_dbg(rtwdev, RTW_DBG_RX, \"zero length packet\");\n \t}\ndiff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c\nindex 5b40d74b16ee08..9cf43df2ec3f9a 100644\n--- a/drivers/net/wireless/realtek/rtw88/sdio.c\n+++ b/drivers/net/wireless/realtek/rtw88/sdio.c\n@@ -20,6 +20,16 @@\n #include \"tx.h\"\n \n #define RTW_SDIO_INDIRECT_RW_RETRIES\t\t\t50\n+#define RTW_SDIO_OQT_TIMEOUT_MS\t\t\t\t1000\n+\n+/* 8723BS SDIO TX FIFO back-pressure watermarks: stop the mac80211 queue once\n+ * the per-AC software FIFO fills past the high watermark, and wake it from the\n+ * TX drain path once it falls back to the low one. Bounds the queueing latency\n+ * that otherwise causes uplink bufferbloat / congestion collapse.\n+ */\n+#define RTW_SDIO_TX_FIFO_HIWATER\t\t\t16\n+#define RTW_SDIO_TX_FIFO_LOWATER\t\t\t8\n+#define RTW_SDIO_TX_RETRY_DELAY\t\t\tmsecs_to_jiffies(1)\n \n static bool rtw_sdio_is_bus_addr(u32 addr)\n {\n@@ -479,8 +489,14 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,\n \t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\n \t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_HIGH);\n \t\tbreak;\n-\tcase RTW_TX_QUEUE_VI:\n \tcase RTW_TX_QUEUE_VO:\n+\t\tif (rtw_is_8723bs(rtwdev)) {\n+\t\t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\n+\t\t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_HIGH);\n+\t\t\tbreak;\n+\t\t}\n+\t\tfallthrough;\n+\tcase RTW_TX_QUEUE_VI:\n \t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\n \t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_NORMAL);\n \t\tbreak;\n@@ -491,6 +507,8 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,\n \t\tbreak;\n \tcase RTW_TX_QUEUE_MGMT:\n \t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\n+\t\t\t\t    rtw_is_8723bs(rtwdev) ?\n+\t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_HIGH :\n \t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_EXTRA);\n \t\tbreak;\n \tdefault:\n@@ -548,12 +566,91 @@ static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)\n \treturn ret;\n }\n \n+static void rtw_sdio_init_free_txpg(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\tconst struct rtw_page_table *pg_tbl;\n+\tu32 free_txpg;\n+\tu16 pubq_num;\n+\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\treturn;\n+\n+\tpg_tbl = \u0026rtwdev-\u003echip-\u003epage_table[0];\n+\tpubq_num = rtwdev-\u003efifo.acq_pg_num - pg_tbl-\u003ehq_num - pg_tbl-\u003elq_num -\n+\t\t   pg_tbl-\u003enq_num - pg_tbl-\u003eexq_num - pg_tbl-\u003egapq_num;\n+\tfree_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);\n+\tif (free_txpg) {\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_high, free_txpg \u0026 0xff);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_normal, (free_txpg \u003e\u003e 8) \u0026 0xff);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_low, (free_txpg \u003e\u003e 16) \u0026 0xff);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_pub, (free_txpg \u003e\u003e 24) \u0026 0xff);\n+\t} else {\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_high, pg_tbl-\u003ehq_num);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_normal, pg_tbl-\u003enq_num);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_low, pg_tbl-\u003elq_num);\n+\t\tatomic_set(\u0026rtwsdio-\u003efree_pg_pub, pubq_num);\n+\t}\n+\n+\tatomic_set(\u0026rtwsdio-\u003etx_oqt_free,\n+\t\t   rtw_read8(rtwdev, REG_SDIO_OQT_FREE_PG));\n+}\n+\n+static void rtw_sdio_sync_free_txpg(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\tu32 free_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);\n+\n+\tif (!free_txpg)\n+\t\treturn;\n+\n+\tatomic_set(\u0026rtwsdio-\u003efree_pg_high, free_txpg \u0026 0xff);\n+\tatomic_set(\u0026rtwsdio-\u003efree_pg_normal, (free_txpg \u003e\u003e 8) \u0026 0xff);\n+\tatomic_set(\u0026rtwsdio-\u003efree_pg_low, (free_txpg \u003e\u003e 16) \u0026 0xff);\n+\tatomic_set(\u0026rtwsdio-\u003efree_pg_pub, (free_txpg \u003e\u003e 24) \u0026 0xff);\n+}\n+\n+static int rtw_sdio_8723bs_free_txpg(struct rtw_dev *rtwdev, u8 queue)\n+{\n+\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\n+\tswitch (queue) {\n+\tcase RTW_TX_QUEUE_BCN:\n+\tcase RTW_TX_QUEUE_H2C:\n+\tcase RTW_TX_QUEUE_HI0:\n+\tcase RTW_TX_QUEUE_MGMT:\n+\tcase RTW_TX_QUEUE_VO:\n+\t\treturn atomic_read(\u0026rtwsdio-\u003efree_pg_high);\n+\tcase RTW_TX_QUEUE_VI:\n+\t\treturn atomic_read(\u0026rtwsdio-\u003efree_pg_normal);\n+\tcase RTW_TX_QUEUE_BE:\n+\tcase RTW_TX_QUEUE_BK:\n+\t\treturn atomic_read(\u0026rtwsdio-\u003efree_pg_low);\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+}\n+\n static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,\n \t\t\t\t    size_t count)\n {\n \tunsigned int pages_free, pages_needed;\n \n-\tif (rtw_chip_wcpu_8051(rtwdev)) {\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\t\tint dedicated = rtw_sdio_8723bs_free_txpg(rtwdev, queue);\n+\n+\t\tif (dedicated \u003c 0)\n+\t\t\treturn dedicated;\n+\t\tpages_free = dedicated + atomic_read(\u0026rtwsdio-\u003efree_pg_pub);\n+\t\tpages_needed = DIV_ROUND_UP(count, rtwdev-\u003echip-\u003epage_size);\n+\t\tif (pages_needed \u003c= pages_free)\n+\t\t\treturn 0;\n+\n+\t\trtw_sdio_sync_free_txpg(rtwdev);\n+\t\tdedicated = rtw_sdio_8723bs_free_txpg(rtwdev, queue);\n+\t\tpages_free = dedicated + atomic_read(\u0026rtwsdio-\u003efree_pg_pub);\n+\t} else if (rtw_chip_wcpu_8051(rtwdev)) {\n \t\tu32 free_txpg;\n \n \t\tfree_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG);\n@@ -632,44 +729,145 @@ static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,\n \treturn 0;\n }\n \n+static int rtw_sdio_wait_tx_oqt(struct rtw_dev *rtwdev)\n+{\n+\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\tint i;\n+\tu8 free;\n+\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\treturn 0;\n+\n+\tif (atomic_add_unless(\u0026rtwsdio-\u003etx_oqt_free, -1, 0))\n+\t\treturn 0;\n+\n+\tfor (i = 0; i \u003c RTW_SDIO_OQT_TIMEOUT_MS; i++) {\n+\t\tfree = rtw_read8(rtwdev, REG_SDIO_OQT_FREE_PG);\n+\t\tif (free) {\n+\t\t\tatomic_set(\u0026rtwsdio-\u003etx_oqt_free, free - 1);\n+\t\t\treturn 0;\n+\t\t}\n+\t\tusleep_range(1000, 2000);\n+\t}\n+\n+\treturn -EBUSY;\n+}\n+\n+static void rtw_sdio_8723bs_consume_txpg(struct rtw_dev *rtwdev, u8 queue,\n+\t\t\t\t\t unsigned int pages)\n+{\n+\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\tatomic_t *dedicated;\n+\tint free;\n+\n+\tswitch (queue) {\n+\tcase RTW_TX_QUEUE_VI:\n+\t\tdedicated = \u0026rtwsdio-\u003efree_pg_normal;\n+\t\tbreak;\n+\tcase RTW_TX_QUEUE_BE:\n+\tcase RTW_TX_QUEUE_BK:\n+\t\tdedicated = \u0026rtwsdio-\u003efree_pg_low;\n+\t\tbreak;\n+\tdefault:\n+\t\tdedicated = \u0026rtwsdio-\u003efree_pg_high;\n+\t\tbreak;\n+\t}\n+\n+\tfree = atomic_read(dedicated);\n+\tif (pages \u003c= free) {\n+\t\tatomic_sub(pages, dedicated);\n+\t} else {\n+\t\tatomic_set(dedicated, 0);\n+\t\tatomic_sub(pages - free, \u0026rtwsdio-\u003efree_pg_pub);\n+\t}\n+}\n+\n+static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb)\n+{\n+\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n+\n+\tBUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) \u003e\n+\t\t     sizeof(info-\u003estatus.status_driver_data));\n+\n+\treturn (struct rtw_sdio_tx_data *)info-\u003estatus.status_driver_data;\n+}\n+\n static int rtw_sdio_write_port(struct rtw_dev *rtwdev, struct sk_buff *skb,\n \t\t\t       enum rtw_tx_queue_type queue)\n {\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n+\tstruct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb);\n+\tunsigned int orig_len = skb-\u003elen;\n+\tbool rtl8723bs = rtw_is_8723bs(rtwdev);\n+\tbool quiet = rtl8723bs \u0026\u0026 tx_data-\u003eis_mgmt;\n+\tunsigned int pages;\n \tbool bus_claim;\n \tsize_t txsize;\n+\tsize_t write_size;\n \tu32 txaddr;\n \tint ret;\n \n-\ttxaddr = rtw_sdio_get_tx_addr(rtwdev, skb-\u003elen, queue);\n-\tif (!txaddr)\n-\t\treturn -EINVAL;\n+\tif (rtl8723bs) {\n+\t\ttxsize = round_up(orig_len, 4);\n+\t\twrite_size = txsize \u003e RTW_SDIO_BLOCK_SIZE ?\n+\t\t\t     round_up(txsize, RTW_SDIO_BLOCK_SIZE) : txsize;\n+\t} else {\n+\t\ttxsize = sdio_align_size(rtwsdio-\u003esdio_func, orig_len);\n+\t\twrite_size = txsize;\n+\t}\n+\n+\tif (write_size \u003e orig_len) {\n+\t\tunsigned int padding = write_size - orig_len;\n \n-\ttxsize = sdio_align_size(rtwsdio-\u003esdio_func, skb-\u003elen);\n+\t\tif (skb_tailroom(skb) \u003c padding) {\n+\t\t\tret = pskb_expand_head(skb, 0,\n+\t\t\t\t\t       padding - skb_tailroom(skb),\n+\t\t\t\t\t       GFP_KERNEL);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t}\n+\t\tskb_put_zero(skb, padding);\n+\t}\n+\n+\ttxaddr = rtw_sdio_get_tx_addr(rtwdev, txsize, queue);\n+\tif (!txaddr) {\n+\t\tret = -EINVAL;\n+\t\tgoto out_trim;\n+\t}\n \n \tret = rtw_sdio_check_free_txpg(rtwdev, queue, txsize);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto out_trim;\n+\tret = rtw_sdio_wait_tx_oqt(rtwdev);\n+\tif (ret)\n+\t\tgoto out_trim;\n \n \tif (!IS_ALIGNED((unsigned long)skb-\u003edata, RTW_SDIO_DATA_PTR_ALIGN))\n \t\trtw_warn(rtwdev, \"Got unaligned SKB in %s() for queue %u\\n\",\n \t\t\t __func__, queue);\n \n \tbus_claim = rtw_sdio_bus_claim_needed(rtwsdio);\n-\n \tif (bus_claim)\n \t\tsdio_claim_host(rtwsdio-\u003esdio_func);\n-\n-\tret = sdio_memcpy_toio(rtwsdio-\u003esdio_func, txaddr, skb-\u003edata, txsize);\n-\n+\tret = sdio_memcpy_toio(rtwsdio-\u003esdio_func, txaddr, skb-\u003edata,\n+\t\t\t       write_size);\n \tif (bus_claim)\n \t\tsdio_release_host(rtwsdio-\u003esdio_func);\n \n+\tif (!ret \u0026\u0026 quiet)\n+\t\tusleep_range(1000, 2000);\n+\tif (!ret \u0026\u0026 rtl8723bs) {\n+\t\tpages = DIV_ROUND_UP(txsize, rtwdev-\u003echip-\u003epage_size);\n+\t\trtw_sdio_8723bs_consume_txpg(rtwdev, queue, pages);\n+\t}\n \tif (ret)\n \t\trtw_warn(rtwdev,\n \t\t\t \"Failed to write %zu byte(s) to SDIO port 0x%08x\",\n-\t\t\t txsize, txaddr);\n+\t\t\t write_size, txaddr);\n \n+out_trim:\n+\tif (write_size \u003e orig_len)\n+\t\tskb_trim(skb, orig_len);\n \treturn ret;\n }\n \n@@ -677,7 +875,11 @@ static void rtw_sdio_init(struct rtw_dev *rtwdev)\n {\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n \n-\trtwsdio-\u003eirq_mask = REG_SDIO_HIMR_RX_REQUEST | REG_SDIO_HIMR_CPWM1;\n+\tif (rtw_is_8723bs(rtwdev))\n+\t\trtwsdio-\u003eirq_mask = REG_SDIO_HIMR_RX_REQUEST;\n+\telse\n+\t\trtwsdio-\u003eirq_mask = REG_SDIO_HIMR_RX_REQUEST |\n+\t\t\t\t       REG_SDIO_HIMR_CPWM1;\n }\n \n static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n@@ -685,6 +887,7 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n \tu8 size, timeout;\n \n \tswitch (rtwdev-\u003echip-\u003eid) {\n+\tcase RTW_CHIP_TYPE_8723B:\n \tcase RTW_CHIP_TYPE_8703B:\n \tcase RTW_CHIP_TYPE_8821A:\n \tcase RTW_CHIP_TYPE_8812A:\n@@ -712,6 +915,8 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n \t\t    FIELD_PREP(BIT_DMA_AGG_TO_V1, timeout));\n \n \trtw_write8_set(rtwdev, REG_RXDMA_MODE, BIT_DMA_MODE);\n+\tif (rtw_is_8723bs(rtwdev))\n+\t\trtw_write8_set(rtwdev, REG_RXDMA_MODE, 3 \u003c\u003c 2);\n }\n \n static void rtw_sdio_enable_interrupt(struct rtw_dev *rtwdev)\n@@ -749,9 +954,50 @@ static int rtw_sdio_setup(struct rtw_dev *rtwdev)\n \treturn 0;\n }\n \n+static void rtw_sdio_8723bs_check_rqpn(struct rtw_dev *rtwdev)\n+{\n+\tconst struct rtw_chip_info *chip = rtwdev-\u003echip;\n+\tstruct rtw_fifo_conf *fifo = \u0026rtwdev-\u003efifo;\n+\tconst struct rtw_page_table *pg_tbl;\n+\tu32 free_txpg;\n+\tu16 pubq_num;\n+\n+\tif (!rtw_is_8723bs(rtwdev))\n+\t\treturn;\n+\n+\tfree_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);\n+\tif (free_txpg || !fifo-\u003eacq_pg_num)\n+\t\treturn;\n+\n+\tpg_tbl = \u0026chip-\u003epage_table[0];\n+\tif (fifo-\u003eacq_pg_num \u003c= pg_tbl-\u003ehq_num + pg_tbl-\u003elq_num +\n+\t\t\t\t    pg_tbl-\u003enq_num + pg_tbl-\u003eexq_num +\n+\t\t\t\t    pg_tbl-\u003egapq_num)\n+\t\treturn;\n+\n+\tpubq_num = fifo-\u003eacq_pg_num - pg_tbl-\u003ehq_num - pg_tbl-\u003elq_num -\n+\t\t   pg_tbl-\u003enq_num - pg_tbl-\u003eexq_num - pg_tbl-\u003egapq_num;\n+\trtw_write32(rtwdev, REG_RQPN_NPQ,\n+\t\t    BIT_RQPN_NE(pg_tbl-\u003enq_num, pg_tbl-\u003eexq_num));\n+\trtw_write32(rtwdev, REG_RQPN,\n+\t\t    BIT_RQPN_HLP(pg_tbl-\u003ehq_num, pg_tbl-\u003elq_num, pubq_num));\n+}\n+\n static int rtw_sdio_start(struct rtw_dev *rtwdev)\n {\n+\tu32 clear;\n+\n+\trtw_sdio_8723bs_check_rqpn(rtwdev);\n+\trtw_sdio_init_free_txpg(rtwdev);\n \trtw_sdio_enable_rx_aggregation(rtwdev);\n+\n+\tif (rtw_is_8723bs(rtwdev)) {\n+\t\tclear = rtw_read32(rtwdev, REG_SDIO_HISR) \u0026\n+\t\t\tRTW_SDIO_HISR_CLEAR_MASK;\n+\t\tif (clear)\n+\t\t\trtw_write32(rtwdev, REG_SDIO_HISR, clear);\n+\t}\n+\n \trtw_sdio_enable_interrupt(rtwdev);\n \n \treturn 0;\n@@ -815,7 +1061,7 @@ static void rtw_sdio_tx_kick_off(struct rtw_dev *rtwdev)\n {\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n \n-\tqueue_work(rtwsdio-\u003etxwq, \u0026rtwsdio-\u003etx_handler_data-\u003ework);\n+\tmod_delayed_work(rtwsdio-\u003etxwq, \u0026rtwsdio-\u003etx_handler_data-\u003ework, 0);\n }\n \n static void rtw_sdio_link_ps(struct rtw_dev *rtwdev, bool enter)\n@@ -831,55 +1077,87 @@ static void rtw_sdio_interface_cfg(struct rtw_dev *rtwdev)\n \n \tval = rtw_read32(rtwdev, REG_SDIO_TX_CTRL);\n \tval \u0026= 0xfff8;\n+\tif (rtw_is_8723bs(rtwdev))\n+\t\tval |= BIT_SDIO_TX_CTRL_ALWAYS_RECOGNIZE;\n \trtw_write32(rtwdev, REG_SDIO_TX_CTRL, val);\n }\n \n-static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb)\n+static int rtw_sdio_align_tx_skb(struct sk_buff *skb, unsigned int headroom)\n {\n-\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n+\tunsigned int misalign, needed;\n+\tint ret;\n \n-\tBUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) \u003e\n-\t\t     sizeof(info-\u003estatus.status_driver_data));\n+\tmisalign = (unsigned long)skb-\u003edata \u0026 (RTW_SDIO_DATA_PTR_ALIGN - 1);\n+\tif (!misalign)\n+\t\treturn 0;\n \n-\treturn (struct rtw_sdio_tx_data *)info-\u003estatus.status_driver_data;\n+\tneeded = headroom + RTW_SDIO_DATA_PTR_ALIGN - 1;\n+\tif (skb_headroom(skb) \u003c needed) {\n+\t\tret = pskb_expand_head(skb, needed - skb_headroom(skb), 0,\n+\t\t\t\t       GFP_KERNEL);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tmisalign = (unsigned long)skb-\u003edata \u0026\n+\t\t\t   (RTW_SDIO_DATA_PTR_ALIGN - 1);\n+\t\tif (!misalign)\n+\t\t\treturn 0;\n+\t}\n+\n+\tneeded = headroom + misalign;\n+\tif (skb_headroom(skb) \u003c needed)\n+\t\treturn -ENOSPC;\n+\n+\tskb_push(skb, misalign);\n+\tmemmove(skb-\u003edata, skb-\u003edata + misalign, skb-\u003elen - misalign);\n+\tskb_trim(skb, skb-\u003elen - misalign);\n+\n+\treturn 0;\n }\n \n-static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,\n-\t\t\t\t    struct rtw_tx_pkt_info *pkt_info,\n-\t\t\t\t    struct sk_buff *skb,\n-\t\t\t\t    enum rtw_tx_queue_type queue)\n+static int rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,\n+\t\t\t\t   struct rtw_tx_pkt_info *pkt_info,\n+\t\t\t\t   struct sk_buff *skb,\n+\t\t\t\t   enum rtw_tx_queue_type queue)\n {\n \tconst struct rtw_chip_info *chip = rtwdev-\u003echip;\n \tunsigned long data_addr, aligned_addr;\n+\tbool fixed_8723bs_offset;\n \tsize_t offset;\n \tu8 *pkt_desc;\n+\tint ret;\n+\n+\tfixed_8723bs_offset = rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t\t      (queue == RTW_TX_QUEUE_MGMT ||\n+\t\t\t       queue == RTW_TX_QUEUE_BCN);\n+\n+\tif (fixed_8723bs_offset) {\n+\t\tret = rtw_sdio_align_tx_skb(skb, chip-\u003etx_pkt_desc_sz);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n \n \tpkt_desc = skb_push(skb, chip-\u003etx_pkt_desc_sz);\n \n \tdata_addr = (unsigned long)pkt_desc;\n \taligned_addr = ALIGN(data_addr, RTW_SDIO_DATA_PTR_ALIGN);\n \n-\tif (data_addr != aligned_addr) {\n+\tif (!fixed_8723bs_offset \u0026\u0026 data_addr != aligned_addr) {\n \t\t/* Ensure that the start of the pkt_desc is always aligned at\n \t\t * RTW_SDIO_DATA_PTR_ALIGN.\n \t\t */\n \t\toffset = RTW_SDIO_DATA_PTR_ALIGN - (aligned_addr - data_addr);\n-\n \t\tpkt_desc = skb_push(skb, offset);\n-\n-\t\t/* By inserting padding to align the start of the pkt_desc we\n-\t\t * need to inform the firmware that the actual data starts at\n-\t\t * a different offset than normal.\n-\t\t */\n \t\tpkt_info-\u003eoffset += offset;\n+\t\tmemset(pkt_desc + chip-\u003etx_pkt_desc_sz, 0, offset);\n \t}\n \n \tmemset(pkt_desc, 0, chip-\u003etx_pkt_desc_sz);\n-\n \tpkt_info-\u003eqsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);\n-\n \trtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);\n \trtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);\n+\n+\treturn 0;\n }\n \n static int rtw_sdio_write_data(struct rtw_dev *rtwdev,\n@@ -889,9 +1167,10 @@ static int rtw_sdio_write_data(struct rtw_dev *rtwdev,\n {\n \tint ret;\n \n-\trtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);\n-\n-\tret = rtw_sdio_write_port(rtwdev, skb, queue);\n+\tmemset(rtw_sdio_get_tx_data(skb), 0, sizeof(struct rtw_sdio_tx_data));\n+\tret = rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);\n+\tif (!ret)\n+\t\tret = rtw_sdio_write_port(rtwdev, skb, queue);\n \tdev_kfree_skb_any(skb);\n \n \treturn ret;\n@@ -929,14 +1208,37 @@ static int rtw_sdio_tx_write(struct rtw_dev *rtwdev,\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n \tenum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb);\n \tstruct rtw_sdio_tx_data *tx_data;\n-\n-\trtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);\n+\tint ret;\n \n \ttx_data = rtw_sdio_get_tx_data(skb);\n+\tmemset(tx_data, 0, sizeof(*tx_data));\n+\tif (skb-\u003elen \u003e= sizeof(struct ieee80211_hdr_3addr)) {\n+\t\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n+\n+\t\ttx_data-\u003eis_mgmt = ieee80211_is_mgmt(hdr-\u003eframe_control);\n+\t}\n+\n+\tret = rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);\n+\tif (ret)\n+\t\treturn ret;\n+\n \ttx_data-\u003esn = pkt_info-\u003esn;\n+\ttx_data-\u003etx_pkt_offset = pkt_info-\u003eoffset;\n \n \tskb_queue_tail(\u0026rtwsdio-\u003etx_queue[queue], skb);\n \n+\t/* Back-pressure on the data ACs (BK/BE/VI/VO): once the FIFO fills past\n+\t * the high watermark, stop the corresponding mac80211 queue so it stops\n+\t * handing us frames, bounding the queueing latency. Resumed from the TX\n+\t * drain path once the FIFO drains below the low watermark.\n+\t */\n+\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 queue \u003c RTW_TX_QUEUE_BCN \u0026\u0026\n+\t    !rtwsdio-\u003equeue_stopped[queue] \u0026\u0026\n+\t    skb_queue_len(\u0026rtwsdio-\u003etx_queue[queue]) \u003e= RTW_SDIO_TX_FIFO_HIWATER) {\n+\t\trtwsdio-\u003equeue_stopped[queue] = true;\n+\t\tieee80211_stop_queue(rtwdev-\u003ehw, skb_get_queue_mapping(skb));\n+\t}\n+\n \treturn 0;\n }\n \n@@ -965,6 +1267,11 @@ static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,\n \trtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat);\n \trtw_rx_stats(rtwdev, pkt_stat-\u003evif, skb);\n \n+\tif (skb-\u003elen \u003e= sizeof(struct ieee80211_hdr_3addr))\n+\t\trtw8723bs_auth_sync_rx(rtwdev,\n+\t\t\t\t       (struct ieee80211_hdr *)skb-\u003edata,\n+\t\t\t\t       skb-\u003elen, pkt_stat, rx_status);\n+\n \tieee80211_rx_irqsafe(rtwdev-\u003ehw, skb);\n }\n \n@@ -1079,6 +1386,7 @@ static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func)\n \tstruct ieee80211_hw *hw = sdio_get_drvdata(sdio_func);\n \tstruct rtw_sdio *rtwsdio;\n \tstruct rtw_dev *rtwdev;\n+\tu32 clear;\n \tu32 hisr;\n \n \trtwdev = hw-\u003epriv;\n@@ -1095,7 +1403,12 @@ static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func)\n \t\trtw_sdio_rx_isr(rtwdev);\n \t}\n \n-\trtw_write32(rtwdev, REG_SDIO_HISR, hisr);\n+\tif (rtw_is_8723bs(rtwdev))\n+\t\tclear = hisr \u0026 rtwsdio-\u003eirq_mask \u0026 RTW_SDIO_HISR_CLEAR_MASK;\n+\telse\n+\t\tclear = hisr \u0026 RTW_SDIO_HISR_CLEAR_MASK;\n+\tif (clear)\n+\t\trtw_write32(rtwdev, REG_SDIO_HISR, clear);\n \n \trtwsdio-\u003eirq_thread = NULL;\n }\n@@ -1212,11 +1525,20 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,\n \tstruct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb);\n \tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n \tstruct ieee80211_hw *hw = rtwdev-\u003ehw;\n-\n-\tskb_pull(skb, rtwdev-\u003echip-\u003etx_pkt_desc_sz);\n-\n-\t/* enqueue to wait for tx report */\n-\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_REQ_TX_STATUS) {\n+\tu8 tx_pkt_offset = tx_data-\u003etx_pkt_offset;\n+\n+\tif (!tx_pkt_offset)\n+\t\ttx_pkt_offset = rtwdev-\u003echip-\u003etx_pkt_desc_sz;\n+\tskb_pull(skb, tx_pkt_offset);\n+\n+\t/* The RTL8723BS vendor descriptor uses SW_DEFINE/sn=0 for management\n+\t * frames, so there is no unique key for matching asynchronous C2H TX\n+\t * reports. Report completion at SDIO DMA completion, as the vendor\n+\t * dump_mgntframe_and_wait() path does; data frames keep the normal C2H\n+\t * report queue.\n+\t */\n+\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_REQ_TX_STATUS \u0026\u0026\n+\t    !(rtw_is_8723bs(rtwdev) \u0026\u0026 tx_data-\u003eis_mgmt)) {\n \t\trtw_tx_report_enqueue(rtwdev, skb, tx_data-\u003esn);\n \t\treturn;\n \t}\n@@ -1231,32 +1553,48 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,\n \tieee80211_tx_status_irqsafe(hw, skb);\n }\n \n-static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,\n-\t\t\t\t      enum rtw_tx_queue_type queue)\n+static int rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,\n+\t\t\t\t     enum rtw_tx_queue_type queue,\n+\t\t\t\t     bool *processed)\n {\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n \tstruct sk_buff *skb;\n+\tu16 q_map;\n \tint ret;\n \n+\t*processed = false;\n \tskb = skb_dequeue(\u0026rtwsdio-\u003etx_queue[queue]);\n \tif (!skb)\n-\t\treturn;\n+\t\treturn 0;\n \n+\t*processed = true;\n+\tq_map = skb_get_queue_mapping(skb);\n \tret = rtw_sdio_write_port(rtwdev, skb, queue);\n \tif (ret) {\n \t\tskb_queue_head(\u0026rtwsdio-\u003etx_queue[queue], skb);\n-\t\treturn;\n+\t\treturn ret;\n \t}\n \n \trtw_sdio_indicate_tx_status(rtwdev, skb);\n+\n+\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 queue \u003c RTW_TX_QUEUE_BCN \u0026\u0026\n+\t    rtwsdio-\u003equeue_stopped[queue] \u0026\u0026\n+\t    skb_queue_len(\u0026rtwsdio-\u003etx_queue[queue]) \u003c= RTW_SDIO_TX_FIFO_LOWATER) {\n+\t\trtwsdio-\u003equeue_stopped[queue] = false;\n+\t\tieee80211_wake_queue(rtwdev-\u003ehw, q_map);\n+\t}\n+\n+\treturn 0;\n }\n \n static void rtw_sdio_tx_handler(struct work_struct *work)\n {\n \tstruct rtw_sdio_work_data *work_data =\n-\t\tcontainer_of(work, struct rtw_sdio_work_data, work);\n+\t\tcontainer_of(to_delayed_work(work), struct rtw_sdio_work_data,\n+\t\t\t     work);\n \tstruct rtw_sdio *rtwsdio;\n \tstruct rtw_dev *rtwdev;\n+\tbool processed;\n \tint limit, queue;\n \n \trtwdev = work_data-\u003ertwdev;\n@@ -1267,7 +1605,24 @@ static void rtw_sdio_tx_handler(struct work_struct *work)\n \n \tfor (queue = RTK_MAX_TX_QUEUE_NUM - 1; queue \u003e= 0; queue--) {\n \t\tfor (limit = 0; limit \u003c 1000; limit++) {\n-\t\t\trtw_sdio_process_tx_queue(rtwdev, queue);\n+\t\t\tint ret;\n+\n+\t\t\tret = rtw_sdio_process_tx_queue(rtwdev, queue, \u0026processed);\n+\t\t\tif (ret) {\n+\t\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 ret == -EBUSY) {\n+\t\t\t\t\tmod_delayed_work(rtwsdio-\u003etxwq,\n+\t\t\t\t\t\t\t \u0026work_data-\u003ework,\n+\t\t\t\t\t\t\t RTW_SDIO_TX_RETRY_DELAY);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\n+\t\t\t    queue == RTW_TX_QUEUE_MGMT \u0026\u0026 processed) {\n+\t\t\t\tmod_delayed_work(rtwsdio-\u003etxwq, \u0026work_data-\u003ework, 0);\n+\t\t\t\treturn;\n+\t\t\t}\n \n \t\t\tif (skb_queue_empty(\u0026rtwsdio-\u003etx_queue[queue]))\n \t\t\t\tbreak;\n@@ -1294,14 +1649,16 @@ static int rtw_sdio_init_tx(struct rtw_dev *rtwdev)\n \t\treturn -ENOMEM;\n \t}\n \n-\tfor (i = 0; i \u003c RTK_MAX_TX_QUEUE_NUM; i++)\n+\tfor (i = 0; i \u003c RTK_MAX_TX_QUEUE_NUM; i++) {\n \t\tskb_queue_head_init(\u0026rtwsdio-\u003etx_queue[i]);\n+\t\trtwsdio-\u003equeue_stopped[i] = false;\n+\t}\n \trtwsdio-\u003etx_handler_data = kmalloc_obj(*rtwsdio-\u003etx_handler_data);\n \tif (!rtwsdio-\u003etx_handler_data)\n \t\tgoto err_destroy_wq;\n \n \trtwsdio-\u003etx_handler_data-\u003ertwdev = rtwdev;\n-\tINIT_WORK(\u0026rtwsdio-\u003etx_handler_data-\u003ework, rtw_sdio_tx_handler);\n+\tINIT_DELAYED_WORK(\u0026rtwsdio-\u003etx_handler_data-\u003ework, rtw_sdio_tx_handler);\n \n \treturn 0;\n \n@@ -1315,6 +1672,7 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)\n \tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n \tint i;\n \n+\tcancel_delayed_work_sync(\u0026rtwsdio-\u003etx_handler_data-\u003ework);\n \tdestroy_workqueue(rtwsdio-\u003etxwq);\n \tkfree(rtwsdio-\u003etx_handler_data);\n \ndiff --git a/drivers/net/wireless/realtek/rtw88/sdio.h b/drivers/net/wireless/realtek/rtw88/sdio.h\nindex 457e8b02380e5b..3dd0f44676bffa 100644\n--- a/drivers/net/wireless/realtek/rtw88/sdio.h\n+++ b/drivers/net/wireless/realtek/rtw88/sdio.h\n@@ -22,6 +22,7 @@\n \n /* SDIO Tx Control */\n #define REG_SDIO_TX_CTRL\t\t\t(SDIO_LOCAL_OFFSET + 0x0000)\n+#define BIT_SDIO_TX_CTRL_ALWAYS_RECOGNIZE\tBIT(4)\n \n /*SDIO status timeout*/\n #define REG_SDIO_TIMEOUT\t\t\t(SDIO_LOCAL_OFFSET + 0x0002)\n@@ -77,6 +78,14 @@\n /* the following two are RTL8188 SDIO Specific */\n #define REG_SDIO_HISR_MCU_ERR\t\t\tBIT(28)\n #define REG_SDIO_HISR_TSF_BIT32_TOGGLE\t\tBIT(29)\n+#define RTW_SDIO_HISR_CLEAR_MASK\t\t\\\n+\t(REG_SDIO_HISR_TXERR | REG_SDIO_HISR_RXERR | \\\n+\t REG_SDIO_HISR_TXFOVW | REG_SDIO_HISR_RXFOVW | \\\n+\t REG_SDIO_HISR_TXBCNOK | REG_SDIO_HISR_TXBCNERR | \\\n+\t REG_SDIO_HISR_C2HCMD | REG_SDIO_HISR_CPWM1 | \\\n+\t REG_SDIO_HISR_CPWM2 | REG_SDIO_HISR_HSISR_IND | \\\n+\t REG_SDIO_HISR_GTINT3_IND | REG_SDIO_HISR_GTINT4_IND | \\\n+\t REG_SDIO_HISR_PSTIMEOUT | REG_SDIO_HISR_OCPINT)\n \n /* HCI Current Power Mode */\n #define REG_SDIO_HCPWM\t\t\t\t(SDIO_LOCAL_OFFSET + 0x0019)\n@@ -140,10 +149,12 @@ struct sdio_device_id;\n \n struct rtw_sdio_tx_data {\n \tu8 sn;\n+\tu8 tx_pkt_offset;\n+\tbool is_mgmt;\n };\n \n struct rtw_sdio_work_data {\n-\tstruct work_struct work;\n+\tstruct delayed_work work;\n \tstruct rtw_dev *rtwdev;\n };\n \n@@ -159,6 +170,13 @@ struct rtw_sdio {\n \tstruct workqueue_struct *txwq;\n \tstruct rtw_sdio_work_data *tx_handler_data;\n \tstruct sk_buff_head tx_queue[RTK_MAX_TX_QUEUE_NUM];\n+\tbool queue_stopped[RTK_MAX_TX_QUEUE_NUM];\n+\n+\tatomic_t free_pg_high;\n+\tatomic_t free_pg_normal;\n+\tatomic_t free_pg_low;\n+\tatomic_t free_pg_pub;\n+\tatomic_t tx_oqt_free;\n };\n \n extern const struct dev_pm_ops rtw_sdio_pm_ops;\ndiff --git a/drivers/net/wireless/realtek/rtw88/sec.h b/drivers/net/wireless/realtek/rtw88/sec.h\nindex efcf45433999af..73f2af66effe85 100644\n--- a/drivers/net/wireless/realtek/rtw88/sec.h\n+++ b/drivers/net/wireless/realtek/rtw88/sec.h\n@@ -22,6 +22,7 @@\n #define RTW_SEC_RX_DEC_EN\t\tBIT(3)\n #define RTW_SEC_TX_BC_USE_DK\t\tBIT(6)\n #define RTW_SEC_RX_BC_USE_DK\t\tBIT(7)\n+#define RTW_SEC_CHK_KEYID\t\tBIT(8)\n \n #define RTW_SEC_ENGINE_EN\t\tBIT(9)\n \ndiff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c\nindex 9d747a060b984c..797c1e0402f228 100644\n--- a/drivers/net/wireless/realtek/rtw88/tx.c\n+++ b/drivers/net/wireless/realtek/rtw88/tx.c\n@@ -208,8 +208,9 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)\n \t__skb_queue_tail(\u0026tx_report-\u003equeue, skb);\n \tspin_unlock_irqrestore(\u0026tx_report-\u003eq_lock, flags);\n \n-\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723D \u0026\u0026\n-\t    rtwdev-\u003ehci.type == RTW_HCI_TYPE_USB)\n+\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723D \u0026\u0026\n+\t     rtwdev-\u003ehci.type == RTW_HCI_TYPE_USB) ||\n+\t    rtw_is_8723bs(rtwdev))\n \t\ttimeout = msecs_to_jiffies(2500);\n \n \tmod_timer(\u0026tx_report-\u003epurge_timer, jiffies + timeout);\n"
}

2/1 2026/07/26 07:18 agent patch-evaluator
5m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch adds support for the RTL8723BS SDIO WiFi/BT coexistence and related SDIO handling. However, the chip definition for RTL8723BS (which would set `chip-\u003eid = RTW_CHIP_TYPE_8723B`) is not present in the kernel tree, meaning `rtw_is_8723bs()` will always evaluate to false and the core logic is unreachable. Furthermore, the few generic SDIO changes in `sdio.c` are unreachable in virtualized environments because there is no software-emulated SDIO host controller (like `dummy_hcd` for USB) available for fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit d186f4a873ba6b92056bb5d3129a2c126320d6fe
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Jul 26 07:18:47 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index 37c336def41915..dc74e479351d8d 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -1443,6 +1443,191 @@ static void rtw_coex_set_ant_path(struct rtw_dev *rtwdev, bool force, u8 phase)
 #define case_ALGO(src) \
 	case COEX_ALGO_##src: return #src
 
+/* 8723BS SDIO WiFi/BT coexistence antenna handling. On BT-disabled boards the
+ * scan/auth window still routes through the PTA mux; these helpers force the
+ * vendor-shaped WiFi-owned antenna path so directed management TX reaches air.
+ */
+#define REG_8723BS_BT_COEX_CTRL		0x0039
+#define REG_8723BS_BB_ANT_CFG		0x0930
+#define REG_8723BS_BB_ANT_CFG1		0x0944
+#define REG_8723BS_BB_ANT_BUF		0x0974
+#define RTW8723BS_COEX_H_WLAN_ACTIVE	0x1800101b
+
+static bool rtw_coex_8723bs_ant_is_aux(struct rtw_dev *rtwdev)
+{
+	return !!(rtwdev->efuse.bt_setting & BIT(6));
+}
+
+static bool rtw_coex_8723bs_bt_disabled(struct rtw_dev *rtwdev)
+{
+	return rtw_is_8723bs(rtwdev) && rtwdev->coex.stat.bt_disabled;
+}
+
+static u32 rtw_coex_8723bs_pta_ant_path(struct rtw_dev *rtwdev)
+{
+	return rtw_coex_8723bs_ant_is_aux(rtwdev) ? 0x80 : 0x200;
+}
+
+/* Write BB_SEL_BTG (0x948), retrying once with SYS_FUNC BB reset if the first
+ * write does not stick (RF/BB clock may have been gated).
+ */
+static u32 rtw_coex_8723bs_write_bb_sel_btg(struct rtw_dev *rtwdev, u32 value)
+{
+	u8 sys_func_before;
+	u32 readback;
+
+	sys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+	if ((sys_func_before & (BIT(0) | BIT(1))) != (BIT(0) | BIT(1))) {
+		rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
+		usleep_range(10, 11);
+	}
+
+	rtw_write32(rtwdev, 0x948, value);
+	readback = rtw_read32(rtwdev, 0x948);
+	if (readback == value)
+		return readback;
+
+	usleep_range(10, 11);
+	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
+	rtw_write32(rtwdev, 0x948, value);
+
+	return rtw_read32(rtwdev, 0x948);
+}
+
+static u32 rtw_coex_8723bs_reassert_pta_ant(struct rtw_dev *rtwdev)
+{
+	return rtw_coex_8723bs_write_bb_sel_btg(rtwdev,
+						rtw_coex_8723bs_pta_ant_path(rtwdev));
+}
+
+static void rtw_coex_8723bs_set_cck_pri(struct rtw_dev *rtwdev, bool high)
+{
+	if (!rtw_coex_8723bs_bt_disabled(rtwdev))
+		return;
+
+	if (high) {
+		rtw_write32(rtwdev, REG_BT_COEX_TABLE_H,
+			    RTW8723BS_COEX_H_WLAN_ACTIVE);
+	} else {
+		rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_CCK, false);
+		rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, false);
+	}
+}
+
+static void rtw_coex_8723bs_restore_pad_ctrl(struct rtw_dev *rtwdev,
+					     bool keep_pta_owner)
+{
+	u32 before, after;
+
+	before = rtw_read32(rtwdev, REG_PAD_CTRL1);
+	after = before & ~(BIT_LNAON_WLBT_SEL | BIT_SW_DPDT_SEL_DATA);
+	if (keep_pta_owner)
+		after |= BIT_PAPE_WLBT_SEL;
+	else
+		after &= ~BIT_PAPE_WLBT_SEL;
+	if (after != before)
+		rtw_write32(rtwdev, REG_PAD_CTRL1, after);
+}
+
+static void rtw_coex_8723bs_fw_gnt_bt_low(struct rtw_dev *rtwdev)
+{
+	if (!rtw_coex_8723bs_bt_disabled(rtwdev))
+		return;
+
+	if (rtw_read8(rtwdev, 0x765) == 0x00 &&
+	    rtw_read8(rtwdev, 0x76e) == 0x0c)
+		return;
+
+	rtw_fw_set_gnt_bt(rtwdev, 0);
+}
+
+static void rtw_coex_8723bs_force_assoc_pta_ant(struct rtw_dev *rtwdev)
+{
+	u32 ant_target;
+
+	if (!rtw_coex_8723bs_bt_disabled(rtwdev))
+		return;
+
+	ant_target = rtw_coex_8723bs_pta_ant_path(rtwdev);
+
+	rtw_coex_8723bs_fw_gnt_bt_low(rtwdev);
+	rtw_coex_set_ant_switch(rtwdev, COEX_SWITCH_CTRL_BY_PTA,
+				COEX_SWITCH_TO_NOCARE);
+	rtw_coex_8723bs_set_cck_pri(rtwdev, true);
+	rtw_coex_8723bs_write_bb_sel_btg(rtwdev, ant_target);
+	rtw_coex_8723bs_restore_pad_ctrl(rtwdev, true);
+}
+
+static void rtw_coex_8723bs_reassert_ant_buffer(struct rtw_dev *rtwdev)
+{
+	u8 sys_func_before;
+
+	sys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+	if ((sys_func_before & (BIT(0) | BIT(1))) != (BIT(0) | BIT(1))) {
+		rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
+		usleep_range(10, 11);
+	}
+
+	rtw_write8_mask(rtwdev, REG_8723BS_BT_COEX_CTRL, BIT(3), 0x1);
+	rtw_write8(rtwdev, REG_8723BS_BB_ANT_BUF, 0xff);
+	rtw_write8_mask(rtwdev, REG_8723BS_BB_ANT_CFG1, 0x3, 0x3);
+	rtw_write8(rtwdev, REG_8723BS_BB_ANT_CFG, 0x77);
+}
+
+static void rtw_coex_8723bs_apply_scan_table(struct rtw_dev *rtwdev)
+{
+	rtwdev->coex.dm.cur_table = 2;
+	rtw_coex_set_table(rtwdev, true, 0x5a5a5a5a, 0x5a5a5a5a);
+}
+
+/* Non-connected scan/auth workaround: PS-TDMA type 8 off, PTA antenna path,
+ * coex table type 2 (matches the vendor non-connected arbitration).
+ */
+void rtw_coex_8723bs_scan_workaround(struct rtw_dev *rtwdev)
+{
+	struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm;
+	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
+
+	if (!rtw_is_8723bs(rtwdev))
+		return;
+
+	coex_dm->cur_ps_tdma_on = false;
+	coex_dm->cur_ps_tdma = 8;
+	coex_dm->ps_tdma_para[0] = 0x08;
+	coex_dm->ps_tdma_para[1] = 0x00;
+	coex_dm->ps_tdma_para[2] = 0x00;
+	coex_dm->ps_tdma_para[3] = 0x00;
+	coex_dm->ps_tdma_para[4] = 0x00;
+
+	rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+	rtw_coex_8723bs_fw_gnt_bt_low(rtwdev);
+	rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
+	rtw_coex_8723bs_reassert_ant_buffer(rtwdev);
+	rtw_coex_8723bs_apply_scan_table(rtwdev);
+	if (coex_stat->bt_disabled)
+		rtw_coex_8723bs_set_cck_pri(rtwdev, true);
+	rtw_coex_8723bs_reassert_pta_ant(rtwdev);
+	rtw_coex_8723bs_restore_pad_ctrl(rtwdev, true);
+}
+
+/* Replayed immediately before start_clnt_join()/auth: BT_INFO + PS-TDMA type 8
+ * then the forced WiFi PTA antenna path, so the auth window is clean.
+ */
+void rtw_coex_8723bs_pre_auth_h2c(struct rtw_dev *rtwdev)
+{
+	lockdep_assert_held(&rtwdev->mutex);
+
+	if (!rtw_coex_8723bs_bt_disabled(rtwdev))
+		return;
+
+	rtw_fw_query_bt_info(rtwdev);
+	rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+	rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+	rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+	rtw_coex_8723bs_fw_gnt_bt_low(rtwdev);
+	rtw_coex_8723bs_force_assoc_pta_ant(rtwdev);
+}
+
 static const char *rtw_coex_get_algo_string(u8 algo)
 {
 	switch (algo) {
@@ -2877,6 +3062,33 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type)
 	coex->freeze = false;
 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
 
+	/* 8723BS SDIO BT-disabled: keep the scan/auth PTA antenna state the
+	 * vendor uses and skip the generic coex run. At scan start (firmware
+	 * has been up long enough for stable RX DMA) replay the vendor BT_MP /
+	 * BT_INFO queries, then re-establish the scan-path PTA setup.
+	 */
+	if (rtw_coex_8723bs_bt_disabled(rtwdev)) {
+		if (type == COEX_SCAN_START_2G || type == COEX_SCAN_START) {
+			struct rtw_coex_info_req req = {};
+
+			coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] = 0;
+			coex_stat->wl_hi_pri_task2 = true;
+
+			req.seq = 0x0e;
+			req.op_code = BT_MP_INFO_OP_SUPP_VER;
+			rtw_fw_query_bt_mp_info(rtwdev, &req);
+			req.seq = 0x0f;
+			req.op_code = BT_MP_INFO_OP_PATCH_VER;
+			rtw_fw_query_bt_mp_info(rtwdev, &req);
+			rtw_fw_query_bt_info(rtwdev);
+
+			rtw_coex_8723bs_scan_workaround(rtwdev);
+		} else {
+			coex_stat->wl_hi_pri_task2 = false;
+		}
+		return;
+	}
+
 	if (type == COEX_SCAN_START_5G) {
 		rtw_dbg(rtwdev, RTW_DBG_COEX,
 			"[BTCoex], SCAN START notify (5G)\n");
@@ -2938,6 +3150,17 @@ void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type)
 	if (coex->manual_control || coex->stop_dm)
 		return;
 
+	/* 8723BS SDIO BT-disabled: the vendor ConnectNotify() early-returns
+	 * without sending H2Cs; scan_workaround already established the PTA
+	 * path / coex table / PS-TDMA. Keep only the register-level PTA
+	 * reassertion at associate-start.
+	 */
+	if (rtw_coex_8723bs_bt_disabled(rtwdev)) {
+		if (type == COEX_ASSOCIATE_START)
+			rtw_coex_8723bs_force_assoc_pta_ant(rtwdev);
+		return;
+	}
+
 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
 
 	if (type == COEX_ASSOCIATE_5G_START) {
diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h
index c398be8391f7b0..c58ae0a50b30b1 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.h
+++ b/drivers/net/wireless/realtek/rtw88/coex.h
@@ -430,4 +430,7 @@ static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)
 		rtw_coex_query_bt_info(rtwdev);
 }
 
+void rtw_coex_8723bs_scan_workaround(struct rtw_dev *rtwdev);
+void rtw_coex_8723bs_pre_auth_h2c(struct rtw_dev *rtwdev);
+
 #endif
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 945fedcd375b62..20f19675238147 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -317,6 +317,15 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
 	case C2H_CCX_TX_RPT:
 		rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);
 		break;
+	case C2H_VENDOR_TX_RPT:
+	case C2H_WLAN_RFON:
+		/*
+		 * The RTL8723BS firmware reports management TX through these
+		 * two events instead, using the same payload layout.
+		 */
+		if (rtw_is_8723bs(rtwdev))
+			rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);
+		break;
 	case C2H_BT_INFO:
 		rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
 		break;
@@ -365,6 +374,15 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
 		rtw_coex_info_response(rtwdev, skb);
 		break;
 	case C2H_WLAN_RFON:
+		/* On 8723BS SDIO with v41 firmware, C2H 0x32 carries a scan TX
+		 * report, not a WLAN_RFON event: defer it to rtw_fw_c2h_cmd_handle().
+		 */
+		if (rtw_is_8723bs(rtwdev)) {
+			*((u32 *)skb->cb) = pkt_offset;
+			skb_queue_tail(&rtwdev->c2h_queue, skb);
+			ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
+			break;
+		}
 		complete(&rtwdev->lps_leave_check);
 		dev_kfree_skb_any(skb);
 		break;
@@ -726,9 +744,19 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
 
 	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RSSI_MONITOR);
 
-	SET_RSSI_INFO_MACID(h2c_pkt, si->mac_id);
-	SET_RSSI_INFO_RSSI(h2c_pkt, rssi);
-	SET_RSSI_INFO_STBC(h2c_pkt, stbc_en);
+	if (rtw_is_8723bs(rtwdev)) {
+		/* Vendor v5.2.17 RA_INFO byte layout (H2C 0x42):
+		 * [1] mac_id, [2] 0x00, [3] rssi, [4] stbc?0x04:0x00.
+		 */
+		h2c_pkt[1] = si->mac_id & 0x7f;
+		h2c_pkt[2] = 0x00;
+		h2c_pkt[3] = rssi;
+		h2c_pkt[4] = stbc_en ? 0x04 : 0x00;
+	} else {
+		SET_RSSI_INFO_MACID(h2c_pkt, si->mac_id);
+		SET_RSSI_INFO_RSSI(h2c_pkt, rssi);
+		SET_RSSI_INFO_STBC(h2c_pkt, stbc_en);
+	}
 
 	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
@@ -742,6 +770,37 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
 
 	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
 
+	if (rtw_is_8723bs(rtwdev)) {
+		/* The v41 firmware parses the vendor v5.2.17 MACID_CFG (0x40)
+		 * byte layout, not the bit-packed rtw88 RA_INFO below:
+		 * [1] mac_id, [2] rate_id | sgi_en(bit7),
+		 * [3] bw(bits 1-0) | no_update(bit3), [4..7] 4-byte mask.
+		 *
+		 * no_update(bit3)=1 tells the firmware to keep its existing
+		 * rate mask, so a mask that changes under no_update is dropped.
+		 * Force no_update=0 whenever the mask actually changes so the
+		 * update is applied, and keep no_update=1 for identical
+		 * refreshes so the firmware retains the rate it has learned.
+		 */
+		bool apply = reset_ra_mask || si->ra_mask != si->ra_mask_last;
+
+		h2c_pkt[1] = si->mac_id & 0x7f;
+		h2c_pkt[2] = (si->rate_id & 0x1f) |
+			     (si->sgi_enable ? BIT(7) : 0);
+		h2c_pkt[3] = ((si->bw_mode ? 3 : 1) & 0x3) |
+			     (apply ? 0 : BIT(3));
+		h2c_pkt[4] = si->ra_mask & 0xff;
+		h2c_pkt[5] = (si->ra_mask >> 8) & 0xff;
+		h2c_pkt[6] = (si->ra_mask >> 16) & 0xff;
+		h2c_pkt[7] = (si->ra_mask >> 24) & 0xff;
+
+		si->ra_mask_last = si->ra_mask;
+		si->init_ra_lv = 0;
+
+		rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+		return;
+	}
+
 	SET_RA_INFO_MACID(h2c_pkt, si->mac_id);
 	SET_RA_INFO_RATE_ID(h2c_pkt, si->rate_id);
 	SET_RA_INFO_INIT_RA_LVL(h2c_pkt, si->init_ra_lv);
@@ -780,8 +839,78 @@ void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect)
 	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 
 	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_MEDIA_STATUS_RPT);
-	MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect);
-	MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id);
+
+	if (rtw_is_8723bs(rtwdev)) {
+		/* Vendor v5.2.17 MEDIA_STATUS_RPT: connect = 21 00 00,
+		 * disconnect = 00 00 00. Byte1[0]=OPMODE, [5]=ROLE(STA=0),
+		 * [1]=MACID_IND; byte2=MACID; byte3=MACID_END.
+		 */
+		h2c_pkt[1] = connect ? 0x21 : 0x00;
+		h2c_pkt[2] = mac_id & 0x7f;
+		h2c_pkt[3] = 0x00;
+	} else {
+		MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, connect);
+		MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, mac_id);
+	}
+
+	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
+/* 8723BS SDIO: post-assoc rate-adaptation config in the vendor v5.2.17
+ * MACID_CFG byte layout. disra (bit7 of [2]) must stay 0 so the firmware keeps
+ * running rate adaptation for this mac_id.
+ */
+void rtw_fw_macid_cfg(struct rtw_dev *rtwdev, u8 mac_id, u8 raid, u8 bw,
+		      u8 sgi, u32 rate_mask)
+{
+	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+
+	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
+
+	h2c_pkt[1] = mac_id & 0x7f;
+	h2c_pkt[2] = (raid & 0x1f) | (sgi ? BIT(7) : 0) | 0x60;
+	h2c_pkt[3] = (bw ? 3 : 1) & 0x3;
+	h2c_pkt[4] = rate_mask & 0xff;
+	h2c_pkt[5] = (rate_mask >> 8) & 0xff;
+	h2c_pkt[6] = (rate_mask >> 16) & 0xff;
+	h2c_pkt[7] = (rate_mask >> 24) & 0xff;
+
+	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
+/* 8723BS SDIO: report the connected channel/bandwidth to the vendor firmware. */
+void rtw_fw_send_wl_ch_info(struct rtw_dev *rtwdev, u8 ch, u8 bw)
+{
+	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+	u8 bw_byte = bw == RTW_CHANNEL_WIDTH_40 ? 0x30 : 0x20;
+
+	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_CH_INFO);
+	h2c_pkt[1] = 0x00;
+	h2c_pkt[2] = ch;
+	h2c_pkt[3] = bw_byte;
+
+	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
+/* 8723BS SDIO: set the firmware GNT_BT state (0 = WiFi owns the antenna). */
+void rtw_fw_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
+{
+	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+
+	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_GNT_BT);
+	SET_GNT_BT_STATE(h2c_pkt, state);
+
+	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
+/* 8723BS SDIO: vendor coex antenna-select reserve H2C (part of the init toggle). */
+void rtw_fw_coex_ant_sel_rsv(struct rtw_dev *rtwdev, u8 inverse, u8 type)
+{
+	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+
+	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_COEX_ANT_SEL_RSV);
+	SET_COEX_ANT_SEL_RSV_INVERSE(h2c_pkt, inverse);
+	SET_COEX_ANT_SEL_RSV_TYPE(h2c_pkt, type);
 
 	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
@@ -1466,10 +1595,14 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
 	rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_INFO, true);
 }
 
+/* REG_DWBCN1_CTRL bit 20 (SW_BCN_SEL for port 0), relative to byte +2 */
+#define BIT_OFFSET_DWBCN1_SW_BCN_SEL_PORT0	(20 - 16)
+
 int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 				u8 *buf, u32 size)
 {
-	u8 bckp[3];
+	const bool is_8723bs_sdio = rtw_is_8723bs(rtwdev);
+	u8 bckp[4];
 	u8 val;
 	u16 rsvd_pg_head;
 	u32 bcn_valid_addr;
@@ -1499,13 +1632,28 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 	rtw_write8(rtwdev, REG_BCN_CTRL,
 		   (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT);
 
-	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {
+	/* Clear BIT_EN_BCNQ_DL so the chip does not treat the reserved-page
+	 * upload as a real beacon; otherwise BIT_BCN_VALID never asserts. The
+	 * vendor rtl8723bs driver does this unconditionally; rtw88 only did it
+	 * for PCIe, which left 8723BS SDIO's BCN_VALID handshake failing.
+	 */
+	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE || is_8723bs_sdio) {
 		val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
 		bckp[1] = val;
 		val &= ~(BIT_EN_BCNQ_DL >> 16);
 		rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val);
 	}
 
+	/* 8723BS SDIO: point the SW beacon download path at port 0, else
+	 * BIT_BCN_VALID is never asserted after the SDIO upload completes.
+	 */
+	if (is_8723bs_sdio) {
+		val = rtw_read8(rtwdev, REG_DWBCN1_CTRL + 2);
+		bckp[3] = val;
+		val &= ~BIT(BIT_OFFSET_DWBCN1_SW_BCN_SEL_PORT0);
+		rtw_write8(rtwdev, REG_DWBCN1_CTRL + 2, val);
+	}
+
 	ret = rtw_hci_write_data_rsvd_page(rtwdev, buf, size);
 	if (ret) {
 		rtw_err(rtwdev, "failed to write data to rsvd page\n");
@@ -1526,11 +1674,13 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 	}
 
 restore:
+	if (is_8723bs_sdio)
+		rtw_write8(rtwdev, REG_DWBCN1_CTRL + 2, bckp[3]);
 	rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
 	rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
 		    rsvd_pg_head | BIT_BCN_VALID_V1);
 	rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]);
-	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
+	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE || is_8723bs_sdio)
 		rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
 	rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
 
diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index 48ad9ceab6ea12..8b238b41decfa2 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -54,6 +54,10 @@ enum rtw_c2h_cmd_id {
 	C2H_BT_MP_INFO = 0x0b,
 	C2H_BT_HID_INFO = 0x45,
 	C2H_RA_RPT = 0x0c,
+	/* 8723BS SDIO vendor v41 firmware management TX report (0x32 is
+	 * reported as C2H_WLAN_RFON, handled per-chip in the C2H dispatch).
+	 */
+	C2H_VENDOR_TX_RPT = 0x12,
 	C2H_HW_FEATURE_REPORT = 0x19,
 	C2H_WLAN_INFO = 0x27,
 	C2H_WLAN_RFON = 0x32,
@@ -568,10 +572,12 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
 #define H2C_CMD_QUERY_BT_INFO		0x61
 #define H2C_CMD_FORCE_BT_TX_POWER	0x62
 #define H2C_CMD_IGNORE_WLAN_ACTION	0x63
+#define H2C_CMD_COEX_ANT_SEL_RSV	0x65
 #define H2C_CMD_WL_CH_INFO		0x66
 #define H2C_CMD_QUERY_BT_MP_INFO	0x67
 #define H2C_CMD_BT_WIFI_CONTROL		0x69
 #define H2C_CMD_WIFI_CALIBRATION	0x6d
+#define H2C_CMD_GNT_BT			0x6e
 #define H2C_CMD_QUERY_BT_HID_INFO	0x73
 
 #define H2C_CMD_KEEP_ALIVE		0x03
@@ -684,6 +690,12 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
 	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(31, 24))
 #define SET_QUERY_BT_INFO(h2c_pkt, value)                                      \
 	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
+#define SET_GNT_BT_STATE(h2c_pkt, value)                                       \
+	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
+#define SET_COEX_ANT_SEL_RSV_INVERSE(h2c_pkt, value)                           \
+	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
+#define SET_COEX_ANT_SEL_RSV_TYPE(h2c_pkt, value)                              \
+	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
 #define SET_WL_CH_INFO_LINK(h2c_pkt, value)                                    \
 	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
 #define SET_WL_CH_INFO_CHNL(h2c_pkt, value)                                    \
@@ -849,6 +861,11 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
 void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
 			 bool reset_ra_mask);
 void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn);
+void rtw_fw_macid_cfg(struct rtw_dev *rtwdev, u8 mac_id, u8 raid, u8 bw,
+		      u8 sgi, u32 rate_mask);
+void rtw_fw_send_wl_ch_info(struct rtw_dev *rtwdev, u8 ch, u8 bw);
+void rtw_fw_set_gnt_bt(struct rtw_dev *rtwdev, u8 state);
+void rtw_fw_coex_ant_sel_rsv(struct rtw_dev *rtwdev, u8 inverse, u8 type);
 void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev);
 void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,
 				 struct ieee80211_vif *vif);
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 766f22d31079ee..f920321b8874e5 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -15,6 +15,463 @@
 #include "wow.h"
 #include "sar.h"
 
+/* 8723BS SDIO: record a beacon/probe-resp seen from the target BSSID during
+ * the pre-auth window so the join sequence (mgd_prepare_tx) can wait for it,
+ * mirroring the vendor start_clnt_join(). Called from the SDIO RX path.
+ */
+void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,
+			    const struct ieee80211_hdr *hdr, u32 len,
+			    const struct rtw_rx_pkt_stat *pkt_stat,
+			    const struct ieee80211_rx_status *rx_status)
+{
+	struct rtw_auth_sync *sync = &rtwdev->auth_sync;
+	unsigned long flags;
+	__le16 fc = hdr->frame_control;
+
+	if (!rtw_is_8723bs(rtwdev) ||
+	    test_bit(RTW_FLAG_SCANNING, rtwdev->flags) ||
+	    pkt_stat->crc_err || pkt_stat->icv_err)
+		return;
+
+	if (!ieee80211_is_beacon(fc) && !ieee80211_is_probe_resp(fc))
+		return;
+
+	spin_lock_irqsave(&sync->lock, flags);
+	if (sync->active && ether_addr_equal(hdr->addr3, sync->bssid)) {
+		sync->seen = true;
+		sync->seen_count++;
+		wake_up(&sync->wait);
+	}
+	spin_unlock_irqrestore(&sync->lock, flags);
+}
+EXPORT_SYMBOL(rtw8723bs_auth_sync_rx);
+
+/* ---- 8723BS SDIO association sequence (vendor start_clnt_join) ---- */
+
+#define RTW8723BS_JOIN_RETRY_LIMIT		0x30
+#define RTW8723BS_AUTH_SYNC_WAIT_FALLBACK_MS	120
+#define RTW8723BS_AUTH_SYNC_WAIT_MIN_MS		80
+#define RTW8723BS_AUTH_SYNC_WAIT_MAX_MS		160
+#define RTW8723BS_ACK_PREAMBLE_SHORT		BIT(7)
+#define RTW8723BS_SHORT_SLOT_TIME		9
+#define RTW8723BS_LONG_SLOT_TIME		20
+#define RTW8723BS_RRSR_1M			BIT(0)
+#define RTW8723BS_RRSR_2M			BIT(1)
+#define RTW8723BS_RRSR_5_5M			BIT(2)
+#define RTW8723BS_RRSR_11M			BIT(3)
+#define RTW8723BS_RRSR_6M			BIT(4)
+#define RTW8723BS_RRSR_9M			BIT(5)
+#define RTW8723BS_RRSR_12M			BIT(6)
+#define RTW8723BS_RRSR_18M			BIT(7)
+#define RTW8723BS_RRSR_24M			BIT(8)
+#define RTW8723BS_RRSR_36M			BIT(9)
+#define RTW8723BS_RRSR_48M			BIT(10)
+#define RTW8723BS_RRSR_54M			BIT(11)
+#define RTW8723BS_RRSR_CCK_RATES \
+	(RTW8723BS_RRSR_1M | RTW8723BS_RRSR_2M | \
+	 RTW8723BS_RRSR_5_5M | RTW8723BS_RRSR_11M)
+#define RTW8723BS_RRSR_2G_FORCE			RTW8723BS_RRSR_CCK_RATES
+#define RTW8723BS_RRSR_2G_ALLOW \
+	(RTW8723BS_RRSR_CCK_RATES | RTW8723BS_RRSR_6M | \
+	 RTW8723BS_RRSR_12M | RTW8723BS_RRSR_24M)
+
+/* Keep the RCR at the vendor target-only state (AMF + CBSSID) across the whole
+ * connect window, matching the vendor STA path. accept_all is kept only for the
+ * caller's intent; both paths converge the filter to target-only.
+ */
+static void rtw8723bs_auth_rx_filter(struct rtw_dev *rtwdev, bool accept_all)
+{
+	rtwdev->hal.rcr |= BIT_AMF | BIT_CBSSID_DATA | BIT_CBSSID_BCN;
+	rtwdev->hal.rcr &= ~BIT_AAP;
+	rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
+}
+
+static void rtw8723bs_config_sec_cfg(struct rtw_dev *rtwdev)
+{
+	u16 sec = rtw_read16(rtwdev, RTW_SEC_CONFIG);
+
+	sec |= RTW_SEC_CHK_KEYID | RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;
+	rtw_write16(rtwdev, RTW_SEC_CONFIG, sec);
+}
+
+static void rtw8723bs_config_default_key_search(struct rtw_dev *rtwdev,
+						bool enable)
+{
+	u16 sec = rtw_read16(rtwdev, RTW_SEC_CONFIG);
+
+	if (enable)
+		sec |= RTW_SEC_TX_BC_USE_DK | RTW_SEC_TX_UNI_USE_DK |
+		       RTW_SEC_RX_UNI_USE_DK;
+	else
+		sec &= ~(RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |
+			 RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK);
+	rtw_write16(rtwdev, RTW_SEC_CONFIG, sec);
+}
+
+static void rtw8723bs_enable_tsf_update(struct rtw_dev *rtwdev)
+{
+	rtw_write8_clr(rtwdev, REG_BCN_CTRL, BIT_DIS_TSF_UDT);
+}
+
+static void rtw8723bs_set_ack_preamble(struct rtw_dev *rtwdev,
+				       bool short_preamble)
+{
+	u8 val = rtw_read8(rtwdev, REG_RRSR + 2) & ~RTW8723BS_ACK_PREAMBLE_SHORT;
+
+	if (short_preamble)
+		val |= RTW8723BS_ACK_PREAMBLE_SHORT;
+	rtw_write8(rtwdev, REG_RRSR + 2, val);
+}
+
+static void rtw8723bs_set_slot_time(struct rtw_dev *rtwdev, bool short_slot)
+{
+	rtw_write8(rtwdev, REG_SLOT,
+		   short_slot ? RTW8723BS_SHORT_SLOT_TIME :
+				RTW8723BS_LONG_SLOT_TIME);
+}
+
+static u16 rtw8723bs_rrsr_from_ie_rate(u8 rate)
+{
+	switch (rate & 0x7f) {
+	case 2:   return RTW8723BS_RRSR_1M;
+	case 4:   return RTW8723BS_RRSR_2M;
+	case 11:  return RTW8723BS_RRSR_5_5M;
+	case 22:  return RTW8723BS_RRSR_11M;
+	case 12:  return RTW8723BS_RRSR_6M;
+	case 18:  return RTW8723BS_RRSR_9M;
+	case 24:  return RTW8723BS_RRSR_12M;
+	case 36:  return RTW8723BS_RRSR_18M;
+	case 48:  return RTW8723BS_RRSR_24M;
+	case 72:  return RTW8723BS_RRSR_36M;
+	case 96:  return RTW8723BS_RRSR_48M;
+	case 108: return RTW8723BS_RRSR_54M;
+	default:  return 0;
+	}
+}
+
+static void rtw8723bs_collect_basic_rates(const u8 *ie, u16 *basic_rates,
+					  bool *valid)
+{
+	int i;
+
+	if (!ie)
+		return;
+
+	for (i = 0; i < ie[1]; i++) {
+		u16 r;
+
+		if (!(ie[i + 2] & 0x80))
+			continue;
+		r = rtw8723bs_rrsr_from_ie_rate(ie[i + 2]);
+		if (!r)
+			continue;
+		*basic_rates |= r;
+		*valid = true;
+	}
+}
+
+static void rtw8723bs_reset_response_rates(struct rtw_dev *rtwdev)
+{
+	rtw_write32(rtwdev, REG_RRSR, 0xffff1);
+	rtwdev->dm_info.rrsr_val_init = 0xffff1;
+}
+
+static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,
+					struct ieee80211_vif *vif,
+					const u8 *bssid)
+{
+	struct ieee80211_bss_conf *conf = &vif->bss_conf;
+	struct cfg80211_bss *lookup_bss = NULL;
+	struct cfg80211_bss *bss = NULL;
+	bool valid = false;
+	u16 basic_rates = 0;
+
+	if (!rtw_is_8723bs(rtwdev) || vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (conf->bss) {
+		bss = conf->bss;
+	} else if (bssid && is_valid_ether_addr(bssid)) {
+		lookup_bss = cfg80211_get_bss(rtwdev->hw->wiphy, NULL,
+					      bssid, NULL, 0,
+					      IEEE80211_BSS_TYPE_ESS,
+					      IEEE80211_PRIVACY_ANY);
+		bss = lookup_bss;
+	}
+
+	if (bss) {
+		const u8 *rates, *ext;
+
+		rcu_read_lock();
+		rates = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
+		ext = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
+		rtw8723bs_collect_basic_rates(rates, &basic_rates, &valid);
+		rtw8723bs_collect_basic_rates(ext, &basic_rates, &valid);
+		rcu_read_unlock();
+	}
+
+	if (valid) {
+		basic_rates |= RTW8723BS_RRSR_2G_FORCE;
+		basic_rates &= RTW8723BS_RRSR_2G_ALLOW;
+		rtw_write16(rtwdev, REG_RRSR, basic_rates);
+		rtw_write8(rtwdev, REG_RRSR + 2,
+			   rtw_read8(rtwdev, REG_RRSR + 2) & 0xf0);
+		rtwdev->dm_info.rrsr_val_init = basic_rates;
+	}
+
+	if (lookup_bss)
+		cfg80211_put_bss(rtwdev->hw->wiphy, lookup_bss);
+}
+
+/* Program response slot time (and, when set_preamble, the ACK preamble) from
+ * the selected scan BSS capabilities; the AP capabilities are not yet in
+ * bss_conf at mgd_prepare_tx() time.
+ */
+static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,
+				    struct ieee80211_vif *vif,
+				    const u8 *bssid, bool set_preamble)
+{
+	struct ieee80211_bss_conf *conf = &vif->bss_conf;
+	struct cfg80211_bss *lookup_bss = NULL;
+	struct cfg80211_bss *bss = NULL;
+	bool short_preamble, short_slot;
+	u16 cap = 0;
+
+	if (!rtw_is_8723bs(rtwdev) || vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (conf->bss) {
+		bss = conf->bss;
+	} else if (bssid && is_valid_ether_addr(bssid)) {
+		lookup_bss = cfg80211_get_bss(rtwdev->hw->wiphy, NULL,
+					      bssid, NULL, 0,
+					      IEEE80211_BSS_TYPE_ESS,
+					      IEEE80211_PRIVACY_ANY);
+		bss = lookup_bss;
+	}
+
+	if (bss) {
+		cap = bss->capability;
+	} else if (conf->assoc_capability) {
+		cap = conf->assoc_capability;
+	} else {
+		short_preamble = conf->use_short_preamble;
+		short_slot = conf->use_short_slot;
+		goto program;
+	}
+	short_preamble = !!(cap & WLAN_CAPABILITY_SHORT_PREAMBLE);
+	short_slot = !!(cap & WLAN_CAPABILITY_SHORT_SLOT_TIME);
+
+program:
+	if (set_preamble)
+		rtw8723bs_set_ack_preamble(rtwdev, short_preamble);
+	rtw8723bs_set_slot_time(rtwdev, short_slot);
+
+	if (lookup_bss)
+		cfg80211_put_bss(rtwdev->hw->wiphy, lookup_bss);
+}
+
+static unsigned int rtw8723bs_auth_sync_wait_ms(struct ieee80211_vif *vif)
+{
+	u16 beacon_int = vif->bss_conf.beacon_int;
+	unsigned int wait_ms;
+
+	if (!beacon_int)
+		return RTW8723BS_AUTH_SYNC_WAIT_FALLBACK_MS;
+
+	wait_ms = DIV_ROUND_UP(beacon_int * 1024, 1000) + 20;
+	return clamp_t(unsigned int, wait_ms, RTW8723BS_AUTH_SYNC_WAIT_MIN_MS,
+		       RTW8723BS_AUTH_SYNC_WAIT_MAX_MS);
+}
+
+static void rtw8723bs_auth_sync_start(struct rtw_dev *rtwdev, const u8 *bssid)
+{
+	struct rtw_auth_sync *sync = &rtwdev->auth_sync;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sync->lock, flags);
+	ether_addr_copy(sync->bssid, bssid);
+	sync->seen = false;
+	sync->seen_count = 0;
+	sync->active = true;
+	spin_unlock_irqrestore(&sync->lock, flags);
+}
+
+static void rtw8723bs_auth_sync_stop(struct rtw_dev *rtwdev)
+{
+	struct rtw_auth_sync *sync = &rtwdev->auth_sync;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sync->lock, flags);
+	sync->active = false;
+	spin_unlock_irqrestore(&sync->lock, flags);
+}
+
+static bool rtw8723bs_auth_sync_seen(struct rtw_dev *rtwdev)
+{
+	struct rtw_auth_sync *sync = &rtwdev->auth_sync;
+	unsigned long flags;
+	bool seen;
+
+	spin_lock_irqsave(&sync->lock, flags);
+	seen = sync->seen;
+	spin_unlock_irqrestore(&sync->lock, flags);
+
+	return seen;
+}
+
+static bool rtw8723bs_auth_sync_wait(struct rtw_dev *rtwdev,
+				     unsigned int wait_ms)
+{
+	struct rtw_auth_sync *sync = &rtwdev->auth_sync;
+
+	return wait_event_timeout(sync->wait, rtw8723bs_auth_sync_seen(rtwdev),
+				  msecs_to_jiffies(wait_ms)) > 0;
+}
+
+static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,
+					  struct ieee80211_prep_tx_info *info)
+{
+	return rtw_is_8723bs(rtwdev) && info &&
+	       info->subtype == IEEE80211_STYPE_AUTH;
+}
+
+/* Replicate the vendor start_clnt_join() register programming right before
+ * auth. Returns true for a fresh join (BSSID changed).
+ */
+static bool rtw8723bs_mgd_prepare_join(struct rtw_dev *rtwdev,
+				       struct ieee80211_vif *vif,
+				       const u8 *bssid)
+{
+	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+	bool fresh_join;
+	u16 retry_limit;
+
+	if (!is_valid_ether_addr(bssid))
+		return false;
+
+	fresh_join = !ether_addr_equal(rtwvif->bssid, bssid);
+
+	ether_addr_copy(rtwvif->bssid, bssid);
+	rtwvif->aid = 0;
+	rtwvif->net_type = RTW_NET_MGD_LINKED;
+	rtw_vif_port_config(rtwdev, rtwvif,
+			    PORT_SET_BSSID | PORT_SET_AID | PORT_SET_NET_TYPE);
+
+	/* Do not narrow RRSR or switch to short-preamble responses before the
+	 * exchange: the whole auth/assoc runs on the init response set
+	 * (0xffff1, long preamble). Only slot time is programmed early.
+	 */
+	rtw8723bs_apply_bss_cap(rtwdev, vif, bssid, false);
+
+	rtw_fw_beacon_filter_config(rtwdev, false, vif);
+
+	/* Match the vendor start_clnt_join() TX state (set_msr directly, keep
+	 * BCN_CTRL / BCNQ_DL set, reassert TBTT/RESP_SIFS every join).
+	 */
+	rtw_write8(rtwdev, REG_BCN_CTRL,
+		   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
+	rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT_EN_BCNQ_DL);
+	rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1, 0x64 & 0xff);
+	rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2,
+		   (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xf0) | (0x64 >> 8));
+	rtw_write16(rtwdev, REG_RESP_SIFS_CCK, 0x0808);
+	rtw_write16(rtwdev, REG_RESP_SIFS_OFDM, 0x0a0a);
+
+	rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff);
+	rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);
+	rtw8723bs_auth_rx_filter(rtwdev, true);
+
+	retry_limit = (RTW8723BS_JOIN_RETRY_LIMIT << 8) |
+		      RTW8723BS_JOIN_RETRY_LIMIT;
+	rtw_write16(rtwdev, REG_RETRY_LIMIT, retry_limit);
+
+	rtw8723bs_config_sec_cfg(rtwdev);
+
+	return fresh_join;
+}
+
+/* The vendor sends a deauth to the target before auth to clear stale AP-side
+ * state; synthesize and TX one, then let the AP settle.
+ */
+static void rtw8723bs_tx_pre_auth_deauth(struct rtw_dev *rtwdev,
+					 struct ieee80211_vif *vif,
+					 const u8 *bssid)
+{
+	struct ieee80211_tx_control control = {};
+	struct ieee80211_tx_info *info;
+	struct ieee80211_mgmt *mgmt;
+	struct sk_buff *skb;
+	unsigned int frame_len, headroom;
+
+	frame_len = sizeof(struct ieee80211_hdr_3addr) + sizeof(mgmt->u.deauth);
+	headroom = rtwdev->chip->tx_pkt_desc_sz + 8;
+
+	skb = dev_alloc_skb(headroom + frame_len);
+	if (!skb)
+		return;
+
+	skb_reserve(skb, headroom);
+	mgmt = skb_put_zero(skb, frame_len);
+	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+					  IEEE80211_STYPE_DEAUTH);
+	memcpy(mgmt->da, bssid, ETH_ALEN);
+	memcpy(mgmt->sa, vif->addr, ETH_ALEN);
+	memcpy(mgmt->bssid, bssid, ETH_ALEN);
+	mgmt->u.deauth.reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
+
+	info = IEEE80211_SKB_CB(skb);
+	memset(info, 0, sizeof(*info));
+	info->control.vif = vif;
+
+	rtw_tx(rtwdev, &control, skb);
+	msleep(100);
+}
+
+/* Orchestrate the pre-auth join: program the vendor join state, send the
+ * pre-auth deauth, wait for a beacon from the target, then replay the
+ * pre-auth coex H2Cs - once per fresh BSSID.
+ */
+static void rtw8723bs_mgd_prepare_auth_join(struct rtw_dev *rtwdev,
+					    struct ieee80211_vif *vif,
+					    struct ieee80211_prep_tx_info *info)
+{
+	struct rtw_vif *rtwvif;
+	const u8 *bssid = NULL;
+	bool fresh_join;
+
+	if (!rtw8723bs_mgd_prepare_is_auth(rtwdev, info) || !vif ||
+	    test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
+		return;
+
+	rtwvif = (struct rtw_vif *)vif->drv_priv;
+
+	if (!is_zero_ether_addr(vif->cfg.ap_addr))
+		bssid = vif->cfg.ap_addr;
+	else if (vif->bss_conf.bssid && !is_zero_ether_addr(vif->bss_conf.bssid))
+		bssid = vif->bss_conf.bssid;
+
+	if (!bssid)
+		return;
+
+	fresh_join = rtw8723bs_mgd_prepare_join(rtwdev, vif, bssid);
+
+	if (fresh_join || !rtwvif->pre_auth_join_done) {
+		unsigned int wait_ms = rtw8723bs_auth_sync_wait_ms(vif);
+
+		rtw8723bs_auth_sync_start(rtwdev, bssid);
+		rtw8723bs_tx_pre_auth_deauth(rtwdev, vif, bssid);
+		rtw8723bs_auth_sync_wait(rtwdev, wait_ms);
+		rtw8723bs_auth_sync_stop(rtwdev);
+		rtwvif->pre_auth_join_done = true;
+	}
+
+	if (!rtwvif->pre_auth_h2c_sent) {
+		rtw_coex_8723bs_pre_auth_h2c(rtwdev);
+		rtwvif->pre_auth_h2c_sent = true;
+	}
+}
+
 static void rtw_ops_tx(struct ieee80211_hw *hw,
 		       struct ieee80211_tx_control *control,
 		       struct sk_buff *skb)
@@ -387,6 +844,28 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_ASSOC) {
 		rtw_vif_assoc_changed(rtwvif, conf);
 		if (vif->cfg.assoc) {
+			if (rtw_is_8723bs(rtwdev) &&
+			    vif->type == NL80211_IFTYPE_STATION) {
+				rtw8723bs_auth_rx_filter(rtwdev, false);
+				rtw8723bs_apply_bss_cap(rtwdev, vif, NULL, true);
+				rtw8723bs_apply_basic_rates(rtwdev, vif, NULL);
+				rtw8723bs_enable_tsf_update(rtwdev);
+				/* Vendor mlmeext_joinbss sends MACID_CFG before
+				 * MEDIA_STATUS_RPT, then WL_CH_INFO.
+				 */
+				rtw_fw_macid_cfg(rtwdev, rtwvif->mac_id,
+						 1, 0, 1, 0x0ff015);
+				if (!rtwvif->fw_media_connected) {
+					rtw_fw_media_status_report(rtwdev,
+								   rtwvif->mac_id,
+								   true);
+					rtwvif->fw_media_connected = true;
+				}
+				rtw_fw_send_wl_ch_info(rtwdev,
+						       rtwdev->hal.current_channel,
+						       rtwdev->hal.current_band_width);
+			}
+
 			rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH);
 
 			rtw_fw_download_rsvd_page(rtwdev);
@@ -408,6 +887,13 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 			if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
 				rtw_hw_scan_abort(rtwdev);
 
+			if (rtw_is_8723bs(rtwdev) &&
+			    vif->type == NL80211_IFTYPE_STATION) {
+				rtw8723bs_auth_rx_filter(rtwdev, false);
+				rtw8723bs_reset_response_rates(rtwdev);
+				rtwvif->pre_auth_h2c_sent = false;
+				rtwvif->pre_auth_join_done = false;
+			}
 		}
 
 		config |= PORT_SET_NET_TYPE;
@@ -415,8 +901,26 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if (changed & BSS_CHANGED_BSSID) {
+		bool bssid_cleared = is_zero_ether_addr(conf->bssid);
+		bool bssid_changed = !ether_addr_equal(rtwvif->bssid,
+						       conf->bssid);
+
+		if (rtw_is_8723bs(rtwdev) &&
+		    vif->type == NL80211_IFTYPE_STATION && bssid_changed) {
+			rtwvif->pre_auth_h2c_sent = false;
+			rtwvif->pre_auth_join_done = false;
+		}
 		ether_addr_copy(rtwvif->bssid, conf->bssid);
 		config |= PORT_SET_BSSID;
+		if (rtw_is_8723bs(rtwdev) &&
+		    vif->type == NL80211_IFTYPE_STATION && bssid_cleared) {
+			rtwvif->aid = 0;
+			rtwvif->net_type = RTW_NET_NO_LINK;
+			config |= PORT_SET_NET_TYPE | PORT_SET_AID;
+			rtw_write8(rtwdev, REG_BCN_CTRL,
+				   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION |
+				   BIT_DIS_ATIM);
+		}
 		if (!rtw_core_check_sta_active(rtwdev))
 			rtw_clear_op_chan(rtwdev);
 		else
@@ -448,8 +952,17 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_MU_GROUPS)
 		rtw_chip_set_gid_table(rtwdev, vif, conf);
 
-	if (changed & BSS_CHANGED_ERP_SLOT)
+	if (changed & BSS_CHANGED_ERP_PREAMBLE &&
+	    rtw_is_8723bs(rtwdev) &&
+	    vif->type == NL80211_IFTYPE_STATION)
+		rtw8723bs_set_ack_preamble(rtwdev, conf->use_short_preamble);
+
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (rtw_is_8723bs(rtwdev) &&
+		    vif->type == NL80211_IFTYPE_STATION)
+			rtw8723bs_set_slot_time(rtwdev, conf->use_short_slot);
 		rtw_conf_tx(rtwdev, rtwvif);
+	}
 
 	if (changed & BSS_CHANGED_PS)
 		rtw_recalc_lps(rtwdev, NULL);
@@ -609,11 +1122,19 @@ static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		key->hw_key_idx = hw_key_idx;
 		rtw_sec_write_cam(rtwdev, sec, sta, key,
 				  hw_key_type, hw_key_idx);
+		if (rtw_is_8723bs(rtwdev) && vif &&
+		    vif->type == NL80211_IFTYPE_STATION &&
+		    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			rtw8723bs_config_default_key_search(rtwdev, true);
 		break;
 	case DISABLE_KEY:
 		rtw_hci_flush_all_queues(rtwdev, false);
 		rtw_mac_flush_all_queues(rtwdev, false);
 		rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
+		if (rtw_is_8723bs(rtwdev) && vif &&
+		    vif->type == NL80211_IFTYPE_STATION &&
+		    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			rtw8723bs_config_default_key_search(rtwdev, false);
 		break;
 	}
 
@@ -703,8 +1224,23 @@ static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
 
 	mutex_lock(&rtwdev->mutex);
 	rtw_leave_lps_deep(rtwdev);
-	rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);
-	rtw_chip_prepare_tx(rtwdev);
+
+	if (rtw_is_8723bs(rtwdev)) {
+		/* Wake from soft IPS and run the vendor join sequence. The RFK
+		 * is handled by the once-only power-on IQK plus the ps.c
+		 * post-IPS RF-bus recovery, not a fresh calibration here.
+		 */
+		if (rtw_leave_ips(rtwdev)) {
+			rtw_err(rtwdev, "failed to leave idle state for mgd tx\n");
+			goto out;
+		}
+		rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);
+		rtw8723bs_mgd_prepare_auth_join(rtwdev, vif, info);
+	} else {
+		rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);
+		rtw_chip_prepare_tx(rtwdev);
+	}
+out:
 	mutex_unlock(&rtwdev->mutex);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index cd9254370fcc72..e2f0fd367bebfa 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -43,6 +43,108 @@ MODULE_PARM_DESC(disable_lps_deep, "Set Y to disable Deep PS");
 MODULE_PARM_DESC(support_bf, "Set Y to enable beamformee support");
 MODULE_PARM_DESC(debug_mask, "Debugging mask");
 
+#define RTW8723BS_REG_BB_SEL_BTG	0x0948
+#define RTW8723BS_SCAN_IGI		0x1e
+
+struct rtw8723bs_txagc_entry {
+	u8 rate;
+	u8 pwr_idx;
+};
+
+/* Vendor/staging per-rate TXAGC PG bytes for 8723BS 2.4 GHz. */
+static const struct rtw8723bs_txagc_entry rtw8723bs_pg_txagc[] = {
+	{ DESC_RATE1M, 0x38 }, { DESC_RATE2M, 0x36 },
+	{ DESC_RATE5_5M, 0x34 }, { DESC_RATE11M, 0x32 },
+	{ DESC_RATE6M, 0x44 }, { DESC_RATE9M, 0x44 },
+	{ DESC_RATE12M, 0x42 }, { DESC_RATE18M, 0x40 },
+	{ DESC_RATE24M, 0x38 }, { DESC_RATE36M, 0x36 },
+	{ DESC_RATE48M, 0x32 }, { DESC_RATE54M, 0x28 },
+	{ DESC_RATEMCS0, 0x44 }, { DESC_RATEMCS1, 0x42 },
+	{ DESC_RATEMCS2, 0x40 }, { DESC_RATEMCS3, 0x38 },
+	{ DESC_RATEMCS4, 0x36 }, { DESC_RATEMCS5, 0x34 },
+	{ DESC_RATEMCS6, 0x30 }, { DESC_RATEMCS7, 0x26 },
+};
+
+/* Lower the scan-time initial gain so the 8723BS SDIO site-survey hears the AP. */
+static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)
+{
+	if (!rtw_is_8723bs(rtwdev))
+		return;
+
+	rtw_write32_mask(rtwdev, REG_RXIGI_A, MASKBYTE0, RTW8723BS_SCAN_IGI);
+}
+
+/* rtw_load_table() only populates the by-rate cache; restore the staging
+ * 8723BS PG bytes after the generic channel power update and push them to the
+ * chip TXAGC registers.
+ */
+static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)
+{
+	struct rtw_hal *hal = &rtwdev->hal;
+	u8 path;
+	int i;
+
+	if (!rtw_is_8723bs(rtwdev) || hal->current_band_type != RTW_BAND_2G)
+		return;
+
+	mutex_lock(&hal->tx_power_mutex);
+	for (path = 0; path < hal->rf_path_num && path < RTW_RF_PATH_MAX; path++)
+		for (i = 0; i < ARRAY_SIZE(rtw8723bs_pg_txagc); i++)
+			hal->tx_pwr_tbl[path][rtw8723bs_pg_txagc[i].rate] =
+				rtw8723bs_pg_txagc[i].pwr_idx;
+	rtwdev->chip->ops->set_tx_power_index(rtwdev);
+	mutex_unlock(&hal->tx_power_mutex);
+}
+
+/* Staging runs PHY_IQCalibrate_8723B() only during initial hal_init, never on
+ * IPS leave. Match that: run IQK once on the first power-on, then on later
+ * (IPS-leave) power-ons just restore the PTA antenna path and reset RF_WLINT.
+ */
+static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_efuse *efuse = &rtwdev->efuse;
+	u32 pta_path;
+	u32 saved_path;
+
+	if (!rtw_is_8723bs(rtwdev) || !chip->ops->phy_calibration)
+		return;
+
+	pta_path = (efuse->bt_setting & BIT(6)) ? 0x80 : 0x200;
+
+	if (rtwdev->initial_rfk_done) {
+		rtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, pta_path);
+		rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780);
+		return;
+	}
+
+	saved_path = rtw_read32(rtwdev, RTW8723BS_REG_BB_SEL_BTG);
+	rtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, pta_path);
+	chip->ops->phy_calibration(rtwdev);
+	rtwdev->need_rfk = false;
+	rtw_write32(rtwdev, RTW8723BS_REG_BB_SEL_BTG, saved_path);
+	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,},
@@ -299,6 +401,18 @@ 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
+	 * constantly. Gate LPS on the smoothed throughput instead so the chip
+	 * only sleeps after sustained idle and stays awake through an active
+	 * session. Other chips keep the normal behaviour.
+	 */
+	if (rtw_is_8723bs(rtwdev) &&
+	    (stats->tx_throughput || stats->rx_throughput))
+		ps_active = true;
+
 	if (rtwdev->ps_enabled && data.rtwvif && !ps_active &&
 	    !rtwdev->beacon_loss && !rtwdev->ap_active)
 		rtw_enter_lps(rtwdev, data.rtwvif->port);
@@ -367,7 +481,13 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
 	INIT_WORK(&si->rc_work, rtw_sta_rc_work);
 
 	rtw_update_sta_info(rtwdev, si, true);
-	rtw_fw_media_status_report(rtwdev, si->mac_id, true);
+	if (rtw8723bs_defer_sta_media_status(rtwdev, sta, vif)) {
+		rtwvif->fw_media_connected = false;
+	} else {
+		rtw_fw_media_status_report(rtwdev, si->mac_id, true);
+		if (rtw8723bs_station_media_status(rtwdev, sta, vif))
+			rtwvif->fw_media_connected = true;
+	}
 
 	rtwdev->sta_cnt++;
 	rtwdev->beacon_loss = false;
@@ -382,14 +502,21 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
 {
 	struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
 	struct ieee80211_vif *vif = si->vif;
+	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
 	int i;
 
 	cancel_work_sync(&si->rc_work);
 
 	if (vif->type != NL80211_IFTYPE_STATION || sta->tdls)
 		rtw_release_macid(rtwdev, si->mac_id);
-	if (fw_exist)
+	if (fw_exist && rtw8723bs_station_media_status(rtwdev, sta, vif) &&
+	    !rtwvif->fw_media_connected) {
+		/* connect status was deferred and never sent; nothing to undo */
+	} else if (fw_exist) {
 		rtw_fw_media_status_report(rtwdev, si->mac_id, false);
+		if (rtw8723bs_station_media_status(rtwdev, sta, vif))
+			rtwvif->fw_media_connected = false;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
 		rtw_txq_cleanup(rtwdev, sta->txq[i]);
@@ -904,6 +1031,8 @@ void rtw_set_channel(struct rtw_dev *rtwdev)
 
 	rtw_phy_set_tx_power_level(rtwdev, center_chan);
 
+	rtw8723bs_reapply_pg_txagc(rtwdev);
+
 	/* if the channel isn't set for scanning, we will do RF calibration
 	 * in ieee80211_ops::mgd_prepare_tx(). Performing the calibration
 	 * during scanning on each channel takes too long.
@@ -1429,6 +1558,34 @@ int rtw_power_on(struct rtw_dev *rtwdev)
 	rtw_fw_send_phydm_info(rtwdev);
 
 	wifi_only = !rtwdev->efuse.btcoex;
+
+	/* 8723BS SDIO: on an IPS-leave power-on (IQK already done once) skip the
+	 * BT-path coex init entirely - scan_workaround re-establishes the PTA /
+	 * coex state. Run the once-only IQK via the RFK helper; on the first
+	 * power-on, finalise coex with the vendor init H2C toggle that enables
+	 * the 8051 management TX scheduler.
+	 */
+	if (rtw_is_8723bs(rtwdev)) {
+		bool ips_wake = rtwdev->initial_rfk_done;
+
+		if (!ips_wake)
+			rtw_coex_power_on_setting(rtwdev);
+
+		rtw_power_on_8723bs_sdio_rfk(rtwdev);
+
+		if (!ips_wake) {
+			rtw_coex_init_hw_config(rtwdev, wifi_only);
+			rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+			rtw_fw_set_gnt_bt(rtwdev, 1);
+			rtw_fw_coex_ant_sel_rsv(rtwdev, 0, 0);
+			rtw_fw_query_bt_info(rtwdev);
+			rtw_fw_coex_tdma_type(rtwdev, 0x08, 0x00, 0x00, 0x00, 0x00);
+			rtw_fw_set_gnt_bt(rtwdev, 0);
+		}
+
+		return 0;
+	}
+
 	rtw_coex_power_on_setting(rtwdev);
 	rtw_coex_init_hw_config(rtwdev, wifi_only);
 
@@ -1485,6 +1642,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
 	set_bit(RTW_FLAG_SCANNING, rtwdev->flags);
 
 	rtw_phy_dig_set_max_coverage(rtwdev);
+	rtw_scan_set_8723bs_igi(rtwdev);
 }
 
 void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
@@ -1965,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.
+		 */
+		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) {
@@ -2174,11 +2345,13 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 
 	spin_lock_init(&rtwdev->txq_lock);
 	spin_lock_init(&rtwdev->tx_report.q_lock);
+	spin_lock_init(&rtwdev->auth_sync.lock);
 
 	mutex_init(&rtwdev->mutex);
 	mutex_init(&rtwdev->hal.tx_power_mutex);
 
 	init_waitqueue_head(&rtwdev->coex.wait);
+	init_waitqueue_head(&rtwdev->auth_sync.wait);
 	init_completion(&rtwdev->lps_leave_check);
 	init_completion(&rtwdev->fw_scan_density);
 
@@ -2270,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.
+	 */
+	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);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 9c0b746540b0ee..5866c96c92723f 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -194,6 +194,7 @@ enum rtw_chip_type {
 	RTW_CHIP_TYPE_8723D,
 	RTW_CHIP_TYPE_8821C,
 	RTW_CHIP_TYPE_8703B,
+	RTW_CHIP_TYPE_8723B,
 	RTW_CHIP_TYPE_8821A,
 	RTW_CHIP_TYPE_8812A,
 	RTW_CHIP_TYPE_8814A,
@@ -781,6 +782,8 @@ struct rtw_sta_info {
 	bool vht_enable;
 	u8 init_ra_lv;
 	u64 ra_mask;
+	/* Last rate mask sent to the firmware, to gate no_update. */
+	u64 ra_mask_last;
 
 	DECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS);
 
@@ -828,6 +831,10 @@ struct rtw_vif {
 	u8 bssid[ETH_ALEN];
 	u8 port;
 	u8 bcn_ctrl;
+	/* Set once the firmware has been told the STA is connected. */
+	bool fw_media_connected;
+	bool pre_auth_h2c_sent;
+	bool pre_auth_join_done;
 	struct list_head rsvd_page_list;
 	struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
 	const struct rtw_vif_port *conf;
@@ -2056,6 +2063,20 @@ struct rtw_hw_scan_info {
 	u8 op_bw;
 };
 
+/*
+ * Synchronises the pre-auth wait on a beacon or probe response from the
+ * target BSSID before the join sequence continues.
+ */
+struct rtw_auth_sync {
+	wait_queue_head_t wait;
+	/* Protects the fields below. */
+	spinlock_t lock;
+	u8 bssid[ETH_ALEN];
+	bool active;
+	bool seen;
+	u32 seen_count;
+};
+
 struct rtw_dev {
 	struct ieee80211_hw *hw;
 	struct device *dev;
@@ -2129,9 +2150,13 @@ struct rtw_dev {
 	struct rtw_wow_param wow;
 
 	bool need_rfk;
+	/* Run the initial IQK once, not on every IPS leave. */
+	bool initial_rfk_done;
 	struct completion fw_scan_density;
 	bool ap_active;
 
+	struct rtw_auth_sync auth_sync;
+
 	bool led_registered;
 	char led_name[32];
 	struct led_classdev led_cdev;
@@ -2193,6 +2218,12 @@ static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev)
 	return rtwdev->chip->tx_stbc;
 }
 
+static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)
+{
+	return rtwdev->chip->id == RTW_CHIP_TYPE_8723B &&
+	       rtwdev->hci.type == RTW_HCI_TYPE_SDIO;
+}
+
 static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
 {
 	unsigned long mac_id;
@@ -2283,4 +2314,8 @@ bool rtw_core_check_sta_active(struct rtw_dev *rtwdev);
 void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable);
 void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 			  struct ieee80211_bss_conf *bss_conf);
+void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,
+			    const struct ieee80211_hdr *hdr, u32 len,
+			    const struct rtw_rx_pkt_stat *pkt_stat,
+			    const struct ieee80211_rx_status *rx_status);
 #endif
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 08e9494977e06a..455303bc28a954 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -479,6 +479,7 @@
 #define BIT_DIS_TSF_UDT		BIT(4)
 #define BIT_EN_BCN_FUNCTION	BIT(3)
 #define BIT_EN_TXBCN_RPT	BIT(2)
+#define BIT_DIS_ATIM		BIT(0)
 #define REG_BCN_CTRL_CLINT0	0x0551
 #define REG_DRVERLYINT		0x0558
 #define REG_BCNDMATIM		0x0559
@@ -518,6 +519,7 @@
 #define BIT_UC_MD_EN		BIT(16)
 #define BIT_RXSK_PERPKT		BIT(15)
 #define BIT_HTC_LOC_CTRL	BIT(14)
+#define BIT_AMF			BIT(13)
 #define BIT_RPFM_CAM_ENABLE	BIT(12)
 #define BIT_TA_BCN		BIT(11)
 #define BIT_RCR_ADF		BIT(11)
diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c
index 01fd299abb7fe9..57facbc1b41f76 100644
--- a/drivers/net/wireless/realtek/rtw88/rx.c
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -253,10 +253,12 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
 
 	rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
 
-	/* Rtl8723cs driver checks for size < 14 or size > 8192 and
-	 * simply drops the packet.
+	/* Rtl8723cs and rtl8723bs drivers check for size < 14 or size > 8192
+	 * and simply drop the packet.
 	 */
-	if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) {
+	if ((rtwdev->chip->id == RTW_CHIP_TYPE_8703B ||
+	     rtwdev->chip->id == RTW_CHIP_TYPE_8723B) &&
+	    pkt_stat->pkt_len == 0) {
 		rx_status->flag |= RX_FLAG_NO_PSDU;
 		rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
 	}
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 5b40d74b16ee08..9cf43df2ec3f9a 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -20,6 +20,16 @@
 #include "tx.h"
 
 #define RTW_SDIO_INDIRECT_RW_RETRIES			50
+#define RTW_SDIO_OQT_TIMEOUT_MS				1000
+
+/* 8723BS SDIO TX FIFO back-pressure watermarks: stop the mac80211 queue once
+ * the per-AC software FIFO fills past the high watermark, and wake it from the
+ * TX drain path once it falls back to the low one. Bounds the queueing latency
+ * that otherwise causes uplink bufferbloat / congestion collapse.
+ */
+#define RTW_SDIO_TX_FIFO_HIWATER			16
+#define RTW_SDIO_TX_FIFO_LOWATER			8
+#define RTW_SDIO_TX_RETRY_DELAY			msecs_to_jiffies(1)
 
 static bool rtw_sdio_is_bus_addr(u32 addr)
 {
@@ -479,8 +489,14 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,
 		txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,
 				    REG_SDIO_CMD_ADDR_TXFF_HIGH);
 		break;
-	case RTW_TX_QUEUE_VI:
 	case RTW_TX_QUEUE_VO:
+		if (rtw_is_8723bs(rtwdev)) {
+			txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,
+					    REG_SDIO_CMD_ADDR_TXFF_HIGH);
+			break;
+		}
+		fallthrough;
+	case RTW_TX_QUEUE_VI:
 		txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,
 				    REG_SDIO_CMD_ADDR_TXFF_NORMAL);
 		break;
@@ -491,6 +507,8 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,
 		break;
 	case RTW_TX_QUEUE_MGMT:
 		txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,
+				    rtw_is_8723bs(rtwdev) ?
+				    REG_SDIO_CMD_ADDR_TXFF_HIGH :
 				    REG_SDIO_CMD_ADDR_TXFF_EXTRA);
 		break;
 	default:
@@ -548,12 +566,91 @@ static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
 	return ret;
 }
 
+static void rtw_sdio_init_free_txpg(struct rtw_dev *rtwdev)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	const struct rtw_page_table *pg_tbl;
+	u32 free_txpg;
+	u16 pubq_num;
+
+	if (!rtw_is_8723bs(rtwdev))
+		return;
+
+	pg_tbl = &rtwdev->chip->page_table[0];
+	pubq_num = rtwdev->fifo.acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
+		   pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
+	free_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
+	if (free_txpg) {
+		atomic_set(&rtwsdio->free_pg_high, free_txpg & 0xff);
+		atomic_set(&rtwsdio->free_pg_normal, (free_txpg >> 8) & 0xff);
+		atomic_set(&rtwsdio->free_pg_low, (free_txpg >> 16) & 0xff);
+		atomic_set(&rtwsdio->free_pg_pub, (free_txpg >> 24) & 0xff);
+	} else {
+		atomic_set(&rtwsdio->free_pg_high, pg_tbl->hq_num);
+		atomic_set(&rtwsdio->free_pg_normal, pg_tbl->nq_num);
+		atomic_set(&rtwsdio->free_pg_low, pg_tbl->lq_num);
+		atomic_set(&rtwsdio->free_pg_pub, pubq_num);
+	}
+
+	atomic_set(&rtwsdio->tx_oqt_free,
+		   rtw_read8(rtwdev, REG_SDIO_OQT_FREE_PG));
+}
+
+static void rtw_sdio_sync_free_txpg(struct rtw_dev *rtwdev)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	u32 free_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
+
+	if (!free_txpg)
+		return;
+
+	atomic_set(&rtwsdio->free_pg_high, free_txpg & 0xff);
+	atomic_set(&rtwsdio->free_pg_normal, (free_txpg >> 8) & 0xff);
+	atomic_set(&rtwsdio->free_pg_low, (free_txpg >> 16) & 0xff);
+	atomic_set(&rtwsdio->free_pg_pub, (free_txpg >> 24) & 0xff);
+}
+
+static int rtw_sdio_8723bs_free_txpg(struct rtw_dev *rtwdev, u8 queue)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+
+	switch (queue) {
+	case RTW_TX_QUEUE_BCN:
+	case RTW_TX_QUEUE_H2C:
+	case RTW_TX_QUEUE_HI0:
+	case RTW_TX_QUEUE_MGMT:
+	case RTW_TX_QUEUE_VO:
+		return atomic_read(&rtwsdio->free_pg_high);
+	case RTW_TX_QUEUE_VI:
+		return atomic_read(&rtwsdio->free_pg_normal);
+	case RTW_TX_QUEUE_BE:
+	case RTW_TX_QUEUE_BK:
+		return atomic_read(&rtwsdio->free_pg_low);
+	default:
+		return -EINVAL;
+	}
+}
+
 static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,
 				    size_t count)
 {
 	unsigned int pages_free, pages_needed;
 
-	if (rtw_chip_wcpu_8051(rtwdev)) {
+	if (rtw_is_8723bs(rtwdev)) {
+		struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+		int dedicated = rtw_sdio_8723bs_free_txpg(rtwdev, queue);
+
+		if (dedicated < 0)
+			return dedicated;
+		pages_free = dedicated + atomic_read(&rtwsdio->free_pg_pub);
+		pages_needed = DIV_ROUND_UP(count, rtwdev->chip->page_size);
+		if (pages_needed <= pages_free)
+			return 0;
+
+		rtw_sdio_sync_free_txpg(rtwdev);
+		dedicated = rtw_sdio_8723bs_free_txpg(rtwdev, queue);
+		pages_free = dedicated + atomic_read(&rtwsdio->free_pg_pub);
+	} else if (rtw_chip_wcpu_8051(rtwdev)) {
 		u32 free_txpg;
 
 		free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG);
@@ -632,44 +729,145 @@ static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,
 	return 0;
 }
 
+static int rtw_sdio_wait_tx_oqt(struct rtw_dev *rtwdev)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	int i;
+	u8 free;
+
+	if (!rtw_is_8723bs(rtwdev))
+		return 0;
+
+	if (atomic_add_unless(&rtwsdio->tx_oqt_free, -1, 0))
+		return 0;
+
+	for (i = 0; i < RTW_SDIO_OQT_TIMEOUT_MS; i++) {
+		free = rtw_read8(rtwdev, REG_SDIO_OQT_FREE_PG);
+		if (free) {
+			atomic_set(&rtwsdio->tx_oqt_free, free - 1);
+			return 0;
+		}
+		usleep_range(1000, 2000);
+	}
+
+	return -EBUSY;
+}
+
+static void rtw_sdio_8723bs_consume_txpg(struct rtw_dev *rtwdev, u8 queue,
+					 unsigned int pages)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	atomic_t *dedicated;
+	int free;
+
+	switch (queue) {
+	case RTW_TX_QUEUE_VI:
+		dedicated = &rtwsdio->free_pg_normal;
+		break;
+	case RTW_TX_QUEUE_BE:
+	case RTW_TX_QUEUE_BK:
+		dedicated = &rtwsdio->free_pg_low;
+		break;
+	default:
+		dedicated = &rtwsdio->free_pg_high;
+		break;
+	}
+
+	free = atomic_read(dedicated);
+	if (pages <= free) {
+		atomic_sub(pages, dedicated);
+	} else {
+		atomic_set(dedicated, 0);
+		atomic_sub(pages - free, &rtwsdio->free_pg_pub);
+	}
+}
+
+static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	BUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) >
+		     sizeof(info->status.status_driver_data));
+
+	return (struct rtw_sdio_tx_data *)info->status.status_driver_data;
+}
+
 static int rtw_sdio_write_port(struct rtw_dev *rtwdev, struct sk_buff *skb,
 			       enum rtw_tx_queue_type queue)
 {
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	struct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb);
+	unsigned int orig_len = skb->len;
+	bool rtl8723bs = rtw_is_8723bs(rtwdev);
+	bool quiet = rtl8723bs && tx_data->is_mgmt;
+	unsigned int pages;
 	bool bus_claim;
 	size_t txsize;
+	size_t write_size;
 	u32 txaddr;
 	int ret;
 
-	txaddr = rtw_sdio_get_tx_addr(rtwdev, skb->len, queue);
-	if (!txaddr)
-		return -EINVAL;
+	if (rtl8723bs) {
+		txsize = round_up(orig_len, 4);
+		write_size = txsize > RTW_SDIO_BLOCK_SIZE ?
+			     round_up(txsize, RTW_SDIO_BLOCK_SIZE) : txsize;
+	} else {
+		txsize = sdio_align_size(rtwsdio->sdio_func, orig_len);
+		write_size = txsize;
+	}
+
+	if (write_size > orig_len) {
+		unsigned int padding = write_size - orig_len;
 
-	txsize = sdio_align_size(rtwsdio->sdio_func, skb->len);
+		if (skb_tailroom(skb) < padding) {
+			ret = pskb_expand_head(skb, 0,
+					       padding - skb_tailroom(skb),
+					       GFP_KERNEL);
+			if (ret)
+				return ret;
+		}
+		skb_put_zero(skb, padding);
+	}
+
+	txaddr = rtw_sdio_get_tx_addr(rtwdev, txsize, queue);
+	if (!txaddr) {
+		ret = -EINVAL;
+		goto out_trim;
+	}
 
 	ret = rtw_sdio_check_free_txpg(rtwdev, queue, txsize);
 	if (ret)
-		return ret;
+		goto out_trim;
+	ret = rtw_sdio_wait_tx_oqt(rtwdev);
+	if (ret)
+		goto out_trim;
 
 	if (!IS_ALIGNED((unsigned long)skb->data, RTW_SDIO_DATA_PTR_ALIGN))
 		rtw_warn(rtwdev, "Got unaligned SKB in %s() for queue %u\n",
 			 __func__, queue);
 
 	bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
-
 	if (bus_claim)
 		sdio_claim_host(rtwsdio->sdio_func);
-
-	ret = sdio_memcpy_toio(rtwsdio->sdio_func, txaddr, skb->data, txsize);
-
+	ret = sdio_memcpy_toio(rtwsdio->sdio_func, txaddr, skb->data,
+			       write_size);
 	if (bus_claim)
 		sdio_release_host(rtwsdio->sdio_func);
 
+	if (!ret && quiet)
+		usleep_range(1000, 2000);
+	if (!ret && rtl8723bs) {
+		pages = DIV_ROUND_UP(txsize, rtwdev->chip->page_size);
+		rtw_sdio_8723bs_consume_txpg(rtwdev, queue, pages);
+	}
 	if (ret)
 		rtw_warn(rtwdev,
 			 "Failed to write %zu byte(s) to SDIO port 0x%08x",
-			 txsize, txaddr);
+			 write_size, txaddr);
 
+out_trim:
+	if (write_size > orig_len)
+		skb_trim(skb, orig_len);
 	return ret;
 }
 
@@ -677,7 +875,11 @@ static void rtw_sdio_init(struct rtw_dev *rtwdev)
 {
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
 
-	rtwsdio->irq_mask = REG_SDIO_HIMR_RX_REQUEST | REG_SDIO_HIMR_CPWM1;
+	if (rtw_is_8723bs(rtwdev))
+		rtwsdio->irq_mask = REG_SDIO_HIMR_RX_REQUEST;
+	else
+		rtwsdio->irq_mask = REG_SDIO_HIMR_RX_REQUEST |
+				       REG_SDIO_HIMR_CPWM1;
 }
 
 static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)
@@ -685,6 +887,7 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)
 	u8 size, timeout;
 
 	switch (rtwdev->chip->id) {
+	case RTW_CHIP_TYPE_8723B:
 	case RTW_CHIP_TYPE_8703B:
 	case RTW_CHIP_TYPE_8821A:
 	case RTW_CHIP_TYPE_8812A:
@@ -712,6 +915,8 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)
 		    FIELD_PREP(BIT_DMA_AGG_TO_V1, timeout));
 
 	rtw_write8_set(rtwdev, REG_RXDMA_MODE, BIT_DMA_MODE);
+	if (rtw_is_8723bs(rtwdev))
+		rtw_write8_set(rtwdev, REG_RXDMA_MODE, 3 << 2);
 }
 
 static void rtw_sdio_enable_interrupt(struct rtw_dev *rtwdev)
@@ -749,9 +954,50 @@ static int rtw_sdio_setup(struct rtw_dev *rtwdev)
 	return 0;
 }
 
+static void rtw_sdio_8723bs_check_rqpn(struct rtw_dev *rtwdev)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_fifo_conf *fifo = &rtwdev->fifo;
+	const struct rtw_page_table *pg_tbl;
+	u32 free_txpg;
+	u16 pubq_num;
+
+	if (!rtw_is_8723bs(rtwdev))
+		return;
+
+	free_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
+	if (free_txpg || !fifo->acq_pg_num)
+		return;
+
+	pg_tbl = &chip->page_table[0];
+	if (fifo->acq_pg_num <= pg_tbl->hq_num + pg_tbl->lq_num +
+				    pg_tbl->nq_num + pg_tbl->exq_num +
+				    pg_tbl->gapq_num)
+		return;
+
+	pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
+		   pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
+	rtw_write32(rtwdev, REG_RQPN_NPQ,
+		    BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num));
+	rtw_write32(rtwdev, REG_RQPN,
+		    BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num));
+}
+
 static int rtw_sdio_start(struct rtw_dev *rtwdev)
 {
+	u32 clear;
+
+	rtw_sdio_8723bs_check_rqpn(rtwdev);
+	rtw_sdio_init_free_txpg(rtwdev);
 	rtw_sdio_enable_rx_aggregation(rtwdev);
+
+	if (rtw_is_8723bs(rtwdev)) {
+		clear = rtw_read32(rtwdev, REG_SDIO_HISR) &
+			RTW_SDIO_HISR_CLEAR_MASK;
+		if (clear)
+			rtw_write32(rtwdev, REG_SDIO_HISR, clear);
+	}
+
 	rtw_sdio_enable_interrupt(rtwdev);
 
 	return 0;
@@ -815,7 +1061,7 @@ static void rtw_sdio_tx_kick_off(struct rtw_dev *rtwdev)
 {
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
 
-	queue_work(rtwsdio->txwq, &rtwsdio->tx_handler_data->work);
+	mod_delayed_work(rtwsdio->txwq, &rtwsdio->tx_handler_data->work, 0);
 }
 
 static void rtw_sdio_link_ps(struct rtw_dev *rtwdev, bool enter)
@@ -831,55 +1077,87 @@ static void rtw_sdio_interface_cfg(struct rtw_dev *rtwdev)
 
 	val = rtw_read32(rtwdev, REG_SDIO_TX_CTRL);
 	val &= 0xfff8;
+	if (rtw_is_8723bs(rtwdev))
+		val |= BIT_SDIO_TX_CTRL_ALWAYS_RECOGNIZE;
 	rtw_write32(rtwdev, REG_SDIO_TX_CTRL, val);
 }
 
-static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb)
+static int rtw_sdio_align_tx_skb(struct sk_buff *skb, unsigned int headroom)
 {
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	unsigned int misalign, needed;
+	int ret;
 
-	BUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) >
-		     sizeof(info->status.status_driver_data));
+	misalign = (unsigned long)skb->data & (RTW_SDIO_DATA_PTR_ALIGN - 1);
+	if (!misalign)
+		return 0;
 
-	return (struct rtw_sdio_tx_data *)info->status.status_driver_data;
+	needed = headroom + RTW_SDIO_DATA_PTR_ALIGN - 1;
+	if (skb_headroom(skb) < needed) {
+		ret = pskb_expand_head(skb, needed - skb_headroom(skb), 0,
+				       GFP_KERNEL);
+		if (ret)
+			return ret;
+
+		misalign = (unsigned long)skb->data &
+			   (RTW_SDIO_DATA_PTR_ALIGN - 1);
+		if (!misalign)
+			return 0;
+	}
+
+	needed = headroom + misalign;
+	if (skb_headroom(skb) < needed)
+		return -ENOSPC;
+
+	skb_push(skb, misalign);
+	memmove(skb->data, skb->data + misalign, skb->len - misalign);
+	skb_trim(skb, skb->len - misalign);
+
+	return 0;
 }
 
-static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
-				    struct rtw_tx_pkt_info *pkt_info,
-				    struct sk_buff *skb,
-				    enum rtw_tx_queue_type queue)
+static int rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
+				   struct rtw_tx_pkt_info *pkt_info,
+				   struct sk_buff *skb,
+				   enum rtw_tx_queue_type queue)
 {
 	const struct rtw_chip_info *chip = rtwdev->chip;
 	unsigned long data_addr, aligned_addr;
+	bool fixed_8723bs_offset;
 	size_t offset;
 	u8 *pkt_desc;
+	int ret;
+
+	fixed_8723bs_offset = rtw_is_8723bs(rtwdev) &&
+			      (queue == RTW_TX_QUEUE_MGMT ||
+			       queue == RTW_TX_QUEUE_BCN);
+
+	if (fixed_8723bs_offset) {
+		ret = rtw_sdio_align_tx_skb(skb, chip->tx_pkt_desc_sz);
+		if (ret)
+			return ret;
+	}
 
 	pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
 
 	data_addr = (unsigned long)pkt_desc;
 	aligned_addr = ALIGN(data_addr, RTW_SDIO_DATA_PTR_ALIGN);
 
-	if (data_addr != aligned_addr) {
+	if (!fixed_8723bs_offset && data_addr != aligned_addr) {
 		/* Ensure that the start of the pkt_desc is always aligned at
 		 * RTW_SDIO_DATA_PTR_ALIGN.
 		 */
 		offset = RTW_SDIO_DATA_PTR_ALIGN - (aligned_addr - data_addr);
-
 		pkt_desc = skb_push(skb, offset);
-
-		/* By inserting padding to align the start of the pkt_desc we
-		 * need to inform the firmware that the actual data starts at
-		 * a different offset than normal.
-		 */
 		pkt_info->offset += offset;
+		memset(pkt_desc + chip->tx_pkt_desc_sz, 0, offset);
 	}
 
 	memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
-
 	pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
-
 	rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
 	rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
+
+	return 0;
 }
 
 static int rtw_sdio_write_data(struct rtw_dev *rtwdev,
@@ -889,9 +1167,10 @@ static int rtw_sdio_write_data(struct rtw_dev *rtwdev,
 {
 	int ret;
 
-	rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);
-
-	ret = rtw_sdio_write_port(rtwdev, skb, queue);
+	memset(rtw_sdio_get_tx_data(skb), 0, sizeof(struct rtw_sdio_tx_data));
+	ret = rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);
+	if (!ret)
+		ret = rtw_sdio_write_port(rtwdev, skb, queue);
 	dev_kfree_skb_any(skb);
 
 	return ret;
@@ -929,14 +1208,37 @@ static int rtw_sdio_tx_write(struct rtw_dev *rtwdev,
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
 	enum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb);
 	struct rtw_sdio_tx_data *tx_data;
-
-	rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);
+	int ret;
 
 	tx_data = rtw_sdio_get_tx_data(skb);
+	memset(tx_data, 0, sizeof(*tx_data));
+	if (skb->len >= sizeof(struct ieee80211_hdr_3addr)) {
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+
+		tx_data->is_mgmt = ieee80211_is_mgmt(hdr->frame_control);
+	}
+
+	ret = rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue);
+	if (ret)
+		return ret;
+
 	tx_data->sn = pkt_info->sn;
+	tx_data->tx_pkt_offset = pkt_info->offset;
 
 	skb_queue_tail(&rtwsdio->tx_queue[queue], skb);
 
+	/* Back-pressure on the data ACs (BK/BE/VI/VO): once the FIFO fills past
+	 * the high watermark, stop the corresponding mac80211 queue so it stops
+	 * handing us frames, bounding the queueing latency. Resumed from the TX
+	 * drain path once the FIFO drains below the low watermark.
+	 */
+	if (rtw_is_8723bs(rtwdev) && queue < RTW_TX_QUEUE_BCN &&
+	    !rtwsdio->queue_stopped[queue] &&
+	    skb_queue_len(&rtwsdio->tx_queue[queue]) >= RTW_SDIO_TX_FIFO_HIWATER) {
+		rtwsdio->queue_stopped[queue] = true;
+		ieee80211_stop_queue(rtwdev->hw, skb_get_queue_mapping(skb));
+	}
+
 	return 0;
 }
 
@@ -965,6 +1267,11 @@ static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,
 	rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat);
 	rtw_rx_stats(rtwdev, pkt_stat->vif, skb);
 
+	if (skb->len >= sizeof(struct ieee80211_hdr_3addr))
+		rtw8723bs_auth_sync_rx(rtwdev,
+				       (struct ieee80211_hdr *)skb->data,
+				       skb->len, pkt_stat, rx_status);
+
 	ieee80211_rx_irqsafe(rtwdev->hw, skb);
 }
 
@@ -1079,6 +1386,7 @@ static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func)
 	struct ieee80211_hw *hw = sdio_get_drvdata(sdio_func);
 	struct rtw_sdio *rtwsdio;
 	struct rtw_dev *rtwdev;
+	u32 clear;
 	u32 hisr;
 
 	rtwdev = hw->priv;
@@ -1095,7 +1403,12 @@ static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func)
 		rtw_sdio_rx_isr(rtwdev);
 	}
 
-	rtw_write32(rtwdev, REG_SDIO_HISR, hisr);
+	if (rtw_is_8723bs(rtwdev))
+		clear = hisr & rtwsdio->irq_mask & RTW_SDIO_HISR_CLEAR_MASK;
+	else
+		clear = hisr & RTW_SDIO_HISR_CLEAR_MASK;
+	if (clear)
+		rtw_write32(rtwdev, REG_SDIO_HISR, clear);
 
 	rtwsdio->irq_thread = NULL;
 }
@@ -1212,11 +1525,20 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
 	struct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb);
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hw *hw = rtwdev->hw;
-
-	skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz);
-
-	/* enqueue to wait for tx report */
-	if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
+	u8 tx_pkt_offset = tx_data->tx_pkt_offset;
+
+	if (!tx_pkt_offset)
+		tx_pkt_offset = rtwdev->chip->tx_pkt_desc_sz;
+	skb_pull(skb, tx_pkt_offset);
+
+	/* The RTL8723BS vendor descriptor uses SW_DEFINE/sn=0 for management
+	 * frames, so there is no unique key for matching asynchronous C2H TX
+	 * reports. Report completion at SDIO DMA completion, as the vendor
+	 * dump_mgntframe_and_wait() path does; data frames keep the normal C2H
+	 * report queue.
+	 */
+	if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS &&
+	    !(rtw_is_8723bs(rtwdev) && tx_data->is_mgmt)) {
 		rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
 		return;
 	}
@@ -1231,32 +1553,48 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
 	ieee80211_tx_status_irqsafe(hw, skb);
 }
 
-static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,
-				      enum rtw_tx_queue_type queue)
+static int rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,
+				     enum rtw_tx_queue_type queue,
+				     bool *processed)
 {
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
 	struct sk_buff *skb;
+	u16 q_map;
 	int ret;
 
+	*processed = false;
 	skb = skb_dequeue(&rtwsdio->tx_queue[queue]);
 	if (!skb)
-		return;
+		return 0;
 
+	*processed = true;
+	q_map = skb_get_queue_mapping(skb);
 	ret = rtw_sdio_write_port(rtwdev, skb, queue);
 	if (ret) {
 		skb_queue_head(&rtwsdio->tx_queue[queue], skb);
-		return;
+		return ret;
 	}
 
 	rtw_sdio_indicate_tx_status(rtwdev, skb);
+
+	if (rtw_is_8723bs(rtwdev) && queue < RTW_TX_QUEUE_BCN &&
+	    rtwsdio->queue_stopped[queue] &&
+	    skb_queue_len(&rtwsdio->tx_queue[queue]) <= RTW_SDIO_TX_FIFO_LOWATER) {
+		rtwsdio->queue_stopped[queue] = false;
+		ieee80211_wake_queue(rtwdev->hw, q_map);
+	}
+
+	return 0;
 }
 
 static void rtw_sdio_tx_handler(struct work_struct *work)
 {
 	struct rtw_sdio_work_data *work_data =
-		container_of(work, struct rtw_sdio_work_data, work);
+		container_of(to_delayed_work(work), struct rtw_sdio_work_data,
+			     work);
 	struct rtw_sdio *rtwsdio;
 	struct rtw_dev *rtwdev;
+	bool processed;
 	int limit, queue;
 
 	rtwdev = work_data->rtwdev;
@@ -1267,7 +1605,24 @@ static void rtw_sdio_tx_handler(struct work_struct *work)
 
 	for (queue = RTK_MAX_TX_QUEUE_NUM - 1; queue >= 0; queue--) {
 		for (limit = 0; limit < 1000; limit++) {
-			rtw_sdio_process_tx_queue(rtwdev, queue);
+			int ret;
+
+			ret = rtw_sdio_process_tx_queue(rtwdev, queue, &processed);
+			if (ret) {
+				if (rtw_is_8723bs(rtwdev) && ret == -EBUSY) {
+					mod_delayed_work(rtwsdio->txwq,
+							 &work_data->work,
+							 RTW_SDIO_TX_RETRY_DELAY);
+					return;
+				}
+				break;
+			}
+
+			if (rtw_is_8723bs(rtwdev) &&
+			    queue == RTW_TX_QUEUE_MGMT && processed) {
+				mod_delayed_work(rtwsdio->txwq, &work_data->work, 0);
+				return;
+			}
 
 			if (skb_queue_empty(&rtwsdio->tx_queue[queue]))
 				break;
@@ -1294,14 +1649,16 @@ static int rtw_sdio_init_tx(struct rtw_dev *rtwdev)
 		return -ENOMEM;
 	}
 
-	for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
+	for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) {
 		skb_queue_head_init(&rtwsdio->tx_queue[i]);
+		rtwsdio->queue_stopped[i] = false;
+	}
 	rtwsdio->tx_handler_data = kmalloc_obj(*rtwsdio->tx_handler_data);
 	if (!rtwsdio->tx_handler_data)
 		goto err_destroy_wq;
 
 	rtwsdio->tx_handler_data->rtwdev = rtwdev;
-	INIT_WORK(&rtwsdio->tx_handler_data->work, rtw_sdio_tx_handler);
+	INIT_DELAYED_WORK(&rtwsdio->tx_handler_data->work, rtw_sdio_tx_handler);
 
 	return 0;
 
@@ -1315,6 +1672,7 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
 	int i;
 
+	cancel_delayed_work_sync(&rtwsdio->tx_handler_data->work);
 	destroy_workqueue(rtwsdio->txwq);
 	kfree(rtwsdio->tx_handler_data);
 
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.h b/drivers/net/wireless/realtek/rtw88/sdio.h
index 457e8b02380e5b..3dd0f44676bffa 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.h
+++ b/drivers/net/wireless/realtek/rtw88/sdio.h
@@ -22,6 +22,7 @@
 
 /* SDIO Tx Control */
 #define REG_SDIO_TX_CTRL			(SDIO_LOCAL_OFFSET + 0x0000)
+#define BIT_SDIO_TX_CTRL_ALWAYS_RECOGNIZE	BIT(4)
 
 /*SDIO status timeout*/
 #define REG_SDIO_TIMEOUT			(SDIO_LOCAL_OFFSET + 0x0002)
@@ -77,6 +78,14 @@
 /* the following two are RTL8188 SDIO Specific */
 #define REG_SDIO_HISR_MCU_ERR			BIT(28)
 #define REG_SDIO_HISR_TSF_BIT32_TOGGLE		BIT(29)
+#define RTW_SDIO_HISR_CLEAR_MASK		\
+	(REG_SDIO_HISR_TXERR | REG_SDIO_HISR_RXERR | \
+	 REG_SDIO_HISR_TXFOVW | REG_SDIO_HISR_RXFOVW | \
+	 REG_SDIO_HISR_TXBCNOK | REG_SDIO_HISR_TXBCNERR | \
+	 REG_SDIO_HISR_C2HCMD | REG_SDIO_HISR_CPWM1 | \
+	 REG_SDIO_HISR_CPWM2 | REG_SDIO_HISR_HSISR_IND | \
+	 REG_SDIO_HISR_GTINT3_IND | REG_SDIO_HISR_GTINT4_IND | \
+	 REG_SDIO_HISR_PSTIMEOUT | REG_SDIO_HISR_OCPINT)
 
 /* HCI Current Power Mode */
 #define REG_SDIO_HCPWM				(SDIO_LOCAL_OFFSET + 0x0019)
@@ -140,10 +149,12 @@ struct sdio_device_id;
 
 struct rtw_sdio_tx_data {
 	u8 sn;
+	u8 tx_pkt_offset;
+	bool is_mgmt;
 };
 
 struct rtw_sdio_work_data {
-	struct work_struct work;
+	struct delayed_work work;
 	struct rtw_dev *rtwdev;
 };
 
@@ -159,6 +170,13 @@ struct rtw_sdio {
 	struct workqueue_struct *txwq;
 	struct rtw_sdio_work_data *tx_handler_data;
 	struct sk_buff_head tx_queue[RTK_MAX_TX_QUEUE_NUM];
+	bool queue_stopped[RTK_MAX_TX_QUEUE_NUM];
+
+	atomic_t free_pg_high;
+	atomic_t free_pg_normal;
+	atomic_t free_pg_low;
+	atomic_t free_pg_pub;
+	atomic_t tx_oqt_free;
 };
 
 extern const struct dev_pm_ops rtw_sdio_pm_ops;
diff --git a/drivers/net/wireless/realtek/rtw88/sec.h b/drivers/net/wireless/realtek/rtw88/sec.h
index efcf45433999af..73f2af66effe85 100644
--- a/drivers/net/wireless/realtek/rtw88/sec.h
+++ b/drivers/net/wireless/realtek/rtw88/sec.h
@@ -22,6 +22,7 @@
 #define RTW_SEC_RX_DEC_EN		BIT(3)
 #define RTW_SEC_TX_BC_USE_DK		BIT(6)
 #define RTW_SEC_RX_BC_USE_DK		BIT(7)
+#define RTW_SEC_CHK_KEYID		BIT(8)
 
 #define RTW_SEC_ENGINE_EN		BIT(9)
 
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 9d747a060b984c..797c1e0402f228 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -208,8 +208,9 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
 	__skb_queue_tail(&tx_report->queue, skb);
 	spin_unlock_irqrestore(&tx_report->q_lock, flags);
 
-	if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D &&
-	    rtwdev->hci.type == RTW_HCI_TYPE_USB)
+	if ((rtwdev->chip->id == RTW_CHIP_TYPE_8723D &&
+	     rtwdev->hci.type == RTW_HCI_TYPE_USB) ||
+	    rtw_is_8723bs(rtwdev))
 		timeout = msecs_to_jiffies(2500);
 
 	mod_timer(&tx_report->purge_timer, jiffies + timeout);

3/2 2026/07/26 07:18 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39859
							output: 24
							thoughts: 639
						

Thoughts:
**WorthFuzzing Assessment for rtw88 Patch**

Okay, so I've got this patch for the `rtw88` driver. It's adding support for the RTL8723BS, specifically SDIO WiFi/BT coexistence, some scan workarounds, authentication sync, and TX FIFO back-pressure stuff. It touches a bunch of files: `coex.c`, `fw.c`, `mac80211.c`, `main.c`, `rx.c`, `sdio.c`, and `tx.c`. This is a functional change to the kernel, and it's specifically about the `rtw88` driver. My initial thought is, can we actually *reach* this in a virtualized environment? That's the crucial question.

The `rtw88` driver handles SDIO, PCIe, and USB. This patch is *specifically* for the RTL8723BS, which is an SDIO device. Hmm, can we emulate or fuzz SDIO devices in something like QEMU? I know standard QEMU usually struggles with this unless there's dedicated SDIO host controller and device emulation. Syzkaller has some support for fuzzing WiFi via `mac80211_hwsim` or USB, but SDIO is a different beast.

Wait, let me go back to the prompt, I need to make sure I don't miss something:

"Return WorthFuzzing=false if the patch only contains:
...
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU."

Is the RTL8723BS a vendor-specific PCIe switch, SmartNIC, or GPU? Nope, it's a WiFi card, so that's not the issue. Can we fuzz WiFi drivers? Yes, but *mac80211_hwsim* is a software simulator. For *actual* hardware drivers, syzkaller can fuzz USB devices with the USB gadget (dummy_hcd). But SDIO? I don't think there's a generic SDIO fuzzer in Syzkaller *yet*.

Okay, so the prompt also says: "Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim)." Since this is an SDIO driver (`rtw88_8723bs`), it *requires* an SDIO bus. Does QEMU/syzkaller have an SDIO emulator? No, there isn't an SDIO dummy host in the upstream kernel like `dummy_hcd` for USB.

I need to see if `rtw88` can be fuzzed, it seems like a new territory. Let's start by searching the kernel.



4/2 2026/07/26 07:19 tool grepper
0m Args:
{
  "Expression": "rtw_is_8723bs"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/coex.c=1461=static bool rtw_coex_8723bs_bt_disabled(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/coex.c-1462-{\ndrivers/net/wireless/realtek/rtw88/coex.c:1463:\treturn rtw_is_8723bs(rtwdev) \u0026\u0026 rtwdev-\u003ecoex.stat.bt_disabled;\ndrivers/net/wireless/realtek/rtw88/coex.c-1464-}\n--\ndrivers/net/wireless/realtek/rtw88/coex.c=1586=void rtw_coex_8723bs_scan_workaround(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/coex.c-1590-\ndrivers/net/wireless/realtek/rtw88/coex.c:1591:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/coex.c-1592-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=301=void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-325-\t\t */\ndrivers/net/wireless/realtek/rtw88/fw.c:326:\t\tif (rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/fw.c-327-\t\t\trtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=359=void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-379-\t\t */\ndrivers/net/wireless/realtek/rtw88/fw.c:380:\t\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/fw.c-381-\t\t\t*((u32 *)skb-\u003ecb) = pkt_offset;\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=739=void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-746-\ndrivers/net/wireless/realtek/rtw88/fw.c:747:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/fw.c-748-\t\t/* Vendor v5.2.17 RA_INFO byte layout (H2C 0x42):\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=764=void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-772-\ndrivers/net/wireless/realtek/rtw88/fw.c:773:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/fw.c-774-\t\t/* The v41 firmware parses the vendor v5.2.17 MACID_CFG (0x40)\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=837=void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect)\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-842-\ndrivers/net/wireless/realtek/rtw88/fw.c:843:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/fw.c-844-\t\t/* Vendor v5.2.17 MEDIA_STATUS_RPT: connect = 21 00 00,\n--\ndrivers/net/wireless/realtek/rtw88/fw.c=1601=int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,\n--\ndrivers/net/wireless/realtek/rtw88/fw.c-1603-{\ndrivers/net/wireless/realtek/rtw88/fw.c:1604:\tconst bool is_8723bs_sdio = rtw_is_8723bs(rtwdev);\ndrivers/net/wireless/realtek/rtw88/fw.c-1605-\tu8 bckp[4];\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=22=void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-30-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:31:\tif (!rtw_is_8723bs(rtwdev) ||\ndrivers/net/wireless/realtek/rtw88/mac80211.c-32-\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags) ||\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=179=static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-188-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:189:\tif (!rtw_is_8723bs(rtwdev) || vif-\u003etype != NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-190-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=230=static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-239-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:240:\tif (!rtw_is_8723bs(rtwdev) || vif-\u003etype != NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-241-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=332=static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-334-{\ndrivers/net/wireless/realtek/rtw88/mac80211.c:335:\treturn rtw_is_8723bs(rtwdev) \u0026\u0026 info \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-336-\t       info-\u003esubtype == IEEE80211_STYPE_AUTH;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=829=static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-846-\t\tif (vif-\u003ecfg.assoc) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:847:\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-848-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-889-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:890:\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-891-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-907-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:908:\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-909-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 bssid_changed) {\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-914-\t\tconfig |= PORT_SET_BSSID;\ndrivers/net/wireless/realtek/rtw88/mac80211.c:915:\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-916-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 bssid_cleared) {\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-955-\tif (changed \u0026 BSS_CHANGED_ERP_PREAMBLE \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c:956:\t    rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-957-\t    vif-\u003etype == NL80211_IFTYPE_STATION)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-960-\tif (changed \u0026 BSS_CHANGED_ERP_SLOT) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:961:\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-962-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1064=static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1124-\t\t\t\t  hw_key_type, hw_key_idx);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1125:\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 vif \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1126-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1133-\t\trtw_sec_clear_cam(rtwdev, sec, key-\u003ehw_key_idx);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1134:\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 vif \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1135-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1219=static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1227-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1228:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1229-\t\t/* Wake from soft IPS and run the vendor join sequence. The RFK\n--\ndrivers/net/wireless/realtek/rtw88/main.c=69=static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-70-{\ndrivers/net/wireless/realtek/rtw88/main.c:71:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/main.c-72-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=81=static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-86-\ndrivers/net/wireless/realtek/rtw88/main.c:87:\tif (!rtw_is_8723bs(rtwdev) || hal-\u003ecurrent_band_type != RTW_BAND_2G)\ndrivers/net/wireless/realtek/rtw88/main.c-88-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=103=static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-109-\ndrivers/net/wireless/realtek/rtw88/main.c:110:\tif (!rtw_is_8723bs(rtwdev) || !chip-\u003eops-\u003ephy_calibration)\ndrivers/net/wireless/realtek/rtw88/main.c-111-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=129=static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-132-{\ndrivers/net/wireless/realtek/rtw88/main.c:133:\treturn rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-134-\t       vif-\u003etype == NL80211_IFTYPE_STATION \u0026\u0026 !sta-\u003etdls;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=326=static void rtw_watch_dog_work(struct work_struct *work)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-411-\t */\ndrivers/net/wireless/realtek/rtw88/main.c:412:\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-413-\t    (stats-\u003etx_throughput || stats-\u003erx_throughput))\n--\ndrivers/net/wireless/realtek/rtw88/main.c=1503=int rtw_power_on(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1567-\t */\ndrivers/net/wireless/realtek/rtw88/main.c:1568:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/main.c-1569-\t\tbool ips_wake = rtwdev-\u003einitial_rfk_done;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=2118=static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-2132-\t\t */\ndrivers/net/wireless/realtek/rtw88/main.c:2133:\t\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/main.c-2134-\t\t\tefuse-\u003ehw_cap.nss = rtwdev-\u003ehal.rf_path_num ? : 1;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=2428=int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-2449-\t */\ndrivers/net/wireless/realtek/rtw88/main.c:2450:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/main.c-2451-\t\tieee80211_hw_set(hw, RX_INCLUDES_FCS);\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2216=static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.h-2220-\ndrivers/net/wireless/realtek/rtw88/main.h:2221:static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=480=static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-492-\tcase RTW_TX_QUEUE_VO:\ndrivers/net/wireless/realtek/rtw88/sdio.c:493:\t\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/sdio.c-494-\t\t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-509-\t\ttxaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK,\ndrivers/net/wireless/realtek/rtw88/sdio.c:510:\t\t\t\t    rtw_is_8723bs(rtwdev) ?\ndrivers/net/wireless/realtek/rtw88/sdio.c-511-\t\t\t\t    REG_SDIO_CMD_ADDR_TXFF_HIGH :\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=569=static void rtw_sdio_init_free_txpg(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-575-\ndrivers/net/wireless/realtek/rtw88/sdio.c:576:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-577-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=634=static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-638-\ndrivers/net/wireless/realtek/rtw88/sdio.c:639:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/sdio.c-640-\t\tstruct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev-\u003epriv;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=732=static int rtw_sdio_wait_tx_oqt(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-737-\ndrivers/net/wireless/realtek/rtw88/sdio.c:738:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-739-\t\treturn 0;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=795=static int rtw_sdio_write_port(struct rtw_dev *rtwdev, struct sk_buff *skb,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-800-\tunsigned int orig_len = skb-\u003elen;\ndrivers/net/wireless/realtek/rtw88/sdio.c:801:\tbool rtl8723bs = rtw_is_8723bs(rtwdev);\ndrivers/net/wireless/realtek/rtw88/sdio.c-802-\tbool quiet = rtl8723bs \u0026\u0026 tx_data-\u003eis_mgmt;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=874=static void rtw_sdio_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-877-\ndrivers/net/wireless/realtek/rtw88/sdio.c:878:\tif (rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-879-\t\trtwsdio-\u003eirq_mask = REG_SDIO_HIMR_RX_REQUEST;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=885=static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-917-\trtw_write8_set(rtwdev, REG_RXDMA_MODE, BIT_DMA_MODE);\ndrivers/net/wireless/realtek/rtw88/sdio.c:918:\tif (rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-919-\t\trtw_write8_set(rtwdev, REG_RXDMA_MODE, 3 \u003c\u003c 2);\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=957=static void rtw_sdio_8723bs_check_rqpn(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-964-\ndrivers/net/wireless/realtek/rtw88/sdio.c:965:\tif (!rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-966-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=986=static int rtw_sdio_start(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-993-\ndrivers/net/wireless/realtek/rtw88/sdio.c:994:\tif (rtw_is_8723bs(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/sdio.c-995-\t\tclear = rtw_read32(rtwdev, REG_SDIO_HISR) \u0026\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1072=static void rtw_sdio_interface_cfg(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1079-\tval \u0026= 0xfff8;\ndrivers/net/wireless/realtek/rtw88/sdio.c:1080:\tif (rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-1081-\t\tval |= BIT_SDIO_TX_CTRL_ALWAYS_RECOGNIZE;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1118=static int rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1129-\ndrivers/net/wireless/realtek/rtw88/sdio.c:1130:\tfixed_8723bs_offset = rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/sdio.c-1131-\t\t\t      (queue == RTW_TX_QUEUE_MGMT ||\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1204=static int rtw_sdio_tx_write(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1234-\t */\ndrivers/net/wireless/realtek/rtw88/sdio.c:1235:\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 queue \u003c RTW_TX_QUEUE_BCN \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/sdio.c-1236-\t    !rtwsdio-\u003equeue_stopped[queue] \u0026\u0026\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1384=static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1405-\ndrivers/net/wireless/realtek/rtw88/sdio.c:1406:\tif (rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/sdio.c-1407-\t\tclear = hisr \u0026 rtwsdio-\u003eirq_mask \u0026 RTW_SDIO_HISR_CLEAR_MASK;\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1522=static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1540-\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_REQ_TX_STATUS \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/sdio.c:1541:\t    !(rtw_is_8723bs(rtwdev) \u0026\u0026 tx_data-\u003eis_mgmt)) {\ndrivers/net/wireless/realtek/rtw88/sdio.c-1542-\t\trtw_tx_report_enqueue(rtwdev, skb, tx_data-\u003esn);\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1556=static int rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1579-\ndrivers/net/wireless/realtek/rtw88/sdio.c:1580:\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 queue \u003c RTW_TX_QUEUE_BCN \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/sdio.c-1581-\t    rtwsdio-\u003equeue_stopped[queue] \u0026\u0026\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1590=static void rtw_sdio_tx_handler(struct work_struct *work)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1611-\t\t\tif (ret) {\ndrivers/net/wireless/realtek/rtw88/sdio.c:1612:\t\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026 ret == -EBUSY) {\ndrivers/net/wireless/realtek/rtw88/sdio.c-1613-\t\t\t\t\tmod_delayed_work(rtwsdio-\u003etxwq,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1620-\ndrivers/net/wireless/realtek/rtw88/sdio.c:1621:\t\t\tif (rtw_is_8723bs(rtwdev) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/sdio.c-1622-\t\t\t    queue == RTW_TX_QUEUE_MGMT \u0026\u0026 processed) {\n--\ndrivers/net/wireless/realtek/rtw88/tx.c=196=void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)\n--\ndrivers/net/wireless/realtek/rtw88/tx.c-212-\t     rtwdev-\u003ehci.type == RTW_HCI_TYPE_USB) ||\ndrivers/net/wireless/realtek/rtw88/tx.c:213:\t    rtw_is_8723bs(rtwdev))\ndrivers/net/wireless/realtek/rtw88/tx.c-214-\t\ttimeout = msecs_to_jiffies(2500);\n"
}

5/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49248
							output: 18
							thoughts: 761
						

Thoughts:
**Unreachable Code Paths in RTL8723BS SDIO Driver**

Okay, so this patch is specifically targeting the RTL8723BS SDIO WiFi/BT coexistence and related SDIO handling, right? My initial thought is, can we even reach this code in a virtualized environment like QEMU? And the answer, as I dig deeper, is a resounding no.

QEMU has some SDHCI emulation, but it's not specific enough to emulate the RTL8723BS SDIO WiFi card. The prompt explicitly calls out code paths impossible to hit in environments without physical hardware or proper hardware emulation, referencing things like virtualized environments. This patch falls squarely into that category, as it's dealing with a very specific SDIO device.

I start thinking about fuzzing this code. Would Syzkaller be able to help here? It's a great tool, but does it even have SDIO fuzzing capabilities? I check, and nope, it focuses on USB (with dummy_hcd), PCI (though basic PCI fuzzing, not specific device emulation), and mac80211_hwsim.

I briefly consider the rtw88 driver and if mac80211_hwsim might be relevant, but quickly realize mac80211_hwsim is a software simulator for mac80211 and doesn't directly interact with `rtw88`. However, Syzkaller does have USB fuzzing, and I know `rtw88` has USB support. But, the patch is specifically for `rtw_is_8723bs(rtwdev)`, which relies on the SDIO version of the 8723B chip.

The code itself makes it clear:

```c
static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)
{
	return rtwdev->chip->id == RTW_CHIP_TYPE_8723B &&
	       rtwdev->hci.type == RTW_HCI_TYPE_SDIO;
}
```

So, given the lack of SDIO device emulation in either QEMU or Syzkaller for this specific card, this code path is simply unreachable.

Then I consider a user-space program interacting with the driver directly. Could that somehow trigger it? The crucial step here is the driver's probe function. To probe an SDIO driver, the SDIO bus must enumerate the device first. Without the actual hardware or a sufficiently detailed emulator, the driver's `probe` function won't be called. Consequently, `rtwdev` won't be allocated with `RTW_HCI_TYPE_SDIO` and `RTW_CHIP_TYPE_8723B`, and therefore, all the code under that `if` statement is unreachable in a virtualized environment.

Just to be absolutely sure, I try to think of other avenues, perhaps injecting SDIO devices somehow. But there's no `dummy_sdio` equivalent in the kernel. I check for any SDIO injection frameworks and come up empty. In conclusion, this code is, for all intents and purposes, unreachable without the specific hardware.



6/2 2026/07/26 07:19 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "dummy_sdio"
}

Results:
{
  "error": "no matches"
}

7/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 50733
							output: 20
							thoughts: 18
						

Thoughts:
Okay, here's my thought process summarized, geared towards an expert:

**Investigating Syzkaller's SDIO Fuzzing Capabilities**

Right, let's get down to it. My initial thought is to quickly ascertain if syzkaller has any dedicated fuzzing support for SDIO. I need to know if there's any pre-existing foundation I can build upon. This isn't necessarily a deep dive into the code base just yet; it's a triage step. I'm looking for a quick win, a readily available "yes" or "no" answer, or at least a starting point. So, I'll be looking for any indications of an SDIO fuzzer within the syzkaller ecosystem. This could be anything from a specific target, a dedicated configuration, or perhaps relevant syscall definitions or code instrumentation related to SDIO devices. Finding something here would significantly impact my next steps – it'd save me time if someone has done this.



8/2 2026/07/26 07:19 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "sdio_fuzzer"
}

Results:
{
  "error": "no matches"
}

9/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 50990
							output: 18
							thoughts: 80
						

Thoughts:
Okay, here's my summary, presented as a stream of thought:

**Probing SDIO Drivers from Userspace - A Feasibility Check**

Right, let's see about testing the SDIO drivers, specifically from userspace. The goal is to see if I can interact with them directly, maybe for some debugging or custom control. I know `drivers/mmc/core/sdio.c` is the key file, that's where the core SDIO functionality resides. But immediately, I'm hitting a roadblock. It looks like this code is inherently dependent on an MMC host controller being present.

So, the next question is can I somehow fake one, build a dummy MMC host controller in the system? That's the first option I'm considering. Even if I could create a dummy host, I'd still have the issue of mimicking the specific SDIO device ID for the RTL8723BS. My test needs to behave as though the real hardware is responding. That emulation aspect could be pretty involved. Hmmm, the next logical question to ask is, does a dummy MMC host even *exist* in the kernel? I need to research that, so that I can see the level of effort needed to get this done.



10/2 2026/07/26 07:19 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "dummy_mmc"
}

Results:
{
  "error": "no matches"
}

11/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 51364
							output: 25
							thoughts: 13
						

Thoughts:
Here's my take on the thought process:

**Diving into the MMC Host Drivers**

Okay, time to get started. My initial instinct is to dig into the MMC host drivers. Let's start by navigating to the `drivers/mmc/host/` directory. I'm assuming that's where I'll find the core code responsible for interfacing with MMC (MultiMediaCard) controllers. It’s the logical first place to look when debugging or extending MMC functionality. From there, I can begin to assess the current implementation and determine what needs tweaking.



12/2 2026/07/26 07:19 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/mmc/host/"
}

Results:
{
  "Files": [
    "alcor.c",
    "atmel-mci.c",
    "au1xmmc.c",
    "bcm2835.c",
    "cavium-octeon.c",
    "cavium-thunderx.c",
    "cavium.c",
    "cavium.h",
    "cb710-mmc.c",
    "cb710-mmc.h",
    "cqhci-core.c",
    "cqhci-crypto.c",
    "cqhci-crypto.h",
    "cqhci.h",
    "davinci_mmc.c",
    "dw_mmc-bluefield.c",
    "dw_mmc-exynos.c",
    "dw_mmc-exynos.h",
    "dw_mmc-hi3798cv200.c",
    "dw_mmc-hi3798mv200.c",
    "dw_mmc-k3.c",
    "dw_mmc-pci.c",
    "dw_mmc-pltfm.c",
    "dw_mmc-pltfm.h",
    "dw_mmc-rockchip.c",
    "dw_mmc-starfive.c",
    "dw_mmc.c",
    "dw_mmc.h",
    "jz4740_mmc.c",
    "litex_mmc.c",
    "loongson2-mmc.c",
    "meson-gx-mmc.c",
    "meson-mx-sdhc-clkc.c",
    "meson-mx-sdhc-mmc.c",
    "meson-mx-sdhc.h",
    "meson-mx-sdio.c",
    "mmc_hsq.c",
    "mmc_hsq.h",
    "mmc_spi.c",
    "mmci.c",
    "mmci.h",
    "mmci_qcom_dml.c",
    "mmci_stm32_sdmmc.c",
    "moxart-mmc.c",
    "mtk-sd.c",
    "mvsdio.c",
    "mvsdio.h",
    "mxcmmc.c",
    "mxs-mmc.c",
    "of_mmc_spi.c",
    "omap.c",
    "omap_hsmmc.c",
    "owl-mmc.c",
    "pxamci.c",
    "pxamci.h",
    "renesas_sdhi.h",
    "renesas_sdhi_core.c",
    "renesas_sdhi_internal_dmac.c",
    "renesas_sdhi_sys_dmac.c",
    "rtsx_pci_sdmmc.c",
    "rtsx_usb_sdmmc.c",
    "sdhci-acpi.c",
    "sdhci-bcm-kona.c",
    "sdhci-brcmstb.c",
    "sdhci-cadence.c",
    "sdhci-cqhci.h",
    "sdhci-dove.c",
    "sdhci-esdhc-imx.c",
    "sdhci-esdhc-mcf.c",
    "sdhci-esdhc.h",
    "sdhci-iproc.c",
    "sdhci-milbeaut.c",
    "sdhci-msm.c",
    "sdhci-npcm.c",
    "sdhci-of-arasan.c",
    "sdhci-of-aspeed-test.c",
    "sdhci-of-aspeed.c",
    "sdhci-of-at91.c",
    "sdhci-of-bst.c",
    "sdhci-of-dwcmshc.c",
    "sdhci-of-esdhc.c",
    "sdhci-of-hlwd.c",
    "sdhci-of-k1.c",
    "sdhci-of-ma35d1.c",
    "sdhci-of-sparx5.c",
    "sdhci-omap.c",
    "sdhci-pci-arasan.c",
    "sdhci-pci-core.c",
    "sdhci-pci-dwc-mshc.c",
    "sdhci-pci-gli.c",
    "sdhci-pci-o2micro.c",
    "sdhci-pci.h",
    "sdhci-pic32.c",
    "sdhci-pltfm.c",
    "sdhci-pltfm.h",
    "sdhci-pxav2.c",
    "sdhci-pxav3.c",
    "sdhci-s3c.c",
    "sdhci-spear.c",
    "sdhci-sprd.c",
    "sdhci-st.c",
    "sdhci-tegra.c",
    "sdhci-uhs2.c",
    "sdhci-uhs2.h",
    "sdhci-xenon-phy.c",
    "sdhci-xenon.c",
    "sdhci-xenon.h",
    "sdhci.c",
    "sdhci.h",
    "sdhci_am654.c",
    "sdhci_f_sdh30.c",
    "sdhci_f_sdh30.h",
    "sdricoh_cs.c",
    "sh_mmcif.c",
    "sunplus-mmc.c",
    "sunxi-mmc.c",
    "tifm_sd.c",
    "tmio_mmc.h",
    "tmio_mmc_core.c",
    "toshsd.c",
    "toshsd.h",
    "uniphier-sd.c",
    "usdhi6rol0.c",
    "ushc.c",
    "via-sdmmc.c",
    "vub300.c",
    "wbsd.c",
    "wbsd.h",
    "wmt-sdmmc.c"
  ],
  "Subdirs": null
}

13/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 52937
							output: 27
							thoughts: 323
						

Thoughts:
**Analyzing the Fuzzing Potential of RTL8723BS Driver via USB**

Okay, so I'm looking at this from a fuzzing perspective, specifically focusing on the RTL8723BS driver. I see `vub300.c`, a USB to SDIO bridge, and `ushc.c`, which is the USB SD Host Controller. The idea is that syzkaller could *potentially* emulate a USB SD Host Controller and then enumerate an SDIO device. That's a clever attack vector, in principle.

However, syzkaller *doesn't* currently do that; it doesn't emulate SDIO devices over USB SD Host Controllers. Doing so would be a significant undertaking because it would need to fully understand the SDIO protocol and know specific device IDs, like those for the RTL8723BS. It would be a pretty complex emulation job.

But, the prompt... ah, right. It specifically mentions, "Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware". So, if this isn't reachable in a virtualized environment, which sounds pretty likely given what I know, I need to return `WorthFuzzing=false`.

But wait, is it truly *impossible*? I can't be too hasty. I should double-check if there's *any* other path for `rtw_is_8723bs` to evaluate to true. Let's see... looking at the code, it requires two things: `rtwdev->chip->id == RTW_CHIP_TYPE_8723B` AND `rtwdev->hci.type == RTW_HCI_TYPE_SDIO`. That means the driver has to be probed via the SDIO bus. That, in turn, suggests a match based on the SDIO vendor and device IDs. Right, I should look at `drivers/net/wireless/realtek/rtw88/sdio.c` and check what the device IDs are there. That's the key. From there I can determine if this is really impossible to reach or not.



14/2 2026/07/26 07:19 tool grepper
0m Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.h=191=enum rtw_chip_type {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-196-\tRTW_CHIP_TYPE_8703B,\ndrivers/net/wireless/realtek/rtw88/main.h:197:\tRTW_CHIP_TYPE_8723B,\ndrivers/net/wireless/realtek/rtw88/main.h-198-\tRTW_CHIP_TYPE_8821A,\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2221=static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\ndrivers/net/wireless/realtek/rtw88/main.h:2223:\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.h-2224-\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n--\ndrivers/net/wireless/realtek/rtw88/rx.c=197=static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rx.c-259-\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\ndrivers/net/wireless/realtek/rtw88/rx.c:260:\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rx.c-261-\t    pkt_stat-\u003epkt_len == 0) {\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=885=static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-889-\tswitch (rtwdev-\u003echip-\u003eid) {\ndrivers/net/wireless/realtek/rtw88/sdio.c:890:\tcase RTW_CHIP_TYPE_8723B:\ndrivers/net/wireless/realtek/rtw88/sdio.c-891-\tcase RTW_CHIP_TYPE_8703B:\n"
}

15/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 54429
							output: 32
							thoughts: 39
						

Thoughts:
Okay, let's dive into this. Here's how I'd approach this task.

**Investigating RTW8723BS Driver Registration**

Right, so I need to understand how this `rtw8723bs.c` driver is being registered. Since I'm familiar with this architecture, my initial thought is to go straight to the source. Specifically, I should look within the `drivers/net/wireless/realtek/rtw88/` directory and check the `rtw8723bs.c` file itself, or a closely related file. I'm going to look for the fundamental driver registration mechanisms – things like `module_init()`, `platform_driver_register()`, `pci_driver_register()`, or similar calls depending on how the device is hooked into the system. Knowing the registration process is key to understanding how the driver interacts with the kernel and the hardware. That’s my jumping-off point.



16/2 2026/07/26 07:19 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Files": [
    "bf.c",
    "bf.h",
    "coex.c",
    "coex.h",
    "debug.c",
    "debug.h",
    "efuse.c",
    "efuse.h",
    "fw.c",
    "fw.h",
    "hci.h",
    "led.c",
    "led.h",
    "mac.c",
    "mac.h",
    "mac80211.c",
    "main.c",
    "main.h",
    "pci.c",
    "pci.h",
    "phy.c",
    "phy.h",
    "ps.c",
    "ps.h",
    "reg.h",
    "regd.c",
    "regd.h",
    "rtw8703b.c",
    "rtw8703b.h",
    "rtw8703b_tables.c",
    "rtw8703b_tables.h",
    "rtw8723cs.c",
    "rtw8723d.c",
    "rtw8723d.h",
    "rtw8723d_table.c",
    "rtw8723d_table.h",
    "rtw8723de.c",
    "rtw8723ds.c",
    "rtw8723du.c",
    "rtw8723x.c",
    "rtw8723x.h",
    "rtw8812a.c",
    "rtw8812a.h",
    "rtw8812a_table.c",
    "rtw8812a_table.h",
    "rtw8812au.c",
    "rtw8814a.c",
    "rtw8814a.h",
    "rtw8814a_table.c",
    "rtw8814a_table.h",
    "rtw8814ae.c",
    "rtw8814au.c",
    "rtw8821a.c",
    "rtw8821a.h",
    "rtw8821a_table.c",
    "rtw8821a_table.h",
    "rtw8821au.c",
    "rtw8821c.c",
    "rtw8821c.h",
    "rtw8821c_table.c",
    "rtw8821c_table.h",
    "rtw8821ce.c",
    "rtw8821cs.c",
    "rtw8821cu.c",
    "rtw8822b.c",
    "rtw8822b.h",
    "rtw8822b_table.c",
    "rtw8822b_table.h",
    "rtw8822be.c",
    "rtw8822bs.c",
    "rtw8822bu.c",
    "rtw8822c.c",
    "rtw8822c.h",
    "rtw8822c_table.c",
    "rtw8822c_table.h",
    "rtw8822ce.c",
    "rtw8822cs.c",
    "rtw8822cu.c",
    "rtw88xxa.c",
    "rtw88xxa.h",
    "rx.c",
    "rx.h",
    "sar.c",
    "sar.h",
    "sdio.c",
    "sdio.h",
    "sec.c",
    "sec.h",
    "tx.c",
    "tx.h",
    "usb.c",
    "usb.h",
    "util.c",
    "util.h",
    "wow.c",
    "wow.h"
  ],
  "Subdirs": null
}

17/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 55660
							output: 21
							thoughts: 45
						

Thoughts:
Okay, let's see... I'm looking at this list and hold on a second... I'm not seeing `rtw8723bs.c` anywhere. That's a bit odd. Okay, my first thought is to check if it's even present in this file tree. I need to make sure this file even exists before going any further with troubleshooting. Let's get that verified.



18/2 2026/07/26 07:19 tool grepper
0m Args:
{
  "Expression": "rtw8723bs"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac80211.c-21- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:22:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-23-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-46-}\ndrivers/net/wireless/realtek/rtw88/mac80211.c:47:EXPORT_SYMBOL(rtw8723bs_auth_sync_rx);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-48-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-81- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:82:static void rtw8723bs_auth_rx_filter(struct rtw_dev *rtwdev, bool accept_all)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-83-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-88-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:89:static void rtw8723bs_config_sec_cfg(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-90-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-96-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:97:static void rtw8723bs_config_default_key_search(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-98-\t\t\t\t\t\tbool enable)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-110-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:111:static void rtw8723bs_enable_tsf_update(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-112-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-115-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:116:static void rtw8723bs_set_ack_preamble(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-117-\t\t\t\t       bool short_preamble)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-125-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:126:static void rtw8723bs_set_slot_time(struct rtw_dev *rtwdev, bool short_slot)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-127-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-132-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:133:static u16 rtw8723bs_rrsr_from_ie_rate(u8 rate)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-134-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-151-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:152:static void rtw8723bs_collect_basic_rates(const u8 *ie, u16 *basic_rates,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-153-\t\t\t\t\t  bool *valid)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-164-\t\t\tcontinue;\ndrivers/net/wireless/realtek/rtw88/mac80211.c:165:\t\tr = rtw8723bs_rrsr_from_ie_rate(ie[i + 2]);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-166-\t\tif (!r)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-172-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:173:static void rtw8723bs_reset_response_rates(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-174-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-178-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:179:static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-180-\t\t\t\t\tstruct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-207-\t\text = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:208:\t\trtw8723bs_collect_basic_rates(rates, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:209:\t\trtw8723bs_collect_basic_rates(ext, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-210-\t\trcu_read_unlock();\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-229- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:230:static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-231-\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-266-\tif (set_preamble)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:267:\t\trtw8723bs_set_ack_preamble(rtwdev, short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:268:\trtw8723bs_set_slot_time(rtwdev, short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-269-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-273-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:274:static unsigned int rtw8723bs_auth_sync_wait_ms(struct ieee80211_vif *vif)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-275-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-286-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:287:static void rtw8723bs_auth_sync_start(struct rtw_dev *rtwdev, const u8 *bssid)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-288-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-299-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:300:static void rtw8723bs_auth_sync_stop(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-301-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-309-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:310:static bool rtw8723bs_auth_sync_seen(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-311-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-322-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:323:static bool rtw8723bs_auth_sync_wait(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-324-\t\t\t\t     unsigned int wait_ms)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-327-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:328:\treturn wait_event_timeout(sync-\u003ewait, rtw8723bs_auth_sync_seen(rtwdev),\ndrivers/net/wireless/realtek/rtw88/mac80211.c-329-\t\t\t\t  msecs_to_jiffies(wait_ms)) \u003e 0;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-331-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:332:static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-333-\t\t\t\t\t  struct ieee80211_prep_tx_info *info)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-341- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:342:static bool rtw8723bs_mgd_prepare_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-343-\t\t\t\t       struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-364-\t */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:365:\trtw8723bs_apply_bss_cap(rtwdev, vif, bssid, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-366-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-382-\trtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:383:\trtw8723bs_auth_rx_filter(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-384-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-388-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:389:\trtw8723bs_config_sec_cfg(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-390-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-396- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:397:static void rtw8723bs_tx_pre_auth_deauth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-398-\t\t\t\t\t struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-434- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:435:static void rtw8723bs_mgd_prepare_auth_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-436-\t\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-442-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:443:\tif (!rtw8723bs_mgd_prepare_is_auth(rtwdev, info) || !vif ||\ndrivers/net/wireless/realtek/rtw88/mac80211.c-444-\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags))\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-456-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:457:\tfresh_join = rtw8723bs_mgd_prepare_join(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-458-\ndrivers/net/wireless/realtek/rtw88/mac80211.c-459-\tif (fresh_join || !rtwvif-\u003epre_auth_join_done) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:460:\t\tunsigned int wait_ms = rtw8723bs_auth_sync_wait_ms(vif);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-461-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:462:\t\trtw8723bs_auth_sync_start(rtwdev, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:463:\t\trtw8723bs_tx_pre_auth_deauth(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:464:\t\trtw8723bs_auth_sync_wait(rtwdev, wait_ms);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:465:\t\trtw8723bs_auth_sync_stop(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-466-\t\trtwvif-\u003epre_auth_join_done = true;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=829=static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-848-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:849:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:850:\t\t\t\trtw8723bs_apply_bss_cap(rtwdev, vif, NULL, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:851:\t\t\t\trtw8723bs_apply_basic_rates(rtwdev, vif, NULL);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:852:\t\t\t\trtw8723bs_enable_tsf_update(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-853-\t\t\t\t/* Vendor mlmeext_joinbss sends MACID_CFG before\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-891-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:892:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:893:\t\t\t\trtw8723bs_reset_response_rates(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-894-\t\t\t\trtwvif-\u003epre_auth_h2c_sent = false;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-957-\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:958:\t\trtw8723bs_set_ack_preamble(rtwdev, conf-\u003euse_short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-959-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-962-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:963:\t\t\trtw8723bs_set_slot_time(rtwdev, conf-\u003euse_short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-964-\t\trtw_conf_tx(rtwdev, rtwvif);\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1064=static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1127-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1128:\t\t\trtw8723bs_config_default_key_search(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1129-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1136-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1137:\t\t\trtw8723bs_config_default_key_search(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1138-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1219=static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1237-\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1238:\t\trtw8723bs_mgd_prepare_auth_join(rtwdev, vif, info);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1239-\t} else {\n--\ndrivers/net/wireless/realtek/rtw88/main.c=44=MODULE_PARM_DESC(debug_mask, \"Debugging mask\");\n--\ndrivers/net/wireless/realtek/rtw88/main.c-48-\ndrivers/net/wireless/realtek/rtw88/main.c:49:struct rtw8723bs_txagc_entry {\ndrivers/net/wireless/realtek/rtw88/main.c-50-\tu8 rate;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-54-/* Vendor/staging per-rate TXAGC PG bytes for 8723BS 2.4 GHz. */\ndrivers/net/wireless/realtek/rtw88/main.c:55:static const struct rtw8723bs_txagc_entry rtw8723bs_pg_txagc[] = {\ndrivers/net/wireless/realtek/rtw88/main.c-56-\t{ DESC_RATE1M, 0x38 }, { DESC_RATE2M, 0x36 },\n--\ndrivers/net/wireless/realtek/rtw88/main.c=69=static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-80- */\ndrivers/net/wireless/realtek/rtw88/main.c:81:static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-82-{\n--\ndrivers/net/wireless/realtek/rtw88/main.c-91-\tfor (path = 0; path \u003c hal-\u003erf_path_num \u0026\u0026 path \u003c RTW_RF_PATH_MAX; path++)\ndrivers/net/wireless/realtek/rtw88/main.c:92:\t\tfor (i = 0; i \u003c ARRAY_SIZE(rtw8723bs_pg_txagc); i++)\ndrivers/net/wireless/realtek/rtw88/main.c:93:\t\t\thal-\u003etx_pwr_tbl[path][rtw8723bs_pg_txagc[i].rate] =\ndrivers/net/wireless/realtek/rtw88/main.c:94:\t\t\t\trtw8723bs_pg_txagc[i].pwr_idx;\ndrivers/net/wireless/realtek/rtw88/main.c-95-\trtwdev-\u003echip-\u003eops-\u003eset_tx_power_index(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=103=static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-128-\ndrivers/net/wireless/realtek/rtw88/main.c:129:static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-130-\t\t\t\t\t   struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-139- */\ndrivers/net/wireless/realtek/rtw88/main.c:140:static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-141-\t\t\t\t\t     struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-143-{\ndrivers/net/wireless/realtek/rtw88/main.c:144:\treturn rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-145-\t       !vif-\u003ecfg.assoc;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=459=int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-483-\trtw_update_sta_info(rtwdev, si, true);\ndrivers/net/wireless/realtek/rtw88/main.c:484:\tif (rtw8723bs_defer_sta_media_status(rtwdev, sta, vif)) {\ndrivers/net/wireless/realtek/rtw88/main.c-485-\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-487-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, true);\ndrivers/net/wireless/realtek/rtw88/main.c:488:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-489-\t\t\trtwvif-\u003efw_media_connected = true;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=500=void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-511-\t\trtw_release_macid(rtwdev, si-\u003emac_id);\ndrivers/net/wireless/realtek/rtw88/main.c:512:\tif (fw_exist \u0026\u0026 rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-513-\t    !rtwvif-\u003efw_media_connected) {\n--\ndrivers/net/wireless/realtek/rtw88/main.c-516-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, false);\ndrivers/net/wireless/realtek/rtw88/main.c:517:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-518-\t\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=998=void rtw_set_channel(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1033-\ndrivers/net/wireless/realtek/rtw88/main.c:1034:\trtw8723bs_reapply_pg_txagc(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1035-\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2315=void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/realtek/rtw88/main.h-2316-\t\t\t  struct ieee80211_bss_conf *bss_conf);\ndrivers/net/wireless/realtek/rtw88/main.h:2317:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.h-2318-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1252=static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1270-\tif (skb-\u003elen \u003e= sizeof(struct ieee80211_hdr_3addr))\ndrivers/net/wireless/realtek/rtw88/sdio.c:1271:\t\trtw8723bs_auth_sync_rx(rtwdev,\ndrivers/net/wireless/realtek/rtw88/sdio.c-1272-\t\t\t\t       (struct ieee80211_hdr *)skb-\u003edata,\n"
}

19/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 63669
							output: 24
							thoughts: 137
						

Thoughts:
**Investigating the RTW8723BS Implementation**

Okay, so it looks like `rtw8723bs` isn't a standalone file, which is interesting. The patch is defining `rtw_is_8723bs` and integrating it across several modules like `mac80211.c`, `main.c`, and `sdio.c`. My immediate thought is, is there a complete `rtw8723bs.c` implementation that I'm overlooking? Or are we dealing solely with the `rtw8723b.c` code with conditional logic? I need to clarify the source code structure. Time to check the `Makefile` in the `rtw88` directory, or perhaps the relevant `Kconfig` files. I'm assuming there's a configuration option to handle the specific differences, but I need to confirm the build system's approach to incorporating the `bs` variant. This is key to understanding the full scope of the patch's changes.



20/2 2026/07/26 07:19 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "RTW88_8723BS"
}

Results:
{
  "error": "no matches"
}

21/2 2026/07/26 07:19 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 64066
							output: 18
							thoughts: 29
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Investigating the Realtek 8723 Wireless Driver Configuration**

Right, let's dive into the `Kconfig` file for the Realtek wireless driver, specifically targeting the `rtw88` directory. My aim here is to understand the configuration options available for the 8723 chip. This usually means I'm looking for things like:

*   **Feature Flags:** Are there specific compile-time options to enable or disable certain features for that hardware? This could include things like power management settings, support for different Wi-Fi standards (802.11a/b/g/n/ac, etc.), or specific hardware acceleration features.
*   **Module Dependencies:** Are there any dependencies on other kernel subsystems or modules? Understanding those dependencies can be crucial when troubleshooting build issues or conflicts. It's important to understand the full dependency tree.
*   **Device-Specific Configuration:** Are there any vendor-specific or chip-specific tuning parameters exposed through the Kconfig file? Sometimes there are hidden configuration knobs that are not exposed to the user as defaults.
*   **Documentation clues:** Are there comment blocks in the Kconfig file that reveal implementation detail? This can greatly speed up my troubleshooting or configuration process.
*   **Defaults and Triggers:** What are the default values for the relevant configuration options and how are they triggered in different kernel builds?

Essentially, I'm trying to get a complete picture of how the driver for the 8723 is controlled at build time. This knowledge is invaluable for debugging any wireless issues, customizing the driver, or integrating it into a specific kernel configuration. I'm assuming that the build system is correctly set up, so I will be looking for bugs or missing features in the configuration stage.



22/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "8723"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 21316 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=5=$schema: http://devicetree.org/meta-schemas/core.yaml#\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-6-\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:7:title: RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS Bluetooth\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-8-\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=13=description:\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:14:  RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-15-  is connected over SDIO, while BT is connected over serial. It speaks\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=19=properties:\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-22-      - enum:\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:23:          - realtek,rtl8723bs-bt\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:24:          - realtek,rtl8723cs-bt\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:25:          - realtek,rtl8723ds-bt\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-26-          - realtek,rtl8822cs-bt\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-29-              - realtek,rtl8821cs-bt\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:30:          - const: realtek,rtl8723bs-bt\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-31-\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=54=examples:\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-63-        bluetooth {\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:64:            compatible = \"realtek,rtl8723bs-bt\";\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-65-            device-wake-gpios = \u003c\u0026r_pio 0 5 GPIO_ACTIVE_HIGH\u003e; /* PL5 */\n--\nDocumentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg-130-       height=\"409.44757\"\nDocumentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg:131:       x=\"1363.8723\"\nDocumentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg-132-       y=\"1147.7572\" /\u003e\n--\nDocumentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg-130-       height=\"409.44757\"\nDocumentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg:131:       x=\"1363.8723\"\nDocumentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg-132-       y=\"1147.7572\" /\u003e\n--\nDocumentation/images/logo.svg-1394-         inkscape:connector-curvature=\"0\"\nDocumentation/images/logo.svg:1395:         d=\"m 386.1875,285.32775 c -0.40516,-1.10369 -1.11845,-2.08156 -1.9907,-2.86987 -0.87226,-0.78832 -1.90049,-1.39229 -2.98278,-1.85155 -2.16459,-0.91852 -4.52...\nDocumentation/images/logo.svg-1396-         id=\"path535\"\n--\nDocumentation/images/logo.svg-1406-         id=\"path540\"\nDocumentation/images/logo.svg:1407:         d=\"m 386.1875,285.32775 c -0.40516,-1.10369 -1.11845,-2.08156 -1.9907,-2.86987 -0.87226,-0.78832 -1.90049,-1.39229 -2.98278,-1.85155 -2.16459,-0.91852 -4.52...\nDocumentation/images/logo.svg-1408-         inkscape:connector-curvature=\"0\"\n--\nDocumentation/trace/ftrace.rst=917=Error conditions\n--\nDocumentation/trace/ftrace.rst-937-    # cat /sys/kernel/tracing/error_log\nDocumentation/trace/ftrace.rst:938:    [ 5348.887237] location: error: Couldn't yyy: zzz\nDocumentation/trace/ftrace.rst-939-      Command: xxx\n--\narch/arm/boot/dts/allwinner/sun5i-r8-chip.dts=259=\tbluetooth {\narch/arm/boot/dts/allwinner/sun5i-r8-chip.dts:260:\t\tcompatible = \"realtek,rtl8723bs-bt\";\narch/arm/boot/dts/allwinner/sun5i-r8-chip.dts-261-\t\tdevice-wake-gpios = \u003c\u0026axp_gpio 3 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts=22=\taliases {\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-27-\t\tspi1 = \u0026spi2;\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts:28:\t\tethernet1 = \u0026rtl8723bs;\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-29-\t};\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts=173=\u0026mmc3 {\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-179-\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts:180:\trtl8723bs: wifi@1 {\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-181-\t\treg = \u003c1\u003e;\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts=282=\u0026uart0 {\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-287-\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts:288:/* Used for RTL8723BS bluetooth */\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-289-\u0026uart3 {\n--\narch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts=73=\u0026mmc1 {\n--\narch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts-80-\narch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts:81:\trtl8723bs: wifi@1 {\narch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts-82-\t\treg = \u003c1\u003e;\n--\narch/arm/boot/dts/amlogic/meson8b-ec100.dts=455=\u0026uart_AO {\n--\narch/arm/boot/dts/amlogic/meson8b-ec100.dts-461-/*\narch/arm/boot/dts/amlogic/meson8b-ec100.dts:462: * connected to the Bluetooth part of the RTL8723BS SDIO wifi / Bluetooth\narch/arm/boot/dts/amlogic/meson8b-ec100.dts-463- * combo chip. This is only available on the variant with 2GB RAM.\n--\narch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi=379=\tbluetooth {\narch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi:380:\t\tcompatible = \"realtek,rtl8723ds-bt\";\narch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi-381-\t\tdevice-wake-gpios = \u003c\u0026gpio1 RK_PC7 GPIO_ACTIVE_HIGH\u003e; /* BT_WAKE */\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts=140=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts-149-\narch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts:150:\trtl8723bs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts-151-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts=20=\taliases {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts-21-\t\tserial0 = \u0026uart0;\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts:22:\t\tethernet0 = \u0026rtl8723cs;\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts-23-\t};\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts=151=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts-160-\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts:161:\trtl8723cs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts-162-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts=417=\tbluetooth {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts:418:\t\tcompatible = \"realtek,rtl8723cs-bt\";\narch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts-419-\t\tdevice-wake-gpios = \u003c\u0026r_pio 0 5 GPIO_ACTIVE_LOW\u003e; /* PL5 */\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi=17=\taliases {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi:18:\t\tethernet0 = \u0026rtl8723cs;\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi-19-\t\tserial0 = \u0026uart0;\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi=275=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi-283-\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi:284:\trtl8723cs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi-285-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi=521=\tbluetooth {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi:522:\t\tcompatible = \"realtek,rtl8723cs-bt\";\narch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi-523-\t\tdevice-wake-gpios = \u003c\u0026pio 7 6 GPIO_ACTIVE_LOW\u003e; /* PH6 */\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts=21=\taliases {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts-22-\t\tserial0 = \u0026uart0;\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts:23:\t\tethernet0 = \u0026rtl8723cs;\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts-24-\t};\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts=240=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts-249-\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts:250:\trtl8723cs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts-251-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts=167=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts-176-\narch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts:177:\trtl8723bs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts-178-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts=44=\tbluetooth {\narch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts:45:\t\tcompatible = \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts-46-\t\tdevice-wake-gpios = \u003c\u0026r_pio 1 2 GPIO_ACTIVE_HIGH\u003e; /* PM2 */\n--\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts=16=\taliases {\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts:17:\t\tethernet1 = \u0026rtl8723bs;\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts-18-\t\tserial0 = \u0026uart0;\n--\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts=125=\u0026mmc1 {\n--\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts-134-\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts:135:\trtl8723bs: wifi@1 {\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts-136-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts=340=\tbluetooth {\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts:341:\t\tcompatible = \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts-342-\t\tenable-gpios = \u003c\u0026r_pio 0 4 GPIO_ACTIVE_HIGH\u003e; /* PL4 */\n--\narch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts=47=\tbluetooth {\narch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts:48:\t\tcompatible = \"realtek,rtl8821cs-bt\", \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts-49-\t\tdevice-wake-gpios = \u003c\u0026pio 6 17 GPIO_ACTIVE_HIGH\u003e; /* PG17 */\n--\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts=305=\u0026sdio {\n--\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts-320-\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts:321:\trtl8723ds: wifi@1 {\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts-322-\t\treg = \u003c1\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts=363=\tbluetooth {\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts:364:\t\tcompatible = \"realtek,rtl8723ds-bt\";\narch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts-365-\t\tdevice-wake-gpios = \u003c\u0026gpio4 RK_PB2 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts=789=\tbluetooth: bluetooth {\narch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts:790:\t\tcompatible = \"realtek,rtl8723ds-bt\";\narch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts-791-\t\tdevice-wake-gpios = \u003c\u0026gpio0 RK_PA1 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi=651=\tbluetooth {\narch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi:652:\t\tcompatible = \"realtek,rtl8821cs-bt\", \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi-653-\t\tdevice-wake-gpios = \u003c\u0026gpio4 4 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts=15=\u0026bluetooth {\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts:16:\tcompatible = \"realtek,rtl8723ds-bt\";\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts-17-};\n--\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb20sx.dts=41=\u0026bluetooth {\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb20sx.dts:42:\tcompatible = \"realtek,rtl8723ds-bt\";\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb20sx.dts-43-};\n--\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi=794=\tbluetooth: bluetooth {\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi:795:\t\tcompatible = \"realtek,rtl8821cs-bt\", \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi-796-\t\tdevice-wake-gpios = \u003c\u0026gpio4 4 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts=870=\tbluetooth {\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts:871:\t\tcompatible = \"realtek,rtl8821cs-bt\", \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts-872-\t\tdevice-wake-gpios = \u003c\u0026gpio0 RK_PB6 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts=1205=\tbluetooth {\narch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts:1206:\t\tcompatible = \"realtek,rtl8821cs-bt\", \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts-1207-\t\tdevice-wake-gpios = \u003c\u0026gpio0 RK_PD3 GPIO_ACTIVE_HIGH\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts=988=\tbluetooth {\narch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts-989-\t\tcompatible = \"realtek,rtl8821cs-bt\",\narch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts:990:\t\t\t     \"realtek,rtl8723bs-bt\";\narch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts-991-\t\tdevice-wake-gpios = \u003c\u0026gpio0 RK_PC6 GPIO_ACTIVE_HIGH\u003e;\n--\narch/loongarch/configs/loongson32_defconfig=666=CONFIG_RTL8192DE=m\narch/loongarch/configs/loongson32_defconfig:667:CONFIG_RTL8723AE=m\narch/loongarch/configs/loongson32_defconfig:668:CONFIG_RTL8723BE=m\narch/loongarch/configs/loongson32_defconfig-669-CONFIG_RTL8188EE=m\n--\narch/loongarch/configs/loongson32_defconfig=680=CONFIG_RTW88_8822CU=m\narch/loongarch/configs/loongson32_defconfig:681:CONFIG_RTW88_8723DE=m\narch/loongarch/configs/loongson32_defconfig:682:CONFIG_RTW88_8723DU=m\narch/loongarch/configs/loongson32_defconfig-683-CONFIG_RTW88_8821CE=m\n--\narch/loongarch/configs/loongson64_defconfig=682=CONFIG_RTL8192DE=m\narch/loongarch/configs/loongson64_defconfig:683:CONFIG_RTL8723AE=m\narch/loongarch/configs/loongson64_defconfig:684:CONFIG_RTL8723BE=m\narch/loongarch/configs/loongson64_defconfig-685-CONFIG_RTL8188EE=m\n--\narch/loongarch/configs/loongson64_defconfig=696=CONFIG_RTW88_8822CU=m\narch/loongarch/configs/loongson64_defconfig:697:CONFIG_RTW88_8723DE=m\narch/loongarch/configs/loongson64_defconfig:698:CONFIG_RTW88_8723DU=m\narch/loongarch/configs/loongson64_defconfig-699-CONFIG_RTW88_8821CE=m\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts=14=\taliases {\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts:15:\t\tethernet1 = \u0026rtl8723ds;\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts-16-\t};\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts=74=\u0026mmc1 {\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts-83-\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts:84:\trtl8723ds: wifi@1 {\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts-85-\t\treg = \u003c1\u003e;\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts=99=\tbluetooth {\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts:100:\t\tcompatible = \"realtek,rtl8723ds-bt\";\narch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts-101-\t\tdevice-wake-gpios = \u003c\u0026pio 6 15 GPIO_ACTIVE_HIGH\u003e; /* PG16 */\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts=16=\taliases {\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts:17:\t\tethernet0 = \u0026rtl8723ds;\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts-18-\t\tserial0 = \u0026uart0;\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts=88=\u0026mmc1 {\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts-97-\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts:98:\trtl8723ds: wifi@1 {\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts-99-\t\treg = \u003c1\u003e;\n--\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts=126=\tbluetooth {\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts:127:\t\tcompatible = \"realtek,rtl8723ds-bt\";\narch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts-128-\t\tdevice-wake-gpios = \u003c\u0026pio 6 18 GPIO_ACTIVE_HIGH\u003e; /* PG18 */\n--\ndrivers/bluetooth/btrtl.c-19-\ndrivers/bluetooth/btrtl.c:20:#define RTL_CHIP_8723CS_CG\t3\ndrivers/bluetooth/btrtl.c:21:#define RTL_CHIP_8723CS_VF\t4\ndrivers/bluetooth/btrtl.c:22:#define RTL_CHIP_8723CS_XX\t5\ndrivers/bluetooth/btrtl.c-23-#define RTL_EPATCH_SIGNATURE\t\"Realtech\"\n--\ndrivers/bluetooth/btrtl.c-25-#define RTL_ROM_LMP_8703B\t0x8703\ndrivers/bluetooth/btrtl.c:26:#define RTL_ROM_LMP_8723A\t0x1200\ndrivers/bluetooth/btrtl.c:27:#define RTL_ROM_LMP_8723B\t0x8723\ndrivers/bluetooth/btrtl.c-28-#define RTL_ROM_LMP_8821A\t0x8821\n--\ndrivers/bluetooth/btrtl.c-33-#define RTL_ROM_LMP_8922A\t0x8922\ndrivers/bluetooth/btrtl.c:34:#define RTL_CONFIG_MAGIC\t0x8723ab55\ndrivers/bluetooth/btrtl.c-35-\n--\ndrivers/bluetooth/btrtl.c=59=enum btrtl_chip_id {\ndrivers/bluetooth/btrtl.c:60:\tCHIP_ID_8723A,\ndrivers/bluetooth/btrtl.c:61:\tCHIP_ID_8723B,\ndrivers/bluetooth/btrtl.c-62-\tCHIP_ID_8821A,\n--\ndrivers/bluetooth/btrtl.c-64-\tCHIP_ID_8822B = 8,\ndrivers/bluetooth/btrtl.c:65:\tCHIP_ID_8723D,\ndrivers/bluetooth/btrtl.c-66-\tCHIP_ID_8821C,\n--\ndrivers/bluetooth/btrtl.c=106=static const struct id_table ic_id_table[] = {\ndrivers/bluetooth/btrtl.c:107:\t/* 8723A */\ndrivers/bluetooth/btrtl.c:108:\t{ IC_INFO(RTL_ROM_LMP_8723A, 0xb, 0x6, HCI_USB),\ndrivers/bluetooth/btrtl.c-109-\t  .config_needed = false,\ndrivers/bluetooth/btrtl.c-110-\t  .has_rom_version = false,\ndrivers/bluetooth/btrtl.c:111:\t  .fw_name = \"rtl_bt/rtl8723a_fw\",\ndrivers/bluetooth/btrtl.c-112-\t  .cfg_name = NULL,\ndrivers/bluetooth/btrtl.c:113:\t  .hw_info = \"rtl8723au\" },\ndrivers/bluetooth/btrtl.c-114-\ndrivers/bluetooth/btrtl.c:115:\t/* 8723BS */\ndrivers/bluetooth/btrtl.c:116:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_UART),\ndrivers/bluetooth/btrtl.c-117-\t  .config_needed = true,\ndrivers/bluetooth/btrtl.c-118-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:119:\t  .fw_name  = \"rtl_bt/rtl8723bs_fw\",\ndrivers/bluetooth/btrtl.c:120:\t  .cfg_name = \"rtl_bt/rtl8723bs_config\",\ndrivers/bluetooth/btrtl.c:121:\t  .hw_info  = \"rtl8723bs\" },\ndrivers/bluetooth/btrtl.c-122-\ndrivers/bluetooth/btrtl.c:123:\t/* 8723B */\ndrivers/bluetooth/btrtl.c:124:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_USB),\ndrivers/bluetooth/btrtl.c-125-\t  .config_needed = false,\ndrivers/bluetooth/btrtl.c-126-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:127:\t  .fw_name  = \"rtl_bt/rtl8723b_fw\",\ndrivers/bluetooth/btrtl.c:128:\t  .cfg_name = \"rtl_bt/rtl8723b_config\",\ndrivers/bluetooth/btrtl.c:129:\t  .hw_info  = \"rtl8723bu\" },\ndrivers/bluetooth/btrtl.c-130-\ndrivers/bluetooth/btrtl.c:131:\t/* 8723CS-CG */\ndrivers/bluetooth/btrtl.c-132-\t{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |\n--\ndrivers/bluetooth/btrtl.c-134-\t  .lmp_subver = RTL_ROM_LMP_8703B,\ndrivers/bluetooth/btrtl.c:135:\t  .chip_type = RTL_CHIP_8723CS_CG,\ndrivers/bluetooth/btrtl.c-136-\t  .hci_bus = HCI_UART,\n--\ndrivers/bluetooth/btrtl.c-138-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:139:\t  .fw_name  = \"rtl_bt/rtl8723cs_cg_fw\",\ndrivers/bluetooth/btrtl.c:140:\t  .cfg_name = \"rtl_bt/rtl8723cs_cg_config\",\ndrivers/bluetooth/btrtl.c:141:\t  .hw_info  = \"rtl8723cs-cg\" },\ndrivers/bluetooth/btrtl.c-142-\ndrivers/bluetooth/btrtl.c:143:\t/* 8723CS-VF */\ndrivers/bluetooth/btrtl.c-144-\t{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |\n--\ndrivers/bluetooth/btrtl.c-146-\t  .lmp_subver = RTL_ROM_LMP_8703B,\ndrivers/bluetooth/btrtl.c:147:\t  .chip_type = RTL_CHIP_8723CS_VF,\ndrivers/bluetooth/btrtl.c-148-\t  .hci_bus = HCI_UART,\n--\ndrivers/bluetooth/btrtl.c-150-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:151:\t  .fw_name  = \"rtl_bt/rtl8723cs_vf_fw\",\ndrivers/bluetooth/btrtl.c:152:\t  .cfg_name = \"rtl_bt/rtl8723cs_vf_config\",\ndrivers/bluetooth/btrtl.c:153:\t  .hw_info  = \"rtl8723cs-vf\" },\ndrivers/bluetooth/btrtl.c-154-\ndrivers/bluetooth/btrtl.c:155:\t/* 8723CS-XX */\ndrivers/bluetooth/btrtl.c-156-\t{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |\n--\ndrivers/bluetooth/btrtl.c-158-\t  .lmp_subver = RTL_ROM_LMP_8703B,\ndrivers/bluetooth/btrtl.c:159:\t  .chip_type = RTL_CHIP_8723CS_XX,\ndrivers/bluetooth/btrtl.c-160-\t  .hci_bus = HCI_UART,\n--\ndrivers/bluetooth/btrtl.c-162-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:163:\t  .fw_name  = \"rtl_bt/rtl8723cs_xx_fw\",\ndrivers/bluetooth/btrtl.c:164:\t  .cfg_name = \"rtl_bt/rtl8723cs_xx_config\",\ndrivers/bluetooth/btrtl.c:165:\t  .hw_info  = \"rtl8723cs\" },\ndrivers/bluetooth/btrtl.c-166-\ndrivers/bluetooth/btrtl.c:167:\t/* 8723D */\ndrivers/bluetooth/btrtl.c:168:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB),\ndrivers/bluetooth/btrtl.c-169-\t  .config_needed = true,\ndrivers/bluetooth/btrtl.c-170-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:171:\t  .fw_name  = \"rtl_bt/rtl8723d_fw\",\ndrivers/bluetooth/btrtl.c:172:\t  .cfg_name = \"rtl_bt/rtl8723d_config\",\ndrivers/bluetooth/btrtl.c:173:\t  .hw_info  = \"rtl8723du\" },\ndrivers/bluetooth/btrtl.c-174-\ndrivers/bluetooth/btrtl.c:175:\t/* 8723DS */\ndrivers/bluetooth/btrtl.c:176:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_UART),\ndrivers/bluetooth/btrtl.c-177-\t  .config_needed = true,\ndrivers/bluetooth/btrtl.c-178-\t  .has_rom_version = true,\ndrivers/bluetooth/btrtl.c:179:\t  .fw_name  = \"rtl_bt/rtl8723ds_fw\",\ndrivers/bluetooth/btrtl.c:180:\t  .cfg_name = \"rtl_bt/rtl8723ds_config\",\ndrivers/bluetooth/btrtl.c:181:\t  .hw_info  = \"rtl8723ds\" },\ndrivers/bluetooth/btrtl.c-182-\n--\ndrivers/bluetooth/btrtl.c=639=static int rtlbt_parse_firmware(struct hci_dev *hdev,\n--\ndrivers/bluetooth/btrtl.c-658-\t} project_id_to_lmp_subver[] = {\ndrivers/bluetooth/btrtl.c:659:\t\t{ RTL_ROM_LMP_8723A, 0 },\ndrivers/bluetooth/btrtl.c:660:\t\t{ RTL_ROM_LMP_8723B, 1 },\ndrivers/bluetooth/btrtl.c-661-\t\t{ RTL_ROM_LMP_8821A, 2 },\n--\ndrivers/bluetooth/btrtl.c-664-\t\t{ RTL_ROM_LMP_8822B, 8 },\ndrivers/bluetooth/btrtl.c:665:\t\t{ RTL_ROM_LMP_8723B, 9 },\t/* 8723D */\ndrivers/bluetooth/btrtl.c-666-\t\t{ RTL_ROM_LMP_8821A, 10 },\t/* 8821C */\n--\ndrivers/bluetooth/btrtl.c=888=static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)\n--\ndrivers/bluetooth/btrtl.c-906-\ndrivers/bluetooth/btrtl.c:907:static int btrtl_setup_rtl8723a(struct hci_dev *hdev,\ndrivers/bluetooth/btrtl.c-908-\t\t\t\tstruct btrtl_device_info *btrtl_dev)\n--\ndrivers/bluetooth/btrtl.c-913-\t/* Check that the firmware doesn't have the epatch signature\ndrivers/bluetooth/btrtl.c:914:\t * (which is only for RTL8723B and newer).\ndrivers/bluetooth/btrtl.c-915-\t */\n--\ndrivers/bluetooth/btrtl.c-924-\ndrivers/bluetooth/btrtl.c:925:static int btrtl_setup_rtl8723b(struct hci_dev *hdev,\ndrivers/bluetooth/btrtl.c-926-\t\t\t\tstruct btrtl_device_info *btrtl_dev)\n--\ndrivers/bluetooth/btrtl.c=1257=int btrtl_download_firmware(struct hci_dev *hdev,\n--\ndrivers/bluetooth/btrtl.c-1274-\tswitch (btrtl_dev-\u003eic_info-\u003elmp_subver) {\ndrivers/bluetooth/btrtl.c:1275:\tcase RTL_ROM_LMP_8723A:\ndrivers/bluetooth/btrtl.c:1276:\t\terr = btrtl_setup_rtl8723a(hdev, btrtl_dev);\ndrivers/bluetooth/btrtl.c-1277-\t\tbreak;\ndrivers/bluetooth/btrtl.c:1278:\tcase RTL_ROM_LMP_8723B:\ndrivers/bluetooth/btrtl.c-1279-\tcase RTL_ROM_LMP_8821A:\n--\ndrivers/bluetooth/btrtl.c-1285-\tcase RTL_ROM_LMP_8922A:\ndrivers/bluetooth/btrtl.c:1286:\t\terr = btrtl_setup_rtl8723b(hdev, btrtl_dev);\ndrivers/bluetooth/btrtl.c-1287-\t\tbreak;\n--\ndrivers/bluetooth/btrtl.c=1300=void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)\n--\ndrivers/bluetooth/btrtl.c-1359-\tcase RTL_ROM_LMP_8703B:\ndrivers/bluetooth/btrtl.c:1360:\t\t/* 8723CS reports two pages for local ext features,\ndrivers/bluetooth/btrtl.c-1361-\t\t * but it doesn't support any features from page 2 -\n--\ndrivers/bluetooth/btrtl.c=1530=MODULE_LICENSE(\"GPL\");\ndrivers/bluetooth/btrtl.c:1531:MODULE_FIRMWARE(\"rtl_bt/rtl8723a_fw.bin\");\ndrivers/bluetooth/btrtl.c:1532:MODULE_FIRMWARE(\"rtl_bt/rtl8723b_fw.bin\");\ndrivers/bluetooth/btrtl.c:1533:MODULE_FIRMWARE(\"rtl_bt/rtl8723b_config.bin\");\ndrivers/bluetooth/btrtl.c:1534:MODULE_FIRMWARE(\"rtl_bt/rtl8723bs_fw.bin\");\ndrivers/bluetooth/btrtl.c:1535:MODULE_FIRMWARE(\"rtl_bt/rtl8723bs_config.bin\");\ndrivers/bluetooth/btrtl.c:1536:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_cg_fw.bin\");\ndrivers/bluetooth/btrtl.c:1537:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_cg_config.bin\");\ndrivers/bluetooth/btrtl.c:1538:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_vf_fw.bin\");\ndrivers/bluetooth/btrtl.c:1539:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_vf_config.bin\");\ndrivers/bluetooth/btrtl.c:1540:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_xx_fw.bin\");\ndrivers/bluetooth/btrtl.c:1541:MODULE_FIRMWARE(\"rtl_bt/rtl8723cs_xx_config.bin\");\ndrivers/bluetooth/btrtl.c:1542:MODULE_FIRMWARE(\"rtl_bt/rtl8723d_fw.bin\");\ndrivers/bluetooth/btrtl.c:1543:MODULE_FIRMWARE(\"rtl_bt/rtl8723d_config.bin\");\ndrivers/bluetooth/btrtl.c:1544:MODULE_FIRMWARE(\"rtl_bt/rtl8723ds_fw.bin\");\ndrivers/bluetooth/btrtl.c:1545:MODULE_FIRMWARE(\"rtl_bt/rtl8723ds_config.bin\");\ndrivers/bluetooth/btrtl.c-1546-MODULE_FIRMWARE(\"rtl_bt/rtl8761a_fw.bin\");\n--\ndrivers/bluetooth/btusb.c=180=static const struct usb_device_id quirks_table[] = {\n--\ndrivers/bluetooth/btusb.c-807-\ndrivers/bluetooth/btusb.c:808:\t/* Additional Realtek 8723AE Bluetooth devices */\ndrivers/bluetooth/btusb.c-809-\t{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },\n--\ndrivers/bluetooth/btusb.c-811-\ndrivers/bluetooth/btusb.c:812:\t/* Additional Realtek 8723BE Bluetooth devices */\ndrivers/bluetooth/btusb.c-813-\t{ USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK },\n--\ndrivers/bluetooth/btusb.c-820-\ndrivers/bluetooth/btusb.c:821:\t/* Additional Realtek 8723BU Bluetooth devices */\ndrivers/bluetooth/btusb.c-822-\t{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },\n--\ndrivers/bluetooth/btusb.c-824-\ndrivers/bluetooth/btusb.c:825:\t/* Additional Realtek 8723DE Bluetooth devices */\ndrivers/bluetooth/btusb.c-826-\t{ USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK },\n--\ndrivers/bluetooth/hci_h5.c=1115=static const struct h5_device_data h5_data_rtl8822cs = {\n--\ndrivers/bluetooth/hci_h5.c-1118-\ndrivers/bluetooth/hci_h5.c:1119:static const struct h5_device_data h5_data_rtl8723bs = {\ndrivers/bluetooth/hci_h5.c-1120-\t.driver_info = H5_INFO_WAKEUP_DISABLE,\n--\ndrivers/bluetooth/hci_h5.c=1126=static const struct acpi_device_id h5_acpi_match[] = {\ndrivers/bluetooth/hci_h5.c-1127-#ifdef CONFIG_BT_HCIUART_RTL\ndrivers/bluetooth/hci_h5.c:1128:\t{ \"OBDA0623\", (kernel_ulong_t)\u0026h5_data_rtl8723bs },\ndrivers/bluetooth/hci_h5.c:1129:\t{ \"OBDA8723\", (kernel_ulong_t)\u0026h5_data_rtl8723bs },\ndrivers/bluetooth/hci_h5.c-1130-#endif\n--\ndrivers/bluetooth/hci_h5.c=1141=static const struct of_device_id rtl_bluetooth_of_match[] = {\n--\ndrivers/bluetooth/hci_h5.c-1144-\t  .data = (const void *)\u0026h5_data_rtl8822cs },\ndrivers/bluetooth/hci_h5.c:1145:\t{ .compatible = \"realtek,rtl8723bs-bt\",\ndrivers/bluetooth/hci_h5.c:1146:\t  .data = (const void *)\u0026h5_data_rtl8723bs },\ndrivers/bluetooth/hci_h5.c:1147:\t{ .compatible = \"realtek,rtl8723cs-bt\",\ndrivers/bluetooth/hci_h5.c:1148:\t  .data = (const void *)\u0026h5_data_rtl8723bs },\ndrivers/bluetooth/hci_h5.c:1149:\t{ .compatible = \"realtek,rtl8723ds-bt\",\ndrivers/bluetooth/hci_h5.c:1150:\t  .data = (const void *)\u0026h5_data_rtl8723bs },\ndrivers/bluetooth/hci_h5.c-1151-#endif\n--\ndrivers/gpu/drm/bridge/lontium-lt9211.c=133=static int lt9211_system_init(struct lt9211 *ctx)\n--\ndrivers/gpu/drm/bridge/lontium-lt9211.c-142-\t\t{ 0x8722, 0x08 },\ndrivers/gpu/drm/bridge/lontium-lt9211.c:143:\t\t{ 0x8723, 0x00 },\ndrivers/gpu/drm/bridge/lontium-lt9211.c-144-\t\t{ 0x8726, 0x0f },\n--\ndrivers/iio/light/lv0104cs.c=52=static const struct lv0104cs_mapping lv0104cs_calibscales[] = {\n--\ndrivers/iio/light/lv0104cs.c-74-\t{ 0, 977777, 0x96 },\ndrivers/iio/light/lv0104cs.c:75:\t{ 0, 978723, 0x97 },\ndrivers/iio/light/lv0104cs.c-76-\t{ 0, 979591, 0x98 },\n--\ndrivers/media/i2c/tc358743_regs.h-727-#define PK_AVI_0BYTE                          0x8713\ndrivers/media/i2c/tc358743_regs.h:728:#define PK_AVI_16BYTE                         0x8723\ndrivers/media/i2c/tc358743_regs.h-729-#define PK_AVI_LEN\t\t\t      (PK_AVI_16BYTE - PK_AVI_0HEAD + 1)\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c=1096=static const u16 default_spatial_pred_seg_tree_cdf[SPATIAL_PREDICTION_PROBS]\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-1104-\t{\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c:1105:\t\tAOM_CDF8(27527, 28487, 28723, 28890, 32397, 32647, 32679),\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-1106-\t},\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c=2306=static const u16 av1_default_coeff_lps_multi_cdfs[TOKEN_CDF_Q_CTXS]\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-2352-\t\t\t\t{ AOM_CDF4(15460, 21696, 25469)}, { AOM_CDF4(12170, 19249, 23191)},\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c:2353:\t\t\t\t{ AOM_CDF4(8723, 15027, 19332)}, { AOM_CDF4(6428, 11704, 15874)},\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-2354-\t\t\t\t{ AOM_CDF4(4922, 9292, 13052)}, { AOM_CDF4(4139, 7695, 11010)},\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c=2878=static const u16 av1_default_coeff_base_multi_cdfs\n--\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-3416-\t\t\t\t{ AOM_CDF4(9704, 17294, 21132)}, { AOM_CDF4(26762, 32278, 32633)},\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c:3417:\t\t\t\t{ AOM_CDF4(18382, 29620, 31819)}, { AOM_CDF4(10891, 23475, 28723)},\ndrivers/media/platform/verisilicon/rockchip_av1_entropymode.c-3418-\t\t\t\t{ AOM_CDF4(6358, 16583, 23309)}, { AOM_CDF4(3248, 9118, 14141)},\n--\ndrivers/net/ethernet/dlink/sundance.c=179=The Sundance ST201 datasheet, preliminary version.\ndrivers/net/ethernet/dlink/sundance.c:180:The Kendin KS8723 datasheet, preliminary version.\ndrivers/net/ethernet/dlink/sundance.c-181-The ICplus IP100 datasheet, preliminary version.\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c-10- * This driver was written as a replacement for the vendor provided\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c:11: * rtl8723au driver. As the Realtek 8xxx chips are very similar in\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c-12- * their programming interface, I have started adding support for\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c=146=static const struct rtl8xxxu_reg32val rtl8188e_agc_table[] = {\n\n"
}

23/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 79574
							output: 19
							thoughts: 80
						

Thoughts:
Okay, let's see...

**Investigating a Suspected Realtek Driver Configuration**

Hmm, I seem to recall that the `drivers/net/wireless/realtek/rtw88/Kconfig` file might contain the configuration option for `RTW88_8723BS`. But wait, I didn't spot it when I quickly scanned the `grep` output earlier. That's odd. Let me just confirm that. I'll run a more specific `grep` search for "8723B" within `drivers/net/wireless/realtek/rtw88/Kconfig`. This should help me pinpoint if it exists, and where. It's best to verify this before jumping to any conclusions. This level of diligence prevents wasting time on things that are already present.



24/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "8723B"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 6163 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=5=$schema: http://devicetree.org/meta-schemas/core.yaml#\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-6-\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:7:title: RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS Bluetooth\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-8-\n--\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml=13=description:\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml:14:  RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part\nDocumentation/devicetree/bindings/net/bluetooth/realtek,bluetooth.yaml-15-  is connected over SDIO, while BT is connected over serial. It speaks\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts=282=\u0026uart0 {\n--\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-287-\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts:288:/* Used for RTL8723BS bluetooth */\narch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts-289-\u0026uart3 {\n--\narch/arm/boot/dts/amlogic/meson8b-ec100.dts=455=\u0026uart_AO {\n--\narch/arm/boot/dts/amlogic/meson8b-ec100.dts-461-/*\narch/arm/boot/dts/amlogic/meson8b-ec100.dts:462: * connected to the Bluetooth part of the RTL8723BS SDIO wifi / Bluetooth\narch/arm/boot/dts/amlogic/meson8b-ec100.dts-463- * combo chip. This is only available on the variant with 2GB RAM.\n--\narch/loongarch/configs/loongson32_defconfig=667=CONFIG_RTL8723AE=m\narch/loongarch/configs/loongson32_defconfig:668:CONFIG_RTL8723BE=m\narch/loongarch/configs/loongson32_defconfig-669-CONFIG_RTL8188EE=m\n--\narch/loongarch/configs/loongson64_defconfig=683=CONFIG_RTL8723AE=m\narch/loongarch/configs/loongson64_defconfig:684:CONFIG_RTL8723BE=m\narch/loongarch/configs/loongson64_defconfig-685-CONFIG_RTL8188EE=m\n--\ndrivers/bluetooth/btrtl.c-26-#define RTL_ROM_LMP_8723A\t0x1200\ndrivers/bluetooth/btrtl.c:27:#define RTL_ROM_LMP_8723B\t0x8723\ndrivers/bluetooth/btrtl.c-28-#define RTL_ROM_LMP_8821A\t0x8821\n--\ndrivers/bluetooth/btrtl.c=59=enum btrtl_chip_id {\ndrivers/bluetooth/btrtl.c-60-\tCHIP_ID_8723A,\ndrivers/bluetooth/btrtl.c:61:\tCHIP_ID_8723B,\ndrivers/bluetooth/btrtl.c-62-\tCHIP_ID_8821A,\n--\ndrivers/bluetooth/btrtl.c=106=static const struct id_table ic_id_table[] = {\n--\ndrivers/bluetooth/btrtl.c-114-\ndrivers/bluetooth/btrtl.c:115:\t/* 8723BS */\ndrivers/bluetooth/btrtl.c:116:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_UART),\ndrivers/bluetooth/btrtl.c-117-\t  .config_needed = true,\n--\ndrivers/bluetooth/btrtl.c-122-\ndrivers/bluetooth/btrtl.c:123:\t/* 8723B */\ndrivers/bluetooth/btrtl.c:124:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_USB),\ndrivers/bluetooth/btrtl.c-125-\t  .config_needed = false,\n--\ndrivers/bluetooth/btrtl.c-167-\t/* 8723D */\ndrivers/bluetooth/btrtl.c:168:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB),\ndrivers/bluetooth/btrtl.c-169-\t  .config_needed = true,\n--\ndrivers/bluetooth/btrtl.c-175-\t/* 8723DS */\ndrivers/bluetooth/btrtl.c:176:\t{ IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_UART),\ndrivers/bluetooth/btrtl.c-177-\t  .config_needed = true,\n--\ndrivers/bluetooth/btrtl.c=639=static int rtlbt_parse_firmware(struct hci_dev *hdev,\n--\ndrivers/bluetooth/btrtl.c-659-\t\t{ RTL_ROM_LMP_8723A, 0 },\ndrivers/bluetooth/btrtl.c:660:\t\t{ RTL_ROM_LMP_8723B, 1 },\ndrivers/bluetooth/btrtl.c-661-\t\t{ RTL_ROM_LMP_8821A, 2 },\n--\ndrivers/bluetooth/btrtl.c-664-\t\t{ RTL_ROM_LMP_8822B, 8 },\ndrivers/bluetooth/btrtl.c:665:\t\t{ RTL_ROM_LMP_8723B, 9 },\t/* 8723D */\ndrivers/bluetooth/btrtl.c-666-\t\t{ RTL_ROM_LMP_8821A, 10 },\t/* 8821C */\n--\ndrivers/bluetooth/btrtl.c=907=static int btrtl_setup_rtl8723a(struct hci_dev *hdev,\n--\ndrivers/bluetooth/btrtl.c-913-\t/* Check that the firmware doesn't have the epatch signature\ndrivers/bluetooth/btrtl.c:914:\t * (which is only for RTL8723B and newer).\ndrivers/bluetooth/btrtl.c-915-\t */\n--\ndrivers/bluetooth/btrtl.c=1257=int btrtl_download_firmware(struct hci_dev *hdev,\n--\ndrivers/bluetooth/btrtl.c-1277-\t\tbreak;\ndrivers/bluetooth/btrtl.c:1278:\tcase RTL_ROM_LMP_8723B:\ndrivers/bluetooth/btrtl.c-1279-\tcase RTL_ROM_LMP_8821A:\n--\ndrivers/bluetooth/btusb.c=180=static const struct usb_device_id quirks_table[] = {\n--\ndrivers/bluetooth/btusb.c-811-\ndrivers/bluetooth/btusb.c:812:\t/* Additional Realtek 8723BE Bluetooth devices */\ndrivers/bluetooth/btusb.c-813-\t{ USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK },\n--\ndrivers/bluetooth/btusb.c-820-\ndrivers/bluetooth/btusb.c:821:\t/* Additional Realtek 8723BU Bluetooth devices */\ndrivers/bluetooth/btusb.c-822-\t{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c=423=static void rtl8188eu_config_channel(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c-516-\t\tif (hw-\u003econf.chandef.width == NL80211_CHAN_WIDTH_40)\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c:517:\t\t\tval32 |= MODE_AG_BW_40MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c-518-\t\telse\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c:519:\t\t\tval32 |= MODE_AG_BW_20MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8188e.c-520-\t\trtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c=514=static void rtl8188fu_config_channel(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-619-\t    hw-\u003econf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:620:\t\tval32 |= MODE_AG_BW_20MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-621-\telse if (hw-\u003econf.chandef.width == NL80211_CHAN_WIDTH_40)\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:622:\t\tval32 |= MODE_AG_BW_40MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-623-\trtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c=645=static void rtl8188fu_init_aggregation(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-654-\trtl8xxxu_write32(priv, REG_DWBCN0_CTRL_8188F, val32);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:655:\trtl8xxxu_write8(priv, REG_DWBCN1_CTRL_8723B, usb_tx_agg_desc_num \u003c\u003c 1);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-656-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-664-\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:665:\trxdma_mode = rtl8xxxu_read8(priv, REG_RXDMA_PRO_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-666-\trxdma_mode \u0026= ~BIT(1);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-669-\trtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:670:\trtl8xxxu_write8(priv, REG_RXDMA_PRO_8723B, rxdma_mode);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-671-}\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c=673=static void rtl8188fu_init_statistics(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-677-\t/* Time duration for NHM unit: 4us, 0xc350=200ms */\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:678:\trtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:679:\trtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:680:\trtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:681:\trtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-682-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-688-\t/* Enable CCK */\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:689:\tval32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-690-\tval32 \u0026= ~(BIT(8) | BIT(9) | BIT(10));\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-691-\tval32 |= BIT(8);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c:692:\trtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32);\ndrivers/net/wireless/realtek/rtl8xxxu/8188f.c-693-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c=588=static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c-617-\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c:618:\tfor (i = 1; i \u003c RTL8723B_TX_COUNT; i++) {\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c-619-\t\tpriv-\u003eofdm_tx_power_diff[i].a =\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c=1629=static void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c-1644-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c:1645:\trtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04);\ndrivers/net/wireless/realtek/rtl8xxxu/8192e.c-1646-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c=584=static void rtl8192fu_config_channel(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c-645-\tif (ht40)\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c:646:\t\tval32 |= MODE_AG_BW_40MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c-647-\telse\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c:648:\t\tval32 |= MODE_AG_BW_20MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c-649-\trtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c=682=static int rtl8192fu_parse_efuse(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c-711-\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c:712:\tfor (i = 1; i \u003c RTL8723B_TX_COUNT; i++) {\ndrivers/net/wireless/realtek/rtl8xxxu/8192f.c-713-\t\tpriv-\u003eofdm_tx_power_diff[i].a =\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c=678=static void rtl8710bu_config_channel(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-778-\t\tval32 \u0026= ~MODE_AG_BW_MASK;\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:779:\t\tval32 |= MODE_AG_BW_40MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-780-\t\trtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-798-\t\tval32 \u0026= ~MODE_AG_BW_MASK;\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:799:\t\tval32 |= MODE_AG_BW_20MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-800-\t\trtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c=821=static void rtl8710bu_init_statistics(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-825-\t/* Time duration for NHM unit: 4us, 0xc350=200ms */\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:826:\trtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:827:\trtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:828:\trtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:829:\trtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-830-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-836-\t/* Enable CCK */\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:837:\tval32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-838-\tval32 \u0026= ~(BIT(8) | BIT(9) | BIT(10));\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-839-\tval32 |= BIT(8);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:840:\trtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32);\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-841-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c=1817=struct rtl8xxxu_fileops rtl8710bu_fops = {\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-1871-\t.mactable = rtl8710b_mac_init_table,\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:1872:\t.total_page_num = TX_TOTAL_PAGE_NUM_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:1873:\t.page_num_hi = TX_PAGE_NUM_HI_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:1874:\t.page_num_lo = TX_PAGE_NUM_LO_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c:1875:\t.page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8710b.c-1876-};\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=291=static int rtl8723bu_identify_chip(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-304-\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:305:\tstrscpy(priv-\u003echip_name, \"8723BU\", sizeof(priv-\u003echip_name));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:306:\tpriv-\u003ertl_chip = RTL8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-307-\tpriv-\u003erf_paths = 1;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=338=static void rtl8723bu_write_btreg(struct rtl8xxxu_priv *priv, u8 reg, u8 data)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-343-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:344:\th2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-345-\th2c.bt_mp_oper.operreq = 0 | (reqnum \u003c\u003c 4);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-351-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:352:\th2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-353-\th2c.bt_mp_oper.operreq = 0 | (reqnum \u003c\u003c 4);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=427=static int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-461-\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:462:\tfor (i = 1; i \u003c RTL8723B_TX_COUNT; i++) {\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-463-\t\tpriv-\u003eofdm_tx_power_diff[i].a =\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=575=static int rtl8723bu_iqk_path_a(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-639-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:640:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-641-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-649-\trtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:650:#ifdef RTL8723BU_BT\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-651-\t/* GNT_BT = 1 */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:652:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-653-#endif\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=685=static int rtl8723bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-749-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:750:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-751-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-759-\trtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:760:#ifdef RTL8723BU_BT\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-761-\t/* GNT_BT = 1 */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:762:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-763-#endif\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-848-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:849:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-850-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-858-\trtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:859:#ifdef RTL8723BU_BT\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-860-\t/* GNT_BT = 1 */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:861:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-862-#endif\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=894=static void rtl8723bu_phy_iqcalibrate(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-951-\t/*\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:952:\t * RX IQ calibration setting for 8723B D cut large current issue\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-953-\t * when leaving IPS\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=1102=static void rtl8723bu_phy_iq_calibrate(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1121-\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1122:\tbt_control = rtl8xxxu_read32(priv, REG_BT_CONTROL_8723BU);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1123-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1206-\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1207:\trtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, bt_control);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1208-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1220-\tif (priv-\u003erf_paths \u003e 1)\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1221:\t\tdev_dbg(dev, \"%s: 8723BU 2T not supported\\n\", __func__);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1222-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=1405=static int rtl8723bu_power_on(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1439-\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1440:\trtl8xxxu_write8(priv, REG_BT_CONTROL_8723BU + 1, 0x18);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1441:\trtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1442-\trtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=1503=static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1536-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1537:\th2c.bt_grant.cmd = H2C_8723B_BT_GRANT;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1538-\th2c.bt_grant.data = 0;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1543-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1544:\trtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x0c);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1545-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1580-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1581:\th2c.ant_sel_rsv.cmd = H2C_8723B_ANT_SEL_RSV;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1582-\th2c.ant_sel_rsv.ant_inverse = 1;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1606-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1607:\th2c.bt_info.cmd = H2C_8723B_BT_INFO;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1608-\th2c.bt_info.data = BIT(0);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1611-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1612:\th2c.ignore_wlan.cmd = H2C_8723B_BT_IGNORE_WLANACT;\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1613-\th2c.ignore_wlan.data = 0;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=1636=static void rtl8723bu_init_statistics(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1640-\t/* Time duration for NHM unit: 4us, 0x2710=40ms */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1641:\trtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0x2710);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1642:\trtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1643:\trtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff52);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1644:\trtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1645-\t/* TH8 */\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1649-\t/* Enable CCK */\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1650:\tval32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1651-\tval32 |= BIT(8) | BIT(9) | BIT(10);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1652:\trtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32);\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1653-\t/* Max power amongst all RX antennas */\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c=1710=struct rtl8xxxu_fileops rtl8723bu_fops = {\n--\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1763-\t.mactable = rtl8723b_mac_init_table,\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1764:\t.total_page_num = TX_TOTAL_PAGE_NUM_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1765:\t.page_num_hi = TX_PAGE_NUM_HI_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1766:\t.page_num_lo = TX_PAGE_NUM_LO_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c:1767:\t.page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/8723b.c-1768-};\n--\ndrivers/net/wireless/realtek/rtl8xxxu/Kconfig=5=config RTL8XXXU\n--\ndrivers/net/wireless/realtek/rtl8xxxu/Kconfig-12-\t  The driver is known to work with a number of RTL8723AU,\ndrivers/net/wireless/realtek/rtl8xxxu/Kconfig:13:\t  RL8188CU, RTL8188RU, RTL8191CU, RTL8192CU, RTL8723BU, RTL8192EU,\ndrivers/net/wireless/realtek/rtl8xxxu/Kconfig-14-\t  RTL8188FU, RTL8188EU, RTL8710BU (aka RTL8188GU), and RTL8192FU\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=868=u32 rtl8xxxu_read_rfreg(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-908-/*\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:909: * The RTL8723BU driver indicates that registers 0xb2 and 0xb6 can\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-910- * have write issues in high temperature conditions. We may have to\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=1001=rtl8xxxu_gen2_h2c_cmd(struct rtl8xxxu_priv *priv, struct h2c_cmd *h2c, int len)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1011-\tmbox_reg = REG_HMBOX_0 + (mbox_nr * 4);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:1012:\tmbox_ext_reg = REG_HMBOX_EXT0_8723B + (mbox_nr * 4);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1013-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=1329=void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1447-\t\tcase NL80211_CHAN_WIDTH_80:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:1448:\t\t\tval32 |= MODE_AG_BW_80MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1449-\t\t\tbreak;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1450-\t\tcase NL80211_CHAN_WIDTH_40:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:1451:\t\t\tval32 |= MODE_AG_BW_40MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1452-\t\t\tbreak;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1453-\t\tdefault:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:1454:\t\t\tval32 |= MODE_AG_BW_20MHZ_8723B;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-1455-\t\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=3388=void rtl8xxxu_gen2_prepare_calibrate(struct rtl8xxxu_priv *priv, u8 start)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3392-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3393:\th2c.bt_wlan_calibration.cmd = H2C_8723B_BT_WLAN_CALIBRATION;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3394-\th2c.bt_wlan_calibration.data = start;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=3792=void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3797-\tmemset(\u0026h2c, 0, sizeof(struct h2c_cmd));\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3798:\th2c.b_type_dma.cmd = H2C_8723B_B_TYPE_TDMA;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3799-\th2c.b_type_dma.data1 = arg1;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=3848=void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3854-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3855:\tval8 = rtl8xxxu_read8(priv, REG_RXDMA_PRO_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3856-\tu8p_replace_bits(\u0026val8, 1, RXDMA_PRO_DMA_BURST_SIZE);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3858-\tval8 |= RXDMA_PRO_DMA_MODE;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3859:\trtl8xxxu_write8(priv, REG_RXDMA_PRO_8723B, val8);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3860-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3863-\t */\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3864:\tval8 = rtl8xxxu_read8(priv, REG_HT_SINGLE_AMPDU_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3865-\tval8 |= HT_SINGLE_AMPDU_ENABLE;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3866:\trtl8xxxu_write8(priv, REG_HT_SINGLE_AMPDU_8723B, val8);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3867-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3868-\trtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, priv-\u003efops-\u003emax_aggr_num);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3869:\trtl8xxxu_write8(priv, REG_AMPDU_MAX_TIME_8723B,\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3870-\t\t\tpriv-\u003efops-\u003eampdu_max_time);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3878-\t}\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:3879:\trtl8xxxu_write8(priv, REG_USTIME_TSF_8723B, priv-\u003efops-\u003eustime_tsf_edca);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-3880-\trtl8xxxu_write8(priv, REG_USTIME_EDCA, priv-\u003efops-\u003eustime_tsf_edca);\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=3959=static int rtl8xxxu_init_device(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4050-\t/* RFSW Control - clear bit 14 ?? */\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4051:\tif (priv-\u003ertl_chip != RTL8723B \u0026\u0026 priv-\u003ertl_chip != RTL8192E \u0026\u0026\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4052-\t    priv-\u003ertl_chip != RTL8188E \u0026\u0026 priv-\u003ertl_chip != RTL8710B \u0026\u0026\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4347-\t\tif (priv-\u003ertl_chip == RTL8188F || priv-\u003ertl_chip == RTL8710B) {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4348:\t\t\tval32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_T_METER_8723B);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4349-\t\t\tval32 |= 0x30000;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4350:\t\t\trtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_T_METER_8723B, val32);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4351-\t\t} else {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4352-\t\t\trtl8xxxu_write_rfreg(priv,\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4353:\t\t\t\t\t     RF_A, RF6052_REG_T_METER_8723B, 0x37cf8);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4354-\t\t}\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=4564=void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4577-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4578:\th2c.b_macid_cfg.cmd = H2C_8723B_MACID_CFG_RAID;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4579-\th2c.b_macid_cfg.ramask0 = ramask \u0026 0xff;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=4613=void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4623-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4624:\th2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4625-\tif (connect)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=4650=void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4654-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4655:\tif (priv-\u003ertl_chip == RTL8723B)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4656-\t\th2c_size = 4;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4659-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:4660:\th2c.rssi_report.cmd = H2C_8723B_RSSI_SETTING;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-4661-\th2c.rssi_report.macid = macid;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=5611=static void rtl8xxxu_send_beacon_frame(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5625-\t/* SW_BCN_SEL - Port0 */\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5626:\tval8 = rtl8xxxu_read8(priv, REG_DWBCN1_CTRL_8723B + 2);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5627-\tval8 \u0026= ~(BIT_SW_BCN_SEL \u003e\u003e 16);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5628:\trtl8xxxu_write8(priv, REG_DWBCN1_CTRL_8723B + 2, val8);\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5629-\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=5861=static void rtl8xxxu_rx_urb_work(struct work_struct *work)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5905-/*\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5906: * The RTL8723BU/RTL8192EU vendor driver use coexistence table type\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5907- * 0-7 to represent writing different combinations of register values\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=5965=void rtl8723bu_update_bt_link_info(struct rtl8xxxu_priv *priv, u8 bt_info)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5968-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5969:\tif (bt_info \u0026 BT_INFO_8723B_1ANT_B_INQ_PAGE)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5970-\t\tbtcoex-\u003ec2h_bt_inquiry = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5973-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5974:\tif (!(bt_info \u0026 BT_INFO_8723B_1ANT_B_CONNECTION)) {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5975:\t\tbtcoex-\u003ebt_status = BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5976-\t\tbtcoex-\u003ehas_sco = false;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5980-\t} else {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5981:\t\tif ((bt_info \u0026 0x1f) == BT_INFO_8723B_1ANT_B_CONNECTION)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5982:\t\t\tbtcoex-\u003ebt_status = BT_8723B_1ANT_STATUS_CONNECTED_IDLE;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5983:\t\telse if ((bt_info \u0026 BT_INFO_8723B_1ANT_B_SCO_ESCO) ||\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5984:\t\t\t (bt_info \u0026 BT_INFO_8723B_1ANT_B_SCO_BUSY))\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5985:\t\t\tbtcoex-\u003ebt_status = BT_8723B_1ANT_STATUS_SCO_BUSY;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5986:\t\telse if (bt_info \u0026 BT_INFO_8723B_1ANT_B_ACL_BUSY)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5987:\t\t\tbtcoex-\u003ebt_status = BT_8723B_1ANT_STATUS_ACL_BUSY;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5988-\t\telse\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5989:\t\t\tbtcoex-\u003ebt_status = BT_8723B_1ANT_STATUS_MAX;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5990-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5991:\t\tif (bt_info \u0026 BT_INFO_8723B_1ANT_B_FTP)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5992-\t\t\tbtcoex-\u003ehas_pan = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5995-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:5996:\t\tif (bt_info \u0026 BT_INFO_8723B_1ANT_B_A2DP)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-5997-\t\t\tbtcoex-\u003ehas_a2dp = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6000-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6001:\t\tif (bt_info \u0026 BT_INFO_8723B_1ANT_B_HID)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6002-\t\t\tbtcoex-\u003ehas_hid = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6005-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6006:\t\tif (bt_info \u0026 BT_INFO_8723B_1ANT_B_SCO_ESCO)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6007-\t\t\tbtcoex-\u003ehas_sco = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6023-\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6024:\tif (btcoex-\u003ebt_status == BT_8723B_1ANT_STATUS_SCO_BUSY ||\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6025:\t    btcoex-\u003ebt_status == BT_8723B_1ANT_STATUS_ACL_BUSY)\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6026-\t\tbtcoex-\u003ebt_busy = true;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=6111=static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6130-\t\tswitch (c2h-\u003eid) {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6131:\t\tcase C2H_8723B_BT_INFO:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6132-\t\t\tbt_info = c2h-\u003ebt_info.bt_info;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6140-\t\t\tbreak;\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6141:\t\tcase C2H_8723B_RA_REPORT:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6142-\t\t\tbw = rarpt-\u003etxrate.bw;\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c=6162=static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,\n--\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6174-\tswitch(c2h-\u003eid) {\ndrivers/net/wireless/realtek/rtl8xxxu/core.c:6175:\tcase C2H_8723B_BT_INFO:\ndrivers/net/wireless/realtek/rtl8xxxu/core.c-6176-\t\tif (c2h-\u003ebt_info.response_source \u003e\n\n"
}

25/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 95963
							output: 40
							thoughts: 135
						

Thoughts:
**Locating the RTW88_8723BS Definition**

Okay, so I was looking for the `RTW88_8723BS` definition, and my first instinct was to check the `drivers/net/wireless/realtek/rtw88/Kconfig` file. But hold on... I did a quick grep for "8723B" in the whole project tree, but that's not what I intended. I should have been more precise. I need to focus that grep within the `Kconfig` file itself to avoid false positives. So, back to the console – time to narrow that search down specifically to the `drivers/net/wireless/realtek/rtw88/Kconfig` file.



26/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "8723",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/Kconfig"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/Kconfig=29=config RTW88_8822C\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-31-\ndrivers/net/wireless/realtek/rtw88/Kconfig:32:config RTW88_8723X\ndrivers/net/wireless/realtek/rtw88/Kconfig-33-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig=35=config RTW88_8703B\ndrivers/net/wireless/realtek/rtw88/Kconfig-36-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig:37:\tselect RTW88_8723X\ndrivers/net/wireless/realtek/rtw88/Kconfig-38-\ndrivers/net/wireless/realtek/rtw88/Kconfig:39:config RTW88_8723D\ndrivers/net/wireless/realtek/rtw88/Kconfig-40-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig:41:\tselect RTW88_8723X\ndrivers/net/wireless/realtek/rtw88/Kconfig-42-\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig=115=config RTW88_8822CU\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-125-\ndrivers/net/wireless/realtek/rtw88/Kconfig:126:config RTW88_8723DE\ndrivers/net/wireless/realtek/rtw88/Kconfig:127:\ttristate \"Realtek 8723DE PCI wireless network adapter\"\ndrivers/net/wireless/realtek/rtw88/Kconfig-128-\tdepends on PCI\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-130-\tselect RTW88_PCI\ndrivers/net/wireless/realtek/rtw88/Kconfig:131:\tselect RTW88_8723D\ndrivers/net/wireless/realtek/rtw88/Kconfig-132-\thelp\ndrivers/net/wireless/realtek/rtw88/Kconfig:133:\t  Select this option will enable support for 8723DE chipset\ndrivers/net/wireless/realtek/rtw88/Kconfig-134-\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-136-\ndrivers/net/wireless/realtek/rtw88/Kconfig:137:config RTW88_8723DS\ndrivers/net/wireless/realtek/rtw88/Kconfig:138:\ttristate \"Realtek 8723DS SDIO wireless network adapter\"\ndrivers/net/wireless/realtek/rtw88/Kconfig-139-\tdepends on MMC\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-141-\tselect RTW88_SDIO\ndrivers/net/wireless/realtek/rtw88/Kconfig:142:\tselect RTW88_8723D\ndrivers/net/wireless/realtek/rtw88/Kconfig-143-\thelp\ndrivers/net/wireless/realtek/rtw88/Kconfig:144:\t  Select this option will enable support for 8723DS chipset\ndrivers/net/wireless/realtek/rtw88/Kconfig-145-\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-147-\ndrivers/net/wireless/realtek/rtw88/Kconfig:148:config RTW88_8723CS\ndrivers/net/wireless/realtek/rtw88/Kconfig:149:\ttristate \"Realtek 8723CS SDIO wireless network adapter\"\ndrivers/net/wireless/realtek/rtw88/Kconfig-150-\tdepends on MMC\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-154-\thelp\ndrivers/net/wireless/realtek/rtw88/Kconfig:155:\t  Select this option to enable support for 8723CS chipset (EXPERIMENTAL)\ndrivers/net/wireless/realtek/rtw88/Kconfig-156-\ndrivers/net/wireless/realtek/rtw88/Kconfig:157:\t  This module adds support for the 8723CS 802.11n SDIO\ndrivers/net/wireless/realtek/rtw88/Kconfig-158-\t  wireless network adapter.\ndrivers/net/wireless/realtek/rtw88/Kconfig-159-\ndrivers/net/wireless/realtek/rtw88/Kconfig:160:\t  If you choose to build a module, it'll be called rtw88_8723cs.\ndrivers/net/wireless/realtek/rtw88/Kconfig-161-\ndrivers/net/wireless/realtek/rtw88/Kconfig:162:config RTW88_8723DU\ndrivers/net/wireless/realtek/rtw88/Kconfig:163:\ttristate \"Realtek 8723DU USB wireless network adapter\"\ndrivers/net/wireless/realtek/rtw88/Kconfig-164-\tdepends on USB\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-166-\tselect RTW88_USB\ndrivers/net/wireless/realtek/rtw88/Kconfig:167:\tselect RTW88_8723D\ndrivers/net/wireless/realtek/rtw88/Kconfig-168-\thelp\ndrivers/net/wireless/realtek/rtw88/Kconfig:169:\t  Select this option will enable support for 8723DU chipset\ndrivers/net/wireless/realtek/rtw88/Kconfig-170-\n"
}

27/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 97859
							output: 41
							thoughts: 201
						

Thoughts:
**Investigating the Missing Configuration**

Okay, so I'm looking through this `rtw88` driver code, and I can't find the configuration symbol `RTW88_8723BS` in the `Kconfig` file. That's a bit strange. Could the patch that introduced this functionality have added it? Let me quickly re-examine the patch diff, just to be sure I didn't miss something. Nope, the diff doesn't seem to touch either `Kconfig` or `Makefile`. Now, that really throws me for a loop. If `rtw_is_8723bs` is defined somewhere, but there's no corresponding configuration option or source file like `rtw8723bs.c`, how on earth is this code getting compiled? Unless... wait a minute. Is this part of a larger patch series? Perhaps the file `rtw8723bs.c` was added in a *different* patch upstream. But the prompt specifies that these changes have *already* been integrated into the HEAD commit, so the code should all be present in my workspace. Let's start with the most basic thing - is the source file `rtw8723bs.c` in the workspace at all? Time to take a look.



28/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "rtw8723bs",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac80211.c-21- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:22:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-23-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-46-}\ndrivers/net/wireless/realtek/rtw88/mac80211.c:47:EXPORT_SYMBOL(rtw8723bs_auth_sync_rx);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-48-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-81- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:82:static void rtw8723bs_auth_rx_filter(struct rtw_dev *rtwdev, bool accept_all)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-83-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-88-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:89:static void rtw8723bs_config_sec_cfg(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-90-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-96-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:97:static void rtw8723bs_config_default_key_search(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-98-\t\t\t\t\t\tbool enable)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-110-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:111:static void rtw8723bs_enable_tsf_update(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-112-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-115-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:116:static void rtw8723bs_set_ack_preamble(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-117-\t\t\t\t       bool short_preamble)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-125-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:126:static void rtw8723bs_set_slot_time(struct rtw_dev *rtwdev, bool short_slot)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-127-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-132-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:133:static u16 rtw8723bs_rrsr_from_ie_rate(u8 rate)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-134-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-151-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:152:static void rtw8723bs_collect_basic_rates(const u8 *ie, u16 *basic_rates,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-153-\t\t\t\t\t  bool *valid)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-164-\t\t\tcontinue;\ndrivers/net/wireless/realtek/rtw88/mac80211.c:165:\t\tr = rtw8723bs_rrsr_from_ie_rate(ie[i + 2]);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-166-\t\tif (!r)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-172-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:173:static void rtw8723bs_reset_response_rates(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-174-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-178-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:179:static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-180-\t\t\t\t\tstruct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-207-\t\text = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:208:\t\trtw8723bs_collect_basic_rates(rates, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:209:\t\trtw8723bs_collect_basic_rates(ext, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-210-\t\trcu_read_unlock();\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-229- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:230:static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-231-\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-266-\tif (set_preamble)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:267:\t\trtw8723bs_set_ack_preamble(rtwdev, short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:268:\trtw8723bs_set_slot_time(rtwdev, short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-269-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-273-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:274:static unsigned int rtw8723bs_auth_sync_wait_ms(struct ieee80211_vif *vif)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-275-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-286-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:287:static void rtw8723bs_auth_sync_start(struct rtw_dev *rtwdev, const u8 *bssid)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-288-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-299-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:300:static void rtw8723bs_auth_sync_stop(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-301-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-309-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:310:static bool rtw8723bs_auth_sync_seen(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-311-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-322-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:323:static bool rtw8723bs_auth_sync_wait(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-324-\t\t\t\t     unsigned int wait_ms)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-327-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:328:\treturn wait_event_timeout(sync-\u003ewait, rtw8723bs_auth_sync_seen(rtwdev),\ndrivers/net/wireless/realtek/rtw88/mac80211.c-329-\t\t\t\t  msecs_to_jiffies(wait_ms)) \u003e 0;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-331-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:332:static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-333-\t\t\t\t\t  struct ieee80211_prep_tx_info *info)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-341- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:342:static bool rtw8723bs_mgd_prepare_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-343-\t\t\t\t       struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-364-\t */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:365:\trtw8723bs_apply_bss_cap(rtwdev, vif, bssid, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-366-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-382-\trtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:383:\trtw8723bs_auth_rx_filter(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-384-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-388-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:389:\trtw8723bs_config_sec_cfg(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-390-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-396- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:397:static void rtw8723bs_tx_pre_auth_deauth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-398-\t\t\t\t\t struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-434- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:435:static void rtw8723bs_mgd_prepare_auth_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-436-\t\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-442-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:443:\tif (!rtw8723bs_mgd_prepare_is_auth(rtwdev, info) || !vif ||\ndrivers/net/wireless/realtek/rtw88/mac80211.c-444-\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags))\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-456-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:457:\tfresh_join = rtw8723bs_mgd_prepare_join(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-458-\ndrivers/net/wireless/realtek/rtw88/mac80211.c-459-\tif (fresh_join || !rtwvif-\u003epre_auth_join_done) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:460:\t\tunsigned int wait_ms = rtw8723bs_auth_sync_wait_ms(vif);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-461-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:462:\t\trtw8723bs_auth_sync_start(rtwdev, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:463:\t\trtw8723bs_tx_pre_auth_deauth(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:464:\t\trtw8723bs_auth_sync_wait(rtwdev, wait_ms);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:465:\t\trtw8723bs_auth_sync_stop(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-466-\t\trtwvif-\u003epre_auth_join_done = true;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=829=static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-848-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:849:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:850:\t\t\t\trtw8723bs_apply_bss_cap(rtwdev, vif, NULL, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:851:\t\t\t\trtw8723bs_apply_basic_rates(rtwdev, vif, NULL);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:852:\t\t\t\trtw8723bs_enable_tsf_update(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-853-\t\t\t\t/* Vendor mlmeext_joinbss sends MACID_CFG before\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-891-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:892:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:893:\t\t\t\trtw8723bs_reset_response_rates(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-894-\t\t\t\trtwvif-\u003epre_auth_h2c_sent = false;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-957-\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:958:\t\trtw8723bs_set_ack_preamble(rtwdev, conf-\u003euse_short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-959-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-962-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:963:\t\t\trtw8723bs_set_slot_time(rtwdev, conf-\u003euse_short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-964-\t\trtw_conf_tx(rtwdev, rtwvif);\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1064=static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1127-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1128:\t\t\trtw8723bs_config_default_key_search(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1129-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1136-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1137:\t\t\trtw8723bs_config_default_key_search(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1138-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1219=static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1237-\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1238:\t\trtw8723bs_mgd_prepare_auth_join(rtwdev, vif, info);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1239-\t} else {\n--\ndrivers/net/wireless/realtek/rtw88/main.c=44=MODULE_PARM_DESC(debug_mask, \"Debugging mask\");\n--\ndrivers/net/wireless/realtek/rtw88/main.c-48-\ndrivers/net/wireless/realtek/rtw88/main.c:49:struct rtw8723bs_txagc_entry {\ndrivers/net/wireless/realtek/rtw88/main.c-50-\tu8 rate;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-54-/* Vendor/staging per-rate TXAGC PG bytes for 8723BS 2.4 GHz. */\ndrivers/net/wireless/realtek/rtw88/main.c:55:static const struct rtw8723bs_txagc_entry rtw8723bs_pg_txagc[] = {\ndrivers/net/wireless/realtek/rtw88/main.c-56-\t{ DESC_RATE1M, 0x38 }, { DESC_RATE2M, 0x36 },\n--\ndrivers/net/wireless/realtek/rtw88/main.c=69=static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-80- */\ndrivers/net/wireless/realtek/rtw88/main.c:81:static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-82-{\n--\ndrivers/net/wireless/realtek/rtw88/main.c-91-\tfor (path = 0; path \u003c hal-\u003erf_path_num \u0026\u0026 path \u003c RTW_RF_PATH_MAX; path++)\ndrivers/net/wireless/realtek/rtw88/main.c:92:\t\tfor (i = 0; i \u003c ARRAY_SIZE(rtw8723bs_pg_txagc); i++)\ndrivers/net/wireless/realtek/rtw88/main.c:93:\t\t\thal-\u003etx_pwr_tbl[path][rtw8723bs_pg_txagc[i].rate] =\ndrivers/net/wireless/realtek/rtw88/main.c:94:\t\t\t\trtw8723bs_pg_txagc[i].pwr_idx;\ndrivers/net/wireless/realtek/rtw88/main.c-95-\trtwdev-\u003echip-\u003eops-\u003eset_tx_power_index(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=103=static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-128-\ndrivers/net/wireless/realtek/rtw88/main.c:129:static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-130-\t\t\t\t\t   struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-139- */\ndrivers/net/wireless/realtek/rtw88/main.c:140:static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-141-\t\t\t\t\t     struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-143-{\ndrivers/net/wireless/realtek/rtw88/main.c:144:\treturn rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-145-\t       !vif-\u003ecfg.assoc;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=459=int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-483-\trtw_update_sta_info(rtwdev, si, true);\ndrivers/net/wireless/realtek/rtw88/main.c:484:\tif (rtw8723bs_defer_sta_media_status(rtwdev, sta, vif)) {\ndrivers/net/wireless/realtek/rtw88/main.c-485-\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-487-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, true);\ndrivers/net/wireless/realtek/rtw88/main.c:488:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-489-\t\t\trtwvif-\u003efw_media_connected = true;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=500=void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-511-\t\trtw_release_macid(rtwdev, si-\u003emac_id);\ndrivers/net/wireless/realtek/rtw88/main.c:512:\tif (fw_exist \u0026\u0026 rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-513-\t    !rtwvif-\u003efw_media_connected) {\n--\ndrivers/net/wireless/realtek/rtw88/main.c-516-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, false);\ndrivers/net/wireless/realtek/rtw88/main.c:517:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-518-\t\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=998=void rtw_set_channel(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1033-\ndrivers/net/wireless/realtek/rtw88/main.c:1034:\trtw8723bs_reapply_pg_txagc(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1035-\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2315=void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/realtek/rtw88/main.h-2316-\t\t\t  struct ieee80211_bss_conf *bss_conf);\ndrivers/net/wireless/realtek/rtw88/main.h:2317:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.h-2318-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1252=static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1270-\tif (skb-\u003elen \u003e= sizeof(struct ieee80211_hdr_3addr))\ndrivers/net/wireless/realtek/rtw88/sdio.c:1271:\t\trtw8723bs_auth_sync_rx(rtwdev,\ndrivers/net/wireless/realtek/rtw88/sdio.c-1272-\t\t\t\t       (struct ieee80211_hdr *)skb-\u003edata,\n"
}

29/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 106234
							output: 41
							thoughts: 110
						

Thoughts:
**Analyzing the Realtek Driver Code**

Okay, so I'm diving into this Realtek driver code, specifically looking at `rtw8723bs`. Interesting – it's not a standalone file, which is a bit unusual. The patch I'm examining introduces `rtw_is_8723bs` and then strategically weaves it into the existing codebase. I'm seeing this function being called within `mac80211.c`, `main.c`, `sdio.c`, and other critical modules. That definitely warrants a closer look. Now I wonder, is there a separate file for the `rtw8723b` variant? It would make sense to have that delineation. Let me take a peek at `drivers/net/wireless/realtek/rtw88/rtw8723b.c` to confirm.



30/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "rtw8723b",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac80211.c-21- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:22:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-23-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-46-}\ndrivers/net/wireless/realtek/rtw88/mac80211.c:47:EXPORT_SYMBOL(rtw8723bs_auth_sync_rx);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-48-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-81- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:82:static void rtw8723bs_auth_rx_filter(struct rtw_dev *rtwdev, bool accept_all)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-83-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-88-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:89:static void rtw8723bs_config_sec_cfg(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-90-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-96-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:97:static void rtw8723bs_config_default_key_search(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-98-\t\t\t\t\t\tbool enable)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-110-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:111:static void rtw8723bs_enable_tsf_update(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-112-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-115-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:116:static void rtw8723bs_set_ack_preamble(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-117-\t\t\t\t       bool short_preamble)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-125-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:126:static void rtw8723bs_set_slot_time(struct rtw_dev *rtwdev, bool short_slot)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-127-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-132-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:133:static u16 rtw8723bs_rrsr_from_ie_rate(u8 rate)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-134-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-151-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:152:static void rtw8723bs_collect_basic_rates(const u8 *ie, u16 *basic_rates,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-153-\t\t\t\t\t  bool *valid)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-164-\t\t\tcontinue;\ndrivers/net/wireless/realtek/rtw88/mac80211.c:165:\t\tr = rtw8723bs_rrsr_from_ie_rate(ie[i + 2]);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-166-\t\tif (!r)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-172-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:173:static void rtw8723bs_reset_response_rates(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-174-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-178-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:179:static void rtw8723bs_apply_basic_rates(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-180-\t\t\t\t\tstruct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-207-\t\text = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:208:\t\trtw8723bs_collect_basic_rates(rates, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:209:\t\trtw8723bs_collect_basic_rates(ext, \u0026basic_rates, \u0026valid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-210-\t\trcu_read_unlock();\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-229- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:230:static void rtw8723bs_apply_bss_cap(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-231-\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-266-\tif (set_preamble)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:267:\t\trtw8723bs_set_ack_preamble(rtwdev, short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:268:\trtw8723bs_set_slot_time(rtwdev, short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-269-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-273-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:274:static unsigned int rtw8723bs_auth_sync_wait_ms(struct ieee80211_vif *vif)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-275-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-286-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:287:static void rtw8723bs_auth_sync_start(struct rtw_dev *rtwdev, const u8 *bssid)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-288-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-299-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:300:static void rtw8723bs_auth_sync_stop(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-301-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-309-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:310:static bool rtw8723bs_auth_sync_seen(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac80211.c-311-{\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-322-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:323:static bool rtw8723bs_auth_sync_wait(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-324-\t\t\t\t     unsigned int wait_ms)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-327-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:328:\treturn wait_event_timeout(sync-\u003ewait, rtw8723bs_auth_sync_seen(rtwdev),\ndrivers/net/wireless/realtek/rtw88/mac80211.c-329-\t\t\t\t  msecs_to_jiffies(wait_ms)) \u003e 0;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-331-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:332:static bool rtw8723bs_mgd_prepare_is_auth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-333-\t\t\t\t\t  struct ieee80211_prep_tx_info *info)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-341- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:342:static bool rtw8723bs_mgd_prepare_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-343-\t\t\t\t       struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-364-\t */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:365:\trtw8723bs_apply_bss_cap(rtwdev, vif, bssid, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-366-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-382-\trtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:383:\trtw8723bs_auth_rx_filter(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-384-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-388-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:389:\trtw8723bs_config_sec_cfg(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-390-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-396- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:397:static void rtw8723bs_tx_pre_auth_deauth(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-398-\t\t\t\t\t struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-434- */\ndrivers/net/wireless/realtek/rtw88/mac80211.c:435:static void rtw8723bs_mgd_prepare_auth_join(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac80211.c-436-\t\t\t\t\t    struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-442-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:443:\tif (!rtw8723bs_mgd_prepare_is_auth(rtwdev, info) || !vif ||\ndrivers/net/wireless/realtek/rtw88/mac80211.c-444-\t    test_bit(RTW_FLAG_SCANNING, rtwdev-\u003eflags))\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-456-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:457:\tfresh_join = rtw8723bs_mgd_prepare_join(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-458-\ndrivers/net/wireless/realtek/rtw88/mac80211.c-459-\tif (fresh_join || !rtwvif-\u003epre_auth_join_done) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:460:\t\tunsigned int wait_ms = rtw8723bs_auth_sync_wait_ms(vif);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-461-\ndrivers/net/wireless/realtek/rtw88/mac80211.c:462:\t\trtw8723bs_auth_sync_start(rtwdev, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:463:\t\trtw8723bs_tx_pre_auth_deauth(rtwdev, vif, bssid);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:464:\t\trtw8723bs_auth_sync_wait(rtwdev, wait_ms);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:465:\t\trtw8723bs_auth_sync_stop(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-466-\t\trtwvif-\u003epre_auth_join_done = true;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=829=static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-848-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:849:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:850:\t\t\t\trtw8723bs_apply_bss_cap(rtwdev, vif, NULL, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:851:\t\t\t\trtw8723bs_apply_basic_rates(rtwdev, vif, NULL);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:852:\t\t\t\trtw8723bs_enable_tsf_update(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-853-\t\t\t\t/* Vendor mlmeext_joinbss sends MACID_CFG before\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-891-\t\t\t    vif-\u003etype == NL80211_IFTYPE_STATION) {\ndrivers/net/wireless/realtek/rtw88/mac80211.c:892:\t\t\t\trtw8723bs_auth_rx_filter(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:893:\t\t\t\trtw8723bs_reset_response_rates(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-894-\t\t\t\trtwvif-\u003epre_auth_h2c_sent = false;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-957-\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:958:\t\trtw8723bs_set_ack_preamble(rtwdev, conf-\u003euse_short_preamble);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-959-\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-962-\t\t    vif-\u003etype == NL80211_IFTYPE_STATION)\ndrivers/net/wireless/realtek/rtw88/mac80211.c:963:\t\t\trtw8723bs_set_slot_time(rtwdev, conf-\u003euse_short_slot);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-964-\t\trtw_conf_tx(rtwdev, rtwvif);\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1064=static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1127-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1128:\t\t\trtw8723bs_config_default_key_search(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1129-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1136-\t\t    !(key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1137:\t\t\trtw8723bs_config_default_key_search(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1138-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c=1219=static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1237-\t\trtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:1238:\t\trtw8723bs_mgd_prepare_auth_join(rtwdev, vif, info);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-1239-\t} else {\n--\ndrivers/net/wireless/realtek/rtw88/main.c=44=MODULE_PARM_DESC(debug_mask, \"Debugging mask\");\n--\ndrivers/net/wireless/realtek/rtw88/main.c-48-\ndrivers/net/wireless/realtek/rtw88/main.c:49:struct rtw8723bs_txagc_entry {\ndrivers/net/wireless/realtek/rtw88/main.c-50-\tu8 rate;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-54-/* Vendor/staging per-rate TXAGC PG bytes for 8723BS 2.4 GHz. */\ndrivers/net/wireless/realtek/rtw88/main.c:55:static const struct rtw8723bs_txagc_entry rtw8723bs_pg_txagc[] = {\ndrivers/net/wireless/realtek/rtw88/main.c-56-\t{ DESC_RATE1M, 0x38 }, { DESC_RATE2M, 0x36 },\n--\ndrivers/net/wireless/realtek/rtw88/main.c=69=static void rtw_scan_set_8723bs_igi(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-80- */\ndrivers/net/wireless/realtek/rtw88/main.c:81:static void rtw8723bs_reapply_pg_txagc(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-82-{\n--\ndrivers/net/wireless/realtek/rtw88/main.c-91-\tfor (path = 0; path \u003c hal-\u003erf_path_num \u0026\u0026 path \u003c RTW_RF_PATH_MAX; path++)\ndrivers/net/wireless/realtek/rtw88/main.c:92:\t\tfor (i = 0; i \u003c ARRAY_SIZE(rtw8723bs_pg_txagc); i++)\ndrivers/net/wireless/realtek/rtw88/main.c:93:\t\t\thal-\u003etx_pwr_tbl[path][rtw8723bs_pg_txagc[i].rate] =\ndrivers/net/wireless/realtek/rtw88/main.c:94:\t\t\t\trtw8723bs_pg_txagc[i].pwr_idx;\ndrivers/net/wireless/realtek/rtw88/main.c-95-\trtwdev-\u003echip-\u003eops-\u003eset_tx_power_index(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=103=static void rtw_power_on_8723bs_sdio_rfk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-128-\ndrivers/net/wireless/realtek/rtw88/main.c:129:static bool rtw8723bs_station_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-130-\t\t\t\t\t   struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-139- */\ndrivers/net/wireless/realtek/rtw88/main.c:140:static bool rtw8723bs_defer_sta_media_status(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.c-141-\t\t\t\t\t     struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-143-{\ndrivers/net/wireless/realtek/rtw88/main.c:144:\treturn rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-145-\t       !vif-\u003ecfg.assoc;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=459=int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-483-\trtw_update_sta_info(rtwdev, si, true);\ndrivers/net/wireless/realtek/rtw88/main.c:484:\tif (rtw8723bs_defer_sta_media_status(rtwdev, sta, vif)) {\ndrivers/net/wireless/realtek/rtw88/main.c-485-\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c-487-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, true);\ndrivers/net/wireless/realtek/rtw88/main.c:488:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-489-\t\t\trtwvif-\u003efw_media_connected = true;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=500=void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-511-\t\trtw_release_macid(rtwdev, si-\u003emac_id);\ndrivers/net/wireless/realtek/rtw88/main.c:512:\tif (fw_exist \u0026\u0026 rtw8723bs_station_media_status(rtwdev, sta, vif) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-513-\t    !rtwvif-\u003efw_media_connected) {\n--\ndrivers/net/wireless/realtek/rtw88/main.c-516-\t\trtw_fw_media_status_report(rtwdev, si-\u003emac_id, false);\ndrivers/net/wireless/realtek/rtw88/main.c:517:\t\tif (rtw8723bs_station_media_status(rtwdev, sta, vif))\ndrivers/net/wireless/realtek/rtw88/main.c-518-\t\t\trtwvif-\u003efw_media_connected = false;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=998=void rtw_set_channel(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1033-\ndrivers/net/wireless/realtek/rtw88/main.c:1034:\trtw8723bs_reapply_pg_txagc(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1035-\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2315=void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/realtek/rtw88/main.h-2316-\t\t\t  struct ieee80211_bss_conf *bss_conf);\ndrivers/net/wireless/realtek/rtw88/main.h:2317:void rtw8723bs_auth_sync_rx(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/main.h-2318-\t\t\t    const struct ieee80211_hdr *hdr, u32 len,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=1252=static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-1270-\tif (skb-\u003elen \u003e= sizeof(struct ieee80211_hdr_3addr))\ndrivers/net/wireless/realtek/rtw88/sdio.c:1271:\t\trtw8723bs_auth_sync_rx(rtwdev,\ndrivers/net/wireless/realtek/rtw88/sdio.c-1272-\t\t\t\t       (struct ieee80211_hdr *)skb-\u003edata,\n"
}

31/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 114428
							output: 47
							thoughts: 365
						

Thoughts:
**Analyzing the Introduction of RTW_CHIP_TYPE_8723B**

Okay, so I see that `RTW_CHIP_TYPE_8723B` has been added to the `enum rtw_chip_type` in `main.h`. My immediate thought is, "Wait a minute, where's the corresponding source file?  There's no `rtw8723b.c` or `rtw8723bs.c` in the `rtw88` directory." How does the driver even build without it? This seems like an incomplete piece, or perhaps part of a larger changeset.

My initial assumption is that this patch is part of a series; maybe the file addition comes in a later patch, and this one is focusing specifically on adding SDIO-specific quirks related to the new chip type. That would make some sense.

Now, let's look at this `rtw_is_8723bs` function:

```c
static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)
{
	return rtwdev->chip->id == RTW_CHIP_TYPE_8723B &&
	       rtwdev->hci.type == RTW_HCI_TYPE_SDIO;
}
```

Since the addition of `RTW_CHIP_TYPE_8723B` is happening *right here*, if no other code in the tree can possibly set `rtwdev->chip->id` to `RTW_CHIP_TYPE_8723B` unless it's in this patch itself or a later patch. It seems like the condition for this chip type is not yet satisfied.

I should probably look and see *where else* this is being used. Let's trace usage of `RTW_CHIP_TYPE_8723B` to see where it gets set. That'll be the key to understanding this.



32/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.h=191=enum rtw_chip_type {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-196-\tRTW_CHIP_TYPE_8703B,\ndrivers/net/wireless/realtek/rtw88/main.h:197:\tRTW_CHIP_TYPE_8723B,\ndrivers/net/wireless/realtek/rtw88/main.h-198-\tRTW_CHIP_TYPE_8821A,\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2221=static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\ndrivers/net/wireless/realtek/rtw88/main.h:2223:\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.h-2224-\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n--\ndrivers/net/wireless/realtek/rtw88/rx.c=197=static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rx.c-259-\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\ndrivers/net/wireless/realtek/rtw88/rx.c:260:\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rx.c-261-\t    pkt_stat-\u003epkt_len == 0) {\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=885=static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-889-\tswitch (rtwdev-\u003echip-\u003eid) {\ndrivers/net/wireless/realtek/rtw88/sdio.c:890:\tcase RTW_CHIP_TYPE_8723B:\ndrivers/net/wireless/realtek/rtw88/sdio.c-891-\tcase RTW_CHIP_TYPE_8703B:\n"
}

33/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 115955
							output: 49
							thoughts: 107
						

Thoughts:
**Investigating the RTW_CHIP_TYPE_8723B Implementation**

Okay, so I'm looking at this `RTW_CHIP_TYPE_8723B` definition, and I'm a bit perplexed. I see it referenced in `main.h`, `rx.c`, and `sdio.c`. Standard places, makes sense. But... I don't see any driver file explicitly *registering* or declaring a device that uses this chip ID, like an `rtw8723b.c` or `rtw8723bs.c`. That's unusual. It strongly suggests that I might be missing something crucial in how this chip's support is integrated. My initial assumption that a discrete file handles the chip initialization seems incorrect. Let me double-check the codebase for instances where the `chip->id` is directly assigned to `RTW_CHIP_TYPE_8723B`. I need to figure out where the connection between the definition and actual hardware initialization is occurring. Something is off, and I need to understand the full picture here. Perhaps it's being set in a more generic function or within a conditional branch. This requires a deeper dive.



34/2 2026/07/26 07:20 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "id = RTW_CHIP_TYPE_8723B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "error": "no matches"
}

35/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 116387
							output: 55
							thoughts: 31
						

Thoughts:
Okay, let's see. My first thought is:

**Checking for Usage of `RTW_CHIP_TYPE_8723B` in Struct Initialization**

Right, let me quickly scan the project and see if I can find any instances where `RTW_CHIP_TYPE_8723B` is used within a structure initialization. This is a common pattern when defining and configuring devices or modules, and understanding its usage is critical. Knowing how it's being used helps determine dependencies, potential impacts of changes to its definition, or helps us to understand the purpose of the particular struct in the code. I'll need to figure out the scope of the search: just this module, or the entire codebase? Let's assume the codebase and go from there. After all, it's pretty easy to narrow that down later. Let me make sure I account for any preprocessor directives or conditional compilation that might affect the search results. I'll need to remember to account for that. Let's dig in.



36/2 2026/07/26 07:20 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "\\.id\\s*=\\s*RTW_CHIP_TYPE_8723B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "error": "no matches"
}

37/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 116704
							output: 27
							thoughts: 223
						

Thoughts:
**Analyzing the Kernel Commit for the 8723B Driver**

Okay, so looking at this commit, it's immediately clear that the kernel doesn't *fully* support the `8723B` driver yet. The patch includes SDIO and coex quirks for the `8723BS`, which is a good start, but the fundamental chip definition – things like the `rtw_chip_info rtw8723b_hw_spec` structure and the SDIO device ID table entry – are absent. This is a critical omission.

If the chip definition is missing, there's no way `rtwdev->chip->id` can *ever* be set to `RTW_CHIP_TYPE_8723B`. That means all the code added in this patch that's conditional on either `rtw_is_8723bs(rtwdev)` or `rtwdev->chip->id == RTW_CHIP_TYPE_8723B` is, for all intents and purposes, unreachable. It's dead code, a no-op, at least for this particular chip.

Hold on, I need to double-check that. Let me review the code again to be absolutely sure that there aren't any other pathways, any implicit or indirect mechanisms, for `rtwdev->chip->id` to get set to that specific value. I need to be absolutely certain I haven't missed something before I flag this as a potential issue.



38/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.h=191=enum rtw_chip_type {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-196-\tRTW_CHIP_TYPE_8703B,\ndrivers/net/wireless/realtek/rtw88/main.h:197:\tRTW_CHIP_TYPE_8723B,\ndrivers/net/wireless/realtek/rtw88/main.h-198-\tRTW_CHIP_TYPE_8821A,\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2221=static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\ndrivers/net/wireless/realtek/rtw88/main.h:2223:\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.h-2224-\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n--\ndrivers/net/wireless/realtek/rtw88/rx.c=197=static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rx.c-259-\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\ndrivers/net/wireless/realtek/rtw88/rx.c:260:\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rx.c-261-\t    pkt_stat-\u003epkt_len == 0) {\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=885=static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-889-\tswitch (rtwdev-\u003echip-\u003eid) {\ndrivers/net/wireless/realtek/rtw88/sdio.c:890:\tcase RTW_CHIP_TYPE_8723B:\ndrivers/net/wireless/realtek/rtw88/sdio.c-891-\tcase RTW_CHIP_TYPE_8703B:\n"
}

39/2 2026/07/26 07:20 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 117956
							output: 18
							thoughts: 94
						

Thoughts:
**Investigating the RTW_CHIP_TYPE_8723B Mystery**

Okay, so I'm focusing on this `RTW_CHIP_TYPE_8723B` constant, and I'm pretty sure it's only being used in specific contexts. The immediate thing that pops into my head is, where is this value being *defined*? I can't seem to locate a `struct rtw_chip_info` where `.id` is directly initialized to `RTW_CHIP_TYPE_8723B`. Hmm, that's interesting.

This makes me wonder if it's being assigned dynamically. Could there be some runtime detection or initialization happening that I'm missing? To get to the bottom of this, I need to dig deeper. Let's see... a good starting point would be the core driver files. I'm thinking I should check `drivers/net/wireless/realtek/rtw88/main.c` and possibly even `sdio.c`. One of those should shed light on how and where this `RTW_CHIP_TYPE_8723B` is actually getting assigned. Time to go hunting!



40/2 2026/07/26 07:20 tool grepper
0m Args:
{
  "Expression": "chip-\u003eid ="
}

Results:
{
  "Output": "drivers/dma/dw/pci.c=15=static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)\n--\ndrivers/dma/dw/pci.c-47-\tchip-\u003edev = \u0026pdev-\u003edev;\ndrivers/dma/dw/pci.c:48:\tchip-\u003eid = pdev-\u003edevfn;\ndrivers/dma/dw/pci.c-49-\tchip-\u003eregs = pcim_iomap_table(pdev)[0];\n--\ndrivers/dma/dw/platform.c=24=static int dw_probe(struct platform_device *pdev)\n--\ndrivers/dma/dw/platform.c-61-\tchip-\u003edev = dev;\ndrivers/dma/dw/platform.c:62:\tchip-\u003eid = pdev-\u003eid;\ndrivers/dma/dw/platform.c-63-\tchip-\u003epdata = data-\u003epdata;\n--\ndrivers/iio/light/tsl2772.c=1766=static int tsl2772_probe(struct i2c_client *clientp)\n--\ndrivers/iio/light/tsl2772.c-1832-\tchip-\u003epdata = dev_get_platdata(\u0026clientp-\u003edev);\ndrivers/iio/light/tsl2772.c:1833:\tchip-\u003eid = id-\u003edriver_data;\ndrivers/iio/light/tsl2772.c-1834-\tchip-\u003echip_info =\n--\ndrivers/input/misc/88pm860x_onkey.c=60=static int pm860x_onkey_probe(struct platform_device *pdev)\n--\ndrivers/input/misc/88pm860x_onkey.c-74-\tinfo-\u003echip = chip;\ndrivers/input/misc/88pm860x_onkey.c:75:\tinfo-\u003ei2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/input/misc/88pm860x_onkey.c-76-\tinfo-\u003edev = \u0026pdev-\u003edev;\n--\ndrivers/input/touchscreen/88pm860x-ts.c=116=static int pm860x_touch_dt_init(struct platform_device *pdev,\n--\ndrivers/input/touchscreen/88pm860x-ts.c-119-{\ndrivers/input/touchscreen/88pm860x-ts.c:120:\tstruct i2c_client *i2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient \\\ndrivers/input/touchscreen/88pm860x-ts.c-121-\t\t\t\t : chip-\u003ecompanion;\n--\ndrivers/input/touchscreen/88pm860x-ts.c=172=static int pm860x_touch_probe(struct platform_device *pdev)\n--\ndrivers/input/touchscreen/88pm860x-ts.c-176-\tstruct pm860x_touch *touch;\ndrivers/input/touchscreen/88pm860x-ts.c:177:\tstruct i2c_client *i2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient \\\ndrivers/input/touchscreen/88pm860x-ts.c-178-\t\t\t\t : chip-\u003ecompanion;\n--\ndrivers/leds/leds-88pm860x.c=143=static int pm860x_led_probe(struct platform_device *pdev)\n--\ndrivers/leds/leds-88pm860x.c-193-\tdata-\u003echip = chip;\ndrivers/leds/leds-88pm860x.c:194:\tdata-\u003ei2c = (chip-\u003eid == CHIP_PM8606) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/leds/leds-88pm860x.c-195-\tdata-\u003eport = pdev-\u003eid;\n--\ndrivers/mfd/88pm860x-core.c=462=static irqreturn_t pm860x_irq(int irq, void *data)\n--\ndrivers/mfd/88pm860x-core.c-469-\ndrivers/mfd/88pm860x-core.c:470:\ti2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/mfd/88pm860x-core.c-471-\tfor (i = 0; i \u003c ARRAY_SIZE(pm860x_irqs); i++) {\n--\ndrivers/mfd/88pm860x-core.c=490=static void pm860x_irq_sync_unlock(struct irq_data *data)\n--\ndrivers/mfd/88pm860x-core.c-498-\ndrivers/mfd/88pm860x-core.c:499:\ti2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/mfd/88pm860x-core.c-500-\t/* Load cached value. In initial, all IRQs are masked */\n--\ndrivers/mfd/88pm860x-core.c=567=static int device_irq_init(struct pm860x_chip *chip,\n--\ndrivers/mfd/88pm860x-core.c-569-{\ndrivers/mfd/88pm860x-core.c:570:\tstruct i2c_client *i2c = (chip-\u003eid == CHIP_PM8607) ?\ndrivers/mfd/88pm860x-core.c-571-\t\tchip-\u003eclient : chip-\u003ecompanion;\n--\ndrivers/mfd/88pm860x-core.c=651=int pm8606_osc_enable(struct pm860x_chip *chip, unsigned short client)\n--\ndrivers/mfd/88pm860x-core.c-653-\tint ret = -EIO;\ndrivers/mfd/88pm860x-core.c:654:\tstruct i2c_client *i2c = (chip-\u003eid == CHIP_PM8606) ?\ndrivers/mfd/88pm860x-core.c-655-\t\tchip-\u003eclient : chip-\u003ecompanion;\n--\ndrivers/mfd/88pm860x-core.c=692=int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client)\n--\ndrivers/mfd/88pm860x-core.c-694-\tint ret = -EIO;\ndrivers/mfd/88pm860x-core.c:695:\tstruct i2c_client *i2c = (chip-\u003eid == CHIP_PM8606) ?\ndrivers/mfd/88pm860x-core.c-696-\t\tchip-\u003eclient : chip-\u003ecompanion;\n--\ndrivers/mfd/88pm860x-core.c=1130=static int pm860x_probe(struct i2c_client *client)\n--\ndrivers/mfd/88pm860x-core.c-1156-\ndrivers/mfd/88pm860x-core.c:1157:\tchip-\u003eid = verify_addr(client);\ndrivers/mfd/88pm860x-core.c-1158-\tchip-\u003eregmap = devm_regmap_init_i2c(client, \u0026pm860x_regmap_config);\n--\ndrivers/mfd/adp5520.c=207=static int adp5520_probe(struct i2c_client *client)\n--\ndrivers/mfd/adp5520.c-234-\tchip-\u003eirq = client-\u003eirq;\ndrivers/mfd/adp5520.c:235:\tchip-\u003eid = id-\u003edriver_data;\ndrivers/mfd/adp5520.c-236-\tmutex_init(\u0026chip-\u003elock);\n--\ndrivers/mux/core.c=102=struct mux_chip *mux_chip_alloc(struct device *dev,\n--\ndrivers/mux/core.c-122-\ndrivers/mux/core.c:123:\tmux_chip-\u003eid = ida_alloc(\u0026mux_ida, GFP_KERNEL);\ndrivers/mux/core.c-124-\tif (mux_chip-\u003eid \u003c 0) {\n--\ndrivers/net/wireless/realtek/rtw88/bf.c=124=void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/bf.c-129-\ndrivers/net/wireless/realtek/rtw88/bf.c:130:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C)\ndrivers/net/wireless/realtek/rtw88/bf.c-131-\t\tcsi_rsc = CSI_RSC_PRIMARY_20M_BW;\n--\ndrivers/net/wireless/realtek/rtw88/bf.c=384=void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,\n--\ndrivers/net/wireless/realtek/rtw88/bf.c-392-\ndrivers/net/wireless/realtek/rtw88/bf.c:393:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C)\ndrivers/net/wireless/realtek/rtw88/bf.c-394-\t\tcsi_cfg |= BIT_CSI_FORCE_RATE;\n--\ndrivers/net/wireless/realtek/rtw88/coex.c=3248=void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)\n--\ndrivers/net/wireless/realtek/rtw88/coex.c-3334-\ndrivers/net/wireless/realtek/rtw88/coex.c:3335:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/coex.c-3336-\t\tcoex_stat-\u003ebt_info_c2h[rsp_source][5] = 0;\n--\ndrivers/net/wireless/realtek/rtw88/coex.h=423=static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/coex.h-428-\t */\ndrivers/net/wireless/realtek/rtw88/coex.h:429:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A \u0026\u0026 rtwdev-\u003eefuse.btcoex)\ndrivers/net/wireless/realtek/rtw88/coex.h-430-\t\trtw_coex_query_bt_info(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/debug.c=1306=void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)\n--\ndrivers/net/wireless/realtek/rtw88/debug.c-1323-\trtw_debugfs_add_r(bb_1f);\ndrivers/net/wireless/realtek/rtw88/debug.c:1324:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C) {\ndrivers/net/wireless/realtek/rtw88/debug.c-1325-\t\trtw_debugfs_add_r(bb_2c);\n--\ndrivers/net/wireless/realtek/rtw88/mac.c=150=static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-168-\tvalue = rtw_read8(rtwdev, REG_SYS_PW_CTRL);\ndrivers/net/wireless/realtek/rtw88/mac.c:169:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723D)\ndrivers/net/wireless/realtek/rtw88/mac.c-170-\t\trtw_write8(rtwdev, REG_SYS_PW_CTRL, value \u0026 ~BIT_PFM_WOWL);\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-172-\trtw_write8(rtwdev, REG_SYS_PW_CTRL, value \u0026 ~BIT_PFM_WOWL);\ndrivers/net/wireless/realtek/rtw88/mac.c:173:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723D)\ndrivers/net/wireless/realtek/rtw88/mac.c-174-\t\trtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL);\n--\ndrivers/net/wireless/realtek/rtw88/mac.c=272=static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-314-\tif (pwr_on \u0026\u0026 rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) {\ndrivers/net/wireless/realtek/rtw88/mac.c:315:\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/mac.c:316:\t\t    chip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/mac.c:317:\t\t    chip-\u003eid == RTW_CHIP_TYPE_8821C)\ndrivers/net/wireless/realtek/rtw88/mac.c-318-\t\t\trtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0));\n--\ndrivers/net/wireless/realtek/rtw88/mac.c=948=static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-953-\t/* reset firmware if still present */\ndrivers/net/wireless/realtek/rtw88/mac.c:954:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac.c-955-\t    rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) {\n--\ndrivers/net/wireless/realtek/rtw88/mac.c=990=int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-998-\tif (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/mac.c:999:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C)\ndrivers/net/wireless/realtek/rtw88/mac.c-1000-\t\trtw_fw_set_recover_bt_device(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=1807=static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1813-\tif (!rtw_fw_feature_check(\u0026rtwdev-\u003efw, FW_FEATURE_SCAN_OFFLOAD) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c:1814:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C)\ndrivers/net/wireless/realtek/rtw88/main.c-1815-\t\tlen = IEEE80211_MAX_DATA_LEN;\n--\ndrivers/net/wireless/realtek/rtw88/main.c=1912=static void __update_firmware_feature(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1921-\ndrivers/net/wireless/realtek/rtw88/main.c:1922:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.c-1923-\t    RTW_FW_SUIT_VER_CODE(rtwdev-\u003efw) \u003c RTW_FW_VER_CODE(9, 9, 13))\n--\ndrivers/net/wireless/realtek/rtw88/main.c=2428=int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-2476-\ndrivers/net/wireless/realtek/rtw88/main.c:2477:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C) {\ndrivers/net/wireless/realtek/rtw88/main.c-2478-\t\thw-\u003ewiphy-\u003eiface_combinations = rtw_iface_combs;\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2221=static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\ndrivers/net/wireless/realtek/rtw88/main.h:2223:\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.h-2224-\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n--\ndrivers/net/wireless/realtek/rtw88/pci.c=1405=static void rtw_pci_link_cfg(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1415-\t */\ndrivers/net/wireless/realtek/rtw88/pci.c:1416:\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C)\ndrivers/net/wireless/realtek/rtw88/pci.c-1417-\t\trtw_dbi_write8(rtwdev, RTK_PCIE_CLKDLY_CTRL, 0);\n--\ndrivers/net/wireless/realtek/rtw88/pci.c=1462=static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1507-\t/* Disable 8821ce completion timeout by default */\ndrivers/net/wireless/realtek/rtw88/pci.c:1508:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821C) {\ndrivers/net/wireless/realtek/rtw88/pci.c-1509-\t\tret = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1515-\ndrivers/net/wireless/realtek/rtw88/pci.c:1516:\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C \u0026\u0026 efuse-\u003erfe_option == 5)\ndrivers/net/wireless/realtek/rtw88/pci.c-1517-\t\trtw_write32_mask(rtwdev, REG_ANAPARSW_MAC_0, BIT_CF_L_V2, 0x1);\n--\ndrivers/net/wireless/realtek/rtw88/pci.c=1520=static int __maybe_unused rtw_pci_suspend(struct device *dev)\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1526-\ndrivers/net/wireless/realtek/rtw88/pci.c:1527:\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C \u0026\u0026 efuse-\u003erfe_option == 6)\ndrivers/net/wireless/realtek/rtw88/pci.c-1528-\t\trtw_pci_clkreq_pad_low(rtwdev, true);\n--\ndrivers/net/wireless/realtek/rtw88/pci.c=1532=static int __maybe_unused rtw_pci_resume(struct device *dev)\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1538-\ndrivers/net/wireless/realtek/rtw88/pci.c:1539:\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C \u0026\u0026 efuse-\u003erfe_option == 6)\ndrivers/net/wireless/realtek/rtw88/pci.c-1540-\t\trtw_pci_clkreq_pad_low(rtwdev, false);\n--\ndrivers/net/wireless/realtek/rtw88/pci.c=1785=int rtw_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/realtek/rtw88/pci.c-1846-\t/* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */\ndrivers/net/wireless/realtek/rtw88/pci.c:1847:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/pci.c-1848-\t    bridge \u0026\u0026 bridge-\u003evendor == PCI_VENDOR_ID_INTEL)\n--\ndrivers/net/wireless/realtek/rtw88/phy.c=536=static void rtw_phy_dig(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/phy.c-588-\t */\ndrivers/net/wireless/realtek/rtw88/phy.c:589:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A \u0026\u0026 rtwdev-\u003ebeacon_loss \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/phy.c-590-\t    linked \u0026\u0026 dm_info-\u003etotal_fa_cnt \u003c DIG_PERF_FA_TH_EXTRA_HIGH)\n--\ndrivers/net/wireless/realtek/rtw88/phy.c=1103=void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)\n--\ndrivers/net/wireless/realtek/rtw88/phy.c-1127-\ndrivers/net/wireless/realtek/rtw88/phy.c:1128:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A ||\ndrivers/net/wireless/realtek/rtw88/phy.c:1129:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/phy.c-1130-\t\tcond.rfe = 0;\n--\ndrivers/net/wireless/realtek/rtw88/phy.c=1150=static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond,\n--\ndrivers/net/wireless/realtek/rtw88/phy.c-1165-\ndrivers/net/wireless/realtek/rtw88/phy.c:1166:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A ||\ndrivers/net/wireless/realtek/rtw88/phy.c:1167:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/phy.c-1168-\t\tif (!(cond.rfe \u0026 0x0f))\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=124=static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-136-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:137:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-138-\t\tefuse-\u003ehw_cap.nss = 1;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-141-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:142:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-143-\t\tgoto print_hw_cap;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=200=int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-206-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:207:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-208-\t\trtwdev-\u003ehal.cut_version += 1;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-223-\tefuse-\u003elna_type_5g = map-\u003elna_type_5g;\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:224:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-225-\t\trtw8812a_read_amplifier_type(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-242-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:243:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-244-\t\tefuse-\u003ebtcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-261-\tcase RTW_HCI_TYPE_USB:\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:262:\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-263-\t\t\tether_addr_copy(efuse-\u003eaddr, map-\u003ertw8821au.mac_addr);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=278=static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-284-\trtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:285:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-286-\t\trtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3));\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-294-\trtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:295:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-296-\t\trtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3));\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=344=static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-361-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:362:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-363-\t\tif (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) \u0026 BIT(0))\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=545=static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-551-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:552:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-553-\t\trtw_write8(rtwdev, REG_DWBCN1_CTRL,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=572=static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-593-\tcrystal_cap = rtwdev-\u003eefuse.crystal_cap \u0026 0x3F;\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:594:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-595-\t\trtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=677=static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-683-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:684:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-685-\t\tdm_info-\u003edefault_cck_index = 0;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=927=static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-934-\t */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:935:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A \u0026\u0026 !rtwdev-\u003eefuse.btcoex \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-936-\t    rtwdev-\u003eefuse.ant_div_cfg == 0)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-941-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:942:\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-943-\t\t\trtw8821a_phy_set_rfe_reg_24g(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-972-\t} else { /* RTW_BAND_5G */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:973:\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-974-\t\t\trtw8821a_phy_set_rfe_reg_5g(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-982-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:983:\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-984-\t\t\trtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=1006=int rtw88xxa_power_on(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1017-\t/* Override rtw_chip_efuse_info_setup() */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1018:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1019-\t\tefuse-\u003ebtcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1022-\t/* Override rtw_chip_efuse_info_setup() */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1023:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1024-\t\trtw8812a_read_amplifier_type(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1035-\t */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1036:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1037-\t\trtw_write8(rtwdev, REG_RF_CTRL, 5);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1091-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1092:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1093-\t\trtw_write8(rtwdev, REG_PBP,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1125-\t/* 0x456 = 0x70, sugguested by Zhilin */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1126:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1127-\t\trtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1145-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1146:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1147-\t\t/* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1179-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1180:\tif (chip-\u003eid == RTW_CHIP_TYPE_8812A \u0026\u0026 hal-\u003erf_path_num == 1)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1181-\t\trtw8812a_config_1t(rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=1245=u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1265-\t */\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1266:\tset_cca = addr != 0x0 \u0026\u0026 chip-\u003eid == RTW_CHIP_TYPE_8812A \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1267-\t\t  hal-\u003ecut_version != RTW_CHIP_VER_CUT_C;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1277-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1278:\tif (chip-\u003eid == RTW_CHIP_TYPE_8821A ||\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1279-\t    hal-\u003ecut_version == RTW_CHIP_VER_CUT_C)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=1324=static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1368-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1369:\t\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1370-\t\t\trtw8812a_phy_fix_spur(rtwdev, channel, bw);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=1489=void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1510-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1511:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8812A)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1512-\t\trtw8812a_phy_fix_spur(rtwdev, channel, bw);\n--\ndrivers/net/wireless/realtek/rtw88/rx.c=197=static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rx.c-258-\t */\ndrivers/net/wireless/realtek/rtw88/rx.c:259:\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\ndrivers/net/wireless/realtek/rtw88/rx.c:260:\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rx.c-261-\t    pkt_stat-\u003epkt_len == 0) {\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=155=static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr)\ndrivers/net/wireless/realtek/rtw88/sdio.c-156-{\ndrivers/net/wireless/realtek/rtw88/sdio.c:157:\tbool might_indirect_under_power_off = rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C;\ndrivers/net/wireless/realtek/rtw88/sdio.c-158-\n--\ndrivers/net/wireless/realtek/rtw88/tx.c=196=void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)\n--\ndrivers/net/wireless/realtek/rtw88/tx.c-210-\ndrivers/net/wireless/realtek/rtw88/tx.c:211:\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723D \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/tx.c-212-\t     rtwdev-\u003ehci.type == RTW_HCI_TYPE_USB) ||\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=72=static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-96-\ndrivers/net/wireless/realtek/rtw88/usb.c:97:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/usb.c:98:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/usb.c:99:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C)\ndrivers/net/wireless/realtek/rtw88/usb.c-100-\t\trtw_usb_reg_sec(rtwdev, addr, data);\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=120=static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-146-\ndrivers/net/wireless/realtek/rtw88/usb.c:147:\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/usb.c:148:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/usb.c:149:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C)\ndrivers/net/wireless/realtek/rtw88/usb.c-150-\t\trtw_usb_reg_sec(rtwdev, addr, data);\n--\ndrivers/pinctrl/pinctrl-at91.c=1818=static int at91_gpio_probe(struct platform_device *pdev)\n--\ndrivers/pinctrl/pinctrl-at91.c-1858-\tat91_chip-\u003echip = at91_gpio_template;\ndrivers/pinctrl/pinctrl-at91.c:1859:\tat91_chip-\u003eid = alias_idx;\ndrivers/pinctrl/pinctrl-at91.c-1860-\n--\ndrivers/power/supply/88pm860x_battery.c=912=static int pm860x_battery_probe(struct platform_device *pdev)\n--\ndrivers/power/supply/88pm860x_battery.c-932-\tinfo-\u003ei2c =\ndrivers/power/supply/88pm860x_battery.c:933:\t    (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/power/supply/88pm860x_battery.c-934-\tinfo-\u003edev = \u0026pdev-\u003edev;\n--\ndrivers/power/supply/88pm860x_charger.c=663=static int pm860x_charger_probe(struct platform_device *pdev)\n--\ndrivers/power/supply/88pm860x_charger.c-687-\tinfo-\u003ei2c =\ndrivers/power/supply/88pm860x_charger.c:688:\t    (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/power/supply/88pm860x_charger.c-689-\tinfo-\u003ei2c_8606 =\ndrivers/power/supply/88pm860x_charger.c:690:\t    (chip-\u003eid == CHIP_PM8607) ? chip-\u003ecompanion : chip-\u003eclient;\ndrivers/power/supply/88pm860x_charger.c-691-\tif (!info-\u003ei2c_8606) {\n--\ndrivers/pwm/core.c=2451=int __pwmchip_add(struct pwm_chip *chip, struct module *owner)\n--\ndrivers/pwm/core.c-2482-\ndrivers/pwm/core.c:2483:\tchip-\u003eid = ret;\ndrivers/pwm/core.c-2484-\n--\ndrivers/regulator/88pm8607.c=315=static int pm8607_regulator_probe(struct platform_device *pdev)\n--\ndrivers/regulator/88pm8607.c-354-\ndrivers/regulator/88pm8607.c:355:\tif (chip-\u003eid == CHIP_PM8607)\ndrivers/regulator/88pm8607.c-356-\t\tconfig.regmap = chip-\u003eregmap;\n--\ndrivers/rtc/rtc-88pm860x.c=267=static int pm860x_rtc_probe(struct platform_device *pdev)\n--\ndrivers/rtc/rtc-88pm860x.c-281-\tinfo-\u003echip = chip;\ndrivers/rtc/rtc-88pm860x.c:282:\tinfo-\u003ei2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/rtc/rtc-88pm860x.c-283-\tinfo-\u003edev = \u0026pdev-\u003edev;\n--\ndrivers/staging/iio/adc/ad7816.c=64=static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)\n--\ndrivers/staging/iio/adc/ad7816.c-86-\ndrivers/staging/iio/adc/ad7816.c:87:\tif (chip-\u003eid == ID_AD7816 || chip-\u003eid == ID_AD7817) {\ndrivers/staging/iio/adc/ad7816.c-88-\t\twhile (gpiod_get_value(chip-\u003ebusy_pin))\n--\ndrivers/staging/iio/adc/ad7816.c=352=static int ad7816_probe(struct spi_device *spi_dev)\n--\ndrivers/staging/iio/adc/ad7816.c-366-\ndrivers/staging/iio/adc/ad7816.c:367:\tchip-\u003eid = spi_get_device_id(spi_dev)-\u003edriver_data;\ndrivers/staging/iio/adc/ad7816.c-368-\tchip-\u003erdwr_pin = devm_gpiod_get(\u0026spi_dev-\u003edev, \"rdwr\", GPIOD_OUT_HIGH);\n--\ndrivers/staging/iio/adc/ad7816.c-382-\t}\ndrivers/staging/iio/adc/ad7816.c:383:\tif (chip-\u003eid == ID_AD7816 || chip-\u003eid == ID_AD7817) {\ndrivers/staging/iio/adc/ad7816.c-384-\t\tchip-\u003ebusy_pin = devm_gpiod_get(\u0026spi_dev-\u003edev, \"busy\",\n--\ndrivers/staging/iio/addac/adt7316.c=635=static ssize_t adt7316_store_da_high_resolution(struct device *dev,\n--\ndrivers/staging/iio/addac/adt7316.c-644-\ndrivers/staging/iio/addac/adt7316.c:645:\tif (chip-\u003eid == ID_ADT7318 || chip-\u003eid == ID_ADT7519)\ndrivers/staging/iio/addac/adt7316.c-646-\t\treturn -EPERM;\n--\ndrivers/staging/iio/addac/adt7316.c=2116=int adt7316_probe(struct device *dev, struct adt7316_bus *bus,\n--\ndrivers/staging/iio/addac/adt7316.c-2132-\tif (name[4] == '3')\ndrivers/staging/iio/addac/adt7316.c:2133:\t\tchip-\u003eid = ID_ADT7316 + (name[6] - '6');\ndrivers/staging/iio/addac/adt7316.c-2134-\telse if (name[4] == '5')\ndrivers/staging/iio/addac/adt7316.c:2135:\t\tchip-\u003eid = ID_ADT7516 + (name[6] - '6');\ndrivers/staging/iio/addac/adt7316.c-2136-\telse\n--\ndrivers/staging/iio/addac/adt7316.c-2138-\ndrivers/staging/iio/addac/adt7316.c:2139:\tif (chip-\u003eid == ID_ADT7316 || chip-\u003eid == ID_ADT7516)\ndrivers/staging/iio/addac/adt7316.c-2140-\t\tchip-\u003edac_bits = 12;\ndrivers/staging/iio/addac/adt7316.c:2141:\telse if (chip-\u003eid == ID_ADT7317 || chip-\u003eid == ID_ADT7517)\ndrivers/staging/iio/addac/adt7316.c-2142-\t\tchip-\u003edac_bits = 10;\n--\ndrivers/tty/serial/8250/8250_lpss.c=202=static void qrk_serial_setup_dma(struct lpss8250 *lpss, struct uart_port *port)\n--\ndrivers/tty/serial/8250/8250_lpss.c-211-\tchip-\u003edev = \u0026pdev-\u003edev;\ndrivers/tty/serial/8250/8250_lpss.c:212:\tchip-\u003eid = pdev-\u003edevfn;\ndrivers/tty/serial/8250/8250_lpss.c-213-\tchip-\u003eirq = pci_irq_vector(pdev, 0);\n--\ndrivers/video/backlight/88pm860x_bl.c=178=static int pm860x_backlight_probe(struct platform_device *pdev)\n--\ndrivers/video/backlight/88pm860x_bl.c-215-\tdata-\u003echip = chip;\ndrivers/video/backlight/88pm860x_bl.c:216:\tdata-\u003ei2c = (chip-\u003eid == CHIP_PM8606) ? chip-\u003eclient : chip-\u003ecompanion;\ndrivers/video/backlight/88pm860x_bl.c-217-\tdata-\u003ecurrent_brightness = MAX_BRIGHTNESS;\n--\nsound/soc/codecs/88pm860x-codec.c=1351=static int pm860x_codec_probe(struct platform_device *pdev)\n--\nsound/soc/codecs/88pm860x-codec.c-1363-\tpm860x-\u003echip = chip;\nsound/soc/codecs/88pm860x-codec.c:1364:\tpm860x-\u003ei2c = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eclient\nsound/soc/codecs/88pm860x-codec.c-1365-\t\t\t: chip-\u003ecompanion;\nsound/soc/codecs/88pm860x-codec.c:1366:\tpm860x-\u003eregmap = (chip-\u003eid == CHIP_PM8607) ? chip-\u003eregmap\nsound/soc/codecs/88pm860x-codec.c-1367-\t\t\t: chip-\u003eregmap_companion;\n"
}

41/2 2026/07/26 07:20 llm patch-evaluator
1m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 132956
							output: 47
							thoughts: 89
						

Thoughts:
Here's my thought process, as if I were analyzing this code:

**Investigating a Potential RTW88 Driver Issue**

Alright, the code tells me that `RTW_CHIP_TYPE_8723B` isn't directly assigned to `chip->id` within the core `rtw88` driver. That raises a red flag. I need to figure out where that chip type is being initialized. My first instinct is to check if it's handled in a more specific, device-dependent file.

So, where would that be? Given the context, I immediately think of the `rtw8822b.c` file. It makes sense that the 8723B would be defined in an adapter-specific source. I need to examine `drivers/net/wireless/realtek/rtw88/rtw8822b.c` to confirm. I'll search that file for that define. Hopefully, this explains where `RTW_CHIP_TYPE_8723B` is tied to a specific adapter.



42/2 2026/07/26 07:21 tool grepper
0m Args:
{
  "Expression": "RTW_CHIP_TYPE_8822B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac.c=272=static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-315-\t\tif (chip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/mac.c:316:\t\t    chip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/mac.c-317-\t\t    chip-\u003eid == RTW_CHIP_TYPE_8821C)\n--\ndrivers/net/wireless/realtek/rtw88/main.h=191=enum rtw_chip_type {\ndrivers/net/wireless/realtek/rtw88/main.h:192:\tRTW_CHIP_TYPE_8822B,\ndrivers/net/wireless/realtek/rtw88/main.h-193-\tRTW_CHIP_TYPE_8822C,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=2520=const struct rtw_chip_info rtw8822b_hw_spec = {\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2521-\t.ops = \u0026rtw8822b_ops,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2522:\t.id = RTW_CHIP_TYPE_8822B,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2523-\t.fw_name = \"rtw88/rtw8822b_fw.bin\",\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=72=static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-97-\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/usb.c:98:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/usb.c-99-\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=120=static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-147-\tif (rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/usb.c:148:\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8822B ||\ndrivers/net/wireless/realtek/rtw88/usb.c-149-\t    rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8821C)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=929=static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-932-\tcase RTW_CHIP_TYPE_8822C:\ndrivers/net/wireless/realtek/rtw88/usb.c:933:\tcase RTW_CHIP_TYPE_8822B:\ndrivers/net/wireless/realtek/rtw88/usb.c-934-\tcase RTW_CHIP_TYPE_8821C:\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=1112=static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-1144-\t/* Enable IO wrapper timeout */\ndrivers/net/wireless/realtek/rtw88/usb.c:1145:\tif (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C)\ndrivers/net/wireless/realtek/rtw88/usb.c-1146-\t\trtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0));\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=1167=static bool rtw_usb3_chip_new(u8 chip_id)\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-1169-\treturn chip_id == RTW_CHIP_TYPE_8822C ||\ndrivers/net/wireless/realtek/rtw88/usb.c:1170:\t       chip_id == RTW_CHIP_TYPE_8822B;\ndrivers/net/wireless/realtek/rtw88/usb.c-1171-}\n"
}

43/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 134746
							output: 25
							thoughts: 138
						

Thoughts:
**Unreachable Code? A Deep Dive into the RTW88 Driver**

Okay, so I'm looking at this `rtw8822b_hw_spec` structure and how it's setting the `.id` to `RTW_CHIP_TYPE_8822B`. My first thought is, why isn't there a corresponding `rtw8723b_hw_spec` defined anywhere that sets the `.id` to `RTW_CHIP_TYPE_8723B` within this specific driver? If that's the case, then this new code they've added for the 8723B is effectively unreachable, right? That's a classic case of dead code.

Wait, hold on a second. I need to be absolutely sure. This could be a configuration defined in another file, or even in a different module altogether, you know how these things can be. Let me do a quick grep for `rtw8723b_hw_spec` across the whole codebase, just to be thorough. I don't want to jump to conclusions before I've exhausted every possible location where that configuration might be defined. Let's see what turns up.



44/2 2026/07/26 07:22 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "rtw8723b_hw_spec"
}

Results:
{
  "error": "no matches"
}

45/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 135186
							output: 27
							thoughts: 28
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Double-Checking the Target**

Alright, I'm just running that `grep` again, specifically for `RTW_CHIP_TYPE_8723B`. It's a bit of a belt-and-suspenders approach, I know, but given the intricacies of this project and the potential for a mis-configuration, I'm just double-checking to ensure that I've nailed down the right target. No need for assumptions, I want absolute certainty before I move forward. A fresh search will give me that.



46/2 2026/07/26 07:22 tool grepper
0m Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.h=191=enum rtw_chip_type {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-196-\tRTW_CHIP_TYPE_8703B,\ndrivers/net/wireless/realtek/rtw88/main.h:197:\tRTW_CHIP_TYPE_8723B,\ndrivers/net/wireless/realtek/rtw88/main.h-198-\tRTW_CHIP_TYPE_8821A,\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2221=static inline bool rtw_is_8723bs(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.h-2222-{\ndrivers/net/wireless/realtek/rtw88/main.h:2223:\treturn rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/main.h-2224-\t       rtwdev-\u003ehci.type == RTW_HCI_TYPE_SDIO;\n--\ndrivers/net/wireless/realtek/rtw88/rx.c=197=static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rx.c-259-\tif ((rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8703B ||\ndrivers/net/wireless/realtek/rtw88/rx.c:260:\t     rtwdev-\u003echip-\u003eid == RTW_CHIP_TYPE_8723B) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rx.c-261-\t    pkt_stat-\u003epkt_len == 0) {\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c=885=static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/sdio.c-889-\tswitch (rtwdev-\u003echip-\u003eid) {\ndrivers/net/wireless/realtek/rtw88/sdio.c:890:\tcase RTW_CHIP_TYPE_8723B:\ndrivers/net/wireless/realtek/rtw88/sdio.c-891-\tcase RTW_CHIP_TYPE_8703B:\n"
}

47/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 136051
							output: 25
							thoughts: 173
						

Thoughts:
**Analyzing Potential False Condition in Realtek Driver**

Okay, so I'm looking at this Realtek driver code, and it seems like this particular block is *only* ever executed in these specific locations. I see that the condition `rtw_is_8723bs(rtwdev)` is checked, and from my understanding of the code flow here, `rtwdev->chip->id` is *never* set to `RTW_CHIP_TYPE_8723B` before this point. So, logically, this whole section will *always* evaluate to false.

But, hang on a second... Could there be a situation where the `rtwdev->chip->id` is being populated later, perhaps by reading a hardware register somewhere down the line? I need to verify how `rtwdev->chip` gets its initial value. Let me dig a bit deeper.

Ah, right. In the `rtw88` framework, the `chip` pointer is typically passed in from the bus driver, right? For example, the `rtw8822bs.c` module, if it's an SDIO device. Let's see what's happening there. I'm going to take a closer look at `drivers/net/wireless/realtek/rtw88/rtw8822bs.c` to trace how that `chip` struct gets initialized and if there's any chance the `id` field gets updated after the initial assignment. I need to make sure I'm not missing some late-stage hardware probe or initialization.



48/2 2026/07/26 07:22 tool grepper
0m Args:
{
  "Expression": "rtw8822b_hw_spec"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822b.c=2515=static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2519-\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2520:const struct rtw_chip_info rtw8822b_hw_spec = {\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2521-\t.ops = \u0026rtw8822b_ops,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2611-};\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2612:EXPORT_SYMBOL(rtw8822b_hw_spec);\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2613-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h=110=_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h-186-\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h:187:extern const struct rtw_chip_info rtw8822b_hw_spec;\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h-188-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822be.c=10=static const struct pci_device_id rtw_8822be_id_table[] = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822be.c-12-\t\tPCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822),\ndrivers/net/wireless/realtek/rtw88/rtw8822be.c:13:\t\t.driver_data = (kernel_ulong_t)\u0026rtw8822b_hw_spec\ndrivers/net/wireless/realtek/rtw88/rtw8822be.c-14-\t},\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822bs.c=12=static const struct sdio_device_id rtw_8822bs_id_table[] =  {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822bs.c-15-\t\t\t    SDIO_DEVICE_ID_REALTEK_RTW8822BS),\ndrivers/net/wireless/realtek/rtw88/rtw8822bs.c:16:\t\t.driver_data = (kernel_ulong_t)\u0026rtw8822b_hw_spec,\ndrivers/net/wireless/realtek/rtw88/rtw8822bs.c-17-\t},\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c=11=static const struct usb_device_id rtw_8822bu_id_table[] = {\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-12-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:13:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-14-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:15:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-16-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:17:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* CCNC */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-18-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:19:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-20-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:21:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-22-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:23:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Edimax */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-24-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:25:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Edimax */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-26-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:27:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-28-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:29:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Default ID */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-30-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:31:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-32-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:33:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ASUS U2 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-34-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:35:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-36-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:37:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ASUS */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-38-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:39:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ASUS */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-40-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:41:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-42-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:43:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-44-\t{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:45:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-46-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:47:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-48-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:49:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-50-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:51:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-52-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:53:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-54-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:55:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-56-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:57:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-LINK */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-58-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:59:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-LINK */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-60-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:61:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TP-LINK */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-62-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:63:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Netgear A6150 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-64-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:65:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Hawking HW12ACU */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-66-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:67:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* LiteOn */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-68-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:69:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-70-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:71:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-72-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:73:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-74-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:75:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Mercusys MA30H */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-76-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x010a, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:77:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* Mercusys MA30N */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-78-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:79:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-80-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d1, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:81:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* BUFFALO WI-U2-866DM */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-82-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d0, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:83:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822b_hw_spec) }, /* BUFFALO WI-U3-866DHP */\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-84-\t{},\n"
}

49/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 142292
							output: 25
							thoughts: 113
						

Thoughts:
**Locating the Hardware Specification**

Alright, the `rtw8723b_hw_spec` structure – it's just not showing up. Hmm, could it be defined within `rtw8723b.c` itself? Perhaps I missed it because I was looking specifically within `drivers/net/wireless/realtek/rtw88/`, but the file is located elsewhere in the tree? Let me do a quick search; I need to confirm if that file even *exists* within this entire kernel source.



50/2 2026/07/26 07:22 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "rtw8723b_hw_spec"
}

Results:
{
  "error": "no matches"
}

51/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 142559
							output: 35
							thoughts: 61
						

Thoughts:
**Investigating the Missing Hardware Specification**

Okay, so I'm looking for this `rtw8723b_hw_spec` structure within this code base, and it's just not showing up. Hmm, that's unusual, especially given the context. My immediate thought is, "Perhaps the naming convention has changed." It's not uncommon for these internal structures to be renamed over time for various reasons - maybe a refactoring or a more descriptive naming scheme.

So, instead of just assuming it's absent, I should check for an alternative name. I need to see if there's any code that's *using* a specific identifier related to this chip, specifically, `RTW_CHIP_TYPE_8723B`. If that constant is being used, it should give me a lead on a struct, even if it's named something else. This will let me identify the equivalent structure, and then I can verify its intended role. Let me start digging into the codebase for that exact identifier.



52/2 2026/07/26 07:22 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "\\.id\\s*=\\s*RTW_CHIP_TYPE_8723B"
}

Results:
{
  "error": "no matches"
}

53/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 142887
							output: 56
							thoughts: 146
						

Thoughts:
**Analyzing the RTL8723BS Driver Implementation**

Okay, so I'm looking at this patch and my initial thought is, "There's no actual implementation here." It seems the driver for the RTL8723BS is still not fully integrated into the kernel. The code in this patch only deals with some SDIO and co-existence (coex) quirks. The real work – defining and registering the chip itself – is missing entirely.

That means, as far as I can see, this code is *completely* unreachable within the kernel. Even with the actual hardware present, it's not going to do anything. Forget about testing it in a virtualized environment; it won't even register as a device.

Hang on, let me quickly double-check. Could I be mistaken? Is this part of the `rtw8723d.c` file or some other related Realtek implementation? I'll quickly look in `drivers/net/wireless/realtek/rtw88/rtw8723d.c`.



54/2 2026/07/26 07:22 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8723d.c"
}

Results:
{
  "error": "no matches"
}

55/2 2026/07/26 07:22 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 143329
							output: 56
							thoughts: 29
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Diving into the Realtek 8703B Driver**

Right, let's see... the code's pointing me at `drivers/net/wireless/realtek/rtw88/rtw8703b.c`.  Okay, that's the kernel module for the Realtek 8703B chipset. Been a while since I last poked around in a Realtek wireless driver, but the rtw88 framework is pretty standardized these days, so shouldn't be too bad. I'll need to remember all the quirks though. Gotta keep an eye out for any specific hardware initialization routines, especially concerning power management and antenna selection. Need to make sure the firmware loading is handled correctly, too. Always a potential trouble spot there, with Realtek's proprietary blobs. Let's see if there are any obvious areas of concern based on recent bug reports. Specifically, I'll need to check the interrupt handling and see what's happening there as well.



56/2 2026/07/26 07:23 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "RTW_CHIP_TYPE_8723B",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8703b.c"
}

Results:
{
  "error": "no matches"
}

57/2 2026/07/26 07:23 llm patch-evaluator
1m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 143660
							output: 172
							thoughts: 7483
						

Thoughts:
**Unreachable Code: RTL8723BS SDIO Coexistence Patch Analysis**

Alright, let's break this down. The patch introduces RTL8723BS SDIO WiFi/BT coexistence functionality. Initially, I thought it was all about `RTW_CHIP_TYPE_8723B`, but now I've delved deeper, and it's looking like a dead end. The core problem is that `RTW_CHIP_TYPE_8723B` isn't actually assigned to *any* `chip->id` value within the driver, meaning `rtw_is_8723bs(rtwdev)` is *always* going to return false. So, any code guarded by `rtw_is_8723bs()` or `rtwdev->chip->id == RTW_CHIP_TYPE_8723B` is, for all intents and purposes, unreachable.

I went through every single file affected by this patch – `coex.c`, `fw.c`, `mac80211.c`, `main.c`, `rx.c`, `sdio.c`, and `tx.c` – and confirmed this. The vast majority of the changes are gated by that `rtw_is_8723bs()` check. There are a few exceptions, mostly in `sdio.c`, where there are some generic SDIO changes. For example, there is changes to padding and delayed work queue handling in `sdio.c`. However, since the primary chip detection is missing, any change to the function is unreachable. Also, these changes are not guarded by `rtw_is_8723bs()`, instead they are guarded by other `rtw_hci_type` or SDIO conditions.

The clincher is that there is no means to actually *trigger* these changes, not in a normal fuzzing setup, anyway. It's not just that `RTW_CHIP_TYPE_8723B` is missing. More to the point, even if the driver claimed the right IDs, probing an SDIO device in a purely virtualized environment is not something that's feasible. Syzkaller doesn't have a software SDIO host controller to work with, unlike USB's `dummy_hcd` or WiFi's `mac80211_hwsim`. There's no way to emulate an SDIO device responding correctly to commands, leading to enumeration, and thus, reaching any of the SDIO-related code. Even USB emulation, like with the `vub300` bridge, is so unlikely to accidentally enumerate a specific chip that it's practically infeasible, due to the need for a specific sequence of commands and responses to match the correct device ID and Vendor ID.

Therefore, the entire patch is unreachable. There is no code that is worth fuzzing.



58/2 2026/07/26 07:24 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch adds support for the RTL8723BS SDIO WiFi/BT coexistence and related SDIO handling. However, the chip definition for RTL8723BS (which would set `chip-\u003eid = RTW_CHIP_TYPE_8723B`) is not present in the kernel tree, meaning `rtw_is_8723bs()` will always evaluate to false and the core logic is unreachable. Furthermore, the few generic SDIO changes in `sdio.c` are unreachable in virtualized environments because there is no software-emulated SDIO host controller (like `dummy_hcd` for USB) available for fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch adds support for the RTL8723BS SDIO WiFi/BT coexistence and related SDIO handling. However, the chip definition for RTL8723BS (which would set `chip-\u003eid = RTW_CHIP_TYPE_8723B`) is not present in the kernel tree, meaning `rtw_is_8723bs()` will always evaluate to false and the core logic is unreachable. Furthermore, the few generic SDIO changes in `sdio.c` are unreachable in virtualized environments because there is no software-emulated SDIO host controller (like `dummy_hcd` for USB) available for fuzzing.",
  "WorthFuzzing": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)