-: ------------ > 1: eb81ac3805a7 wifi: rtw88: move the shared 88xxa init helpers into the core -: ------------ > 2: c43213a50a9d wifi: rtw88: assign the RCR per chip in rtw_core_init 1: 0a894b903f8a ! 3: 0010f20a9681 wifi: rtw88: 8723b: add the RTL8723B register definitions @@ Metadata ## Commit message ## wifi: rtw88: 8723b: add the RTL8723B register definitions  - Add the register offsets and bit definitions the RTL8723B driver uses: - the power and system function bits, the BT antenna and efuse control - registers, the packet lifetime and MAC ID drop registers, the FPGA0 - HSSI and RF switch control registers, and the RFE antenna path + Add the register offsets and bit definitions the RTL8723B driver uses, + including the power and system function bits, the BT antenna and efuse + control registers, the packet lifetime and MAC ID drop registers, the + FPGA0 HSSI and RF switch control registers, and the RFE antenna path registers.  Signed-off-by: Luka Gejak  @@ drivers/net/wireless/realtek/rtw88/reg.h #define BIT_BTGP_SPI_EN BIT(20) #define BIT_LED1DIS BIT(15) #define BIT_SW_DPDT_SEL_DATA BIT(0) -+#define REG_BT_ANT_SEL_8723B 0x0067 ++#define REG_BT_ANT_SEL 0x0067 ++#define BIT_BT_SEL_BY_WIFI BIT(5)  +/* 0x006b is the high byte of the 16 bit register at 0x006a. */ -+#define REG_BT_EFUSE_CTRL_8723B 0x006b ++#define REG_BT_EFUSE_CTRL 0x006b  +#define BIT_BT_PWR_CUT BIT(6)  +#define BIT_BT_OUT_ISO BIT(7) #define REG_WL_BT_PWR_CTRL 0x0068 @@ drivers/net/wireless/realtek/rtw88/reg.h #define REG_HMEBOX3 0x01DC #define REG_LLT_INIT 0x01E0 #define BIT_LLT_WRITE_ACCESS BIT(30) -+#define REG_RFK_FW_ACK_8723B 0x01E7 -+#define BIT_RFK_FW_ACK_8723B BIT(0) ++#define REG_RFK_FW_ACK 0x01E7 ++#define BIT_RFK_FW_ACK BIT(0) #define REG_HMEBOX0_EX 0x01F0 #define REG_HMEBOX1_EX 0x01F4 #define REG_HMEBOX2_EX 0x01F8 @@ drivers/net/wireless/realtek/rtw88/reg.h #define REG_PRECNT_CTRL 0x04E5 #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) #define BIT_EN_PRECNT BIT(11) -@@ - #define REG_TIMER0_SRC_SEL 0x05B4 - #define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) -  -+#define REG_BWOPMODE 0x0603 -+#define BIT_BWOPMODE_20MHZ BIT(2) - #define REG_TCR 0x0604 - #define BIT_PWRMGT_HWDATA_EN BIT(7) - #define BIT_TCR_UPDATE_TIMIE BIT(5)  @@ #define BIT_UC_MD_EN BIT(16) #define BIT_RXSK_PERPKT BIT(15) @@ drivers/net/wireless/realtek/rtw88/reg.h #define REG_BT_COEX_V2 0x0762 #define BIT_GNT_BT_POLARITY BIT(12) #define BIT_LTE_COEX_EN BIT(7) -+#define REG_BT_CONTROL_8723B 0x0764 ++#define REG_BT_CONTROL 0x0764 #define REG_GNT_BT 0x0765 #define BIT_PTA_SW_CTL GENMASK(4, 3) #define REG_BT_COEX_ENH_INTR_CTRL 0x76E @@ drivers/net/wireless/realtek/rtw88/reg.h  +#define REG_RFE_CTRL_ANTA_SRC 0x0930  +#define REG_RFE_CTRL_ANT_SW 0x0944  +#define BIT_RFE_CTRL_ANT_SW_SEL GENMASK(1, 0) -+#define BIT_BT_SEL_BY_WIFI_8723B BIT(5) #define REG_AGC_TABLE 0x0958 #define REG_RFE_CTRL_E 0x0974 #define REG_2ND_CCA_CTRL 0x0976 2: 08765ded3b70 ! 4: e6b90c92ad81 wifi: rtw88: 8723b: add the RTL8723B BB, RF and AGC tables @@ Metadata ## Commit message ## wifi: rtw88: 8723b: add the RTL8723B BB, RF and AGC tables  - Add the baseband, RF and AGC parameter tables for the RTL8723B, and the - transmit power limit and power by rate tables, in the layout the shared - rtw88 phy code expects. + Add the MAC register table and the baseband, RF and AGC parameter tables + for the RTL8723B, and the transmit power limit and power by rate tables, + in the layout the shared rtw88 phy code expects.  The RTL8723B chip support is based on the initial work by Michael Straube . @@ Commit message ## drivers/net/wireless/realtek/rtw88/rtw8723b_table.c (new) ##  @@  +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* -+ * Copyright(c) 2026 Realtek Corporation ++/* Copyright(c) 2026 Realtek Corporation  + * Copyright(c) Michael Straube   + * Copyright(c) 2024-2026 Luka Gejak   + */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b_table.c (new) ## drivers/net/wireless/realtek/rtw88/rtw8723b_table.h (new) ##  @@  +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* -+ * Copyright(c) 2026 Realtek Corporation ++/* Copyright(c) 2026 Realtek Corporation  + * Copyright(c) Michael Straube   + * Copyright(c) 2024-2026 Luka Gejak   + */ 3: 765479a02859 ! 5: 2aae88059dc0 wifi: rtw88: 8723b: add the RTL8723B chip driver @@ Commit message ## drivers/net/wireless/realtek/rtw88/rtw8723b.c (new) ##  @@  +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* -+ * Copyright(c) 2026 Realtek Corporation ++/* Copyright(c) 2026 Realtek Corporation  + * Copyright(c) Michael Straube   + * Copyright(c) 2024-2026 Luka Gejak   + */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +#define WLAN_BCN_DMA_TIME 0x02  +#define WLAN_BAR_VAL 0x0201ffff  +#define WLAN_SLOT_TIME 0x09 -+#define WLAN_SYS_FUNC_BB_ENABLE (BIT_FEN_BB_GLB_RST | \ -+ BIT_FEN_BB_RSTB)  +#define WLAN_RF_CTRL_ENABLE (BIT_RF_EN | BIT_RF_RSTB | \  + BIT_RF_SDM_RSTB) -+/* -+ * 0x03a05611 is the normal RX path (staging and the BB table agree); -+ * 0x03a05600 is only an IQK temporary value and must not be reasserted. -+ */ -+#define WLAN_RX_PATH_A_8723B 0x03a05611  +  +#define ADDA_ON_VAL_8723B 0x01c00014  + -+#define WLAN_RX_FILTER0 0xFFFF -+#define WLAN_RX_FILTER1 0x400 -+#define WLAN_RX_FILTER2 0xFFFF  +/* -+ * Keep BIT_APP_FCS: rtw88 advertises RX_INCLUDES_FCS for every chip, and -+ * without it mac80211 trims four bytes of real frame data. ++ * Same as the shared rtw8723x WLAN_RCR_CFG plus BIT_APP_FCS: rtw88 ++ * advertises RX_INCLUDES_FCS for every chip, and without it mac80211 ++ * trims four bytes of real frame data.  + */ -+#define WLAN_RCR_CFG (BIT_APM | BIT_AM | BIT_AB | \ ++#define WLAN_RCR_CFG_8723B (BIT_APM | BIT_AM | BIT_AB | \  + BIT_CBSSID_DATA | BIT_CBSSID_BCN | \  + BIT_AMF | BIT_HTC_LOC_CTRL | \  + BIT_APP_PHYSTS | BIT_APP_ICV | \ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +#define IQK_DELAY_TIME_8723B 20  + -+#define BCNQ_PAGE_NUM_8723B 0x08 -+#define BCNQ1_PAGE_NUM_8723B 0x00 -+#define WOWLAN_PAGE_NUM_8723B 0x00 -+#define TX_TOTAL_PAGE_NUMBER_8723B\ -+ (0xFF - BCNQ_PAGE_NUM_8723B - BCNQ1_PAGE_NUM_8723B - \ -+ WOWLAN_PAGE_NUM_8723B) -+  +/* rssi in percent (dbm = % - 100); the values are the vendor driver's. */  +static const u8 wl_rssi_step_8723b[] = {60, 50, 44, 30};  +static const u8 bt_rssi_step_8723b[] = {30, 30, 30, 30}; @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + 0x7f8001fe, /* 42, +6.0dB */  +};  + -+static const u32 rtw8723b_cck_pwr_regs[] = { -+ 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29, -+}; ++/* The eight per-rate CCK transmit power registers are consecutive. */ ++#define REG_CCK_SWING 0x0a22 ++#define RTW_CCK_SWING_REG_NUM 8  +  +/*  + * Row 20 (-6.0 dB) intentionally does not match the v5.2.17 vendor driver, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +/*  + * Swing index field of REG_OFDM_0_XA_TX_IQ_IMBALANCE; the table entries -+ * below hold the full register value, hence the shift by __ffs(). ++ * below hold the full register value, so read them back with ++ * u32_get_bits().  + */  +#define OFDM_SWING_MASK GENMASK(31, 22)  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static void rtw8723b_efuse_grant(struct rtw_dev *rtwdev, bool on)  +{ -+ rtw_write8_set(rtwdev, REG_BT_EFUSE_CTRL_8723B, ++ rtw_write8_set(rtwdev, REG_BT_EFUSE_CTRL,  + on ? BIT_BT_PWR_CUT : BIT_BT_OUT_ISO);  +  + rtw8723x_efuse_grant(rtwdev, on); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static u8 rtw8723b_default_ofdm_index(struct rtw_dev *rtwdev)  +{ -+ u32 val32;  + u32 swing;  + u8 i;  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + OFDM_SWING_MASK);  +  + for (i = 0; i < RTW_OFDM_SWING_TABLE_SIZE; i++) { -+ val32 = rtw8723b_ofdm_swing_table[i]; -+ -+ if (val32 >= 0x100000) -+ val32 >>= __ffs(OFDM_SWING_MASK); -+ -+ if (val32 == swing) ++ if (u32_get_bits(rtw8723b_ofdm_swing_table[i], ++ OFDM_SWING_MASK) == swing)  + break;  + }  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static u8 rtw8723b_default_cck_index(struct rtw_dev *rtwdev)  +{ -+ u8 i; ++ const u8 (*table)[RTW_CCK_SWING_REG_NUM];  + u8 swing; ++ u8 i;  + -+ swing = rtw_read8(rtwdev, rtw8723b_cck_pwr_regs[0]); ++ table = rtw8723b_cck_swing_table_ch1_ch13; ++ if (rtwdev->hal.current_channel == 14) ++ table = rtw8723b_cck_swing_table_ch14; ++ ++ swing = rtw_read8(rtwdev, REG_CCK_SWING);  +  + for (i = 0; i < RTW_CCK_SWING_TABLE_SIZE; i++) { -+ if (rtw8723b_cck_swing_table_ch1_ch13[i][0] == swing) ++ if (table[i][0] == swing)  + break;  + }  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + * The power-on sequence sets both, but it runs before the firmware is  + * downloaded, so reassert them here as the vendor driver does.  + */ -+ rtw_write8_set(rtwdev, 0x0049, BIT(1)); -+ rtw_write8_set(rtwdev, 0x0063, BIT(1)); ++ rtw_write32_set(rtwdev, REG_GPIO_INTM, BIT(9)); ++ rtw_write32_set(rtwdev, REG_GPIO_PIN_CTRL_2, BIT(25));  +  + rtw_write16_set(rtwdev, REG_APS_FSMCO, BIT_EN_PDN);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write16_set(rtwdev, REG_CR, MAC_TRX_ENABLE | BIT_MAC_SEC_EN |  + BIT_32K_CAL_TMR_EN);  + -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO)  + rtw_write16_set(rtwdev, REG_PWR_DATA,  + BIT_EEPRPAD_RFE_CTRL_EN);  + -+ /* -+ * rtw_mac_power_on() sets PAD mux bits this chip must not have; -+ * restore the SDIO PAD mux before RF and coex setup. -+ */ -+ rtw8723b_sdio_restore_pad_ctrl(rtwdev, false); -+ } -+  + rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL, 0);  +  + /* Keep every MACID eligible for firmware-scheduled TX at power-on. */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static void rtw8723b_phy_load_bb_tables(struct rtw_dev *rtwdev)  +{ -+ const struct rtw_chip_info *chip = rtwdev->chip;  + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_chip_info *chip = rtwdev->chip;  +  + rtw_load_table(rtwdev, chip->bb_tbl);  + rtw_load_table(rtwdev, chip->agc_tbl); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static void rtw8723b_phy_lck(struct rtw_dev *rtwdev)  +{ -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xb0, RFREG_MASK, 0xdfbe0); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0xdfbe0);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, 0x8c01);  + fsleep(200 * 1000); -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xb0, RFREG_MASK, 0xdffe0); -+} -+ -+static void rtw8723b_phy_rf_config(struct rtw_dev *rtwdev) -+{ -+ rtw8723b_phy_rf6052_config(rtwdev); -+ -+ /* LCK must run as part of the RF configuration. */ -+ rtw8723b_phy_lck(rtwdev); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0xdffe0);  +}  + -+static void rtw8723b_init_tx_buffer_boundary(struct rtw_dev *rtwdev) ++static void rtw8723b_lck(struct rtw_dev *rtwdev)  +{ -+ u8 val8 = TX_TOTAL_PAGE_NUMBER_8723B + 1; ++ /* ++ * The vendor's LC calibration turns the PFD LDO on before the LCK ++ * trigger and off after it, every time it runs, not only during the ++ * initial RF configuration. ++ */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0xdfbe0);  + -+ rtw_write8(rtwdev, REG_BCNQ_BDNY, val8); -+ rtw_write8(rtwdev, REG_MGQ_BDNY, val8); -+ rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, val8); -+ rtw_write8(rtwdev, REG_TRXFF_BNDY, val8); -+ rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, val8); -+} ++ rtw8723x_lck(rtwdev);  + -+static void rtw8723b_init_page_boundary(struct rtw_dev *rtwdev) -+{ -+ /* Matches the value __priority_queue_cfg_legacy() programs here. */ -+ rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, 0x4000 - REPORT_BUF - 1); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0xdffe0);  +}  + -+static void rtw8723b_init_transfer_page_size(struct rtw_dev *rtwdev) ++static void rtw8723b_phy_rf_config(struct rtw_dev *rtwdev)  +{ -+ rtw_write8(rtwdev, REG_PBP, 0x11); -+} ++ rtw8723b_phy_rf6052_config(rtwdev);  + -+static void rtw8723b_init_driver_info_size(struct rtw_dev *rtwdev) -+{ -+ /* NOTE: also is done in rtw_drv_info_cfg */ -+ rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); ++ /* LCK must run as part of the RF configuration. */ ++ rtw8723b_phy_lck(rtwdev);  +}  + -+static void rtw8723b_init_wmac_setting(struct rtw_dev *rtwdev) ++static void rtw8723b_init_transfer_page_size(struct rtw_dev *rtwdev)  +{ -+ /* -+ * The vendor's 8723x filter value plus BIT_APP_FCS, which rtw88 -+ * needs because it advertises RX_INCLUDES_FCS. It is assigned to -+ * hal.rcr and not merely written because rtw_core_start() -+ * rewrites REG_RCR from hal.rcr after power_on, which would undo -+ * a register-only write; fw.c toggles BIT_CBSSID_BCN in it. -+ */ -+ rtwdev->hal.rcr = WLAN_RCR_CFG; -+ rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); -+ -+ rtw_write32(rtwdev, REG_MAR, 0xffffffff); -+ rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); -+ -+ rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); -+ rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); -+ rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); ++ rtw_write8(rtwdev, REG_PBP, ++ u8_encode_bits(PBP_128, PBP_RX_MASK) | ++ u8_encode_bits(PBP_128, PBP_TX_MASK));  +}  +  +static void rtw8723b_init_adaptive_ctrl(struct rtw_dev *rtwdev)  +{ ++ rtw_mac_init_adaptive_ctrl(rtwdev); ++  + /*  + * Firmware validates RRSR at init: narrowing it to the mandatory -+ * rates makes it drop all management TX, so keep the full set. ++ * rates makes it drop all management TX, so let the power save code ++ * keep writing the full set back.  + */ -+ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1);  + rtwdev->dm_info.rrsr_val_init = 0xffff1; -+ rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030);  +}  +  +static void rtw8723b_init_edca(struct rtw_dev *rtwdev)  +{ -+ rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); -+ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); -+ rtw_write16(rtwdev, REG_SIFS, 0x100a); -+ rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); ++ rtw_mac_init_edca(rtwdev);  +  + /*  + * RESP_SIFS must leave the AP enough slack, or it times out before the @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + */  + rtw_write16(rtwdev, REG_RESP_SIFS_CCK, 0x0808);  + rtw_write16(rtwdev, REG_RESP_SIFS_OFDM, 0x0a0a); -+ -+ /* TXOP */ -+ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); -+ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); -+ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); -+ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); -+} -+ -+static void rtw8723b_init_retry_function(struct rtw_dev *rtwdev) -+{ -+ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); -+ rtw_write8(rtwdev, REG_ACKTO, 0x40); -+} -+ -+static void rtw8723b_init_operation_mode(struct rtw_dev *rtwdev) -+{ -+ rtw_write8(rtwdev, REG_BWOPMODE, BIT_BWOPMODE_20MHZ);  +}  +  +static void rtw8723b_init_beacon_parameters(struct rtw_dev *rtwdev) @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write16(rtwdev, REG_BCNTCFG, 0x660F);  +}  + -+static void rtw8723b_init_burst_pkt_len(struct rtw_dev *rtwdev) -+{ -+ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); -+ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); -+ rtw_write8(rtwdev, REG_MAX_AGGR_NUM, 0x1F); -+ rtw_write8(rtwdev, REG_PIFS, 0x00); -+ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); -+ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); -+} -+  +static void rtw8723b_init_antenna_selection(struct rtw_dev *rtwdev)  +{  + rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL);  +}  + -+#define RF_AC 0x00 -+ -+static void rtw8723b_lck(struct rtw_dev *rtwdev) -+{ -+ u32 rf_mode = 0, lc_cal; -+ int ret; -+ u8 val_ctx; -+ u8 rf_val; -+ -+ val_ctx = rtw_read8(rtwdev, REG_CTX); -+ -+ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) -+ rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); -+ else -+ rtw_write8(rtwdev, REG_TXPAUSE, 0xff); -+ -+ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) { -+ /* 1. Read original RF mode */ -+ rf_mode = rtw_read_rf(rtwdev, RF_PATH_A, RF_AC, MASK12BITS); -+ /* 2. Set RF mode = standby mode */ -+ rtw_write_rf(rtwdev, RF_PATH_A, RF_AC, MASK12BITS, (rf_mode & 0x8ffff) | 0x10000); -+ } -+ -+ /* 3. Read RF reg18 */ -+ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, MASK12BITS); -+ -+ /* 4. Set LC calibration begin bit15 */ -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xb0, RFREG_MASK, 0xdfbe0); -+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, MASK12BITS, lc_cal | BIT_LCK); -+ -+ ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, -+ 10000, 1000000, false, -+ rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); -+ if (ret) -+ rtw_warn(rtwdev, "failed to poll LCK status bit\n"); -+ -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xb0, RFREG_MASK, 0xdffe0); -+ -+ /* Restore original situation */ -+ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) { -+ rtw_write8(rtwdev, REG_CTX, val_ctx); -+ -+ rtw_write_rf(rtwdev, RF_PATH_A, RF_AC, MASK12BITS, rf_mode); -+ } else { -+ rtw_write8(rtwdev, REG_TXPAUSE, 0x00); -+ } -+} -+  +static void rtw8723b_inform_rfk_status(struct rtw_dev *rtwdev, bool start)  +{ -+ int ret;  + u8 val8; ++ int ret;  +  + rtw_fw_inform_rfk_status(rtwdev, start);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + return;  +  + ret = read_poll_timeout(rtw_read8, val8, -+ val8 & BIT_RFK_FW_ACK_8723B, ++ val8 & BIT_RFK_FW_ACK,  + 50000, 400000, false, -+ rtwdev, REG_RFK_FW_ACK_8723B); ++ rtwdev, REG_RFK_FW_ACK);  + if (ret)  + rtw_warn(rtwdev, "failed to poll firmware RFK start ack\n");  +}  + -+static int rtw8723b_mac_init(struct rtw_dev *rtwdev) -+{ -+ rtw_write32(rtwdev, REG_INT_MIG, 0); -+ rtw_write32(rtwdev, REG_MCUTST_1, 0x0); -+ -+ rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); -+ rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0x0); -+ -+ return 0; -+} -+  +static void rtw8723b_phy_set_param(struct rtw_dev *rtwdev)  +{  + const struct rtw_chip_info *chip = rtwdev->chip; @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + /* enable CCK and OFDM block */  + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN);  + -+ rtw8723b_init_tx_buffer_boundary(rtwdev); -+ rtw8723b_init_page_boundary(rtwdev);  + rtw8723b_init_transfer_page_size(rtwdev); -+ rtw8723b_init_driver_info_size(rtwdev);  + -+ /* The MAC table sets REG_RCR and REG_MAR, so apply ours after it. */ -+ rtw8723b_init_wmac_setting(rtwdev); ++ /* ++ * The MAC table overwrites REG_MAR with 0xff, which would restrict ++ * multicast reception; accept every multicast address instead. ++ */ ++ rtw_write32(rtwdev, REG_MAR, 0xffffffff); ++ rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff);  +  + rtw8723b_init_adaptive_ctrl(rtwdev);  + rtw8723b_init_edca(rtwdev); -+ rtw8723b_init_retry_function(rtwdev); ++ ++ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ rtw_write8(rtwdev, REG_ACKTO, 0x40);  +  + /* sdio.c sets the DMA mode, but not the burst parameters. */  + rtw_write8(rtwdev, REG_RXDMA_MODE, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) |  + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE));  + -+ rtw8723b_init_operation_mode(rtwdev);  + rtw8723b_init_beacon_parameters(rtwdev); -+ rtw8723b_init_burst_pkt_len(rtwdev); ++ ++ /* configure packet burst */ ++ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); ++ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); ++ rtw_write8(rtwdev, REG_MAX_AGGR_NUM, 0x1F); ++ rtw_write8(rtwdev, REG_PIFS, 0x00); ++ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70);  +  + /*  + * 256 ms per-AC lifetime: the ROM default of ~1 s lets the chip retry @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static u32 rtw8723b_iqk_ant_switch_path(struct rtw_dev *rtwdev)  +{ -+ if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_SDIO) -+ return rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB ? 0x280 : 0x0; -+ -+ /* Scan and connect use the PTA mux, so calibrate the path they use. */ -+ return (rtwdev->efuse.bt_setting & BIT(6)) ? 0x80 : 0x200; -+} -+ -+static void rtw8723b_reassert_rx_path(struct rtw_dev *rtwdev) -+{ -+ u32 rf_wlint_before; -+ u32 rx_path_before; -+ u32 fpga0_before; -+ u8 sys_func_before; -+ u8 rf_ctrl_before; -+ -+ if (!rtw_is_8723bs(rtwdev)) -+ return; ++ bool shared_ant = rtwdev->efuse.bt_setting & BIT(0); ++ bool ant_path_b;  + -+ sys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN); -+ rf_ctrl_before = rtw_read8(rtwdev, REG_RF_CTRL); -+ fpga0_before = rtw_read32(rtwdev, REG_FPGA0_RFMOD); -+ rx_path_before = rtw_read32(rtwdev, REG_BB_RX_PATH_11N); -+ rf_wlint_before = rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK); -+ -+ if ((sys_func_before & WLAN_SYS_FUNC_BB_ENABLE) != -+ WLAN_SYS_FUNC_BB_ENABLE) -+ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, -+ WLAN_SYS_FUNC_BB_ENABLE); -+ -+ if ((rf_ctrl_before & WLAN_RF_CTRL_ENABLE) != WLAN_RF_CTRL_ENABLE) { -+ rtw_write8_set(rtwdev, REG_RF_CTRL, WLAN_RF_CTRL_ENABLE); -+ usleep_range(10, 11); -+ } ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) ++ ant_path_b = shared_ant; ++ else ++ ant_path_b = rtwdev->efuse.bt_setting & BIT(6);  + -+ if ((fpga0_before & (BIT_CCKEN | BIT_OFDMEN)) != -+ (BIT_CCKEN | BIT_OFDMEN)) { -+ rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, -+ BIT_CCKEN | BIT_OFDMEN); -+ } ++ if (!shared_ant || !ant_path_b) ++ return 0x0;  + -+ if (rx_path_before != WLAN_RX_PATH_A_8723B) { -+ rtw_write32(rtwdev, REG_BB_RX_PATH_11N, -+ WLAN_RX_PATH_A_8723B); -+ } -+ -+ if (rf_wlint_before != 0x0780) { -+ rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, -+ 0x0780); -+ } ++ return 0x280;  +}  +  +static void rtw8723b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  + rf_cfgch = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);  + -+ rf_cfgch &= ~RFCFGCH_CHANNEL_MASK; -+ rf_cfgch |= channel & RFCFGCH_CHANNEL_MASK; ++ u32p_replace_bits(&rf_cfgch, channel, RFCFGCH_CHANNEL_MASK);  +  + rf_cfgch &= ~RFCFGCH_BW_MASK; -+ switch (bw) { -+ case RTW_CHANNEL_WIDTH_20: -+ rf_cfgch |= RFCFGCH_BW_20M; -+ break; -+ case RTW_CHANNEL_WIDTH_40: -+ rf_cfgch |= RFCFGCH_BW_40M; -+ break; -+ default: -+ break; -+ } ++ rf_cfgch |= bw == RTW_CHANNEL_WIDTH_40 ? RFCFGCH_BW_40M : ++ RFCFGCH_BW_20M;  +  + /* The vendor driver programs both paths from the path A value. */  + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw8723b_set_channel_rf(rtwdev, channel, bw);  + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);  + rtw8723b_set_channel_bb(rtwdev, bw, primary_chan_idx); -+ rtw8723b_reassert_rx_path(rtwdev); -+ -+ if (rtw_is_8723bs(rtwdev)) { -+ bool keep_pta_owner; -+ -+ keep_pta_owner = test_bit(RTW_FLAG_SCANNING, rtwdev->flags) || -+ (rtw_read32(rtwdev, REG_PAD_CTRL1) & -+ BIT_PAPE_WLBT_SEL); -+ rtw8723b_sdio_restore_pad_ctrl(rtwdev, keep_pta_owner); -+ -+ rtw_write8(rtwdev, REG_RF_CTRL, WLAN_RF_CTRL_ENABLE); -+ fsleep(1000); -+ -+ /* -+ * RF_WLINT bits 0-1 gate the data path into the BB and a prior -+ * IQK or coex run can leave them blocking TX, so re-arm them. -+ */ -+ rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, -+ 0x0780); -+ }  +}  +  +static s8 rtw8723b_cck_rx_power(u8 lna_idx, u8 vga_idx) @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +static u8 rtw8723b_iqk_tx_path_a(struct rtw_dev *rtwdev)  +{  + u32 path_sel; -+ bool sdio_iqk = rtw_is_8723bs(rtwdev);  + u8 status;  +  + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n"); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + /* enable path A PA in TX IQK mode */  + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, -+ sdio_iqk ? 0x18000 : 0x20000); ++ 0x20000);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0003f);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xc7f87);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);  + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);  + -+ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, -+ sdio_iqk ? 0x821303ea : 0x821403ea); ++ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x821403ea);  + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);  + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);  + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw8723b_iqk_ant_switch_path(rtwdev));  +  + /* GNT_BT = 0 */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00000800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00000800);  +  + /* One shot, path A LOK & IQK */  + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_BB_SEL_BTG, path_sel);  +  + /* GNT_BT = 1 */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00001800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00001800);  +  + /* leave IQK mode */  + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, MASKH3BYTES, 0x000000);  + -+ /* Check failed */  + status = rtw8723b_iqk_check_tx_failed(rtwdev);  +  + return status; @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +static u8 rtw8723b_iqk_rx_path_a(struct rtw_dev *rtwdev)  +{  + u32 reg_e94, reg_e9c, val32, path_sel; -+ bool sdio_iqk = rtw_is_8723bs(rtwdev);  + u8 status;  +  + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step1!\n"); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, -+ sdio_iqk ? 0x18000 : 0x30000); ++ 0x30000);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0001f);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xf7fb7);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);  + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);  + -+ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, -+ sdio_iqk ? 0x82130ff0 : 0x82160ff0); ++ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82160ff0);  + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);  + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);  + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw8723b_iqk_ant_switch_path(rtwdev));  +  + /* GNT_BT = 0 (disable BT) */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00000800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00000800);  +  + /* One shot, path A LOK & IQK */  + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_BB_SEL_BTG, path_sel);  +  + /* GNT_BT = 1 */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00001800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00001800);  +  + /* leave IQK mode */  + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, MASKH3BYTES, 0x000000);  + -+ /* Check failed */  + status = rtw8723b_iqk_check_tx_failed(rtwdev);  +  + /* if Tx not OK, ignore Rx */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, MASKH3BYTES, 0x000000);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, -+ sdio_iqk ? 0x18000 : 0x30000); ++ 0x30000);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0001f);  + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xf7d77);  +  + /* PA, PAD setting */ -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xdf, RFREG_MASK, 0xf80); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, RFREG_MASK, 0xf80);  + rtw_write_rf(rtwdev, RF_PATH_A, 0x55, RFREG_MASK, 0x4021f);  +  + /* IQK setting */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);  +  + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82110000); -+ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, -+ sdio_iqk ? 0x2813001f : 0x2816001f); ++ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x2816001f);  + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);  + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw8723b_iqk_ant_switch_path(rtwdev));  +  + /* GNT_BT = 0 */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00000800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00000800);  +  + /* One shot, path A LOK & IQK */  + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_BB_SEL_BTG, path_sel);  +  + /* GNT_BT = 1 */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, 0x00001800); ++ rtw_write32(rtwdev, REG_BT_CONTROL, 0x00001800);  +  + /* leave IQK mode */  + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, MASKH3BYTES, 0x000000);  + -+ /* Check failed */ -+ -+ rtw_write_rf(rtwdev, RF_PATH_A, 0xdf, RFREG_MASK, 0x780); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, RFREG_MASK, 0x780);  +  + status |= rtw8723b_iqk_check_rx_failed(rtwdev);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +rtw8723b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,  + const struct rtw8723x_iqk_backup_regs *backup)  +{ -+ u32 i;  + u8 a_ok; ++ u32 i;  +  + rtw_dbg(rtwdev, RTW_DBG_RFK,  + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  + for (i = 0; i < PATH_IQK_RETRY; i++) {  + a_ok = rtw8723b_iqk_tx_path_a(rtwdev); -+ if (a_ok == IQK_TX_OK) { ++ if (a_ok != IQK_TX_OK) {  + rtw_dbg(rtwdev, RTW_DBG_RFK, -+ "[IQK] path A TX IQK success!\n"); ++ "[IQK] path A TX IQK fail!\n"); ++ result[t][IQK_S1_TX_X] = 0x100; ++ result[t][IQK_S1_TX_Y] = 0x0; ++ continue; ++ }  + -+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, -+ MASKH3BYTES, 0x000000); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK success!\n");  + -+ result[t][IQK_S1_TX_X] = -+ rtw_read32_mask(rtwdev, REG_IQK_RES_TX, -+ BIT_MASK_RES_TX); -+ result[t][IQK_S1_TX_Y] = -+ rtw_read32_mask(rtwdev, REG_IQK_RES_TY, -+ BIT_MASK_RES_TY); -+ break; -+ } ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, ++ MASKH3BYTES, 0x000000);  + -+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n"); -+ result[t][IQK_S1_TX_X] = 0x100; -+ result[t][IQK_S1_TX_Y] = 0x0; ++ result[t][IQK_S1_TX_X] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_TX, ++ BIT_MASK_RES_TX); ++ result[t][IQK_S1_TX_Y] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_TY, ++ BIT_MASK_RES_TY); ++ break;  + }  +  + for (i = 0; i < PATH_IQK_RETRY; i++) {  + a_ok = rtw8723b_iqk_rx_path_a(rtwdev); -+ if (a_ok == (IQK_TX_OK | IQK_RX_OK)) { ++ if (a_ok != (IQK_TX_OK | IQK_RX_OK)) {  + rtw_dbg(rtwdev, RTW_DBG_RFK, -+ "[IQK] path A RX IQK success!\n"); -+ result[t][IQK_S1_RX_X] = -+ rtw_read32_mask(rtwdev, REG_IQK_RES_RX, -+ BIT_MASK_RES_RX); -+ result[t][IQK_S1_RX_Y] = -+ rtw_read32_mask(rtwdev, REG_IQK_RES_RY, -+ BIT_MASK_RES_RY); -+ break; ++ "[IQK] path A RX IQK fail!\n"); ++ result[t][IQK_S1_RX_X] = 0x100; ++ result[t][IQK_S1_RX_Y] = 0x0; ++ continue;  + }  + -+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n"); -+ result[t][IQK_S1_RX_X] = 0x100; -+ result[t][IQK_S1_RX_Y] = 0x0; ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK success!\n"); ++ result[t][IQK_S1_RX_X] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_RX, ++ BIT_MASK_RES_RX); ++ result[t][IQK_S1_RX_Y] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_RY, ++ BIT_MASK_RES_RY); ++ break;  + }  +  + if (a_ok == 0x0)  + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n");  + -+ /* rtl8723b is 1T1R, so path B is not calibrated. */ ++ /* ++ * The vendor driver calibrates path B only when the board is not ++ * 1-antenna (its is2T), which this driver does not support. ++ */  +  + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, MASKH3BYTES, 0x000000);  +} @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + struct rtw_dm_info *dm_info = &rtwdev->dm_info;  + struct rtw8723x_iqk_backup_regs backup;  + s32 result[IQK_ROUND_SIZE][IQK_NR]; -+ u32 bt_control; ++ u32 bt_control_before; ++ u8 final_candidate;  + bool good; -+ u8 final_candidate = IQK_ROUND_INVALID;  + u8 i, j;  +  + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n");  + memset(result, 0, sizeof(result)); ++ final_candidate = IQK_ROUND_INVALID;  +  + rtw8723b_lck(rtwdev);  + rtw8723b_inform_rfk_status(rtwdev, true); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw8723x_iqk_backup_regs(rtwdev, &backup);  +  + /* save default GNT_BT */ -+ bt_control = rtw_read32(rtwdev, REG_BT_CONTROL_8723B); ++ bt_control_before = rtw_read32(rtwdev, REG_BT_CONTROL);  +  + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { -+ if (!rtw_is_8723bs(rtwdev)) -+ rtw8723x_iqk_config_path_ctrl(rtwdev); -+  + rtw8723b_iqk_one_round(rtwdev, result, i, &backup);  +  + rtw_dbg(rtwdev, RTW_DBG_RFK, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);  + }  + -+ if (!rtw_is_8723bs(rtwdev)) -+ rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); -+  + for (j = IQK_ROUND_0; j < i; j++) {  + good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i);  + if (good) { @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg);  +  + /* restore GNT_BT */ -+ rtw_write32(rtwdev, REG_BT_CONTROL_8723B, bt_control); ++ rtw_write32(rtwdev, REG_BT_CONTROL, bt_control_before);  +  + /* Restore RX mode table parameter */  + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n",  + final_candidate);  + -+ for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) ++ for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] Result %u s1: rege94=%x rege9c=%x regea4=%x regeac=%x\n", ++ i, result[i][0], result[i][1], result[i][2], ++ result[i][3]);  + rtw_dbg(rtwdev, RTW_DBG_RFK, -+ "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", -+ i, -+ result[i][0], result[i][1], result[i][2], result[i][3], -+ result[i][4], result[i][5], result[i][6], result[i][7], -+ final_candidate == i ? "(final candidate)" : ""); ++ "[IQK] Result %u s0: rege94=%x rege9c=%x regea4=%x regeac=%x%s\n", ++ i, result[i][4], result[i][5], result[i][6], ++ result[i][7], ++ final_candidate == i ? " (final candidate)" : ""); ++ }  +  + rtw_dbg(rtwdev, RTW_DBG_RFK,  + "[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + s8 txagc_idx)  +{  + struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ const u8 *table; ++ int i;  +  + dm_info->txagc_remnant_cck = txagc_idx;  +  + swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1);  + -+ BUILD_BUG_ON(ARRAY_SIZE(rtw8723b_cck_pwr_regs) != -+ ARRAY_SIZE(rtw8723b_cck_swing_table_ch1_ch13[0])); ++ BUILD_BUG_ON(ARRAY_SIZE(rtw8723b_cck_swing_table_ch1_ch13[0]) != ++ RTW_CCK_SWING_REG_NUM);  + -+ /* Only ch1-13 is wired up; channel 14 is Japan-only and unreachable. */ -+ for (int i = 0; i < ARRAY_SIZE(rtw8723b_cck_pwr_regs); i++) -+ rtw_write8(rtwdev, rtw8723b_cck_pwr_regs[i], -+ rtw8723b_cck_swing_table_ch1_ch13[swing_idx][i]); ++ table = rtwdev->hal.current_channel == 14 ? ++ rtw8723b_cck_swing_table_ch14[swing_idx] : ++ rtw8723b_cck_swing_table_ch1_ch13[swing_idx]; ++ ++ for (i = 0; i < RTW_CCK_SWING_REG_NUM; i++) ++ rtw_write8(rtwdev, REG_CCK_SWING + i, table[i]);  +}  +  +static void rtw8723b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)  +{  + struct rtw_dm_info *dm_info = &rtwdev->dm_info;  + struct rtw_hal *hal = &rtwdev->hal; -+ u8 limit_ofdm; -+ /* 8703b and 8723d seem to use RTW_CCK_SWING_TABLE_SIZE */ -+ u8 limit_cck = 28; /* -2dB */  + s8 final_ofdm_swing_index;  + s8 final_cck_swing_index; ++ /* 8703b and 8723d seem to use RTW_CCK_SWING_TABLE_SIZE */ ++ u8 limit_cck = 28; /* -2dB */ ++ u8 limit_ofdm;  +  + limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + struct rtw_dm_info *dm_info = &rtwdev->dm_info;  + struct rtw_swing_table swing_table;  + u8 thermal_value, delta, path; -+ bool do_iqk = false; ++ bool do_lck = false;  +  + rtw_phy_config_swing_table(rtwdev, &swing_table);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + /* Average the thermal meter readings. */  + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);  + -+ do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); ++ /* ++ * The vendor's power tracking redoes the LC calibration when the ++ * thermal value drifts, but it skips the IQK for this chip, so the ++ * threshold that rtw_phy_pwrtrack_need_iqk() tracks gates only the ++ * LC calibration here. ++ */ ++ do_lck = rtw_phy_pwrtrack_need_iqk(rtwdev);  + -+ if (do_iqk) -+ rtw8723x_lck(rtwdev); ++ if (do_lck) ++ rtw8723b_lck(rtwdev);  +  + if (dm_info->pwr_trk_init_trigger)  + dm_info->pwr_trk_init_trigger = false;  + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,  + RF_PATH_A)) -+ goto iqk; ++ return;  +  + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);  + -+ /* NOTE: also done in rtw_phy_pwrtrack_get_delta */ -+ delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); -+  + for (path = 0; path < rtwdev->hal.rf_path_num; path++) {  + s8 delta_cur, delta_last;  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + dm_info->delta_power_index[path] = delta_cur;  + rtw8723b_pwrtrack_set(rtwdev, path);  + } -+ -+iqk: -+ if (do_iqk) -+ rtw8723b_phy_calibration(rtwdev);  +}  +  +static void rtw8723b_pwr_track(struct rtw_dev *rtwdev)  +{ -+ struct rtw_efuse *efuse = &rtwdev->efuse;  + struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_efuse *efuse = &rtwdev->efuse;  + -+ if (efuse->power_track_type != 0) { -+ rtw_warn(rtwdev, "unsupported power track type\n"); ++ if (efuse->power_track_type != 0)  + return; -+ }  +  + if (!dm_info->pwr_trk_triggered) {  + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + return !!(rtwdev->efuse.bt_setting & BIT(6));  +}  + -+static void rtw8723b_coex_write8_verify(struct rtw_dev *rtwdev, u32 addr, -+ u8 value) -+{ -+ u8 readback; -+ -+ rtw_write8(rtwdev, addr, value); -+ readback = rtw_read8(rtwdev, addr); -+ if (readback == value) -+ return; -+ -+ usleep_range(10, 11); -+ rtw_write8(rtwdev, addr, value); -+} -+  +static void rtw8723b_coex_set_ant_ctrl_by_wifi(struct rtw_dev *rtwdev)  +{  + /* 0x4c[23] = 1, 0x4c[24] = 0: antenna control by 0x64. */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  +static void rtw8723b_coex_cfg_ant_buffer(struct rtw_dev *rtwdev)  +{ -+ u8 sys_func_before; -+ -+ sys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN); -+ if ((sys_func_before & WLAN_SYS_FUNC_BB_ENABLE) != -+ WLAN_SYS_FUNC_BB_ENABLE) { -+ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, -+ WLAN_SYS_FUNC_BB_ENABLE); -+ usleep_range(10, 11); -+ } -+  + rtw_write8_set(rtwdev, REG_PWR_DATA + 1,  + BIT_EEPRPAD_RFE_CTRL_EN >> 8); -+ rtw8723b_coex_write8_verify(rtwdev, REG_RFE_CTRL_E, 0xff); ++ rtw_write8(rtwdev, REG_RFE_CTRL_E, 0xff);  + rtw_write8_mask(rtwdev, REG_RFE_CTRL_ANT_SW, BIT_RFE_CTRL_ANT_SW_SEL, 0x3);  + rtw_write8(rtwdev, REG_RFE_CTRL_ANTA_SRC, 0x77);  +}  + -+static u32 rtw8723b_coex_write_bb_sel_btg(struct rtw_dev *rtwdev, u32 value) -+{ -+ u32 readback; -+ u8 sys_func_before; -+ -+ if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_SDIO) { -+ rtw_write32(rtwdev, REG_BB_SEL_BTG, value); -+ return rtw_read32(rtwdev, REG_BB_SEL_BTG); -+ } -+ -+ sys_func_before = rtw_read8(rtwdev, REG_SYS_FUNC_EN); -+ if ((sys_func_before & WLAN_SYS_FUNC_BB_ENABLE) != -+ WLAN_SYS_FUNC_BB_ENABLE) { -+ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, -+ WLAN_SYS_FUNC_BB_ENABLE); -+ usleep_range(10, 11); -+ } -+ -+ rtw_write32(rtwdev, REG_BB_SEL_BTG, value); -+ readback = rtw_read32(rtwdev, REG_BB_SEL_BTG); -+ if (readback == value) -+ return readback; -+ -+ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, WLAN_SYS_FUNC_BB_ENABLE); -+ usleep_range(10, 11); -+ rtw_write32(rtwdev, REG_BB_SEL_BTG, value); -+ -+ return rtw_read32(rtwdev, REG_BB_SEL_BTG); -+} -+  +static u32 rtw8723b_coex_ant_path_value(struct rtw_dev *rtwdev, u8 pos_type)  +{  + bool aux = rtw8723b_coex_ant_is_aux(rtwdev); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) {  + rtw_write8(rtwdev, REG_GNT_BT, 0x18);  + rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, 0x4); -+ rtw_write8_clr(rtwdev, REG_BT_ANT_SEL_8723B, -+ BIT_BT_SEL_BY_WIFI_8723B); ++ rtw_write8_clr(rtwdev, REG_BT_ANT_SEL, ++ BIT_BT_SEL_BY_WIFI);  + rtw8723b_coex_set_ant_ctrl_by_bt(rtwdev);  + ant_path = rtw8723b_coex_ant_path_value(rtwdev,  + COEX_SWITCH_TO_BT); -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, ant_path); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, ant_path);  +  + rtw_dbg(rtwdev, RTW_DBG_COEX,  + "[BTCoex], 8723bs ant switch by BT BB_SEL_BTG=0x%08x 0x4c=0x%08x 0x67=0x%02x 0x765=0x%02x 0x76e=0x%02x\n",  + rtw_read32(rtwdev, REG_BB_SEL_BTG),  + rtw_read32(rtwdev, REG_LED_CFG), -+ rtw_read8(rtwdev, REG_BT_ANT_SEL_8723B), ++ rtw_read8(rtwdev, REG_BT_ANT_SEL),  + rtw_read8(rtwdev, REG_GNT_BT),  + rtw_read8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL));  + return;  + }  +  + rtw8723b_coex_set_ant_ctrl_by_wifi(rtwdev); -+ rtw_write8(rtwdev, REG_BT_ANT_SEL_8723B, 0x20); ++ rtw_write8(rtwdev, REG_BT_ANT_SEL, 0x20);  +  + if (ctrl_type == COEX_SWITCH_CTRL_BY_BBSW &&  + pos_type == COEX_SWITCH_TO_BT) { @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + ant_path = rtw8723b_coex_ant_path_value(rtwdev,  + COEX_SWITCH_TO_NOCARE);  + -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, ant_path); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, ant_path);  + rtw8723b_sdio_restore_pad_ctrl(rtwdev,  + ctrl_type == COEX_SWITCH_CTRL_BY_PTA);  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + "[BTCoex], 8723bs ant switch ctrl=%u pos=%u BB_SEL_BTG=0x%08x 0x4c=0x%08x 0x67=0x%02x 0x765=0x%02x 0x76e=0x%02x\n",  + ctrl_type, pos_type, rtw_read32(rtwdev, REG_BB_SEL_BTG),  + rtw_read32(rtwdev, REG_LED_CFG), -+ rtw_read8(rtwdev, REG_BT_ANT_SEL_8723B), ++ rtw_read8(rtwdev, REG_BT_ANT_SEL),  + rtw_read8(rtwdev, REG_GNT_BT),  + rtw_read8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL));  +}  +  +static void rtw8723b_coex_set_rfe_type(struct rtw_dev *rtwdev)  +{ -+ struct rtw_coex *coex = &rtwdev->coex; -+ struct rtw_coex_rfe *coex_rfe = &coex->rfe;  + enum rtw_hci_type hci_type = rtw_hci_type(rtwdev); -+ u32 reg; ++ struct rtw_coex_rfe *coex_rfe = &rtwdev->coex.rfe;  + bool aux = rtw8723b_coex_ant_is_aux(rtwdev); ++ u32 reg;  +  + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;  + coex_rfe->ant_switch_polarity = aux ? 1 : 0; @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + coex_rfe->ant_switch_diversity = false;  + coex_rfe->wlg_at_btg = true;  + -+ rtw_write8(rtwdev, REG_BT_ANT_SEL_8723B, 0x20); ++ rtw_write8(rtwdev, REG_BT_ANT_SEL, 0x20);  +  + /* set GRAN_BT = 1 */  + rtw_write8(rtwdev, REG_GNT_BT, 0x18); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +  + switch (hci_type) {  + case RTW_HCI_TYPE_USB: -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, 0x0); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x0);  + rtw_write8(rtwdev, 0xfe08, 0x1);  + break;  + case RTW_HCI_TYPE_PCIE:  + reg = 0x384;  + /* 0xc3[6]: 0 = S1 (main, path A), 1 = S0 (aux, path B). */  + if (aux) { -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, 0x0); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x0);  + rtw_write8(rtwdev, reg, 0x1);  + } else { -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, 0x280); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x280);  + rtw_write8(rtwdev, reg, 0x0);  + }  + break; @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780);  +  + if (aux) { -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, 0x0); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x0);  + rtw_write8(rtwdev, REG_SDIO_H2C, 0x1);  + } else { -+ rtw8723b_coex_write_bb_sel_btg(rtwdev, 0x280); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x280);  + rtw_write8(rtwdev, REG_SDIO_H2C, 0x0);  + }  + @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  +{  + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;  + const u8 *data = txdesc; -+ u16 checksum = 0;  + int words = 32 / 2; ++ u16 checksum = 0;  +  + /* Unlike the shared 8723x helper, the checksum is not inverted here. */  + le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + return ret;  +  + /* ++ * Report a power track type this driver does not implement once, ++ * here, rather than on every two second pwr_track() tick. ++ */ ++ if (efuse->power_track_type != 0) ++ rtw_warn(rtwdev, "unsupported power track type\n"); ++ ++ /*  + * No firmware hardware feature report exists, so fill the hardware  + * capability here; a zero stream count kills the HT MCS set.  + */ @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + .power_on = rtw_power_on,  + .power_off = rtw_power_off,  + -+ .mac_init = rtw8723b_mac_init, ++ .mac_init = rtw8723x_mac_init,  + .mac_postinit = rtw8723x_mac_postinit,  +  + .dump_fw_crash = NULL, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + .false_alarm_statistics = rtw8723x_false_alarm_statistics,  + .phy_calibration = rtw8723b_phy_calibration,  + .dpk_track = NULL, -+ /* REG_CSRATIO does not exist on this chip generation. */ -+ .cck_pd_set = NULL, ++ .cck_pd_set = rtw_phy_cck_pd_set,  + .pwr_track = rtw8723b_pwr_track,  + .config_bfee = NULL,  + .set_gid_table = NULL, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + .band = RTW_BAND_2G,  + .page_size = TX_PAGE_SIZE,  + .dig_min = 0x20, -+ .usb_tx_agg_desc_num = 1, ++ .usb_tx_agg_desc_num = 6,  + /*  + * The firmware reports id 0xfd instead of C2H_HW_FEATURE_REPORT, so  + * the hardware feature report is not supported on this chip. @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + .vht_supported = false,  + .lps_deep_mode_supported = 0,  + .sys_func_en = 0xfd, ++ .rcr = WLAN_RCR_CFG_8723B,  + .pwr_on_seq = card_enable_flow_8723b,  + .pwr_off_seq = card_disable_flow_8723b,  + .page_table = page_table_8723b, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new)  + /* used only in pci.c, not needed for SDIO devices */  + .intf_table = NULL,  + .dig = rtw8723x_common.dig, -+ .dig_cck = rtw8723x_common.dig_cck, ++ /* The vendor driver never writes the CCK IGI on this chip. */ ++ .dig_cck = NULL,  + .rf_sipi_addr = {0x840, 0x844},  + .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr,  + .fix_rf_phy_num = 2, @@ drivers/net/wireless/realtek/rtw88/rtw8723b.c (new) ## drivers/net/wireless/realtek/rtw88/rtw8723b.h (new) ##  @@  +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* -+ * Copyright(c) 2026 Realtek Corporation ++/* Copyright(c) 2026 Realtek Corporation ++ * Copyright(c) Michael Straube  ++ * Copyright(c) 2024-2026 Luka Gejak   + */  +  +#ifndef __RTW8723B_H__ 4: 0dd677639832 ! 6: f71dba13271d wifi: rtw88: 8723bs: add the RTL8723BS SDIO bind @@ Commit message  The device id table carries the same six ids the staging rtl8723bs driver binds to this chip, so the staging driver can be dropped without - losing hardware support. I only have the 0xb723 variant to test with; - the other five are included for parity with staging, which has carried + losing hardware support. I only have the 0xb723 variant to test with. + The other five are included for parity with staging, which has carried them for years, rather than being left behind.  The RTL8723B chip support is based on the initial work by @@ Commit message ## drivers/net/wireless/realtek/rtw88/rtw8723bs.c (new) ##  @@  +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* -+ * Copyright(c) 2007-2017 Realtek Corporation ++/* Copyright(c) 2026 Realtek Corporation  + * Copyright(c) Michael Straube   + * Copyright(c) 2024-2026 Luka Gejak   + */ @@ drivers/net/wireless/realtek/rtw88/rtw8723bs.c (new)  +};  +module_sdio_driver(rtw_8723bs_driver);  + -+MODULE_AUTHOR("Michael Straube ");  +MODULE_AUTHOR("Luka Gejak "); ++MODULE_AUTHOR("Michael Straube ");  +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723bs driver");  +MODULE_LICENSE("Dual BSD/GPL"); 5: 2038a583f4c3 = 7: d4cd7ae17a32 wifi: rtw88: 8723bs: enable building the RTL8723BS driver 6: a90fbd70078c < -: ------------ MAINTAINERS: add entry for the RTL8723B rtw88 driver