* Re: [PATCH ath-next] wifi: ath12k: use %u for unsigned variables in QMI debug logs
From: Baochen Qiang @ 2026-06-24 9:39 UTC (permalink / raw)
To: Raj Kumar Bhagat, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260623-qmi-debug-log-v1-1-79471aa8b898@oss.qualcomm.com>
On 6/23/2026 12:04 PM, Raj Kumar Bhagat wrote:
> Replace incorrect %d format specifiers with %u for unsigned variables
> in qmi.c debug messages. Also add missing trailing '\n' in log messages
> to ensure proper termination. No functional change intended.
>
> Tested-on: Compile tested only.
>
> Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH ath-next] wifi: ath12k: Fix inconsistencies in struct qmi_elem_info initializers
From: Baochen Qiang @ 2026-06-24 9:36 UTC (permalink / raw)
To: Raj Kumar Bhagat, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260623-qmi-inconsistencies-v1-1-0fc17f2b8338@oss.qualcomm.com>
On 6/23/2026 12:13 PM, Raj Kumar Bhagat wrote:
> Currently, the struct qmi_elem_info initializers in qmi.c are inconsistent
> in how they align the assignments, with tabs being used in the majority of
> places but spaces being used in some places. In those places replace the
> spaces with tabs for consistency.
>
> Also fix incorrect and missing terminating records in the following
> qmi_elem_info initializers:
> - qmi_wlanfw_shadow_reg_cfg_s_v01_ei[]
> - qmi_wlanfw_mem_ready_ind_msg_v01_ei[]
> - qmi_wlanfw_fw_ready_ind_msg_v01_ei[]
>
> Tested-on: Compile tested only.
>
> Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH ath-next v2] wifi: ath12k: advertise ieee_link_id in vdev start MLO params
From: Rameshkumar Sundaram @ 2026-06-24 9:11 UTC (permalink / raw)
To: Manish Dharanenthiran, ath12k
Cc: linux-wireless, Hari Naraayana Desikan Kannan, Karthik M
In-Reply-To: <20260623-ieee_link_id-v2-1-8a89d71baf58@oss.qualcomm.com>
On 6/23/2026 11:16 AM, Manish Dharanenthiran wrote:
> Firmware builds the AP MLD partner profile from the hw_link_id passed in
> the vdev start parameters. However, hw_link_id is not always the same as
> the logical per-MLD ieee_link_id, since ieee_link_id is assigned per MLD
> and not per pdev.
>
> This matters in mixed MLO and SLO setups. For example:
>
> MLD 1 - 5 GHz + 6 GHz (2-link MLO): ieee_link_id 0 and 1
> MLD 2 - 6 GHz only (1-link SLO): ieee_link_id 0
> MLD 3 - 5 GHz only (1-link SLO): ieee_link_id 0
>
> The same physical 6 GHz radio can use ieee_link_id 1 for one
> MLD and ieee_link_id 0 for another. Pass the correct ieee_link_id to
> firmware so it can build accurate per-STA profile elements.
>
> Add ieee_link_id to wmi_vdev_start_mlo_params for the self link and to
> wmi_partner_link_info for each partner link. Populate these fields in
> ath12k_mac_mlo_get_vdev_args() from the corresponding vdev link_id
> before encoding the WMI command.
>
> Introduce two new flags in ML params to indicate to firmware when
> the new fields are valid:
>
> ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID BIT(18) for the self link
> ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19) for partner links
>
> Firmware parses ieee_link_id only when the matching flag is set.
>
> Also fix the debug message by using correct format specifiers and host-endian
> values instead of __le32 values.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>
> Co-developed-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
> Signed-off-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
> Co-developed-by: Karthik M <karthik.m@oss.qualcomm.com>
> Signed-off-by: Karthik M <karthik.m@oss.qualcomm.com>
> Signed-off-by: Manish Dharanenthiran <manish.dharanenthiran@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
--
--
Ramesh
^ permalink raw reply
* [PATCH wireless] wifi: libertas: fix memory leak in helper_firmware_cb()
From: Dawei Feng @ 2026-06-24 8:53 UTC (permalink / raw)
To: linux-wireless
Cc: dcbw, linville, libertas-dev, linux-kernel, jianhao.xu, zilin,
Dawei Feng, stable
helper_firmware_cb() neglects to free the single-stage firmware image
after a successful async load, leading to a memory leak in the USB
firmware-download path.
Fix this memory leak by calling release_firmware() immediately after
lbs_fw_loaded() returns.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still present in
the current wireless tree.
An x86_64 allyesconfig build showed no new warnings. As we do not have
compatible Libertas USB hardware for exercising this firmware-download
path, no runtime testing was able to be performed.
Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
Cc: stable@vger.kernel.org
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
---
drivers/net/wireless/marvell/libertas/firmware.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
index f124110944b7..9bf7d4c207b9 100644
--- a/drivers/net/wireless/marvell/libertas/firmware.c
+++ b/drivers/net/wireless/marvell/libertas/firmware.c
@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
} else {
/* No main firmware needed for this helper --> success! */
lbs_fw_loaded(priv, 0, firmware, NULL);
+ release_firmware(firmware);
}
}
--
2.34.1
^ permalink raw reply related
* Re: [PATCH ath-next] wifi: ath12k: Fix inconsistencies in struct qmi_elem_info initializers
From: Rameshkumar Sundaram @ 2026-06-24 8:51 UTC (permalink / raw)
To: Raj Kumar Bhagat, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260623-qmi-inconsistencies-v1-1-0fc17f2b8338@oss.qualcomm.com>
On 6/23/2026 9:43 AM, Raj Kumar Bhagat wrote:
> Currently, the struct qmi_elem_info initializers in qmi.c are inconsistent
> in how they align the assignments, with tabs being used in the majority of
> places but spaces being used in some places. In those places replace the
> spaces with tabs for consistency.
>
> Also fix incorrect and missing terminating records in the following
> qmi_elem_info initializers:
> - qmi_wlanfw_shadow_reg_cfg_s_v01_ei[]
> - qmi_wlanfw_mem_ready_ind_msg_v01_ei[]
> - qmi_wlanfw_fw_ready_ind_msg_v01_ei[]
>
> Tested-on: Compile tested only.
>
> Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
^ permalink raw reply
* [PATCH wireless] wifi: iwlwifi: dvm: fix memory leak in iwl_op_mode_dvm_start()
From: Dawei Feng @ 2026-06-24 8:44 UTC (permalink / raw)
To: miriam.rachel.korenblit
Cc: tglx, mingo, jiasheng, kees, johannes.berg, error27,
emmanuel.grumbach, linux-wireless, linux-kernel, jianhao.xu,
zilin, Dawei Feng, stable
In iwl_op_mode_dvm_start(), jumping to out_free_eeprom currently bypasses
the out_free_eeprom_blob label. Consequently, error paths triggered after
successfully parsing the EEPROM free priv->nvm_data but leak
priv->eeprom_blob.
Fix this memory leak by reordering the error handling labels so
that out_free_eeprom falls through to out_free_eeprom_blob.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1-rc6.
An x86_64 allyesconfig build showed no new warnings. As we do not have
supported Intel DVM wireless hardware and firmware to test with, no
runtime testing was able to be performed.
Fixes: 26a7ca9a71a3 ("iwlwifi: refactor EEPROM reading/parsing")
Cc: stable@vger.kernel.org
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
---
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index ca5a8140908a..6bd5b6d84b2a 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1511,10 +1511,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
priv->workqueue = NULL;
out_uninit_drv:
iwl_uninit_drv(priv);
-out_free_eeprom_blob:
- kfree(priv->eeprom_blob);
out_free_eeprom:
kfree(priv->nvm_data);
+out_free_eeprom_blob:
+ kfree(priv->eeprom_blob);
out_leave_trans:
iwl_trans_op_mode_leave(priv->trans);
out_free_hw:
--
2.34.1
^ permalink raw reply related
* Re: [PATCH ath-next] wifi: ath12k: use %u for unsigned variables in QMI debug logs
From: Rameshkumar Sundaram @ 2026-06-24 8:33 UTC (permalink / raw)
To: Raj Kumar Bhagat, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260623-qmi-debug-log-v1-1-79471aa8b898@oss.qualcomm.com>
On 6/23/2026 9:34 AM, Raj Kumar Bhagat wrote:
> Replace incorrect %d format specifiers with %u for unsigned variables
> in qmi.c debug messages. Also add missing trailing '\n' in log messages
> to ensure proper termination. No functional change intended.
>
> Tested-on: Compile tested only.
>
> Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v10] Add device-specific reset for Qualcomm devices
From: Baochen Qiang @ 2026-06-24 7:47 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez, bhelgaas, alex, mani
Cc: jjohnson, linux-pci, linux-wireless, ath11k, ath12k, mhi,
linux-kernel
In-Reply-To: <20260623183115.1585273-1-jtornosm@redhat.com>
On 6/24/2026 2:31 AM, Jose Ignacio Tornos Martinez wrote:
> Some Qualcomm PCIe devices (WCN6855/WCN7850 WiFi cards, SDX62/SDX65 modems)
> lack working reset methods for VFIO passthrough scenarios. These devices
> have no FLR capability, advertise NoSoftRst+ (blocking PM reset), and have
> broken bus reset.
>
> The problem manifests in VFIO passthrough scenarios:
>
> - WCN6855 (17cb:1103) and WCN7850 (17cb:1107) WiFi devices:
> Normal VM operation works fine, including clean shutdown/reboot.
> However, when the VM terminates uncleanly (crash, force-off), VFIO
> attempts to reset the device before it can be assigned to another VM.
> Without a working reset method, the device remains in an undefined state,
> preventing reuse.
>
> - SDX62/SDX65 (17cb:0308) 5G modems: Never successfully initialize even
> on first VM assignment without proper reset capability.
>
> Add device-specific reset methods using BAR-space hardware reset registers
> that exist in these devices:
>
> - WCN6855/WCN7850 WiFi devices use SoC global reset via BAR0 (sequence from
> ath11k/ath12k driver: ath11k_pci_soc_global_reset(), ath11k_pci_sw_reset(),
> ath11k_mhi_set_mhictrl_reset()):
> - Write/clear reset bit at offset 0x3008
> - Wait for PCIe link recovery (up to 5 seconds)
> - Clear MHI controller SYSERR status at offset 0x38
>
> - SDX62/SDX65 modem devices use MHI SoC reset via BAR0 (sequence from MHI
> driver: mhi_soc_reset(), mhi_pci_reset_prepare()):
> - Write reset request to offset 0xb0
> - Wait 2 seconds for reset completion
>
> These are true hardware reset mechanisms (not power management or firmware
> error recovery), providing proper device reset for VFIO scenarios.
>
> Testing was performed on desktop platforms with M.2 WiFi and modem cards
> using M.2-to-PCIe adapters, including extensive force-reset cycling to
> verify stability.
>
> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
> ---
> v10:
> - Complete redesign based on maintainer feedback (Manivannan Sadhasivam,
> Alex Williamson): use actual hardware reset registers from
> device drivers instead of D3hot power cycling
> v9: https://lore.kernel.org/all/20260612142638.1243895-1-jtornosm@redhat.com/
>
> drivers/pci/quirks.c | 118 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 118 insertions(+)
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 431c021d7414..8ad3f214e520 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -4240,6 +4240,121 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
> return 0;
> }
>
> +#define QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET 0x3008
> +#define QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET_V BIT(0)
> +#define QUALCOMM_WIFI_MHISTATUS 0x48
> +#define QUALCOMM_WIFI_MHICTRL 0x38
> +#define QUALCOMM_WIFI_MHICTRL_RESET_MASK 0x2
> +
> +/*
> + * Qualcomm WiFi device-specific reset using SoC global reset via BAR0
> + * registers.
> + */
> +static int reset_qualcomm_wifi(struct pci_dev *pdev, bool probe)
> +{
> + bool link_recovered = false;
> + unsigned long timeout;
> + void __iomem *bar;
> + u32 val;
> + u16 cmd;
> +
> + if (probe)
> + return 0;
> +
> + if (pdev->current_state != PCI_D0)
> + return -EINVAL;
> +
> + pci_read_config_word(pdev, PCI_COMMAND, &cmd);
> + pci_write_config_word(pdev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
> +
> + bar = pci_iomap(pdev, 0, 0);
> + if (!bar) {
> + pci_write_config_word(pdev, PCI_COMMAND, cmd);
> + return -ENODEV;
> + }
> +
> + val = ioread32(bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET is beyond the first 4K bar area hence requires MHI
wakeup before accessing, see [1]. the wakeup callback for WCN6855 is
ath11k_pci_bus_wake_up() which calls mhi_device_get_sync(). Not sure how this can be done
here. Maybe Mani can provide some hints?
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/wireless/ath/ath11k/pcic.c#n216
> + val |= QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET_V;
> + iowrite32(val, bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
> + ioread32(bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
> +
> + msleep(10);
> +
> + val &= ~QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET_V;
> + iowrite32(val, bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
> + ioread32(bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
> +
> + msleep(10);
> +
> + timeout = jiffies + msecs_to_jiffies(5000);
> + while (time_before(jiffies, timeout)) {
> + val = ioread32(bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
> + if (val != 0xffffffff) {
> + link_recovered = true;
> + break;
> + }
> + msleep(20);
> + }
> +
> + if (!link_recovered) {
> + pci_err(pdev, "PCIe link failed to recover after reset\n");
> + goto out_restore;
> + }
> +
> + /* After SOC_GLOBAL_RESET, MHISTATUS may still have SYSERR bit set
> + * and thus need to set MHICTRL_RESET to clear SYSERR.
> + */
> + iowrite32(QUALCOMM_WIFI_MHICTRL_RESET_MASK, bar + QUALCOMM_WIFI_MHICTRL);
> + ioread32(bar + QUALCOMM_WIFI_MHICTRL);
> +
> + msleep(10);
> +
> +out_restore:
> + pci_iounmap(pdev, bar);
> + pci_write_config_word(pdev, PCI_COMMAND, cmd);
> +
> + return link_recovered ? 0 : -ETIMEDOUT;
> +}
> +
> +#define MHI_SOC_RESET_REQ_OFFSET 0xb0
> +#define MHI_SOC_RESET_REQ BIT(0)
> +
> +/*
> + * Qualcomm modem device-specific reset using MHI SoC reset via BAR0
> + * register.
> + */
> +static int reset_qualcomm_modem(struct pci_dev *pdev, bool probe)
> +{
> + void __iomem *bar;
> + u16 cmd;
> +
> + if (probe)
> + return 0;
> +
> + if (pdev->current_state != PCI_D0)
> + return -EINVAL;
> +
> + pci_read_config_word(pdev, PCI_COMMAND, &cmd);
> + pci_write_config_word(pdev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
> +
> + bar = pci_iomap(pdev, 0, 0);
> + if (!bar) {
> + pci_write_config_word(pdev, PCI_COMMAND, cmd);
> + return -ENODEV;
> + }
> +
> + iowrite32(MHI_SOC_RESET_REQ, bar + MHI_SOC_RESET_REQ_OFFSET);
> + ioread32(bar + MHI_SOC_RESET_REQ_OFFSET);
> +
> + /* Be sure device reset has been executed */
> + msleep(2000);
> +
> + pci_iounmap(pdev, bar);
> + pci_write_config_word(pdev, PCI_COMMAND, cmd);
> +
> + return 0;
> +}
> +
> static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
> { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
> reset_intel_82599_sfp_virtfn },
> @@ -4255,6 +4370,9 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
> reset_chelsio_generic_dev },
> { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF,
> reset_hinic_vf_dev },
> + { PCI_VENDOR_ID_QCOM, 0x1103, reset_qualcomm_wifi }, /* WCN6855 WiFi */
> + { PCI_VENDOR_ID_QCOM, 0x1107, reset_qualcomm_wifi }, /* WCN7850 WiFi */
> + { PCI_VENDOR_ID_QCOM, 0x0308, reset_qualcomm_modem }, /* SDX62/SDX65 modems */
> { 0 }
> };
>
^ permalink raw reply
* [PATCH] wifi: carl9170: bail out on invalid command response to fix stack-out-of-bounds write
From: hewei-gikaku @ 2026-06-24 5:32 UTC (permalink / raw)
To: Christian Lamparter
Cc: linux-wireless, linux-kernel, HE WEI, syzbot+5c1ca6ccaa1215781cac
From: HE WEI (ギカク) <skyexpoc@gmail.com>
carl9170_cmd_callback() copies a command response coming from the USB
device into ar->readbuf using the device-reported length:
memcpy(ar->readbuf, buffer + 4, len - 4);
ar->readbuf points at the buffer supplied by the caller of
carl9170_exec_cmd(), which is frequently an on-stack buffer sized to the
expected response length (ar->readlen).
The preceding sanity check only emits a warning and schedules a restart
when ar->readlen != len - 4; it does not stop processing, so the
memcpy() still runs with the attacker-controlled length. A malicious or
malfunctioning AR9170 USB device can therefore answer a pending command
with an over-sized response and overflow ar->readbuf, as reported by
syzbot:
BUG: KASAN: stack-out-of-bounds Write in carl9170_handle_command_response
The comment in that branch already documents the intended behaviour
("Do not complete. The command times out, and we get a stack trace from
there."), but the return statement was missing. Return after
carl9170_restart() so an over-/under-sized response is neither copied
into ar->readbuf nor completed; carl9170_exec_cmd() then times out and
clears readbuf in its error path.
Reported-by: syzbot+5c1ca6ccaa1215781cac@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac
Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
---
drivers/net/wireless/ath/carl9170/rx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -145,6 +145,7 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
* and we get a stack trace from there.
*/
carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
+ return;
}
spin_lock(&ar->cmd_lock);
--
2.43.0
^ permalink raw reply
* RE: [REGRESSION] rtw89: RTL8922AE Wi-Fi broken in Kernel 7.0 (and 6.18+) due to mac80211 API changes
From: Ping-Ke Shih @ 2026-06-24 5:23 UTC (permalink / raw)
To: Gmail, linux-wireless@vger.kernel.org
In-Reply-To: <c26fda96-aa91-4372-8d24-35d3fa44fc09@gmail.com>
Gmail <helder.bertoldo@gmail.com> wrote:
> I am reporting a regression regarding the Realtek RTL8922AE Wi-Fi
> adapter (rtw89) on a Gigabyte X870M Aorus Elite Wifi7 motherboard.
>
> The adapter works perfectly on Kernel 6.17.7, but it fails to initialize
> or is not recognized in newer kernels, specifically 6.18, 6.19, and the
> current 7.0.x series used in the Bazzite (Fedora-based) testing branch.
Please share kernel log of 6.17.7 (work well) and 6.18 (failed to initialize).
I checked the change of the rtw89 driver from 6.17 to 6.18, but I can't
find the obvious change for RTL8922AE though.
>
> Technical details:
> The issue seems related to recent architectural changes in the mac80211
> subsystem:
>
> 1. Signature changes in 'struct ieee80211_ops': Several callbacks
> (including .config, .stop, and .set_rts_threshold) now require the
> 'radio_idx' parameter to support multi-radio wiphy/MLO. It appears the
> rtw89 driver in these kernel builds might not have been fully updated to
> match these new signatures, leading to incompatible pointer type errors
> or initialization failures.
Are you sure? The changes of API will be compatible with existing
functionalities.
>
> 2. Removal of init_dummy_netdev: The driver code seems to still
> reference init_dummy_netdev, which was replaced by alloc_netdev_dummy()
> in the wireless-next/net-next trees.
It has been alloc_netdev_dummy() already.
If you are using out-of-tree driver, please just use in-tree driver.
>
> Hardware Info:
> - Chipset: Realtek RTL8922AE
> - PCI ID: [10ec:8922] (Please verify this ID on your system using 'lspci
> -nn')
> - Working Kernel: 6.17.7
> - Broken Kernels: 6.18.x, 6.19.x, 7.0.x
>
> I am using the OGC Kernel from the Bazzite project, but the issue
> appears to stem from the upstream driver synchronization with the new
> mac80211 API.
Can you use 6.17.7 and then apply patches of the rtw89 driver one by one
from 6.18.x? That can find the cause.
>
> Are there any pending patches in the rtw-next tree that address these
> specific ieee80211_ops signature changes for the 8922AE?
The number of rtw89 patches between 6.17 and 6.18 is about 40.
Trying above suggestion will be easier to address problem.
^ permalink raw reply
* [PATCH rtw-next 10/10] wifi: rtw89: coex: Add RTL8922D chip string
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Add string for logic using and show logs.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 6f9bb31b5263..1361d4d54528 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -313,6 +313,7 @@ static u32 chip_id_to_bt_rom_code_id(u32 id)
case RTL8851B:
return 0x8851;
case RTL8922A:
+ case RTL8922D:
return 0x8922;
default:
return 0;
@@ -347,6 +348,8 @@ static char *chip_id_str(u32 id)
return "RTL8851B";
case RTL8922A:
return "RTL8922A";
+ case RTL8922D:
+ return "RTL8922D";
default:
return "UNKNOWN";
}
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 09/10] wifi: rtw89: coex: Add Wi-Fi firmware 0.35.94.1 support for RTL8922D
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
The firmware 0.35.94.1 included several new features. Wi-Fi TX power
setting offload to firmware. Including dual BT / dual Wi-Fi MAC related
configurations.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 62 +++++++++++++++++++----
drivers/net/wireless/realtek/rtw89/core.h | 3 ++
2 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 572eed7939e1..6f9bb31b5263 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -133,6 +133,15 @@ static const u32 cxtbl[] = {
static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
/* firmware version must be in decreasing order for each chip */
+ {RTL8922D, RTW89_FW_VER_CODE(0, 35, 94, 0),
+ .fcxbtcrpt = 11, .fcxtdma = 8, .fcxslots = 7, .fcxcysta = 8,
+ .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 8,
+ .fcxbtver = 8, .fcxbtscan = 8, .fcxbtafh = 8, .fcxbtdevinfo = 8,
+ .fwlrole = 10, .frptmap = 5, .fcxctrl = 9, .fcxinit = 10,
+ .fwevntrptl = 1, .fwc2hfunc = 4, .drvinfo_ver = 3, .info_buf = 1800,
+ .max_role_num = 6, .fcxosi = 6, .fcxmlo = 2, .bt_desired = 8,
+ .fcxtrx = 9,
+ },
{RTL8852BT, RTW89_FW_VER_CODE(0, 29, 122, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
@@ -156,7 +165,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 2, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 3, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9,
.fcxtrx = 7,
},
@@ -2423,6 +2432,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
break;
case 3:
case 4:
+ case 5:
bit_map = BIT(5);
break;
default:
@@ -2438,6 +2448,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
break;
case 3:
case 4:
+ case 5:
bit_map = BIT(6);
break;
default:
@@ -2451,6 +2462,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
break;
case 3:
case 4:
+ case 5:
bit_map = BIT(7);
break;
default:
@@ -2465,6 +2477,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
case 3:
break;
case 4:
+ case 5:
bit_map = BIT(8);
break;
default:
@@ -2481,6 +2494,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
bit_map = BIT(8);
break;
case 4:
+ case 5:
bit_map = BIT(9);
break;
default:
@@ -2488,7 +2502,10 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
}
break;
case RPT_EN_TEST:
- bit_map = BIT(31);
+ if (ver->frptmap == 5)
+ bit_map = BIT(10);
+ else
+ bit_map = BIT(31);
break;
case RPT_EN_WL_ALL:
switch (ver->frptmap) {
@@ -2501,6 +2518,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
bit_map = GENMASK(2, 0) | BIT(8);
break;
case 4:
+ case 5:
bit_map = GENMASK(2, 0) | BIT(9);
break;
default:
@@ -2520,6 +2538,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
bit_map = GENMASK(7, 3);
break;
case 4:
+ case 5:
bit_map = GENMASK(8, 3);
break;
default:
@@ -2539,6 +2558,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
bit_map = GENMASK(8, 0);
break;
case 4:
+ case 5:
bit_map = GENMASK(9, 0);
break;
default:
@@ -2558,6 +2578,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
bit_map = GENMASK(8, 2);
break;
case 4:
+ case 5:
bit_map = GENMASK(9, 2);
break;
default:
@@ -2814,7 +2835,7 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
rtw89_fw_h2c_cxdrv_role_v8(rtwdev, index);
break;
case CXDRVINFO_CTRL:
- if (ver->drvinfo_ver == 1)
+ if (ver->drvinfo_ver != 0)
index = 2;
if (ver->fcxctrl == 7)
@@ -2823,7 +2844,7 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
rtw89_fw_h2c_cxdrv_ctrl(rtwdev, index);
break;
case CXDRVINFO_TRX:
- if (ver->drvinfo_ver == 1)
+ if (ver->drvinfo_ver > 1)
index = 3;
if (ver->fcxtrx == 7)
@@ -2832,7 +2853,7 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
rtw89_fw_h2c_cxdrv_trx_v9(rtwdev, index);
break;
case CXDRVINFO_RFK:
- if (ver->drvinfo_ver == 1)
+ if (ver->drvinfo_ver != 0)
return;
rtw89_fw_h2c_cxdrv_rfk(rtwdev, index);
@@ -2847,12 +2868,26 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
rtw89_fw_h2c_cxtxpwr_v9(rtwdev, index);
break;
case CXDRVINFO_FDDT:
+ if (ver->drvinfo_ver == 3)
+ index = 5;
+ else
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "drv_info FDDT index=%d\n", index);
+ break;
case CXDRVINFO_MLO:
+ if (ver->drvinfo_ver == 3)
+ index = 6;
+ else
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "drv_info MLO index=%d\n", index);
+ break;
case CXDRVINFO_OSI:
if (!ver->fcxosi)
return;
- if (ver->drvinfo_ver == 2)
+ if (ver->drvinfo_ver > 1)
index = 7;
else
return;
@@ -8828,7 +8863,7 @@ static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
return BTF_EVNT_BUF_OVERFLOW;
else if (ver->fwc2hfunc == 2)
return func;
- else if (ver->fwc2hfunc == 3)
+ else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4)
return BTF_EVNT_BUF_OVERFLOW;
else
return BTF_EVNT_MAX;
@@ -8839,19 +8874,26 @@ static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
return BTF_EVNT_C2H_LOOPBACK;
else if (ver->fwc2hfunc == 2)
return func;
- else if (ver->fwc2hfunc == 3)
+ else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4)
return BTF_EVNT_C2H_LOOPBACK;
else
return BTF_EVNT_MAX;
case BTF_EVNT_C2H_LOOPBACK:
if (ver->fwc2hfunc == 2)
return func;
- else if (ver->fwc2hfunc == 3)
+ else if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4)
return BTF_EVNT_BT_LEAUDIO_INFO;
else
return BTF_EVNT_MAX;
case BTF_EVNT_BT_QUERY_TXPWR:
- if (ver->fwc2hfunc == 3)
+ if (ver->fwc2hfunc == 3 || ver->fwc2hfunc == 4)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_ZB_INFO:
+ case BTF_EVNT_ZB_CH:
+ case BTF_EVNT_ZB_QUERY_TXPWR:
+ if (ver->fwc2hfunc == 4)
return func;
else
return BTF_EVNT_MAX;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7a87ffc1931e..6947f4c2c25d 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3224,6 +3224,9 @@ enum rtw89_btc_btf_fw_event {
BTF_EVNT_BUF_OVERFLOW,
BTF_EVNT_C2H_LOOPBACK,
BTF_EVNT_BT_QUERY_TXPWR, /* fwc2hfunc > 3 */
+ BTF_EVNT_ZB_INFO = 11,
+ BTF_EVNT_ZB_CH = 12,
+ BTF_EVNT_ZB_QUERY_TXPWR = 13,
BTF_EVNT_MAX,
};
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 08/10] wifi: rtw89: coex: Renaming drvinfo_type to drvinfo_ver
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
It's more closing to the original meaning. It is defined for rearranging
driver info index by firmware support version.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 84 +++++++++++------------
drivers/net/wireless/realtek/rtw89/core.h | 2 +-
2 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index dd9d6cbc2943..572eed7939e1 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -138,7 +138,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
.fcxtrx = 0,
},
@@ -147,7 +147,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
.fcxtrx = 0,
},
@@ -156,7 +156,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 2, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9,
.fcxtrx = 7,
},
@@ -165,7 +165,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_ver = 2, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9,
.fcxtrx = 0,
},
@@ -174,7 +174,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_ver = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -183,7 +183,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -192,7 +192,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -201,7 +201,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -210,7 +210,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -219,7 +219,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_ver = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
.fcxtrx = 0,
},
@@ -228,7 +228,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -237,7 +237,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -246,7 +246,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -255,7 +255,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_ver = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -264,7 +264,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_ver = 0, .info_buf = 1024,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -275,7 +275,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_ver = 0, .info_buf = 1024,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
.fcxtrx = 0,
},
@@ -2789,62 +2789,62 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
}
-static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
+static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
- switch (type) {
+ switch (index) {
case CXDRVINFO_INIT:
if (ver->fcxinit == 7)
- rtw89_fw_h2c_cxdrv_init_v7(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_init_v7(rtwdev, index);
else
- rtw89_fw_h2c_cxdrv_init(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_init(rtwdev, index);
break;
case CXDRVINFO_ROLE:
if (ver->fwlrole == 0)
- rtw89_fw_h2c_cxdrv_role(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_role(rtwdev, index);
else if (ver->fwlrole == 1)
- rtw89_fw_h2c_cxdrv_role_v1(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_role_v1(rtwdev, index);
else if (ver->fwlrole == 2)
- rtw89_fw_h2c_cxdrv_role_v2(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_role_v2(rtwdev, index);
else if (ver->fwlrole == 7)
- rtw89_fw_h2c_cxdrv_role_v7(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_role_v7(rtwdev, index);
else if (ver->fwlrole == 8)
- rtw89_fw_h2c_cxdrv_role_v8(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_role_v8(rtwdev, index);
break;
case CXDRVINFO_CTRL:
- if (ver->drvinfo_type == 1)
- type = 2;
+ if (ver->drvinfo_ver == 1)
+ index = 2;
if (ver->fcxctrl == 7)
- rtw89_fw_h2c_cxdrv_ctrl_v7(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_ctrl_v7(rtwdev, index);
else
- rtw89_fw_h2c_cxdrv_ctrl(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_ctrl(rtwdev, index);
break;
case CXDRVINFO_TRX:
- if (ver->drvinfo_type == 1)
- type = 3;
+ if (ver->drvinfo_ver == 1)
+ index = 3;
if (ver->fcxtrx == 7)
- rtw89_fw_h2c_cxdrv_trx_v7(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_trx_v7(rtwdev, index);
else if (ver->fcxtrx == 9)
- rtw89_fw_h2c_cxdrv_trx_v9(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_trx_v9(rtwdev, index);
break;
case CXDRVINFO_RFK:
- if (ver->drvinfo_type == 1)
+ if (ver->drvinfo_ver == 1)
return;
- rtw89_fw_h2c_cxdrv_rfk(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_rfk(rtwdev, index);
break;
case CXDRVINFO_TXPWR:
- if (ver->drvinfo_type == 3)
- type = 4;
+ if (ver->drvinfo_ver == 3)
+ index = 4;
if (ver->fcxtrx == 7)
- rtw89_fw_h2c_cxtxpwr_v7(rtwdev, type);
+ rtw89_fw_h2c_cxtxpwr_v7(rtwdev, index);
else if (ver->fcxtrx == 9)
- rtw89_fw_h2c_cxtxpwr_v9(rtwdev, type);
+ rtw89_fw_h2c_cxtxpwr_v9(rtwdev, index);
break;
case CXDRVINFO_FDDT:
case CXDRVINFO_MLO:
@@ -2852,12 +2852,12 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
if (!ver->fcxosi)
return;
- if (ver->drvinfo_type == 2)
- type = 7;
+ if (ver->drvinfo_ver == 2)
+ index = 7;
else
return;
- rtw89_fw_h2c_cxdrv_osi_info(rtwdev, type);
+ rtw89_fw_h2c_cxdrv_osi_info(rtwdev, index);
break;
default:
break;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 70c6ee1a6da2..7a87ffc1931e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3365,7 +3365,7 @@ struct rtw89_btc_ver {
u8 fwevntrptl;
u8 fwc2hfunc;
- u8 drvinfo_type;
+ u8 drvinfo_ver;
u16 info_buf;
u8 max_role_num;
u8 fcxosi;
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 07/10] wifi: rtw89: coex: Add TX/RX RF parameter format version 9
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
In order to support external Zigbee/Thread/Bluetooth etc module,
the version 8 add the parameter for the case. And also update the
related configuration function.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 226 ++++++++++------
drivers/net/wireless/realtek/rtw89/core.h | 40 +--
drivers/net/wireless/realtek/rtw89/fw.c | 252 ++++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.h | 160 +++++------
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 12 +-
.../net/wireless/realtek/rtw89/rtw8852bt.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 4 +
11 files changed, 511 insertions(+), 243 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 5159338960f3..dd9d6cbc2943 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -140,6 +140,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
+ .fcxtrx = 0,
},
{RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0),
.fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
@@ -148,6 +149,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
+ .fcxtrx = 0,
},
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 71, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
@@ -156,6 +158,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9,
+ .fcxtrx = 7,
},
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 63, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
@@ -164,6 +167,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9,
+ .fcxtrx = 0,
},
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
@@ -172,6 +176,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
@@ -180,6 +185,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
@@ -188,6 +194,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
@@ -196,6 +203,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
@@ -204,6 +212,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 122, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
@@ -212,6 +221,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8,
+ .fcxtrx = 0,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
@@ -220,6 +230,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
.fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4,
@@ -228,6 +239,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
@@ -236,6 +248,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
@@ -244,6 +257,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
.fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
@@ -252,6 +266,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
/* keep it to be the last as default entry */
@@ -262,6 +277,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024,
.max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7,
+ .fcxtrx = 0,
},
};
@@ -2777,9 +2793,6 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_rf_trx_para rf_para = dm->rf_trx_para;
switch (type) {
case CXDRVINFO_INIT:
@@ -2813,17 +2826,10 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
if (ver->drvinfo_type == 1)
type = 3;
- dm->trx_info.tx_power = u32_get_bits(rf_para.wl_tx_power,
- RTW89_BTC_WL_DEF_TX_PWR);
- dm->trx_info.rx_gain = u32_get_bits(rf_para.wl_rx_gain,
- RTW89_BTC_WL_DEF_TX_PWR);
- dm->trx_info.bt_tx_power = u32_get_bits(rf_para.bt_tx_power,
- RTW89_BTC_WL_DEF_TX_PWR);
- dm->trx_info.bt_rx_gain = u32_get_bits(rf_para.bt_rx_gain,
- RTW89_BTC_WL_DEF_TX_PWR);
- dm->trx_info.cn = wl->cn_report;
- dm->trx_info.nhm = wl->nhm.pwr;
- rtw89_fw_h2c_cxdrv_trx(rtwdev, type);
+ if (ver->fcxtrx == 7)
+ rtw89_fw_h2c_cxdrv_trx_v7(rtwdev, type);
+ else if (ver->fcxtrx == 9)
+ rtw89_fw_h2c_cxdrv_trx_v9(rtwdev, type);
break;
case CXDRVINFO_RFK:
if (ver->drvinfo_type == 1)
@@ -2832,6 +2838,14 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
rtw89_fw_h2c_cxdrv_rfk(rtwdev, type);
break;
case CXDRVINFO_TXPWR:
+ if (ver->drvinfo_type == 3)
+ type = 4;
+
+ if (ver->fcxtrx == 7)
+ rtw89_fw_h2c_cxtxpwr_v7(rtwdev, type);
+ else if (ver->fcxtrx == 9)
+ rtw89_fw_h2c_cxtxpwr_v9(rtwdev, type);
+ break;
case CXDRVINFO_FDDT:
case CXDRVINFO_MLO:
case CXDRVINFO_OSI:
@@ -3025,53 +3039,84 @@ static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable)
#define B_BTC_WL_TX_POWER_SIGN BIT(7)
#define B_TSSI_WL_TX_POWER_SIGN BIT(8)
-static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level)
+static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level, u8 phy_map)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ const struct rtw89_btc_ver *ver = btc->ver;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ bool level_chg = false;
u32 pwr_val;
- if (wl->rf_para.tx_pwr_freerun == level)
+ if (phy_map & BIT(RTW89_PHY_0))
+ level_chg = !(dm->rf_trx_para.wl_tx_power[RTW89_PHY_0] == level);
+
+ if (phy_map & BIT(RTW89_PHY_1))
+ level_chg |= !(dm->rf_trx_para.wl_tx_power[RTW89_PHY_1] == level);
+
+ if (!level_chg && !btc->cli_h2c_cmd)
return;
- wl->rf_para.tx_pwr_freerun = level;
- btc->dm.rf_trx_para.wl_tx_power = level;
+ if (phy_map & BIT(RTW89_PHY_0))
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_0] = level;
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): level = %d\n",
- __func__, level);
+ if (phy_map & BIT(RTW89_PHY_1))
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_1] = level;
- if (level == RTW89_BTC_WL_DEF_TX_PWR) {
- pwr_val = WL_TX_POWER_NO_BTC_CTRL;
- } else { /* only apply "force tx power" */
- pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level);
- if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR)
- pwr_val = RTW89_BTC_WL_DEF_TX_PWR;
+ dm->wl_tx_pwr_phy_map = phy_map;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): phy_map=0x%x, wl_tx_pwr-> phy0=%d, phy1=%d\n",
+ __func__, phy_map,
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_0],
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_1]);
+
+ if (ver->fcxtrx == 7 && chip->chip_id == RTL8922A) {
+ _fw_set_drv_info(rtwdev, CXDRVINFO_TXPWR);
+ } else if (ver->fcxtrx == 9) {
+ _fw_set_drv_info(rtwdev, CXDRVINFO_TXPWR);
+ } else {
+ if (level == RTW89_BTC_WL_DEF_TX_PWR) {
+ pwr_val = WL_TX_POWER_NO_BTC_CTRL;
+ } else { /* only apply "force tx power" */
+ pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level);
+ if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR)
+ pwr_val = RTW89_BTC_WL_DEF_TX_PWR;
- if (level & B_BTC_WL_TX_POWER_SIGN)
- pwr_val |= B_TSSI_WL_TX_POWER_SIGN;
- pwr_val |= WL_TX_POWER_WITH_BT;
+ if (level & B_BTC_WL_TX_POWER_SIGN)
+ pwr_val |= B_TSSI_WL_TX_POWER_SIGN;
+ pwr_val |= WL_TX_POWER_WITH_BT;
+ }
+ chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val);
}
-
- chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val);
}
-static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
+static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level, u8 phy_map)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ bool level_chg = false;
+
+ if (phy_map & BIT(RTW89_PHY_0))
+ level_chg = !(dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0] == level);
- if (wl->rf_para.rx_gain_freerun == level)
+ if (phy_map & BIT(RTW89_PHY_1))
+ level_chg |= !(dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1] == level);
+
+ if (!level_chg && !btc->cli_h2c_cmd)
return;
- wl->rf_para.rx_gain_freerun = level;
- btc->dm.rf_trx_para.wl_rx_gain = level;
+ if (phy_map & BIT(RTW89_PHY_0))
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0] = level;
+
+ if (phy_map & BIT(RTW89_PHY_1))
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1] = level;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): level = %d\n",
- __func__, level);
+ "[BTC], %s(): phy_map=0x%x, wl_rx_gain-> phy0=%d, phy1=%d\n",
+ __func__, phy_map,
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0],
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1]);
chip->ops->btc_set_wl_rx_gain(rtwdev, level);
}
@@ -3097,7 +3142,7 @@ static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level)
ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_TX_PWR, &buf, 1);
if (!ret) {
bt->rf_para.tx_pwr_freerun = level;
- btc->dm.rf_trx_para.bt_tx_power = level;
+ btc->dm.rf_trx_para.bt_tx_power[BTC_BT_1ST] = level;
}
}
@@ -3117,7 +3162,7 @@ static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level)
return;
bt->rf_para.rx_gain_freerun = level;
- btc->dm.rf_trx_para.bt_rx_gain = level;
+ btc->dm.rf_trx_para.bt_rx_gain[BTC_BT_1ST] = level;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): level = %d\n",
@@ -3141,9 +3186,10 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
- struct rtw89_btc_rf_trx_para para;
+ struct rtw89_btc_rf_trx_para_v9 para;
+ u8 lv, link_mode = 0, i, dbcc_2g_phy = 0;
+ u8 ul_para_num, dl_para_num;
u32 wl_stb_chg = 0;
- u8 level_id = 0, link_mode = 0, i, dbcc_2g_phy = 0;
if (ver->fwlrole == 0) {
link_mode = wl->role_info.link_mode;
@@ -3159,6 +3205,18 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
dbcc_2g_phy = wl->role_info_v2.dbcc_2g_phy;
}
+ if (ver->fcxtrx == 9 && chip->rf_para_ulink_v9) {
+ ul_para_num = chip->rf_para_ulink_num_v9;
+ dl_para_num = chip->rf_para_dlink_num_v9;
+ } else if (ver->fcxtrx == 0 && chip->rf_para_ulink_v0) {
+ ul_para_num = chip->rf_para_ulink_num_v0;
+ dl_para_num = chip->rf_para_dlink_num_v0;
+ } else {
+ rtw89_warn(rtwdev, "[BTC]%s(), No rf_para for verseion %d\n",
+ __func__, ver->fcxtrx);
+ goto next;
+ }
+
/* decide trx_para_level */
if (btc->ant_type == BTC_ANT_SHARED) {
/* fix LNA2 + TIA gain not change by GNT_BT */
@@ -3180,30 +3238,54 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
}
}
- level_id = dm->trx_para_level;
- if (level_id >= chip->rf_para_dlink_num ||
- level_id >= chip->rf_para_ulink_num) {
+ lv = dm->trx_para_level;
+ if (lv >= ul_para_num ||
+ lv >= dl_para_num) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): invalid level_id: %d\n",
- __func__, level_id);
+ __func__, lv);
return;
}
- if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL))
- para = chip->rf_para_ulink[level_id];
- else
- para = chip->rf_para_dlink[level_id];
+ if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
+ if (ver->fcxtrx == 9) {
+ para = chip->rf_para_ulink_v9[lv];
+ } else {
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) {
+ para.wl_tx_power[i] = chip->rf_para_ulink_v0[lv].wl_tx_power;
+ para.wl_rx_gain[i] = chip->rf_para_ulink_v0[lv].wl_rx_gain;
+ }
+ for (i = BTC_BT_1ST; i < BTC_ALL_BT; i++) {
+ para.bt_tx_power[i] = chip->rf_para_ulink_v0[lv].bt_tx_power;
+ para.bt_rx_gain[i] = chip->rf_para_ulink_v0[lv].bt_rx_gain;
+ }
+ }
+ } else {
+ if (ver->fcxtrx == 9) {
+ para = chip->rf_para_dlink_v9[lv];
+ } else {
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) {
+ para.wl_tx_power[i] = chip->rf_para_dlink_v0[lv].wl_tx_power;
+ para.wl_rx_gain[i] = chip->rf_para_dlink_v0[lv].wl_rx_gain;
+ }
+ for (i = BTC_BT_1ST; i < BTC_ALL_BT; i++) {
+ para.bt_tx_power[i] = chip->rf_para_dlink_v0[lv].bt_tx_power;
+ para.bt_rx_gain[i] = chip->rf_para_dlink_v0[lv].bt_rx_gain;
+ }
+ }
+ }
if (dm->fddt_train) {
- _set_wl_rx_gain(rtwdev, 1);
+ _set_wl_rx_gain(rtwdev, 1, RTW89_PHY_0);
_write_scbd(rtwdev, BTC_WSCB_RXGAIN, true);
} else {
- _set_wl_tx_power(rtwdev, para.wl_tx_power);
- _set_wl_rx_gain(rtwdev, para.wl_rx_gain);
- _set_bt_tx_power(rtwdev, para.bt_tx_power);
- _set_bt_rx_gain(rtwdev, para.bt_rx_gain);
+ _set_wl_tx_power(rtwdev, para.wl_tx_power[RTW89_PHY_0], RTW89_PHY_0);
+ _set_wl_rx_gain(rtwdev, para.wl_rx_gain[RTW89_PHY_0], RTW89_PHY_0);
+ _set_bt_tx_power(rtwdev, para.bt_tx_power[BTC_BT_1ST]);
+ _set_bt_rx_gain(rtwdev, para.bt_rx_gain[BTC_BT_1ST]);
}
+next:
if (!bt->enable.now || dm->wl_only || wl_smap->rf_off ||
wl_smap->lps == BTC_LPS_RF_OFF ||
link_mode == BTC_WLINK_5G ||
@@ -7836,7 +7918,7 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
}
_set_init_info(rtwdev);
- _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR);
+ _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR, RTW89_PHY_0);
btc_fw_set_monreg(rtwdev);
rtw89_btc_fw_set_slots(rtwdev);
_fw_set_drv_info(rtwdev, CXDRVINFO_INIT);
@@ -9669,25 +9751,19 @@ static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
(dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ?
"" : "(Mismatch!!)"));
- if (dm->rf_trx_para.wl_tx_power == 0xff)
- p += scnprintf(p, end - p,
- " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ",
- "[trx_ctrl]", wl->rssi_level,
- dm->trx_para_level);
-
- else
- p += scnprintf(p, end - p,
- " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ",
- "[trx_ctrl]", wl->rssi_level,
- dm->trx_para_level,
- dm->rf_trx_para.wl_tx_power);
+ p += scnprintf(p, end - p,
+ " %-15s : wl[rssi_lvl:%d/para:%d/tx_pwr:[%d %d]/rx_lvl:[%d %d]/lna2:%d/stb_chg:%d]\n ",
+ "[dm_rf_ctrl]",
+ wl->rssi_level, dm->trx_para_level,
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_0],
+ dm->rf_trx_para.wl_tx_power[RTW89_PHY_1],
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_0],
+ dm->rf_trx_para.wl_rx_gain[RTW89_PHY_1],
+ dm->wl_lna2, dm->wl_stb_chg);
p += scnprintf(p, end - p,
- "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n",
- dm->rf_trx_para.wl_rx_gain,
- dm->rf_trx_para.bt_tx_power,
- dm->rf_trx_para.bt_rx_gain,
- (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx);
+ " %-15s : pre_agc:%d, btg_rx:%d\n ",
+ "[dm_bb_ctrl]", dm->wl_pre_agc, dm->wl_btg_rx);
p += scnprintf(p, end - p,
" %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n",
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 2366894bf609..70c6ee1a6da2 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2275,6 +2275,14 @@ struct rtw89_btc_bt_info {
u32 bcnt[BTC_BCNT_NUM];
};
+#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0)
+struct rtw89_btc_rf_trx_para_v0 {
+ u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */
+ u32 wl_rx_gain; /* rx gain table index (TBD.) */
+ u8 bt_tx_power; /* decrease Tx power (dB) */
+ u8 bt_rx_gain; /* LNA constrain level */
+};
+
struct rtw89_btc_rf_trx_para_v9 {
u32 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 1's complement -5->0x85 */
u32 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */
@@ -2289,6 +2297,7 @@ struct rtw89_btc_cx {
struct rtw89_btc_bt_info bt0;
struct rtw89_btc_bt_info bt1;
struct rtw89_btc_extsoc_info bt_ext;
+ struct rtw89_btc_rf_trx_para_v9 rf_para;
u32 state_map;
};
@@ -3068,24 +3077,18 @@ struct rtw89_btc_fbtc_btdevinfo {
__le32 flush_time;
} __packed;
-#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0)
-struct rtw89_btc_rf_trx_para {
- u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */
- u32 wl_rx_gain; /* rx gain table index (TBD.) */
- u8 bt_tx_power; /* decrease Tx power (dB) */
- u8 bt_rx_gain; /* LNA constrain level */
-};
-
struct rtw89_btc_trx_info {
u8 tx_lvl;
u8 rx_lvl;
u8 wl_rssi;
u8 bt_rssi;
- s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */
- s8 rx_gain; /* rx gain table index (TBD.) */
- s8 bt_tx_power; /* decrease Tx power (dB) */
- s8 bt_rx_gain; /* LNA constrain level */
+ s8 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 0xff-> no BTC control */
+ s8 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */
+ s8 bt_tx_power[BTC_ALL_BT]; /* decrease Tx power (dB) */
+ s8 bt_rx_gain[BTC_ALL_BT]; /* LNA constrain level */
+ s8 zb_tx_power[BTC_ALL_BT];
+ s8 zb_rx_gain[BTC_ALL_BT];
u8 cn; /* condition_num */
s8 nhm;
@@ -3132,7 +3135,7 @@ struct rtw89_btc_dm {
struct rtw89_btc_fbtc_tdma tdma_now;
struct rtw89_mac_ax_coex_gnt gnt;
union rtw89_btc_init_info_u init_info; /* pass to wl_fw if offload */
- struct rtw89_btc_rf_trx_para rf_trx_para;
+ struct rtw89_btc_rf_trx_para_v9 rf_trx_para;
struct rtw89_btc_wl_tx_limit_para wl_tx_limit;
struct rtw89_btc_dm_step dm_step;
struct rtw89_btc_wl_scc_ctrl wl_scc;
@@ -3169,6 +3172,7 @@ struct rtw89_btc_dm {
u8 run_reason;
u8 run_action;
+ u8 wl_tx_pwr_phy_map;
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
@@ -3367,6 +3371,7 @@ struct rtw89_btc_ver {
u8 fcxosi;
u8 fcxmlo;
u8 bt_desired;
+ u8 fcxtrx;
};
struct rtw89_btc_btf_fwinfo {
@@ -3424,6 +3429,7 @@ struct rtw89_btc {
bool update_policy_force;
bool lps;
bool manual_ctrl;
+ bool cli_h2c_cmd;
};
enum rtw89_btc_hmsg {
@@ -4772,10 +4778,10 @@ struct rtw89_chip_info {
u8 mon_reg_num;
const struct rtw89_btc_fbtc_mreg *mon_reg;
- u8 rf_para_ulink_num;
- const struct rtw89_btc_rf_trx_para *rf_para_ulink;
- u8 rf_para_dlink_num;
- const struct rtw89_btc_rf_trx_para *rf_para_dlink;
+ const struct rtw89_btc_rf_trx_para_v0 *rf_para_ulink_v0;
+ const struct rtw89_btc_rf_trx_para_v0 *rf_para_dlink_v0;
+ u8 rf_para_ulink_num_v0;
+ u8 rf_para_dlink_num_v0;
const struct rtw89_btc_rf_trx_para_v9 *rf_para_ulink_v9;
const struct rtw89_btc_rf_trx_para_v9 *rf_para_dlink_v9;
u8 rf_para_ulink_num_v9;
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index d6a594b75ab2..804ae2a1130d 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -6303,48 +6303,158 @@ int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
return ret;
}
-#define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR)
-int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type)
+int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_rf_trx_para_v9 rf_para = btc->dm.rf_trx_para;
struct rtw89_btc_trx_info *trx = &btc->dm.trx_info;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_h2c_cxtrx_v7 *h2c;
+ u32 len = sizeof(*h2c);
struct sk_buff *skb;
- u8 *cmd;
int ret;
+ u8 i;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX);
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
+ trx->wl_tx_power[i] = u32_get_bits(rf_para.wl_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->wl_rx_gain[i] = u32_get_bits(rf_para.wl_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ }
+ for (i = 0; i < BTC_ALL_BT; i++) {
+ trx->bt_tx_power[i] = u32_get_bits(rf_para.bt_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->bt_rx_gain[i] = u32_get_bits(rf_para.bt_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->zb_tx_power[i] = u32_get_bits(rf_para.zb_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->zb_rx_gain[i] = u32_get_bits(rf_para.zb_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ }
+ trx->cn = wl->cn_report;
+ trx->nhm = wl->nhm.pwr;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n");
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n");
return -ENOMEM;
}
- skb_put(skb, H2C_LEN_CXDRVINFO_TRX);
- cmd = skb->data;
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxtrx_v7 *)skb->data;
- RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR);
-
- RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl);
- RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl);
- RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi);
- RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi);
- RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power);
- RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain);
- RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power);
- RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain);
- RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn);
- RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm);
- RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile);
- RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2);
- RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate);
- RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate);
- RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp);
- RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp);
- RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio);
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxtrx;
+ h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
+
+ h2c->v7_u8.tx_lvl = trx->tx_lvl;
+ h2c->v7_u8.rx_lvl = trx->rx_lvl;
+ h2c->v7_u8.wl_rssi = trx->wl_rssi;
+ h2c->v7_u8.bt_rssi = trx->bt_rssi;
+ h2c->v7_u8.wl_tx_power = trx->wl_tx_power[RTW89_PHY_0];
+ h2c->v7_u8.wl_rx_gain = trx->wl_rx_gain[RTW89_PHY_0];
+ h2c->v7_u8.bt_tx_power = trx->bt_tx_power[BTC_BT_1ST];
+ h2c->v7_u8.bt_rx_gain = trx->bt_rx_gain[BTC_BT_1ST];
+ h2c->v7_u8.zb_tx_power = trx->zb_tx_power[BTC_BT_1ST];
+ h2c->v7_u8.zb_rx_gain = trx->zb_rx_gain[BTC_BT_1ST];
+ h2c->v7_u8.cn = trx->cn;
+ h2c->v7_u8.nhm = trx->nhm;
+ h2c->v7_u8.bt_profile = trx->bt_profile;
+ h2c->v7_u8.rsvd2 = trx->rsvd2;
+ h2c->v7_le.tx_rate = cpu_to_le16(trx->tx_rate);
+ h2c->v7_le.rx_rate = cpu_to_le16(trx->rx_rate);
+ h2c->v7_le.tx_tp = cpu_to_le32(trx->tx_tp);
+ h2c->v7_le.rx_tp = cpu_to_le32(trx->rx_tp);
+ h2c->v7_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
- SET_DRV_INFO, 0, 0,
- H2C_LEN_CXDRVINFO_TRX);
+ SET_DRV_INFO, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_rf_trx_para_v9 rf_para = btc->dm.rf_trx_para;
+ struct rtw89_btc_trx_info *trx = &btc->dm.trx_info;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_h2c_cxtrx_v9 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+ u8 i;
+
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
+ trx->wl_tx_power[i] = u32_get_bits(rf_para.wl_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->wl_rx_gain[i] = u32_get_bits(rf_para.wl_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ }
+ for (i = 0; i < BTC_ALL_BT; i++) {
+ trx->bt_tx_power[i] = u32_get_bits(rf_para.bt_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->bt_rx_gain[i] = u32_get_bits(rf_para.bt_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->zb_tx_power[i] = u32_get_bits(rf_para.zb_tx_power[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ trx->zb_rx_gain[i] = u32_get_bits(rf_para.zb_rx_gain[i],
+ RTW89_BTC_WL_DEF_TX_PWR);
+ }
+ trx->cn = wl->cn_report;
+ trx->nhm = wl->nhm.pwr;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxtrx_v9 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxtrx;
+ h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
+
+ h2c->v9_u8.tx_lvl = trx->tx_lvl;
+ h2c->v9_u8.rx_lvl = trx->rx_lvl;
+ h2c->v9_u8.wl_rssi = trx->wl_rssi;
+ h2c->v9_u8.bt_rssi = trx->bt_rssi;
+
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
+ h2c->v9_u8.wl_tx_power[i] = trx->wl_tx_power[i];
+ h2c->v9_u8.wl_rx_gain[i] = trx->wl_rx_gain[i];
+ }
+
+ for (i = 0; i < BTC_ALL_BT; i++) {
+ h2c->v9_u8.bt_tx_power[i] = trx->bt_tx_power[i];
+ h2c->v9_u8.bt_rx_gain[i] = trx->bt_rx_gain[i];
+ h2c->v9_u8.zb_tx_power[i] = trx->zb_tx_power[i];
+ h2c->v9_u8.zb_rx_gain[i] = trx->zb_rx_gain[i];
+ }
+ h2c->v9_u8.cn = trx->cn;
+ h2c->v9_u8.nhm = trx->nhm;
+ h2c->v9_u8.bt_profile = trx->bt_profile;
+ h2c->v9_u8.rsvd2 = trx->rsvd2;
+ h2c->v9_le.tx_rate = cpu_to_le16(trx->tx_rate);
+ h2c->v9_le.rx_rate = cpu_to_le16(trx->rx_rate);
+ h2c->v9_le.tx_tp = cpu_to_le32(trx->tx_tp);
+ h2c->v9_le.rx_tp = cpu_to_le32(trx->rx_tp);
+ h2c->v9_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0, len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@@ -6404,6 +6514,90 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type)
return ret;
}
+int rtw89_fw_h2c_cxtxpwr_v7(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para;
+ struct rtw89_h2c_cxtxpwr_v7 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxtxpwr_v7 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxtrx;
+ h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
+ h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff;
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxtxpwr_v9(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para;
+ struct rtw89_h2c_cxtxpwr_v9 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxtxpwr_v9 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxtrx;
+ h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
+ if (dm->wl_tx_pwr_phy_map == BIT(RTW89_PHY_1))
+ h2c->pwr = rp.wl_tx_power[RTW89_PHY_1] & 0xff;
+ else
+ h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff;
+ h2c->band = dm->wl_tx_pwr_phy_map;
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
#define H2C_LEN_PKT_OFLD 4
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
{
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 20721d5209aa..36c8430a2e7a 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2499,6 +2499,76 @@ struct rtw89_h2c_cxinit {
u8 rsvd1;
} __packed;
+struct rtw89_btc_trx_info_u8 {
+ u8 tx_lvl;
+ u8 rx_lvl;
+ u8 wl_rssi;
+ u8 bt_rssi;
+
+ s8 wl_tx_power[RTW89_PHY_NUM]; /* absolute Tx power (dBm), 0xff-> no BTC control */
+ s8 wl_rx_gain[RTW89_PHY_NUM]; /* rx gain table index (TBD.) */
+ s8 bt_tx_power[BTC_ALL_BT]; /* decrease Tx power (dB) */
+ s8 bt_rx_gain[BTC_ALL_BT]; /* LNA constrain level */
+ s8 zb_tx_power[BTC_ALL_BT];
+ s8 zb_rx_gain[BTC_ALL_BT];
+
+ u8 cn; /* condition_num */
+ s8 nhm;
+ u8 bt_profile;
+ u8 rsvd2;
+} __packed;
+
+struct rtw89_btc_trx_info_v7_u8 {
+ u8 tx_lvl;
+ u8 rx_lvl;
+ u8 wl_rssi;
+ u8 bt_rssi;
+
+ s8 wl_tx_power;
+ s8 wl_rx_gain;
+ s8 bt_tx_power;
+ s8 bt_rx_gain;
+ s8 zb_tx_power;
+ s8 zb_rx_gain;
+
+ u8 cn;
+ s8 nhm;
+ u8 bt_profile;
+ u8 rsvd2;
+} __packed;
+
+struct rtw89_btc_trx_info_le {
+ __le16 tx_rate;
+ __le16 rx_rate;
+
+ __le32 tx_tp;
+ __le32 rx_tp;
+ __le32 rx_err_ratio;
+} __packed;
+
+struct rtw89_h2c_cxtrx_v9 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_trx_info_u8 v9_u8;
+ struct rtw89_btc_trx_info_le v9_le;
+} __packed;
+
+struct rtw89_h2c_cxtrx_v7 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_trx_info_v7_u8 v7_u8;
+ struct rtw89_btc_trx_info_le v7_le;
+} __packed;
+
+struct rtw89_h2c_cxtxpwr_v7 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ u8 pwr;
+} __packed;
+
+struct rtw89_h2c_cxtxpwr_v9 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ u8 pwr;
+ u8 band;
+} __packed;
+
#define RTW89_H2C_CXINIT_ANT_INFO_POS BIT(0)
#define RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY BIT(1)
#define RTW89_H2C_CXINIT_ANT_INFO_BTG_POS GENMASK(3, 2)
@@ -2760,91 +2830,6 @@ static inline void RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(void *cmd, u32 val)
le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(18, 3));
}
-static inline void RTW89_SET_FWCMD_CXTRX_TXLV(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 2, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RXLV(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 3, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_WLRSSI(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 4, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_BTRSSI(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 5, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_TXPWR(void *cmd, s8 val)
-{
- u8p_replace_bits((u8 *)cmd + 6, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RXGAIN(void *cmd, s8 val)
-{
- u8p_replace_bits((u8 *)cmd + 7, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_BTTXPWR(void *cmd, s8 val)
-{
- u8p_replace_bits((u8 *)cmd + 8, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_BTRXGAIN(void *cmd, s8 val)
-{
- u8p_replace_bits((u8 *)cmd + 9, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_CN(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 10, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_NHM(void *cmd, s8 val)
-{
- u8p_replace_bits((u8 *)cmd + 11, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_BTPROFILE(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 12, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RSVD2(void *cmd, u8 val)
-{
- u8p_replace_bits((u8 *)cmd + 13, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_TXRATE(void *cmd, u16 val)
-{
- le16p_replace_bits((__le16 *)((u8 *)cmd + 14), val, GENMASK(15, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RXRATE(void *cmd, u16 val)
-{
- le16p_replace_bits((__le16 *)((u8 *)cmd + 16), val, GENMASK(15, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_TXTP(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)((u8 *)cmd + 18), val, GENMASK(31, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RXTP(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)((u8 *)cmd + 22), val, GENMASK(31, 0));
-}
-
-static inline void RTW89_SET_FWCMD_CXTRX_RXERRRA(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)((u8 *)cmd + 26), val, GENMASK(31, 0));
-}
-
static inline void RTW89_SET_FWCMD_CXRFK_STATE(void *cmd, u32 val)
{
le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(1, 0));
@@ -5399,8 +5384,11 @@ int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
-int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxtxpwr_v7(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxtxpwr_v9(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id);
int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
struct sk_buff *skb_ofld);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 60f362593696..4caf231c6287 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -355,7 +355,7 @@ static const struct rtw89_pmac_regs rtw8851b_pmac_regs = {
.ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR,
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_ul[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8851b_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -367,7 +367,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_ul[] = {
{13, 1, 0, 7}
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_dl[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8851b_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -2730,10 +2730,10 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8851b_mon_reg),
.mon_reg = rtw89_btc_8851b_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8851b_rf_ul),
- .rf_para_ulink = rtw89_btc_8851b_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8851b_rf_dl),
- .rf_para_dlink = rtw89_btc_8851b_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8851b_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8851b_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8851b_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8851b_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 94027e5b8d28..78addc0aef69 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2049,7 +2049,7 @@ s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
return clamp_t(s8, val + 6, -100, 0) + 100;
}
-static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = {
+static struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852a_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -2061,7 +2061,7 @@ static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = {
{13, 1, 0, 7}
};
-static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_dl[] = {
+static struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852a_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -2468,10 +2468,10 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8852a_mon_reg),
.mon_reg = rtw89_btc_8852a_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_ul),
- .rf_para_ulink = rtw89_btc_8852a_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_dl),
- .rf_para_dlink = rtw89_btc_8852a_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8852a_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8852a_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852a_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852a_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 4e7b068aaa75..debcdb2eacd6 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -307,7 +307,7 @@ static const struct rtw89_pmac_regs rtw8852b_pmac_regs = {
.ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR,
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852b_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -319,7 +319,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = {
{13, 1, 0, 7}
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_dl[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852b_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -1063,10 +1063,10 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8852b_mon_reg),
.mon_reg = rtw89_btc_8852b_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852b_rf_ul),
- .rf_para_ulink = rtw89_btc_8852b_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852b_rf_dl),
- .rf_para_dlink = rtw89_btc_8852b_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8852b_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8852b_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852b_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852b_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
index 7fcc877f6ea0..fc8a17fb95f4 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -250,7 +250,7 @@ static const struct rtw89_pmac_regs rtw8852bt_pmac_regs = {
.ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR,
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852bt_rf_ul[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852bt_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -262,7 +262,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8852bt_rf_ul[] = {
{13, 1, 0, 7}
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852bt_rf_dl[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852bt_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -902,10 +902,10 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8852bt_mon_reg),
.mon_reg = rtw89_btc_8852bt_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852bt_rf_ul),
- .rf_para_ulink = rtw89_btc_8852bt_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852bt_rf_dl),
- .rf_para_dlink = rtw89_btc_8852bt_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8852bt_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8852bt_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852bt_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852bt_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 3861cce42b1b..bec6aa574e9d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -2863,7 +2863,7 @@ s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
return clamp_t(s8, val + 6, -100, 0) + 100;
}
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852c_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -2875,7 +2875,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
{13, 1, 0, 7}
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8852c_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -3270,10 +3270,10 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8852c_mon_reg),
.mon_reg = rtw89_btc_8852c_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_ul),
- .rf_para_ulink = rtw89_btc_8852c_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
- .rf_para_dlink = rtw89_btc_8852c_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8852c_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8852c_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8852c_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8852c_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 91897aeced28..6d4301661b04 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -2874,7 +2874,7 @@ s8 rtw8922a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
return clamp_t(s8, val, -100, 0) + 100;
}
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_ul[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8922a_rf_ul_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -2886,7 +2886,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_ul[] = {
{13, 1, 0, 7}
};
-static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_dl[] = {
+static const struct rtw89_btc_rf_trx_para_v0 rtw89_btc_8922a_rf_dl_v0[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
@@ -3254,10 +3254,10 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8922a_mon_reg),
.mon_reg = rtw89_btc_8922a_mon_reg,
- .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_ul),
- .rf_para_ulink = rtw89_btc_8922a_rf_ul,
- .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_dl),
- .rf_para_dlink = rtw89_btc_8922a_rf_dl,
+ .rf_para_ulink_v0 = rtw89_btc_8922a_rf_ul_v0,
+ .rf_para_dlink_v0 = rtw89_btc_8922a_rf_dl_v0,
+ .rf_para_ulink_num_v0 = ARRAY_SIZE(rtw89_btc_8922a_rf_ul_v0),
+ .rf_para_dlink_num_v0 = ARRAY_SIZE(rtw89_btc_8922a_rf_dl_v0),
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 888973f4ef95..f78d6d46e65f 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -3430,6 +3430,10 @@ const struct rtw89_chip_info rtw8922d_chip_info = {
.rssi_tol = 2,
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8922d_mon_reg),
.mon_reg = rtw89_btc_8922d_mon_reg,
+ .rf_para_ulink_v0 = NULL,
+ .rf_para_dlink_v0 = NULL,
+ .rf_para_ulink_num_v0 = 0,
+ .rf_para_dlink_num_v0 = 0,
.rf_para_ulink_v9 = rtw89_btc_8922d_rf_ul_v9,
.rf_para_dlink_v9 = rtw89_btc_8922d_rf_dl_v9,
.rf_para_ulink_num_v9 = ARRAY_SIZE(rtw89_btc_8922d_rf_ul_v9),
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 06/10] wifi: rtw89: coex: Refine third party module related coexistence
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
The incoming chip reserved several IO ports to coexist with the other
vendor's stand along chips. In order to configured them easier add the
structure.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 8 ++--
drivers/net/wireless/realtek/rtw89/core.h | 31 +++++++++++---
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 2 +-
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 40 +++++++++++++++++++
4 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 8fa51867055b..5159338960f3 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -7655,7 +7655,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (!cx->bt0.enable.now && !cx->other.type) {
+ if (!cx->bt0.enable.now && !cx->bt_ext.func_type) {
_action_bt_off(rtwdev);
goto exit;
}
@@ -7776,7 +7776,7 @@ static void _set_init_info(struct rtw89_dev *rtwdev)
dm->init_info.init_v7.wl_only = (u8)dm->wl_only;
dm->init_info.init_v7.bt_only = (u8)dm->bt_only;
dm->init_info.init_v7.wl_init_ok = (u8)wl->status.map.init_ok;
- dm->init_info.init_v7.cx_other = btc->cx.other.type;
+ dm->init_info.init_v7.cx_other = btc->cx.bt_ext.func_type;
dm->init_info.init_v7.wl_guard_ch = chip->afh_guard_ch;
dm->init_info.init_v7.module = btc->mdinfo.md_v7;
} else {
@@ -7784,7 +7784,7 @@ static void _set_init_info(struct rtw89_dev *rtwdev)
dm->init_info.init.bt_only = (u8)dm->bt_only;
dm->init_info.init.wl_init_ok = (u8)wl->status.map.init_ok;
dm->init_info.init.dbcc_en = rtwdev->dbcc_en;
- dm->init_info.init.cx_other = btc->cx.other.type;
+ dm->init_info.init.cx_other = btc->cx.bt_ext.func_type;
dm->init_info.init.wl_guard_ch = chip->afh_guard_ch;
dm->init_info.init.module = btc->mdinfo.md;
}
@@ -8927,7 +8927,7 @@ static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
"3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n",
- btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss,
+ btc->cx.bt_ext.func_type, rtwdev->dbcc_en, hal->tx_nss,
hal->rx_nss);
return p - buf;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 31ac9fa4282e..2366894bf609 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1445,6 +1445,12 @@ enum rtw89_btc_bt_state_cnt {
BTC_BCNT_NUM,
};
+enum rtw89_btc_bt_rf_band {
+ BTC_BT_B2G = 0x0, /* 2.4GHz */
+ BTC_BT_B5G = 0x1, /* 5GHz or 6GHz */
+ BTC_BT_BMAX = 0x2
+};
+
enum rtw89_btc_bt_profile {
BTC_BT_NOPROFILE = 0,
BTC_BT_HFP = BIT(0),
@@ -1975,10 +1981,25 @@ struct rtw89_btc_bt_link_info {
u32 rsvd: 19;
};
-struct rtw89_btc_3rdcx_info {
- u8 type; /* 0: none, 1:zigbee, 2:LTE */
- u8 hw_coex;
- u16 rsvd;
+struct rtw89_btc_extsoc_info {
+ u8 chip_id;
+ u8 max_tx_pwr;
+ u8 rf_band_map;
+ u8 ant_iso_to_wl;
+
+ u8 link_weight[BTC_BT_BMAX];
+
+ u8 func_type; /* 0: none, 1:zigbee, 2:LTE */
+ u8 hw_coex; /* Hard-Wire coex interface support */
+ u8 pta_type; /* 0: RTK 4-wire mode, 1: 3-wire mode */
+ u8 pta_req_exist;
+
+ u32 hpta_cfg;
+ u32 hmbx_cfg;
+ u32 swout_cfg;
+ u32 swin_cfg;
+ u32 profile_map[BTC_BT_BMAX];
+ u32 bcnt[BTC_BCNT_NUM];
};
struct rtw89_btc_dm_emap {
@@ -2267,7 +2288,7 @@ struct rtw89_btc_cx {
struct rtw89_btc_wl_info wl;
struct rtw89_btc_bt_info bt0;
struct rtw89_btc_bt_info bt1;
- struct rtw89_btc_3rdcx_info other;
+ struct rtw89_btc_extsoc_info bt_ext;
u32 state_map;
};
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index ad3618dfd57d..91897aeced28 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -2745,7 +2745,7 @@ static void rtw8922a_btc_set_rfe(struct rtw89_dev *rtwdev)
if (module->kt_ver <= 1)
module->wa_type |= BTC_WA_HFP_ZB;
- rtwdev->btc.cx.other.type = BTC_3CX_NONE;
+ rtwdev->btc.cx.bt_ext.func_type = BTC_3CX_NONE;
if (module->rfe_type == 0) {
rtwdev->btc.dm.error.map.rfe_type0 = true;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 838c26231897..888973f4ef95 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -2997,6 +2997,46 @@ static u32 rtw8922d_chan_to_rf18_val(struct rtw89_dev *rtwdev,
static void rtw8922d_btc_set_rfe(struct rtw89_dev *rtwdev)
{
+ union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
+ struct rtw89_btc_module_v7 *module = &md->md_v7;
+
+ module->rfe_type = rtwdev->efuse.rfe_type;
+ module->kt_ver = rtwdev->hal.cv;
+ module->bt_solo = 0;
+ module->switch_type = BTC_SWITCH_INTERNAL;
+ module->wa_type = 0;
+
+ module->ant.type = BTC_ANT_SHARED;
+ module->ant.num = 2;
+ module->ant.isolation = 10;
+ module->ant.diversity = 0;
+ module->ant.single_pos = RF_PATH_A;
+ module->ant.btg_pos = RF_PATH_B;
+
+ if (module->kt_ver <= 1)
+ module->wa_type |= BTC_WA_HFP_ZB;
+
+ rtwdev->btc.cx.bt_ext.func_type = BTC_3CX_NONE;
+
+ if (module->rfe_type == 0) {
+ rtwdev->btc.dm.error.map.rfe_type0 = true;
+ return;
+ }
+
+ module->ant.num = (module->rfe_type % 2) ? 2 : 3;
+
+ if (module->kt_ver == 0)
+ module->ant.num = 2;
+
+ if (module->ant.num == 3) {
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->bt_pos = BTC_BT_ALONE;
+ } else {
+ module->ant.type = BTC_ANT_SHARED;
+ module->bt_pos = BTC_BT_BTG;
+ }
+ rtwdev->btc.btg_pos = module->ant.btg_pos;
+ rtwdev->btc.ant_type = module->ant.type;
}
static void rtw8922d_btc_init_cfg(struct rtw89_dev *rtwdev)
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 05/10] wifi: rtw89: coex: Move Bluetooth related counters to BT info
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
In order to support dual Bluetooth chip, move Bluetooth counters to BT
info. Because the two Bluetooth need to collect their own counters.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 163 +++++++++---------
drivers/net/wireless/realtek/rtw89/core.h | 3 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 8 +-
3 files changed, 86 insertions(+), 88 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 659028edccfa..8fa51867055b 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -1218,7 +1218,7 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
dm->error.map.slot_no_sync = false;
break;
case BTC_DCNT_BTTX_HANG:
- cnt = cx->cnt_bt[BTC_BCNT_LOPRI_TX];
+ cnt = bt->bcnt[BTC_BCNT_LOPRI_TX];
if (cnt == 0 && bt->link_info.slave_role)
dm->cnt_dm[BTC_DCNT_BTTX_HANG]++;
@@ -1231,10 +1231,10 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
dm->error.map.bt_tx_hang = false;
break;
case BTC_DCNT_BTCNT_HANG:
- cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] +
- cx->cnt_bt[BTC_BCNT_HIPRI_TX] +
- cx->cnt_bt[BTC_BCNT_LOPRI_RX] +
- cx->cnt_bt[BTC_BCNT_LOPRI_TX];
+ cnt = bt->bcnt[BTC_BCNT_HIPRI_RX] +
+ bt->bcnt[BTC_BCNT_HIPRI_TX] +
+ bt->bcnt[BTC_BCNT_LOPRI_RX] +
+ bt->bcnt[BTC_BCNT_LOPRI_TX];
if (cnt == 0)
dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++;
@@ -1723,7 +1723,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
rtwdev->chip->ops->btc_update_bt_cnt(rtwdev);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
- btc->cx.cnt_bt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLUT] =
rtw89_mac_get_plt_cnt(rtwdev,
RTW89_MAC_0);
}
@@ -1738,15 +1738,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i],
sizeof(dm->gnt.band[i]));
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ bt->bcnt[BTC_BCNT_HIPRI_TX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]);
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ bt->bcnt[BTC_BCNT_HIPRI_RX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ bt->bcnt[BTC_BCNT_LOPRI_TX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ bt->bcnt[BTC_BCNT_LOPRI_RX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]);
- btc->cx.cnt_bt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLUT] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -1770,15 +1770,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]);
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ bt->bcnt[BTC_BCNT_HIPRI_RX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ bt->bcnt[BTC_BCNT_LOPRI_TX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]);
- btc->cx.cnt_bt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLUT] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -1797,15 +1797,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ bt->bcnt[BTC_BCNT_HIPRI_RX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ bt->bcnt[BTC_BCNT_LOPRI_TX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLUT] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -1823,21 +1823,21 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcpy(&dm->gnt.band[i], &prpt->v7.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ bt->bcnt[BTC_BCNT_HIPRI_RX] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_RX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ bt->bcnt[BTC_BCNT_LOPRI_TX] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_RX_V105]);
val1 = le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]);
- if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW])
- val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */
+ if (val1 > bt->bcnt[BTC_BCNT_POLUT_NOW])
+ val1 -= bt->bcnt[BTC_BCNT_POLUT_NOW]; /* diff */
- btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1;
- btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] =
+ bt->bcnt[BTC_BCNT_POLUT_DIFF] = val1;
+ bt->bcnt[BTC_BCNT_POLUT_NOW] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]);
val1 = pfwinfo->event[BTF_EVNT_RPT];
@@ -1855,21 +1855,21 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcpy(&dm->gnt.band[i], &prpt->v8.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ bt->bcnt[BTC_BCNT_HIPRI_RX] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_RX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ bt->bcnt[BTC_BCNT_LOPRI_TX] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_TX_V105]);
- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_RX_V105]);
val1 = le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]);
- if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW])
- val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */
+ if (val1 > bt->bcnt[BTC_BCNT_POLUT_NOW])
+ val1 -= bt->bcnt[BTC_BCNT_POLUT_NOW]; /* diff */
- btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1;
- btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] =
+ bt->bcnt[BTC_BCNT_POLUT_DIFF] = val1;
+ bt->bcnt[BTC_BCNT_POLUT_NOW] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]);
val1 = pfwinfo->event[BTF_EVNT_RPT];
@@ -3083,7 +3083,7 @@ static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level)
int ret;
u8 buf;
- if (btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE] == 0)
+ if (bt->bcnt[BTC_BCNT_INFOUPDATE] == 0)
return;
if (bt->rf_para.tx_pwr_freerun == level)
@@ -3108,7 +3108,7 @@ static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- if (btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE] == 0)
+ if (bt->bcnt[BTC_BCNT_INFOUPDATE] == 0)
return;
if ((bt->rf_para.rx_gain_freerun == level ||
@@ -6059,7 +6059,7 @@ static u32 _read_scbd(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], read scbd: 0x%08x\n",
scbd_val);
- btc->cx.cnt_bt[BTC_BCNT_SCBDREAD]++;
+ btc->cx.bt0.bcnt[BTC_BCNT_SCBDREAD]++;
return scbd_val;
}
@@ -7388,18 +7388,16 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
{
- const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
+ const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
bool bt_link_change = false, lps_ctrl = false;
u32 val, any_bt_connect;
u8 mode;
- if (!chip->scbd)
+ if (rtwdev->chip->scbd)
return;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
@@ -7436,7 +7434,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
/* reset bt info if bt re-enable */
if (bt->enable.now && !bt->enable.last) {
_reset_btc_var(rtwdev, BTC_RESET_BTINFO);
- cx->cnt_bt[BTC_BCNT_REENABLE]++;
+ bt->bcnt[BTC_BCNT_REENABLE]++;
bt->enable.now = 1;
}
@@ -8095,7 +8093,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): return by bt-info duplicate!!\n",
__func__);
- cx->cnt_bt[BTC_BCNT_INFOSAME]++;
+ bt->bcnt[BTC_BCNT_INFOSAME]++;
return;
}
@@ -8116,7 +8114,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->status.map.acl_busy = btinfo.lb2.acl_busy;
b->status.map.inq_pag = btinfo.lb2.inq_pag;
bt->inq_pag.now = btinfo.lb2.inq_pag;
- cx->cnt_bt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last);
+ bt->bcnt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last);
hfp->exist = btinfo.lb2.hfp;
b->profile_cnt.now += (u8)hfp->exist;
@@ -8131,11 +8129,11 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info low-Byte3 */
btinfo.val = bt->raw_info[BTC_BTINFO_L3];
if (btinfo.lb3.retry != 0)
- cx->cnt_bt[BTC_BCNT_RETRY]++;
+ bt->bcnt[BTC_BCNT_RETRY]++;
b->cqddr = btinfo.lb3.cqddr;
- cx->cnt_bt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq);
+ bt->bcnt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq);
bt->inq = btinfo.lb3.inq;
- cx->cnt_bt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag);
+ bt->bcnt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag);
bt->pag = btinfo.lb3.pag;
b->status.map.mesh_busy = btinfo.lb3.mesh_busy;
@@ -8158,11 +8156,11 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
hid->type |= BTC_HID_RCU;
}
- cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
+ bt->bcnt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
bt->reinit = btinfo.hb1.reinit;
- cx->cnt_bt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now);
+ bt->bcnt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now);
b->relink.now = btinfo.hb1.relink;
- cx->cnt_bt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl);
+ bt->bcnt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl);
bt->igno_wl = btinfo.hb1.igno_wl;
if (bt->igno_wl && !cx->wl.status.map.rf_off)
@@ -8170,7 +8168,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
bt->ble_scan_en = btinfo.hb1.ble_scan;
- cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
+ bt->bcnt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
b->role_sw = btinfo.hb1.role_sw;
b->multi_link.now = btinfo.hb1.multi_link;
@@ -8179,7 +8177,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
btinfo.val = bt->raw_info[BTC_BTINFO_H2];
pan->active = !!btinfo.hb2.pan_active;
- cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
+ bt->bcnt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
b->afh_update = btinfo.hb2.afh_update;
a2dp->active = btinfo.hb2.a2dp_active;
b->slave_role = btinfo.hb2.slave;
@@ -8193,7 +8191,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
if (b->tx_3m != (u32)btinfo.hb3.tx_3m)
- cx->cnt_bt[BTC_BCNT_RATECHG]++;
+ bt->bcnt[BTC_BCNT_RATECHG]++;
b->tx_3m = (u32)btinfo.hb3.tx_3m;
a2dp->sink = btinfo.hb3.a2dp_sink;
@@ -8785,6 +8783,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN];
@@ -8812,13 +8811,13 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
case BTF_EVNT_BT_INFO:
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], handle C2H BT INFO with data %8ph\n", buf);
- btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE]++;
+ bt->bcnt[BTC_BCNT_INFOUPDATE]++;
_update_bt_info(rtwdev, buf, len);
break;
case BTF_EVNT_BT_SCBD:
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], handle C2H BT SCBD with data %8ph\n", buf);
- btc->cx.cnt_bt[BTC_BCNT_SCBDUPDATE]++;
+ bt->bcnt[BTC_BCNT_SCBDUPDATE]++;
_update_bt_scbd(rtwdev, false);
break;
case BTF_EVNT_BT_PSD:
@@ -8836,7 +8835,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++;
break;
case BTF_EVNT_BT_QUERY_TXPWR:
- btc->cx.cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]++;
+ bt->bcnt[BTC_BCNT_BTTXPWR_UPDATE]++;
_update_bt_txpwr_info(rtwdev, buf, len);
}
}
@@ -9187,17 +9186,17 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ",
- "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY],
- cx->cnt_bt[BTC_BCNT_RELINK],
- cx->cnt_bt[BTC_BCNT_RATECHG],
- cx->cnt_bt[BTC_BCNT_REINIT],
- cx->cnt_bt[BTC_BCNT_REENABLE]);
+ "[stat_cnt]", bt->bcnt[BTC_BCNT_RETRY],
+ bt->bcnt[BTC_BCNT_RELINK],
+ bt->bcnt[BTC_BCNT_RATECHG],
+ bt->bcnt[BTC_BCNT_REINIT],
+ bt->bcnt[BTC_BCNT_REENABLE]);
p += scnprintf(p, end - p,
"role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n",
- cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH],
- cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ],
- cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]);
+ bt->bcnt[BTC_BCNT_ROLESW], bt->bcnt[BTC_BCNT_AFH],
+ bt->bcnt[BTC_BCNT_INQPAG], bt->bcnt[BTC_BCNT_INQ],
+ bt->bcnt[BTC_BCNT_PAGE], bt->bcnt[BTC_BCNT_IGNOWL]);
p += _show_bt_profile_info(rtwdev, p, end - p);
@@ -9207,16 +9206,16 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
bt->raw_info[4], bt->raw_info[5], bt->raw_info[6],
bt->raw_info[7],
bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
- cx->cnt_bt[BTC_BCNT_INFOUPDATE],
- cx->cnt_bt[BTC_BCNT_INFOSAME]);
+ bt->bcnt[BTC_BCNT_INFOUPDATE],
+ bt->bcnt[BTC_BCNT_INFOSAME]);
p += scnprintf(p, end - p,
" %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)",
- "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX],
- cx->cnt_bt[BTC_BCNT_HIPRI_TX],
- cx->cnt_bt[BTC_BCNT_LOPRI_RX],
- cx->cnt_bt[BTC_BCNT_LOPRI_TX],
- cx->cnt_bt[BTC_BCNT_POLUT]);
+ "[trx_req_cnt]", bt->bcnt[BTC_BCNT_HIPRI_RX],
+ bt->bcnt[BTC_BCNT_HIPRI_TX],
+ bt->bcnt[BTC_BCNT_LOPRI_RX],
+ bt->bcnt[BTC_BCNT_LOPRI_TX],
+ bt->bcnt[BTC_BCNT_POLUT]);
if (!bt->scan_info_update) {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true);
@@ -9252,7 +9251,7 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
else
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, false);
- if (cx->cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]) {
+ if (bt->bcnt[BTC_BCNT_BTTXPWR_UPDATE]) {
p += scnprintf(p, end - p,
" %-15s : br_index:0x%x, le_index:0x%x",
"[bt_txpwr_lvl]",
@@ -10896,7 +10895,6 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL;
- struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
@@ -10914,8 +10912,8 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
" %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
"[scoreboard]", wl->scbd,
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
- cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+ bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
+ bt->bcnt[BTC_BCNT_SCBDUPDATE]);
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
@@ -10981,7 +10979,6 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL;
- struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
@@ -10999,8 +10996,8 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
" %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
"[scoreboard]", wl->scbd,
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
- cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+ bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
+ bt->bcnt[BTC_BCNT_SCBDUPDATE]);
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
@@ -11084,8 +11081,8 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
"\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)",
"[scoreboard]", wl->scbd,
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
- cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+ bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
+ bt->bcnt[BTC_BCNT_SCBDUPDATE]);
/* To avoid I/O if WL LPS or power-off */
dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 13fa7f574e91..31ac9fa4282e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2250,6 +2250,8 @@ struct rtw89_btc_bt_info {
u32 scan_info_update: 1;
u32 lna_constrain: 3;
u32 rsvd: 17;
+
+ u32 bcnt[BTC_BCNT_NUM];
};
struct rtw89_btc_rf_trx_para_v9 {
@@ -2267,7 +2269,6 @@ struct rtw89_btc_cx {
struct rtw89_btc_bt_info bt1;
struct rtw89_btc_3rdcx_info other;
u32 state_map;
- u32 cnt_bt[BTC_BCNT_NUM];
};
struct rtw89_btc_fbtc_tdma {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 2c1f166e687f..94027e5b8d28 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2105,12 +2105,12 @@ void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
return;
val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH);
- cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val);
- cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val);
+ cx->bt0.bcnt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val);
+ cx->bt0.bcnt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val);
val = rtw89_read32(rtwdev, R_AX_BT_STAST_LOW);
- cx->cnt_bt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val);
- cx->cnt_bt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val);
+ cx->bt0.bcnt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val);
+ cx->bt0.bcnt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val);
/* clock-gate off before reset counter*/
rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 04/10] wifi: rtw89: coex: Extend bt_slot_req for dual MAC wifi
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
This variable is for asking driver occupied Bluetooth traffic slot while
wifi is running at multi-port mode. Example like station + AP. The time
slot is separated by wifi driver under these wifi modes. And to ensure
Bluetooth performance, Coex will advice the Bluetooth slot length to
driver. And each MAC is able to run multi-port mode, so extend the
variable's index.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 24 +++++++++++------------
drivers/net/wireless/realtek/rtw89/coex.h | 2 +-
drivers/net/wireless/realtek/rtw89/core.h | 2 +-
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index e4662e7b74e0..659028edccfa 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -975,8 +975,8 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
}
btc->policy_len = 0;
- btc->bt_req_len = 0;
-
+ btc->bt_req_len[RTW89_PHY_0] = 0;
+ btc->bt_req_len[RTW89_PHY_1] = 0;
btc->dm.coex_info_map = BTC_COEX_INFO_ALL;
btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF;
btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF;
@@ -1994,10 +1994,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between real BT slot and EBT/E5G slot */
if (dm->tdma_now.type == CXTDMA_OFF &&
dm->tdma_now.ext_ctrl == CXECTL_EXT &&
- btc->bt_req_len != 0) {
+ btc->bt_req_len[RTW89_PHY_0] != 0) {
bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]);
- if (btc->bt_req_len > bt_slot_real) {
- diff_t = btc->bt_req_len - bt_slot_real;
+ if (btc->bt_req_len[RTW89_PHY_0] > bt_slot_real) {
+ diff_t = btc->bt_req_len[RTW89_PHY_0] - bt_slot_real;
_chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
}
}
@@ -2038,11 +2038,11 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between real BT slot and EBT/E5G slot */
if (dm->tdma_now.type == CXTDMA_OFF &&
dm->tdma_now.ext_ctrl == CXECTL_EXT &&
- btc->bt_req_len != 0) {
+ btc->bt_req_len[RTW89_PHY_0] != 0) {
bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]);
- if (btc->bt_req_len > bt_slot_real) {
- diff_t = btc->bt_req_len - bt_slot_real;
+ if (btc->bt_req_len[RTW89_PHY_0] > bt_slot_real) {
+ diff_t = btc->bt_req_len[RTW89_PHY_0] - bt_slot_real;
_chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
}
}
@@ -2083,7 +2083,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
_chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t);
/* Check diff time between real BT slot and EBT/E5G slot */
- bt_slot_set = btc->bt_req_len;
+ bt_slot_set = btc->bt_req_len[RTW89_PHY_0];
bt_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_BT]);
diff_t = 0;
if (dm->tdma_now.type == CXTDMA_OFF &&
@@ -5861,7 +5861,7 @@ static void _action_wl_2g_scc_v1(struct rtw89_dev *rtwdev)
dm->wl_scc.ebt_null = 0;
policy_type = BTC_CXP_OFFE_2GISOB;
} else if (bt->link_info.a2dp_desc.exist &&
- dur < btc->bt_req_len) {
+ dur < btc->bt_req_len[RTW89_PHY_0]) {
dm->wl_scc.ebt_null = 1; /* tx null at EBT */
policy_type = BTC_CXP_OFFE_2GBWMIXB2;
} else if (bt->link_info.a2dp_desc.exist ||
@@ -5934,7 +5934,7 @@ static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
dm->wl_scc.ebt_null = 0;
policy_type = BTC_CXP_OFFE_2GISOB;
} else if (bt->link_info.a2dp_desc.exist &&
- dur < btc->bt_req_len) {
+ dur < btc->bt_req_len[RTW89_PHY_0]) {
dm->wl_scc.ebt_null = 1; /* tx null at EBT */
policy_type = BTC_CXP_OFFE_2GBWMIXB2;
} else if (bt->link_info.a2dp_desc.exist ||
@@ -9694,7 +9694,7 @@ static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
" %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n",
"[dm_ctrl]", dm->wl_tx_limit.enable,
dm->wl_tx_limit.tx_time,
- dm->wl_tx_limit.tx_retry, btc->bt_req_len,
+ dm->wl_tx_limit.tx_retry, btc->bt_req_len[RTW89_PHY_0],
bt->scan_rx_low_pri);
return p - buf;
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index ea2c1e5d70f5..6ac14611607c 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -329,7 +329,7 @@ static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev,
{
struct rtw89_btc *btc = &rtwdev->btc;
- return btc->bt_req_len;
+ return btc->bt_req_len[phy_idx];
}
static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 0abbde6a2013..13fa7f574e91 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3390,7 +3390,7 @@ struct rtw89_btc {
struct wiphy_work dhcp_notify_work;
struct wiphy_work icmp_notify_work;
- u32 bt_req_len;
+ u32 bt_req_len[RTW89_PHY_NUM];
u8 policy[RTW89_BTC_POLICY_MAXLEN];
u8 ant_type;
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 03/10] wifi: rtw89: coex: Move wifi related counters to wifi info
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Move wifi related counters to wifi main info, it is to facilitate
the after modification for dual MAC wifi structure.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 80 +++++++++++------------
drivers/net/wireless/realtek/rtw89/core.h | 2 +-
2 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index f857ba247c23..e4662e7b74e0 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -3411,7 +3411,7 @@ static void _set_bt_afh_info_v0(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): en=%d, ch=%d, bw=%d\n",
__func__, en, ch, bw);
- btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++;
+ wl->wcnt[BTC_WCNT_CH_UPDATE]++;
}
static void _set_bt_afh_info_v1(struct rtw89_dev *rtwdev)
@@ -3511,7 +3511,7 @@ static void _set_bt_afh_info_v1(struct rtw89_dev *rtwdev)
"[BTC], %s(): en=%d, ch=%d, bw=%d\n",
__func__, en, ch, bw);
- btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++;
+ wl->wcnt[BTC_WCNT_CH_UPDATE]++;
}
}
@@ -5630,7 +5630,7 @@ static void _action_common(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n",
wl->scbd);
wl->scbd_change = false;
- btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++;
+ wl->wcnt[BTC_WCNT_SCBDUPDATE]++;
}
if (btc->ver->fcxosi) {
@@ -6877,7 +6877,7 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
wl_rinfo->dbcc_chg = 1;
wl_rinfo->dbcc_en = rtwdev->dbcc_en;
- btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++;
+ wl->wcnt[BTC_WCNT_DBCC_CHG]++;
}
if (rtwdev->dbcc_en) {
@@ -7321,7 +7321,7 @@ static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id
if (wl_rinfo->dbcc_en != dbcc_en_ori) {
wl->dbcc_chg = true;
- btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++;
+ wl->wcnt[BTC_WCNT_DBCC_CHG]++;
}
}
@@ -7378,7 +7378,7 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
if (wl->rfk_info.state != BTC_WRFK_STOP) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): RFK timeout\n", __func__);
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]++;
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT]++;
dm->error.map.wl_rfk_timeout = true;
wl->rfk_info.state = BTC_WRFK_STOP;
_write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
@@ -7520,13 +7520,13 @@ static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev)
_update_bt_scbd(rtwdev, true);
- cx->cnt_wl[BTC_WCNT_RFK_REQ]++;
+ cx->wl.wcnt[BTC_WCNT_RFK_REQ]++;
if ((bt->rfk_info.map.run || bt->rfk_info.map.req) &&
!bt->rfk_info.map.timeout) {
- cx->cnt_wl[BTC_WCNT_RFK_REJECT]++;
+ cx->wl.wcnt[BTC_WCNT_RFK_REJECT]++;
} else {
- cx->cnt_wl[BTC_WCNT_RFK_GO]++;
+ cx->wl.wcnt[BTC_WCNT_RFK_GO]++;
return true;
}
return false;
@@ -7934,14 +7934,14 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
switch (pkt_type) {
case PACKET_DHCP:
- cnt = ++cx->cnt_wl[BTC_WCNT_DHCP];
+ cnt = ++wl->wcnt[BTC_WCNT_DHCP];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): DHCP cnt=%d\n", __func__, cnt);
wl->status.map.connecting = true;
delay_work = true;
break;
case PACKET_EAPOL:
- cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL];
+ cnt = ++wl->wcnt[BTC_WCNT_EAPOL];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt);
wl->status.map._4way = true;
@@ -7950,7 +7950,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
delay /= 2;
break;
case PACKET_EAPOL_END:
- cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL];
+ cnt = ++wl->wcnt[BTC_WCNT_EAPOL];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): EAPOL_End cnt=%d\n",
__func__, cnt);
@@ -7958,7 +7958,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
break;
case PACKET_ARP:
- cnt = ++cx->cnt_wl[BTC_WCNT_ARP];
+ cnt = ++wl->wcnt[BTC_WCNT_ARP];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): ARP cnt=%d\n", __func__, cnt);
return;
@@ -10913,7 +10913,7 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
"[scoreboard]", wl->scbd,
- cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE],
bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
@@ -10998,7 +10998,7 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
"[scoreboard]", wl->scbd,
- cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE],
bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
@@ -11083,7 +11083,7 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
"\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)",
"[scoreboard]", wl->scbd,
- cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE],
bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
@@ -11189,10 +11189,10 @@ static int _show_summary_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
- "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+ "[RFK]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT]);
p += scnprintf(p, end - p,
", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
@@ -11304,10 +11304,10 @@ static int _show_summary_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
- "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+ "[RFK]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT]);
p += scnprintf(p, end - p,
", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
@@ -11418,10 +11418,10 @@ static int _show_summary_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+ "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT]);
p += scnprintf(p, end - p,
", bt_rfk[req:%d]",
@@ -11539,10 +11539,10 @@ static int _show_summary_v105(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+ "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT]);
p += scnprintf(p, end - p,
", bt_rfk[req:%d]",
@@ -11664,10 +11664,10 @@ static int _show_summary_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
"\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT],
+ "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT],
wl->rfk_info.proc_time);
p += scnprintf(p, end - p, ", bt_rfk[req:%d]",
@@ -11777,10 +11777,10 @@ static int _show_summary_v8(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
"\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT],
+ "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT],
wl->rfk_info.proc_time);
p += scnprintf(p, end - p, ", bt_rfk[req:%d]",
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 2f12252bc26e..0abbde6a2013 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2078,6 +2078,7 @@ struct rtw89_btc_wl_info {
bool link_mode_chg;
bool dbcc_chg;
u32 scbd;
+ u32 wcnt[BTC_WCNT_NUM];
};
struct rtw89_btc_module {
@@ -2267,7 +2268,6 @@ struct rtw89_btc_cx {
struct rtw89_btc_3rdcx_info other;
u32 state_map;
u32 cnt_bt[BTC_BCNT_NUM];
- u32 cnt_wl[BTC_WCNT_NUM];
};
struct rtw89_btc_fbtc_tdma {
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 02/10] wifi: rtw89: coex: offset current BT info to BT0 for dual BT configuration
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
In order to compatible with single/dual Bluetooth structure in one branch,
offset the currently using BT info structure to BT-0.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 130 +++++++++++-----------
drivers/net/wireless/realtek/rtw89/core.h | 3 +-
2 files changed, 67 insertions(+), 66 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 73f271a7ae7a..f857ba247c23 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -924,7 +924,7 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_wl_link_info *wl_linfo;
u8 i;
@@ -1106,7 +1106,7 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_dm *dm = &btc->dm;
@@ -1276,7 +1276,7 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc;
union rtw89_btc_fbtc_btver *pver = &btc->fwinfo.rpt_fbtc_btver.finfo;
@@ -1417,7 +1417,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL;
union rtw89_btc_fbtc_cysta_info *pcysta = NULL;
struct rtw89_btc_prpt *btc_prpt = NULL;
@@ -3079,7 +3079,7 @@ static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
int ret;
u8 buf;
@@ -3106,7 +3106,7 @@ static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level)
static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
if (btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE] == 0)
return;
@@ -3138,7 +3138,7 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
struct rtw89_btc_rf_trx_para para;
@@ -3224,7 +3224,7 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
if (wl->status.map.connecting || wl->status.map._4way ||
@@ -3251,7 +3251,7 @@ static void _set_bt_afh_info_v0(struct rtw89_dev *rtwdev)
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
@@ -3421,7 +3421,7 @@ static void _set_bt_afh_info_v1(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
struct rtw89_btc_wl_afh_info *wl_afh = &wl->afh_info;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_rlink *rlink;
u8 en = 0, ch = 0, bw = 0, buf[3] = {};
u8 i, j, link_mode;
@@ -3527,7 +3527,7 @@ static bool _check_freerun(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
@@ -4000,9 +4000,9 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
- struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc;
- struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
+ struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt0.link_info.hid_desc;
+ struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt0.link_info.hfp_desc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
u8 type, null_role;
u32 tbl_w1, tbl_b1, tbl_b4;
@@ -4483,7 +4483,7 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0;
bool dbcc_chg = false;
@@ -4611,7 +4611,7 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
u32 ant_path_type = rtw89_get_antpath_type(phy_map, type);
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
@@ -4750,7 +4750,7 @@ static void _action_wl_off(struct rtw89_dev *rtwdev, u8 mode)
if (mode == BTC_WLINK_5G) {
_set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OFF);
} else if (wl->status.map.lps == BTC_LPS_RF_ON) {
- if (btc->cx.bt.link_info.a2dp_desc.active)
+ if (btc->cx.bt0.link_info.a2dp_desc.active)
_set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF);
else
_set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_WL_OFF);
@@ -4790,7 +4790,7 @@ static void _action_bt_off(struct rtw89_dev *rtwdev)
static void _action_bt_idle(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_link_info *b = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_link_info *b = &btc->cx.bt0.link_info;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
@@ -4838,7 +4838,7 @@ static void _action_bt_hfp(struct rtw89_dev *rtwdev)
if (btc->cx.wl.status.map._4way) {
_set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP);
} else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
- btc->cx.bt.scan_rx_low_pri = true;
+ btc->cx.bt0.scan_rx_low_pri = true;
_set_policy(rtwdev, BTC_CXP_OFF_BWB2, BTC_ACT_BT_HFP);
} else {
_set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP);
@@ -4858,7 +4858,7 @@ static void _action_bt_hid(struct rtw89_dev *rtwdev)
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_hid_desc *hid = &bt->link_info.hid_desc;
u16 policy_type = BTC_CXP_OFF_BT;
@@ -4868,7 +4868,7 @@ static void _action_bt_hid(struct rtw89_dev *rtwdev)
if (wl->status.map._4way) {
policy_type = BTC_CXP_OFF_WL;
} else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
- btc->cx.bt.scan_rx_low_pri = true;
+ btc->cx.bt0.scan_rx_low_pri = true;
if (hid->type & BTC_HID_BLE)
policy_type = BTC_CXP_OFF_BWB0;
else
@@ -4960,7 +4960,7 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
static void _action_bt_pan(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
@@ -5172,7 +5172,7 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info *wl_rinfo_v0 = &wl->role_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
struct _wl_rinfo_now wl_rinfo;
u32 is_btg = BTC_BTGCTRL_DISABLE;
@@ -5249,13 +5249,13 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info;
- struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2;
struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
u8 is_preagc, val, link_mode, dbcc_2g_phy;
u8 role_ver = rtwdev->btc.ver->fwlrole;
@@ -5285,7 +5285,7 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
} else if (link_mode == BTC_WLINK_5G) {
is_preagc = BTC_PREAGC_DISABLE;
} else if (link_mode == BTC_WLINK_NOLINK ||
- btc->cx.bt.link_info.profile_cnt.now == 0) {
+ btc->cx.bt0.link_info.profile_cnt.now == 0) {
is_preagc = BTC_PREAGC_DISABLE;
} else if (dm->tdma_now.type != CXTDMA_OFF &&
!bt_linfo->hfp_desc.exist &&
@@ -5435,7 +5435,7 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
@@ -5522,7 +5522,7 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
bool bt_hi_lna_rx = false;
u8 mode;
@@ -5551,7 +5551,7 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
_write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri));
}
@@ -5590,7 +5590,7 @@ static void _action_common(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
u32 bt_rom_code_id, bt_fw_ver;
@@ -5650,7 +5650,7 @@ static void _action_common(struct rtw89_dev *rtwdev)
static void _action_by_bt(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
@@ -5747,7 +5747,7 @@ static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
policy_type = BTC_CXP_OFFE_WL;
else if (btc->cx.wl.status.val & btc_scanning_map.val)
policy_type = BTC_CXP_OFFE_2GBWMIXB;
- else if (btc->cx.bt.link_info.status.map.connect == 0)
+ else if (btc->cx.bt0.link_info.status.map.connect == 0)
policy_type = BTC_CXP_OFFE_2GISOB;
else
policy_type = BTC_CXP_OFFE_2GBWISOB;
@@ -5791,7 +5791,7 @@ static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ if (btc->cx.bt0.link_info.profile_cnt.now == 0)
_set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
BTC_ACT_WL_2G_MCC);
else
@@ -5809,7 +5809,7 @@ static void _action_wl_2g_scc(struct rtw89_dev *rtwdev)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ if (btc->cx.bt0.link_info.profile_cnt.now == 0)
_set_policy(rtwdev,
BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_SCC);
else
@@ -5824,7 +5824,7 @@ static void _action_wl_2g_scc_v1(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1;
u16 policy_type = BTC_CXP_OFF_BT;
@@ -5886,7 +5886,7 @@ static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2;
struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
@@ -5959,7 +5959,7 @@ static void _action_wl_2g_scc_v8(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
u16 policy_type = BTC_CXP_OFF_BT;
@@ -5987,7 +5987,7 @@ static void _action_wl_2g_ap(struct rtw89_dev *rtwdev)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
if (btc->ant_type == BTC_ANT_SHARED) {
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ if (btc->cx.bt0.link_info.profile_cnt.now == 0)
_set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
BTC_ACT_WL_2G_AP);
else
@@ -6004,7 +6004,7 @@ static void _action_wl_2g_go(struct rtw89_dev *rtwdev)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ if (btc->cx.bt0.link_info.profile_cnt.now == 0)
_set_policy(rtwdev,
BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_GO);
else
@@ -6035,7 +6035,7 @@ static void _action_wl_2g_nan(struct rtw89_dev *rtwdev)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ if (btc->cx.bt0.link_info.profile_cnt.now == 0)
_set_policy(rtwdev,
BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_NAN);
else
@@ -7352,7 +7352,7 @@ void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work)
coex_bt_devinfo_work.work);
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
lockdep_assert_wiphy(wiphy);
@@ -7392,7 +7392,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
bool bt_link_change = false, lps_ctrl = false;
@@ -7496,7 +7496,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
#define BTC_BTINFO_PWR_LEN 5
static void _update_bt_txpwr_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
{
- struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt;
+ struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
if (len != BTC_BTINFO_PWR_LEN)
@@ -7516,7 +7516,7 @@ static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
_update_bt_scbd(rtwdev, true);
@@ -7540,7 +7540,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
@@ -7657,12 +7657,12 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (!cx->bt.enable.now && !cx->other.type) {
+ if (!cx->bt0.enable.now && !cx->other.type) {
_action_bt_off(rtwdev);
goto exit;
}
- if (cx->bt.whql_test) {
+ if (cx->bt0.whql_test) {
_action_bt_whql(rtwdev);
goto exit;
}
@@ -7925,7 +7925,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_link_info *b = &cx->bt.link_info;
+ struct rtw89_btc_bt_link_info *b = &cx->bt0.link_info;
struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
u32 cnt;
@@ -8030,7 +8030,7 @@ static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
u8 *rssi_st, rssi_th, rssi_level = 0;
u8 i;
@@ -8080,7 +8080,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
@@ -8851,7 +8851,7 @@ static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0;
u8 cv, rfe, iso, ant_num, ant_single_pos;
@@ -9050,7 +9050,7 @@ enum btc_bt_a2dp_type {
static int _show_bt_profile_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info;
struct rtw89_btc_bt_hfp_desc hfp = bt_linfo->hfp_desc;
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
@@ -9108,7 +9108,7 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_wl_info *wl = &cx->wl;
u32 ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex);
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
@@ -9631,7 +9631,7 @@ static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
char *p = buf, *end = buf + bufsz;
u8 igno_bt;
@@ -9853,7 +9853,7 @@ static int _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL;
union rtw89_btc_fbtc_rxflct r;
@@ -9984,7 +9984,7 @@ static int _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz
static int _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx;
@@ -10123,7 +10123,7 @@ static int _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz
static int _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx;
@@ -10262,7 +10262,7 @@ static int _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz
static int _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt0.link_info.a2dp_desc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx;
@@ -10399,7 +10399,7 @@ static int _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz
static int _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
- struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt;
+ struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0;
struct rtw89_btc_bt_a2dp_desc *a2dp = &bt->link_info.a2dp_desc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
struct rtw89_btc_fbtc_cysta_v7 *pcysta = NULL;
@@ -10898,7 +10898,7 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
char *p = buf, *end = buf + bufsz;
@@ -10983,7 +10983,7 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
char *p = buf, *end = buf + bufsz;
@@ -11068,7 +11068,7 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_mac_ax_gnt *gnt = NULL;
struct rtw89_btc_dm *dm = &btc->dm;
char *p = buf, *end = buf + bufsz;
@@ -11146,7 +11146,7 @@ static int _show_summary_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
char *p = buf, *end = buf + bufsz;
u8 i;
@@ -11255,7 +11255,7 @@ static int _show_summary_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_bt_info *bt = &cx->bt0;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
char *p = buf, *end = buf + bufsz;
u8 i;
@@ -11929,7 +11929,7 @@ void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev)
void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms)
{
- struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt.link_info;
+ struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt0.link_info;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index de92e42da614..2f12252bc26e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2262,7 +2262,8 @@ struct rtw89_btc_rf_trx_para_v9 {
struct rtw89_btc_cx {
struct rtw89_btc_wl_info wl;
- struct rtw89_btc_bt_info bt;
+ struct rtw89_btc_bt_info bt0;
+ struct rtw89_btc_bt_info bt1;
struct rtw89_btc_3rdcx_info other;
u32 state_map;
u32 cnt_bt[BTC_BCNT_NUM];
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 01/10] wifi: rtw89: coex: force to exit Wi-Fi LPS while Bluetooth profile exist
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Wi-Fi can not reach LPS leave threshold while Wi-Fi only throughput
not good & Bluetooth share bandwidth. Add logic to let force leave
Wi-Fi LPS while Bluetooth profile exist. Update COEX version to 9.0.1.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 87 +++++++++++++++++------
drivers/net/wireless/realtek/rtw89/core.h | 4 ++
2 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 0f7ae572ef91..73f271a7ae7a 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -11,7 +11,7 @@
#include "ps.h"
#include "reg.h"
-#define RTW89_COEX_VERSION 0x09000013
+#define RTW89_COEX_VERSION 0x09000113
#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
#define BTC_E2G_LIMIT_DEF 80
@@ -434,6 +434,8 @@ enum btc_b2w_scoreboard {
BTC_BSCB_WLRFK = BIT(11),
BTC_BSCB_BT_HILNA = BIT(13),
BTC_BSCB_BT_CONNECT = BIT(16),
+ BTC_BSCB_PAN_ACT = BIT(28),
+ BTC_BSCB_HFP_ACT = BIT(29),
BTC_BSCB_PATCH_CODE = BIT(30),
BTC_BSCB_ALL = GENMASK(30, 0),
};
@@ -2747,7 +2749,9 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
dm->tdma.rxflctrl == CXFLC_QOSNULL)
btc->lps = 1;
else
- btc->lps = 0;
+ btc->lps = dm->lps_ctrl_scbd;
+
+ dm->lps_ctrl_scbd_last = dm->lps_ctrl_scbd;
if (btc->lps == 1)
rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
@@ -4434,7 +4438,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
if (dm->leak_ap && dm->tdma.leak_n > 1)
_tdma_set_lek(btc, 1);
- if (dm->tdma_instant_excute) {
+ if (dm->tdma_instant_excute || dm->lps_ctrl_change) {
btc->dm.tdma.option_ctrl |= BIT(0);
btc->update_policy_force = true;
}
@@ -5638,7 +5642,8 @@ static void _action_common(struct rtw89_dev *rtwdev)
_fw_set_drv_info(rtwdev, CXDRVINFO_OSI);
}
}
- btc->dm.tdma_instant_excute = 0;
+ dm->tdma_instant_excute = 0;
+ dm->lps_ctrl_change = false;
wl->pta_reg_mac_chg = false;
}
@@ -7384,11 +7389,15 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
- u32 val;
- bool status_change = false;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ bool bt_link_change = false, lps_ctrl = false;
+ u32 val, any_bt_connect;
+ u8 mode;
if (!chip->scbd)
return;
@@ -7403,13 +7412,26 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
return;
}
+ if (ver->fwlrole == 0)
+ mode = wl->role_info.link_mode;
+ else if (ver->fwlrole == 1)
+ mode = wl->role_info_v1.link_mode;
+ else if (ver->fwlrole == 2)
+ mode = wl->role_info_v2.link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl->role_info_v7.link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl->role_info_v8.link_mode;
+ else
+ return;
+
if (!(val & BTC_BSCB_ON))
bt->enable.now = 0;
else
bt->enable.now = 1;
if (bt->enable.now != bt->enable.last)
- status_change = true;
+ bt_link_change = true;
/* reset bt info if bt re-enable */
if (bt->enable.now && !bt->enable.last) {
@@ -7423,29 +7445,52 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
bt->mbx_avl = !!(val & BTC_BSCB_ACT);
if (bt->whql_test != !!(val & BTC_BSCB_WHQL))
- status_change = true;
+ bt_link_change = true;
bt->whql_test = !!(val & BTC_BSCB_WHQL);
bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE;
bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT);
+ bt->link_info.pan_desc.exist = !!(val & BTC_BSCB_PAN_ACT);
+ bt->link_info.hfp_desc.exist = !!(val & BTC_BSCB_HFP_ACT);
bt->lna_constrain = !!(val & BTC_BSCB_BT_LNAB0) +
!!(val & BTC_BSCB_BT_LNAB1) * 2 + 4;
/* if rfk run 1->0 */
if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN))
- status_change = true;
+ bt_link_change = true;
bt->rfk_info.map.run = !!(val & BTC_BSCB_RFK_RUN);
bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ);
bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA);
- bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT);
- if (bt->run_patch_code != !!(val & BTC_BSCB_PATCH_CODE))
- status_change = true;
+ any_bt_connect = !!(val & BTC_BSCB_BT_CONNECT);
+
+ /* if connect change */
+ if (bt->link_info.status.map.connect != any_bt_connect)
+ bt_link_change = true;
+
+ /* if specific profile exist */
+ if (((bt->link_info.a2dp_desc.exist || bt->link_info.pan_desc.exist ||
+ bt->link_info.hfp_desc.exist) && mode == BTC_WLINK_2G_STA) ||
+ bt->whql_test)
+ lps_ctrl = true;
+
+ if (dm->lps_ctrl_scbd != lps_ctrl) {
+ dm->lps_ctrl_scbd = lps_ctrl;
+ bt_link_change = true;
+ dm->lps_ctrl_change = true;
+ } else {
+ dm->lps_ctrl_change = false;
+ }
+
+ bt->link_info.status.map.connect = any_bt_connect;
bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
- if (!only_update && status_change)
- _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
+ if (bt_link_change) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s: bt status change!!\n", __func__);
+ /* TODO: Need to notify driver to update EXT-CTRL-BT-SLOT */
+ }
}
#define BTC_BTINFO_PWR_LEN 5
@@ -7560,7 +7605,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
}
if (wl->status.map.rf_off_pre == wl->status.map.rf_off &&
- wl->status.map.lps_pre == wl->status.map.lps) {
+ wl->status.map.lps_pre == wl->status.map.lps &&
+ !dm->lps_ctrl_change && !dm->lps_ctrl_scbd) {
if (reason == BTC_RSN_NTFY_POWEROFF ||
reason == BTC_RSN_NTFY_RADIO_STATE) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -7577,6 +7623,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
}
}
+ if (reason == BTC_RSN_NTFY_INIT || reason == BTC_RSN_NTFY_RADIO_STATE)
+ _update_bt_scbd(rtwdev, false);
+
dm->freerun = false;
dm->cnt_dm[BTC_DCNT_RUN]++;
dm->fddt_train = BTC_FDDT_DISABLE;
@@ -7597,7 +7646,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (wl->status.map.rf_off || wl->status.map.lps || dm->bt_only) {
+ if (wl->status.map.rf_off || dm->bt_only || wl->status.map.lps) {
_action_wl_off(rtwdev, mode);
igno_bt = true;
goto exit;
@@ -7781,7 +7830,6 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
_write_scbd(rtwdev,
BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true);
- _update_bt_scbd(rtwdev, true);
if (rtw89_mac_get_ctrl_path(rtwdev)) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): PTA owner warning!!\n",
@@ -8339,7 +8387,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true);
val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG;
_write_scbd(rtwdev, val, true);
- _update_bt_scbd(rtwdev, true);
chip->ops->btc_init_cfg(rtwdev);
} else {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false);
@@ -8349,10 +8396,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
_write_scbd(rtwdev, BTC_WSCB_ALL, false);
else
_write_scbd(rtwdev, BTC_WSCB_ACTIVE, false);
-
- if (rf_state == BTC_RFCTRL_LPS_WL_ON &&
- wl->status.map.lps_pre != BTC_LPS_OFF)
- _update_bt_scbd(rtwdev, true);
}
btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 5547888d7e67..de92e42da614 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3153,6 +3153,10 @@ struct rtw89_btc_dm {
u8 wl_pre_agc_rb: 2;
u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
u8 slot_req_more: 1;
+ u8 lps_ctrl_scbd: 1;
+
+ u8 lps_ctrl_scbd_last: 1;
+ u8 lps_ctrl_change: 1;
};
struct rtw89_btc_ctrl {
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 00/10] wifi: rtw89: coex: update BT coexistence to support dual BT for RTL8922D
From: Ping-Ke Shih @ 2026-06-24 3:39 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
The RTL8922D is a dual BT combo card. To work with two BT well, extend
the BT coexistence mechanism to consider two BT cases.
Mainly the patches are to adjust struct fields related to BT from one
field to two element size array, and then add new format to support
more parameters needed by RTL8922D.
Ching-Te Ku (10):
wifi: rtw89: coex: force to exit Wi-Fi LPS while Bluetooth profile
exist
wifi: rtw89: coex: offset current BT info to BT0 for dual BT
configuration
wifi: rtw89: coex: Move wifi related counters to wifi info
wifi: rtw89: coex: Extend bt_slot_req for dual MAC wifi
wifi: rtw89: coex: Move Bluetooth related counters to BT info
wifi: rtw89: coex: Refine third party module related coexistence
wifi: rtw89: coex: Add TX/RX RF parameter format version 9
wifi: rtw89: coex: Renaming drvinfo_type to drvinfo_ver
wifi: rtw89: coex: Add Wi-Fi firmware 0.35.94.1 support for RTL8922D
wifi: rtw89: coex: Add RTL8922D chip string
drivers/net/wireless/realtek/rtw89/coex.c | 843 +++++++++++-------
drivers/net/wireless/realtek/rtw89/coex.h | 2 +-
drivers/net/wireless/realtek/rtw89/core.h | 90 +-
drivers/net/wireless/realtek/rtw89/fw.c | 252 +++++-
drivers/net/wireless/realtek/rtw89/fw.h | 160 ++--
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 20 +-
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 12 +-
.../net/wireless/realtek/rtw89/rtw8852bt.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 12 +-
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 14 +-
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 44 +
12 files changed, 948 insertions(+), 525 deletions(-)
base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
--
2.25.1
^ permalink raw reply
* Re: [PATCH 1/2] wifi: mt76: mt7927: set band index for sniffer mode
From: Devin Wittmayer @ 2026-06-24 3:31 UTC (permalink / raw)
To: Sean Wang, Felix Fietkau, Lorenzo Bianconi
Cc: linux-wireless, linux-mediatek, Sean Wang, Devin Wittmayer
In-Reply-To: <20260613225144.2414283-1-sean.wang@kernel.org>
Tested on a real MT7927 (Filogic 380, PCIe). Two monitors on different
bands capture at the same time with the series, and drop back onto one
band without it.
I tried each patch on its own too. [1/2] by itself still collapses both
monitors onto one channel. With [2/2] they stay apart, but then one of
them stops capturing, so it looks like both are needed.
Single-band monitor and a normal station connection were both fine.
Tested-by: Devin Wittmayer <lucid_duck@justthetip.ca>
^ permalink raw reply
* [REGRESSION] rtw89: RTL8922AE Wi-Fi broken in Kernel 7.0 (and 6.18+) due to mac80211 API changes
From: Gmail @ 2026-06-24 3:27 UTC (permalink / raw)
To: linux-wireless; +Cc: pkshih
Hi,
I am reporting a regression regarding the Realtek RTL8922AE Wi-Fi
adapter (rtw89) on a Gigabyte X870M Aorus Elite Wifi7 motherboard.
The adapter works perfectly on Kernel 6.17.7, but it fails to initialize
or is not recognized in newer kernels, specifically 6.18, 6.19, and the
current 7.0.x series used in the Bazzite (Fedora-based) testing branch.
Technical details:
The issue seems related to recent architectural changes in the mac80211
subsystem:
1. Signature changes in 'struct ieee80211_ops': Several callbacks
(including .config, .stop, and .set_rts_threshold) now require the
'radio_idx' parameter to support multi-radio wiphy/MLO. It appears the
rtw89 driver in these kernel builds might not have been fully updated to
match these new signatures, leading to incompatible pointer type errors
or initialization failures.
2. Removal of init_dummy_netdev: The driver code seems to still
reference init_dummy_netdev, which was replaced by alloc_netdev_dummy()
in the wireless-next/net-next trees.
Hardware Info:
- Chipset: Realtek RTL8922AE
- PCI ID: [10ec:8922] (Please verify this ID on your system using 'lspci
-nn')
- Working Kernel: 6.17.7
- Broken Kernels: 6.18.x, 6.19.x, 7.0.x
I am using the OGC Kernel from the Bazzite project, but the issue
appears to stem from the upstream driver synchronization with the new
mac80211 API.
Are there any pending patches in the rtw-next tree that address these
specific ieee80211_ops signature changes for the 8922AE?
Best regards,
Helder Bertoldo
^ permalink raw reply
* [PATCH v4 1/1] wifi: mt76: mt792x: fix use-after-free in mt76_rx_poll_complete
From: Eason Lai @ 2026-06-24 3:05 UTC (permalink / raw)
To: nbd, lorenzo
Cc: linux-wireless, linux-mediatek, Yf.Luo, kun.wu, deren.wu,
sean.wang, quan.zhou, ryder.lee, leon.yen, litien.chang, jb.tsai,
eason.lai, Eason Lai
From: Eason Lai <Eason.Lai@mediatek.com>
A use-after-free issue occurs in mt76_rx_poll_complete due to a race
condition. The STA has already been removed, but the rx_status still
had a pointer to the wcid in the STA.
Set the links' wcid pointers to be NULL for a MLD in
mt7925_sta_pre_rcu_remove()
BUG: KASAN: invalid-access in mt76_rx_poll_complete+0x280/0x470
Call trace:
dump_backtrace+0xec/0x128
show_stack+0x18/0x28
dump_stack_lvl+0x40/0xc8
print_report+0x1b8/0x710
kasan_report+0xe0/0x144
do_bad_area+0x120/0x260
do_tag_check_fault+0x20/0x34
do_mem_abort+0x54/0xa8
el1_abort+0x3c/0x5c
el1h_64_sync_handler+0x40/0xcc
el1h_64_sync+0x7c/0x80
mt76_rx_poll_complete+0x280/0x470
mt76_dma_rx_poll+0x114/0x51c
mt792x_poll_rx+0x60/0xf8
napi_threaded_poll_loop+0xe0/0x450
napi_threaded_poll+0x80/0x9c
kthread+0x11c/0x158
ret_from_fork+0x10/0x20
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for
mt7925 chips")
Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
---
v2: fix mt76x02 build errors
v3: fix mt76x02 build error due to variable set but not used
v4: fix use-after-free in MLO
---
.../net/wireless/mediatek/mt76/mt7925/main.c | 36 ++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 73d3722739d0..e3fb6392eda2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2410,6 +2410,40 @@ static void mt7925_channel_switch_rx_beacon(struct ieee80211_hw *hw,
}
}
+static void mt7925_sta_pre_rcu_remove(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct mt76_phy *phy = hw->priv;
+ struct mt76_dev *dev = phy->dev;
+ struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+
+ mutex_lock(&dev->mutex);
+ spin_lock_bh(&dev->status_lock);
+
+ if (ieee80211_vif_is_mld(vif)) {
+ struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
+ struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+ unsigned long valid = mvif->valid_links;
+ struct mt792x_link_sta *mlink;
+ unsigned int link_id;
+
+ for_each_set_bit(link_id, &valid, IEEE80211_MLD_MAX_NUM_LINKS) {
+ mlink = mt792x_sta_to_link(msta, link_id);
+ if (!mlink || !mlink->wcid.sta)
+ continue;
+ if (mlink->wcid.idx < ARRAY_SIZE(dev->wcid))
+ rcu_assign_pointer(dev->wcid[mlink->wcid.idx],
+ NULL);
+ }
+ } else {
+ rcu_assign_pointer(dev->wcid[wcid->idx], NULL);
+ }
+
+ spin_unlock_bh(&dev->status_lock);
+ mutex_unlock(&dev->mutex);
+}
+
const struct ieee80211_ops mt7925_ops = {
.tx = mt792x_tx,
.start = mt7925_start,
@@ -2422,7 +2456,7 @@ const struct ieee80211_ops mt7925_ops = {
.start_ap = mt7925_start_ap,
.stop_ap = mt7925_stop_ap,
.sta_state = mt76_sta_state,
- .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
+ .sta_pre_rcu_remove = mt7925_sta_pre_rcu_remove,
.set_key = mt7925_set_key,
.sta_set_decap_offload = mt7925_sta_set_decap_offload,
#if IS_ENABLED(CONFIG_IPV6)
--
2.45.2
^ permalink raw reply related
* RE: [PATCH rtw-next] wifi: rtw88: Enable receiving control frames in monitor mode
From: Ping-Ke Shih @ 2026-06-24 0:53 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org; +Cc: Georg Bißeling
In-Reply-To: <3445ca1b-2d5a-43ae-9df1-d3f6440fae78@gmail.com>
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>
> >> Signed-off-by: Bitterblue Smith (S.E.A. Datentechnik GmbH) <rtl8821cerfe2@gmail.com>
> >
> > Once you migrate to your company mail, maybe you can add an entry to .mailmap,
> > which only affects the output of git-shortlog though.
> >
>
> Seeing the company name in parentheses with no explanation makes you
> think I'm part of the company, doesn't it?
I misunderstood the meaning.
> But I'm not, they just
> sponsored this patch:
>
> https://lore.kernel.org/all/20250203174626.1131225-1-kuba@kernel.org/
Thanks for the link.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox