Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/6] dt-bindings: net: bluetooth: Document Qualcomm IPQ5018 Bluetooth controller
From: Krzysztof Kozlowski @ 2026-06-30  7:40 UTC (permalink / raw)
  To: George Moussalem
  Cc: Jens Axboe, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Johannes Berg, Jeff Johnson, Bartosz Golaszewski,
	Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
	Rocky Liao, Saravana Kannan, Andrew Lunn, Heiner Kallweit,
	Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Bjorn Andersson, Konrad Dybcio,
	Mathieu Poirier, Philipp Zabel, linux-block, linux-kernel,
	linux-mmc, devicetree, linux-wireless, ath10k, linux-arm-msm,
	linux-bluetooth, netdev, linux-remoteproc
In-Reply-To: <SN7PR19MB67361ED99501853D6BD968E69DF72@SN7PR19MB6736.namprd19.prod.outlook.com>

On 30/06/2026 09:31, George Moussalem wrote:
> On 6/30/26 11:15, Krzysztof Kozlowski wrote:
>> On Mon, Jun 29, 2026 at 05:01:44PM +0400, George Moussalem wrote:
>>> +unevaluatedProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    #include <dt-bindings/clock/qcom,gcc-ipq5018.h>
>>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +    #include <dt-bindings/reset/qcom,gcc-ipq5018.h>
>>> +
>>> +    bluetooth {
>>
>> Don't send new versions while discussion is still going. I need to
>> repeat my question - what bus does that sit on?
>>
>> Device nodes represent real devices. Real devices sit on a bus, usually.
>> Do you have here a bus?
> 
> I'm afraid I don't have a definitive answer. Again, my understanding
> based on downstream code is that the 'controller' is basically a Cortex
> M0 processor running Bluetooth firmware connected to an RF. Data
> transport is over a shared memory carveout with APPS signaling the
> controller through writes to an IPC mailbox register, while the
> controller has an interrupt line back to signal APPS.

So this looks like should be squashed into remoteproc node. There is no
reason or no data to express it as two separate device nodes.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v2 1/6] dt-bindings: net: bluetooth: Document Qualcomm IPQ5018 Bluetooth controller
From: George Moussalem @ 2026-06-30  7:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Jens Axboe, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Johannes Berg, Jeff Johnson, Bartosz Golaszewski,
	Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
	Rocky Liao, Saravana Kannan, Andrew Lunn, Heiner Kallweit,
	Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Bjorn Andersson, Konrad Dybcio,
	Mathieu Poirier, Philipp Zabel, linux-block, linux-kernel,
	linux-mmc, devicetree, linux-wireless, ath10k, linux-arm-msm,
	linux-bluetooth, netdev, linux-remoteproc
In-Reply-To: <20260630-wondrous-lean-stoat-be0b9a@quoll>

On 6/30/26 11:15, Krzysztof Kozlowski wrote:
> On Mon, Jun 29, 2026 at 05:01:44PM +0400, George Moussalem wrote:
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/qcom,gcc-ipq5018.h>
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/reset/qcom,gcc-ipq5018.h>
>> +
>> +    bluetooth {
> 
> Don't send new versions while discussion is still going. I need to
> repeat my question - what bus does that sit on?
> 
> Device nodes represent real devices. Real devices sit on a bus, usually.
> Do you have here a bus?

I'm afraid I don't have a definitive answer. Again, my understanding
based on downstream code is that the 'controller' is basically a Cortex
M0 processor running Bluetooth firmware connected to an RF. Data
transport is over a shared memory carveout with APPS signaling the
controller through writes to an IPC mailbox register, while the
controller has an interrupt line back to signal APPS.

> 
>> +      compatible = "qcom,ipq5018-bt";
> 
> Best regards,
> Krzysztof
> 

Best regards,
George

^ permalink raw reply

* [PATCH] wifi: rtw89: fix HE extended capability length check
From: Pengpeng Hou @ 2026-06-30  7:28 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, Pengpeng Hou

rtw89_mac_check_he_obss_narrow_bw_ru_iter() reads extended capability
byte 10, but rejects only datalen values below 10.  Byte 10 requires at
least 11 bytes.

Require datalen >= 11 before reading data[10].

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/net/wireless/realtek/rtw89/mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 8c39551..99de1b2 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -5167,7 +5167,7 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
 	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
 				  ies->len);
 
-	if (!elem || elem->datalen < 10 ||
+	if (!elem || elem->datalen < 11 ||
 	    !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
 		*tolerated = false;
 	rcu_read_unlock();


^ permalink raw reply related

* [PATCH] wifi: iwlwifi: fix HE extended capability length checks
From: Pengpeng Hou @ 2026-06-30  7:28 UTC (permalink / raw)
  To: Miri Korenblit; +Cc: linux-wireless, linux-kernel, Pengpeng Hou

The MLD and MVM OBSS narrow bandwidth RU iterators read extended
capability byte 10, but the length check only rejects datalen values
below 10.  Byte 10 requires at least 11 bytes.

Fix both checks to require datalen >= 11 before reading data[10].

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 17286b3..9ac17be 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1708,7 +1708,7 @@ static void iwl_mld_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
 	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
 				  ies->len);
 
-	if (!elem || elem->datalen < 10 ||
+	if (!elem || elem->datalen < 11 ||
 	    !(elem->data[10] &
 	      WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
 		*tolerated = false;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 74bd403..48cc10d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3490,7 +3490,7 @@ static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
 	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
 				  ies->len);
 
-	if (!elem || elem->datalen < 10 ||
+	if (!elem || elem->datalen < 11 ||
 	    !(elem->data[10] &
 	      WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
 		data->tolerated = false;


^ permalink raw reply related

* Re: [PATCH 1/2] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode
From: Johannes Berg @ 2026-06-30  7:25 UTC (permalink / raw)
  To: Jose Ignacio Tornos Martinez
  Cc: emmanuel.grumbach, linux-kernel, linux-wireless,
	miriam.rachel.korenblit
In-Reply-To: <20260630072046.201393-1-jtornosm@redhat.com>

On Tue, 2026-06-30 at 09:20 +0200, Jose Ignacio Tornos Martinez wrote:
> Hi Johannes,
> 
> > There's probably something to be said for the second patch anyway.
> Good to know, should I resend patch 2/2 separately, or would you like me
> to wait until I have the customer use case information?

I think we can just take it as-is.

johannes

^ permalink raw reply

* [PATCH] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length
From: Pengpeng Hou @ 2026-06-30  7:22 UTC (permalink / raw)
  To: Miri Korenblit
  Cc: open list:INTEL WIRELESS WIFI LINK iwlwifi, open list,
	Pengpeng Hou

iwl_uefi_reduce_power_parse() reads three SKU words from
IWL_UCODE_TLV_PNVM_SKU TLVs after only checking the generic TLV length.

Add the same type-specific minimum payload length check before reading
the SKU words.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
index 2ef0a7a..747df65 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -248,6 +248,12 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
 			IWL_DEBUG_FW(trans,
 				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
 				     tlv_len);
+			if (tlv_len < 3 * sizeof(__le32)) {
+				IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
+					tlv_len);
+				return -EINVAL;
+			}
+
 			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
 				     le32_to_cpu(tlv_sku_id->data[0]),
 				     le32_to_cpu(tlv_sku_id->data[1]),


^ permalink raw reply related

* [PATCH] wifi: iwlwifi: validate PNVM SKU TLV length
From: Pengpeng Hou @ 2026-06-30  7:21 UTC (permalink / raw)
  To: Miri Korenblit
  Cc: open list:INTEL WIRELESS WIFI LINK iwlwifi, open list,
	Pengpeng Hou

iwl_pnvm_parse() reads three SKU words from IWL_UCODE_TLV_PNVM_SKU TLVs
after only checking the generic TLV length.

Add a type-specific minimum payload length check before reading the SKU
words.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index afff8d5..f61e69b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -198,6 +198,12 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
 			IWL_DEBUG_FW(trans,
 				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
 				     tlv_len);
+			if (tlv_len < 3 * sizeof(__le32)) {
+				IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
+					tlv_len);
+				return -EINVAL;
+			}
+
 			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
 				     le32_to_cpu(tlv_sku_id->data[0]),
 				     le32_to_cpu(tlv_sku_id->data[1]),


^ permalink raw reply related

* Re: [PATCH 1/2] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode
From: Jose Ignacio Tornos Martinez @ 2026-06-30  7:20 UTC (permalink / raw)
  To: johannes
  Cc: emmanuel.grumbach, jtornosm, linux-kernel, linux-wireless,
	miriam.rachel.korenblit
In-Reply-To: <588f665e6c1e8a24d6cee56762ae754f39ab9703.camel@sipsolutions.net>

Hi Johannes,

> There's probably something to be said for the second patch anyway.
Good to know, should I resend patch 2/2 separately, or would you like me
to wait until I have the customer use case information?

> Also, maybe we'd actually be interested in who's using this and why,
> it's the first I hear of this outside of _very_ niche applications :)
I'm collecting that information from our support team now and I'll share
what I can once I have it.

Thanks

Best regards
José Ignacio


^ permalink raw reply

* Re: [PATCH v2 1/6] dt-bindings: net: bluetooth: Document Qualcomm IPQ5018 Bluetooth controller
From: Krzysztof Kozlowski @ 2026-06-30  7:15 UTC (permalink / raw)
  To: George Moussalem
  Cc: Jens Axboe, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Johannes Berg, Jeff Johnson, Bartosz Golaszewski,
	Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
	Rocky Liao, Saravana Kannan, Andrew Lunn, Heiner Kallweit,
	Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Bjorn Andersson, Konrad Dybcio,
	Mathieu Poirier, Philipp Zabel, linux-block, linux-kernel,
	linux-mmc, devicetree, linux-wireless, ath10k, linux-arm-msm,
	linux-bluetooth, netdev, linux-remoteproc
In-Reply-To: <20260629-ipq5018-bluetooth-v2-1-02770f03b6bb@outlook.com>

On Mon, Jun 29, 2026 at 05:01:44PM +0400, George Moussalem wrote:
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,gcc-ipq5018.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/reset/qcom,gcc-ipq5018.h>
> +
> +    bluetooth {

Don't send new versions while discussion is still going. I need to
repeat my question - what bus does that sit on?

Device nodes represent real devices. Real devices sit on a bus, usually.
Do you have here a bus?

> +      compatible = "qcom,ipq5018-bt";

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH v12] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-30  6:58 UTC (permalink / raw)
  To: bhelgaas, alex, mani
  Cc: jjohnson, linux-pci, linux-wireless, ath11k, ath12k, mhi,
	linux-kernel, Jose Ignacio Tornos Martinez

Some Qualcomm PCIe devices (WCN6855/WCN7850 WLAN 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) WLAN 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 WLAN 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 WLAN 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>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
---
v12: Address Manivannan Sadhasivam feedback:
  - Use WLAN instead of WiFi (Qualcomm's preferred terminology)
  - Fix link recovery check: use !PCI_POSSIBLE_ERROR(val) instead of
    val != PCI_ERROR_RESPONSE (fixes type promotion bug)
v11: https://lore.kernel.org/all/20260626055023.197470-1-jtornosm@redhat.com/

 drivers/pci/quirks.c | 117 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 431c021d7414..0de606366200 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4240,6 +4240,120 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
 	return 0;
 }
 
+#define QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET	0x3008
+#define QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V	BIT(0)
+#define QUALCOMM_WLAN_MHICTRL			0x38
+#define QUALCOMM_WLAN_MHICTRL_RESET_MASK	0x2
+
+/*
+ * Qualcomm WLAN device-specific reset using SoC global reset via BAR0
+ * registers.
+ */
+static int reset_qualcomm_wlan(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_WLAN_PCIE_SOC_GLOBAL_RESET);
+	val |= QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V;
+	iowrite32(val, bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET);
+	ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET);
+
+	msleep(10);
+
+	val &= ~QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V;
+	iowrite32(val, bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET);
+	ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET);
+
+	msleep(10);
+
+	timeout = jiffies + msecs_to_jiffies(5000);
+	while (time_before(jiffies, timeout)) {
+		val = ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET);
+		if (!PCI_POSSIBLE_ERROR(val)) {
+			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_WLAN_MHICTRL_RESET_MASK, bar + QUALCOMM_WLAN_MHICTRL);
+	ioread32(bar + QUALCOMM_WLAN_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 +4369,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, 0x0308, reset_qualcomm_modem }, /* SDX62/SDX65 modems */
+	{ PCI_VENDOR_ID_QCOM, 0x1103, reset_qualcomm_wlan },  /* WCN6855 WLAN */
+	{ PCI_VENDOR_ID_QCOM, 0x1107, reset_qualcomm_wlan },  /* WCN7850 WLAN */
 	{ 0 }
 };
 
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH 1/2] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode
From: Johannes Berg @ 2026-06-30  6:54 UTC (permalink / raw)
  To: Jose Ignacio Tornos Martinez
  Cc: emmanuel.grumbach, linux-kernel, linux-wireless,
	miriam.rachel.korenblit
In-Reply-To: <20260630065054.199048-1-jtornosm@redhat.com>

Hi,

> Now that I understand why MFP cannot work securely in FIPS mode on Intel
> hardware, I'll drop the patches.

There's probably something to be said for the second patch anyway.

Also, maybe we'd actually be interested in who's using this and why,
it's the first I hear of this outside of _very_ niche applications :)

johannes

^ permalink raw reply

* Re: [PATCH 1/2] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode
From: Jose Ignacio Tornos Martinez @ 2026-06-30  6:50 UTC (permalink / raw)
  To: johannes
  Cc: emmanuel.grumbach, jtornosm, linux-kernel, linux-wireless,
	miriam.rachel.korenblit
In-Reply-To: <11d449ef4691092dc669cdffb1bff72d2684b739.camel@sipsolutions.net>

Hi Johannes,
  
Thank you for the detailed explanation about the firmware-handled robust
action frames (CSA, Block-Ack, etc.).

Now that I understand why MFP cannot work securely in FIPS mode on Intel
hardware, I'll drop the patches.

Thanks for your time

Best regards
José Ignacio


^ permalink raw reply

* Re: [PATCH v11] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-30  6:29 UTC (permalink / raw)
  To: mani
  Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, jtornosm, linux-kernel,
	linux-pci, linux-wireless, mhi
In-Reply-To: <5mrwcurlf6xnqla5x5idpt7ug34nv2eqpijnjmccgdwazrmwyv@64tixxe4aa57>

Hi Mani,

No worries! v12 with the fix and WLAN renaming is on the way.
Thanks for catching it and your help

Best regards
Jose Ignacio


^ permalink raw reply

* [PATCH ath-next v2 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
From: Aaradhana Sahu @ 2026-06-30  6:20 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu, Rameshkumar Sundaram,
	Baochen Qiang
In-Reply-To: <20260630062048.1615178-1-aaradhana.sahu@oss.qualcomm.com>

Currently, the Q6 region contains a read-only firmware region along with
the BDF_MEM_REGION_TYPE and HOST_DDR_REGION_TYPE memory areas. The firmware
expects these writable memory regions to be assigned after the Q6 read-only
section.

However, the ath12k driver currently allocates the HOST_DDR_REGION_TYPE
starting from the base of the Q6 region, which includes the read-only
firmware area. As a result, the allocated memory regions overlap with the
read-only section, causing the firmware to assert during QMI memory
allocation. The Q6 memory region layout is as follows:

		Q6 Reserved Memory
	+--------------------------------------+
	|                                      |
	|  Read-only Firmware Region           |
	|  (Q6 RO Region)                      |
	|                                      |
	+--------------------------------------+ <--- bdf_addr_offset
	|  Writable Memory Region              |
	|  (BDF + HOST_DDR allocations)        |
	|                                      |
	+--------------------------------------+

Fix this by allocating the required memory regions only after the end of
the read-only region in the Q6 address space. The bdf_addr_offset parameter
indicates where the writable region starts. Both HOST_DDR and BDF regions
are allocated sequentially after this offset, with each region placed
immediately after the previous one to avoid gaps and overlaps.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Fixes: 6757079c5890 ("wifi: ath12k: add support for fixed QMI firmware memory")
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/qmi.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 5bf045971c94..6d5063229221 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -2746,8 +2746,8 @@ static const char *ath12k_qmi_get_mem_reg_name(int mem_type)
 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 {
 	struct device_node *np = ab->dev->of_node;
+	size_t avail_rmem_size, offset = 0;
 	struct target_mem_chunk *chunk;
-	size_t avail_rmem_size;
 	struct resource res;
 	const char *rname;
 	int i, idx, ret;
@@ -2781,9 +2781,20 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 			goto out;
 
 		avail_rmem_size = resource_size(&res);
-		if (chunk->type == BDF_MEM_REGION_TYPE) {
-			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
-			res.start += ab->hw_params->bdf_addr_offset;
+		if (chunk->type == BDF_MEM_REGION_TYPE ||
+		    chunk->type == HOST_DDR_REGION_TYPE) {
+			if (ab->hw_params->bdf_addr_offset > avail_rmem_size ||
+			    offset > avail_rmem_size - ab->hw_params->bdf_addr_offset) {
+				ath12k_err(ab, "qmi mem offset overflow: bdf_offset=%u offset=%zu size=%zu\n",
+					   ab->hw_params->bdf_addr_offset, offset,
+					   avail_rmem_size);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			avail_rmem_size -= ab->hw_params->bdf_addr_offset + offset;
+			res.start += ab->hw_params->bdf_addr_offset + offset;
+			offset += chunk->size;
 		}
 
 		if (avail_rmem_size < chunk->size) {
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v2 2/3] wifi: ath12k: refactor QMI memory assignment
From: Aaradhana Sahu @ 2026-06-30  6:20 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu, Rameshkumar Sundaram,
	Baochen Qiang
In-Reply-To: <20260630062048.1615178-1-aaradhana.sahu@oss.qualcomm.com>

ath12k_qmi_assign_target_mem_chunk() uses a large switch-case to handle
both memory region identification and allocation for each memory request
type, leading to redundant allocation logic.

Refactor this by introducing ath12k_qmi_get_mem_reg_name() to map memory
request types to their corresponding reserved memory region names.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/qmi.c | 157 ++++++++++----------------
 1 file changed, 61 insertions(+), 96 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 0176d6a4bf8c..5bf045971c94 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -2726,120 +2726,85 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
 	return ret;
 }
 
+static const char *ath12k_qmi_get_mem_reg_name(int mem_type)
+{
+	switch (mem_type) {
+	case HOST_DDR_REGION_TYPE:
+	case BDF_MEM_REGION_TYPE:
+		return "q6-region";
+	case M3_DUMP_REGION_TYPE:
+		return "m3-dump";
+	case CALDB_MEM_REGION_TYPE:
+		return "q6-caldb";
+	case MLO_GLOBAL_MEM_REGION_TYPE:
+		return "mlo-global-mem";
+	default:
+		return NULL;
+	}
+}
+
 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 {
 	struct device_node *np = ab->dev->of_node;
+	struct target_mem_chunk *chunk;
 	size_t avail_rmem_size;
 	struct resource res;
+	const char *rname;
 	int i, idx, ret;
 
 	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
-		switch (ab->qmi.target_mem[i].type) {
-		case HOST_DDR_REGION_TYPE:
-			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
-									&res);
-			if (ret)
-				goto out;
-
-			avail_rmem_size = resource_size(&res);
-			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
-				ath12k_dbg(ab, ATH12K_DBG_QMI,
-					   "failed to assign mem type %u req size %u avail size %zu\n",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
-
-			ab->qmi.target_mem[idx].paddr = res.start;
-			ab->qmi.target_mem[idx].v.ioaddr =
-				ioremap(ab->qmi.target_mem[idx].paddr,
-					ab->qmi.target_mem[i].size);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		case BDF_MEM_REGION_TYPE:
-			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
-									&res);
-			if (ret)
-				goto out;
-
-			avail_rmem_size = resource_size(&res) -
-					  ab->hw_params->bdf_addr_offset;
-			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
-				ath12k_dbg(ab, ATH12K_DBG_QMI,
-					   "failed to assign mem type %u req size %u avail size %zu\n",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].paddr =
-				res.start + ab->hw_params->bdf_addr_offset;
-			ab->qmi.target_mem[idx].v.ioaddr =
-				ioremap(ab->qmi.target_mem[idx].paddr,
-					ab->qmi.target_mem[i].size);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		case CALDB_MEM_REGION_TYPE:
-			/* Cold boot calibration is not enabled in Ath12k. Hence,
+		chunk = &ab->qmi.target_mem[i];
+		if (chunk->type == CALDB_MEM_REGION_TYPE) {
+			/*
+			 * Cold boot calibration is not enabled in Ath12k. Hence,
 			 * assign paddr = 0.
 			 * Once cold boot calibration is enabled add support to
 			 * assign reserved memory from DT.
 			 */
 			ab->qmi.target_mem[idx].paddr = 0;
 			ab->qmi.target_mem[idx].v.ioaddr = NULL;
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
+			ab->qmi.target_mem[idx].size = chunk->size;
+			ab->qmi.target_mem[idx].type = chunk->type;
 			idx++;
-			break;
-		case M3_DUMP_REGION_TYPE:
-			ret = of_reserved_mem_region_to_resource_byname(np, "m3-dump",
-									&res);
-			if (ret)
-				goto out;
-
-			avail_rmem_size = resource_size(&res);
-			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
-				ath12k_dbg(ab, ATH12K_DBG_QMI,
-					   "failed to assign mem type %u req size %u avail size %zu\n",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
+			continue;
+		}
 
-			ab->qmi.target_mem[idx].paddr = res.start;
-			ab->qmi.target_mem[idx].v.ioaddr =
-				ioremap(ab->qmi.target_mem[idx].paddr,
-					ab->qmi.target_mem[i].size);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		default:
+		rname = ath12k_qmi_get_mem_reg_name(chunk->type);
+		if (!rname) {
 			ath12k_warn(ab, "qmi ignore invalid mem req type %u\n",
-				    ab->qmi.target_mem[i].type);
-			break;
+				    chunk->type);
+			continue;
+		}
+
+		ret = of_reserved_mem_region_to_resource_byname(np, rname, &res);
+		if (ret)
+			goto out;
+
+		avail_rmem_size = resource_size(&res);
+		if (chunk->type == BDF_MEM_REGION_TYPE) {
+			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
+			res.start += ab->hw_params->bdf_addr_offset;
 		}
+
+		if (avail_rmem_size < chunk->size) {
+			ath12k_dbg(ab, ATH12K_DBG_QMI,
+				   "failed to assign mem type %u req size %u avail size %zu\n",
+				   chunk->type, chunk->size, avail_rmem_size);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ab->qmi.target_mem[idx].paddr = res.start;
+		ab->qmi.target_mem[idx].v.ioaddr = ioremap(ab->qmi.target_mem[idx].paddr,
+							   chunk->size);
+		if (!ab->qmi.target_mem[idx].v.ioaddr) {
+			ret = -EIO;
+			goto out;
+		}
+
+		ab->qmi.target_mem[idx].size = chunk->size;
+		ab->qmi.target_mem[idx].type = chunk->type;
+		idx++;
 	}
 	ab->qmi.mem_seg_count = idx;
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v2 1/3] wifi: ath12k: switch to name-based reserved memory lookup
From: Aaradhana Sahu @ 2026-06-30  6:20 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu, Rameshkumar Sundaram,
	Baochen Qiang
In-Reply-To: <20260630062048.1615178-1-aaradhana.sahu@oss.qualcomm.com>

The driver currently retrieves reserved memory regions using index-based
lookup, which depends on the ordering of reserved-memory nodes in the
device tree. Since different platforms define these regions in varying
orders and combinations, this approach is not compatible and can result
in incorrect memory region access.

Switch to looking up memory regions by name instead of index so it does
not depend on node order.

Use names already defined in qcom,ipq5332-wifi.yaml, so there are no
backward compatibility issues.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/ahb.c  | 18 ++++++------
 drivers/net/wireless/ath/ath12k/core.c | 25 -----------------
 drivers/net/wireless/ath/ath12k/core.h |  2 --
 drivers/net/wireless/ath/ath12k/qmi.c  | 38 +++++++++++++-------------
 4 files changed, 29 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 30733a244454..6df3b775a214 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -12,6 +12,7 @@
 #include <linux/remoteproc.h>
 #include <linux/soc/qcom/mdt_loader.h>
 #include <linux/soc/qcom/smem_state.h>
+#include <linux/of_reserved_mem.h>
 #include "ahb.h"
 #include "debug.h"
 #include "hif.h"
@@ -338,24 +339,25 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
 	char fw2_name[ATH12K_USERPD_FW_NAME_LEN];
 	struct device *dev = ab->dev;
 	const struct firmware *fw, *fw2;
-	struct reserved_mem *rmem = NULL;
 	unsigned long time_left;
 	phys_addr_t mem_phys;
+	struct resource res;
 	void *mem_region;
 	size_t mem_size;
 	u32 pasid;
 	int ret;
 
-	rmem = ath12k_core_get_reserved_mem(ab, 0);
-	if (!rmem)
-		return -ENODEV;
+	ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region",
+							&res);
+	if (ret)
+		return ret;
 
-	mem_phys = rmem->base;
-	mem_size = rmem->size;
+	mem_phys = res.start;
+	mem_size = resource_size(&res);
 	mem_region = devm_memremap(dev, mem_phys, mem_size, MEMREMAP_WC);
 	if (IS_ERR(mem_region)) {
-		ath12k_err(ab, "unable to map memory region: %pa+%pa\n",
-			   &rmem->base, &rmem->size);
+		ath12k_err(ab, "unable to map memory region: %pa+%zx\n",
+			   &res.start, mem_size);
 		return PTR_ERR(mem_region);
 	}
 
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 742d4fd1b598..617d039b9237 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -637,31 +637,6 @@ u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab)
 }
 EXPORT_SYMBOL(ath12k_core_get_max_peers_per_radio);
 
-struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab,
-						  int index)
-{
-	struct device *dev = ab->dev;
-	struct reserved_mem *rmem;
-	struct device_node *node;
-
-	node = of_parse_phandle(dev->of_node, "memory-region", index);
-	if (!node) {
-		ath12k_dbg(ab, ATH12K_DBG_BOOT,
-			   "failed to parse memory-region for index %d\n", index);
-		return NULL;
-	}
-
-	rmem = of_reserved_mem_lookup(node);
-	of_node_put(node);
-	if (!rmem) {
-		ath12k_dbg(ab, ATH12K_DBG_BOOT,
-			   "unable to get memory-region for index %d\n", index);
-		return NULL;
-	}
-
-	return rmem;
-}
-
 static inline
 void ath12k_core_to_group_ref_get(struct ath12k_base *ab)
 {
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index fc5127b5c1a3..ba2f617d8e5f 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1294,8 +1294,6 @@ void ath12k_fw_stats_init(struct ath12k *ar);
 void ath12k_fw_stats_bcn_free(struct list_head *head);
 void ath12k_fw_stats_free(struct ath12k_fw_stats *stats);
 void ath12k_fw_stats_reset(struct ath12k *ar);
-struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab,
-						  int index);
 enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab);
 
 static inline const char *ath12k_scan_state_str(enum ath12k_scan_state state)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..0176d6a4bf8c 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -13,6 +13,7 @@
 #include <linux/firmware.h>
 #include <linux/of_address.h>
 #include <linux/ioport.h>
+#include <linux/of_reserved_mem.h>
 
 #define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x02
 #define HOST_CSTATE_BIT			0x04
@@ -2727,20 +2728,20 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
 
 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 {
-	struct reserved_mem *rmem;
+	struct device_node *np = ab->dev->of_node;
 	size_t avail_rmem_size;
+	struct resource res;
 	int i, idx, ret;
 
 	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
 		switch (ab->qmi.target_mem[i].type) {
 		case HOST_DDR_REGION_TYPE:
-			rmem = ath12k_core_get_reserved_mem(ab, 0);
-			if (!rmem) {
-				ret = -ENODEV;
+			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
+									&res);
+			if (ret)
 				goto out;
-			}
 
-			avail_rmem_size = rmem->size;
+			avail_rmem_size = resource_size(&res);
 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
 				ath12k_dbg(ab, ATH12K_DBG_QMI,
 					   "failed to assign mem type %u req size %u avail size %zu\n",
@@ -2751,7 +2752,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 				goto out;
 			}
 
-			ab->qmi.target_mem[idx].paddr = rmem->base;
+			ab->qmi.target_mem[idx].paddr = res.start;
 			ab->qmi.target_mem[idx].v.ioaddr =
 				ioremap(ab->qmi.target_mem[idx].paddr,
 					ab->qmi.target_mem[i].size);
@@ -2764,13 +2765,13 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 			idx++;
 			break;
 		case BDF_MEM_REGION_TYPE:
-			rmem = ath12k_core_get_reserved_mem(ab, 0);
-			if (!rmem) {
-				ret = -ENODEV;
+			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
+									&res);
+			if (ret)
 				goto out;
-			}
 
-			avail_rmem_size = rmem->size - ab->hw_params->bdf_addr_offset;
+			avail_rmem_size = resource_size(&res) -
+					  ab->hw_params->bdf_addr_offset;
 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
 				ath12k_dbg(ab, ATH12K_DBG_QMI,
 					   "failed to assign mem type %u req size %u avail size %zu\n",
@@ -2781,7 +2782,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 				goto out;
 			}
 			ab->qmi.target_mem[idx].paddr =
-				rmem->base + ab->hw_params->bdf_addr_offset;
+				res.start + ab->hw_params->bdf_addr_offset;
 			ab->qmi.target_mem[idx].v.ioaddr =
 				ioremap(ab->qmi.target_mem[idx].paddr,
 					ab->qmi.target_mem[i].size);
@@ -2806,13 +2807,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 			idx++;
 			break;
 		case M3_DUMP_REGION_TYPE:
-			rmem = ath12k_core_get_reserved_mem(ab, 1);
-			if (!rmem) {
-				ret = -EINVAL;
+			ret = of_reserved_mem_region_to_resource_byname(np, "m3-dump",
+									&res);
+			if (ret)
 				goto out;
-			}
 
-			avail_rmem_size = rmem->size;
+			avail_rmem_size = resource_size(&res);
 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
 				ath12k_dbg(ab, ATH12K_DBG_QMI,
 					   "failed to assign mem type %u req size %u avail size %zu\n",
@@ -2823,7 +2823,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 				goto out;
 			}
 
-			ab->qmi.target_mem[idx].paddr = rmem->base;
+			ab->qmi.target_mem[idx].paddr = res.start;
 			ab->qmi.target_mem[idx].v.ioaddr =
 				ioremap(ab->qmi.target_mem[idx].paddr,
 					ab->qmi.target_mem[i].size);
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v2 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling
From: Aaradhana Sahu @ 2026-06-30  6:20 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

The current implementation relies on index-based device tree reserved
memory lookup. Different platform variants define reserved memory
regions in different orders and combinations, making the index-based
lookup fragile across platforms.

Currently, the driver allocates the HOST_DDR_REGION_TYPE
starting from the base of the Q6 region, which overlaps the Q6 read-only
firmware section. This causes firmware assertions during QMI memory
allocation, as the firmware expects writable regions to be placed after the
read-only section.

Address these issues by:
- switching to name-based reserved memory lookup to remove dependency on
  device tree node ordering,
- refactoring QMI memory assignment logic to reduce code duplication and
  improve maintainability,
- placing HOST_DDR and BDF regions after the Q6 read-only firmware section
  using the bdf_addr_offset parameter.

This series ensure correct reserved memory handling across different
platform variants, prevent overlapping memory allocations, and maintain
backward compatibility by reusing existing reserved memory region names
defined in device tree bindings.

Overview:
  - Patch [1/3] switches to name-based reserved memory lookup for platform
    compatibility.
  - Patch [2/3] refactors QMI memory assignment to eliminate code
    duplication.
  - Patch [3/3] fixes memory allocation to place HOST_DDR and BDF regions
    after Q6 read-only section.

---
v2:
  -Added bounds check for reserved memory offsets in patch[3/3].
  -Moved system includes before local includes in patch[1/3].
---

Aaradhana Sahu (3):
  wifi: ath12k: switch to name-based reserved memory lookup
  wifi: ath12k: refactor QMI memory assignment
  wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region

 drivers/net/wireless/ath/ath12k/ahb.c  |  18 +--
 drivers/net/wireless/ath/ath12k/core.c |  25 ----
 drivers/net/wireless/ath/ath12k/core.h |   2 -
 drivers/net/wireless/ath/ath12k/qmi.c  | 169 +++++++++++--------------
 4 files changed, 82 insertions(+), 132 deletions(-)


base-commit: 1547a99cd8d8c1ab3e04dbd92b72b3b5f7cb85a9
-- 
2.34.1


^ permalink raw reply

* Re: [PATCH 4/6] dt-bindings: net: bluetooth: Document Qualcomm IPQ5018 Bluetooth controller
From: Krzysztof Kozlowski @ 2026-06-30  6:18 UTC (permalink / raw)
  To: Konrad Dybcio, George Moussalem
  Cc: Jens Axboe, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Johannes Berg, Jeff Johnson, Bartosz Golaszewski,
	Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
	Rocky Liao, Saravana Kannan, Andrew Lunn, Heiner Kallweit,
	Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Bjorn Andersson, Konrad Dybcio,
	Mathieu Poirier, Philipp Zabel, linux-block, linux-kernel,
	linux-mmc, devicetree, linux-wireless, ath10k, linux-arm-msm,
	linux-bluetooth, netdev, linux-remoteproc
In-Reply-To: <0e0fb3af-968f-46d2-be6c-18b76c7d2a1a@oss.qualcomm.com>

On 26/06/2026 13:30, Konrad Dybcio wrote:
> On 6/26/26 1:20 PM, George Moussalem wrote:
>> On 6/26/26 14:53, Krzysztof Kozlowski wrote:
>>> On Thu, Jun 25, 2026 at 06:10:08PM +0400, George Moussalem wrote:
>>>> Document the Qualcomm IPQ5018 Bluetooth controller.
>>>>
>>>> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
>>>> ---
> 
> [...]
> 
>>>> +      compatible = "qcom,ipq5018-bt";
>>>> +
>>>> +      qcom,ipc = <&apcs_glb 8 23>;
>>>> +      interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
>>>
>>> No firmware to load?
>>
>> firmware is loaded by the remoteproc in patch 1
>>
>>>
>>> It feels like remoteproc node split is fake. The property qcom,rproc is
>>> even more supporting that case. Shouldn't this be simply one device -
>>> bluetooth? What sort of two devices do you have exactly? How can I
>>> identify them in the hardware?
>>
>> I wasn't sure how to represent the HW. Should I make this bluetooth node
>> a childnode of the rproc? Essentially, this is the transport layer
>> (using shared memory space and IPC/interrupt).
>>
>> Most QCA BT controllers are also childnodes of a serdev/uart node as
>> they use serdev for transport.
>>
>> From what I understand, it's simply BT firmware running on this
>> dedicated M0 core in the SoC itself connected to an RF.
> 
> Seems like this rhymes with the WPSS remoteproc +ATH1xK_AHB situation
> - the Q6 core power sequences and manages the wireless controller,
> while Linux gets to drive the device as it would if it were connected
> over PCIe/ UART respectively, just with MMIO writes instead.

But the ATH (except the MMIO for remoteproc bringup) are physically
connected over other bus, like PCIe and UART.

What is here?

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup
From: Aaradhana Sahu @ 2026-06-30  5:42 UTC (permalink / raw)
  To: Jeff Johnson, ath12k; +Cc: linux-wireless
In-Reply-To: <7fd9e186-fce6-4c81-8aa5-f0de961fdefe@oss.qualcomm.com>



On 6/30/2026 6:00 AM, Jeff Johnson wrote:
> On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
>> The driver currently retrieves reserved memory regions using index-based
>> lookup, which depends on the ordering of reserved-memory nodes in the
>> device tree. Since different platforms define these regions in varying
>> orders and combinations, this approach is not compatible and can result
>> in incorrect memory region access.
>>
>> Switch to looking up memory regions by name instead of index so it does
>> not depend on node order.
>>
>> Use names already defined in qcom,ipq5332-wifi.yaml, so there are no
>> backward compatibility issues.
>>
>> Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
>> ---
>>  drivers/net/wireless/ath/ath12k/ahb.c  | 18 ++++++------
>>  drivers/net/wireless/ath/ath12k/core.c | 25 -----------------
>>  drivers/net/wireless/ath/ath12k/core.h |  2 --
>>  drivers/net/wireless/ath/ath12k/qmi.c  | 38 +++++++++++++-------------
>>  4 files changed, 29 insertions(+), 54 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
>> index 30733a244454..695b605a92fd 100644
>> --- a/drivers/net/wireless/ath/ath12k/ahb.c
>> +++ b/drivers/net/wireless/ath/ath12k/ahb.c
>> @@ -15,6 +15,7 @@
>>  #include "ahb.h"
>>  #include "debug.h"
>>  #include "hif.h"
>> +#include <linux/of_reserved_mem.h>
> 
> system includes should come before the local includes. I'd fix this in my tree
> except there is another issue in the 3/3 patch so I'll want a v2 for the
> entire series.
> 

Sure, I will fix this and the 3/3 patch review comments and send the next version
of the series. 

^ permalink raw reply

* Re: [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
From: Aaradhana Sahu @ 2026-06-30  5:30 UTC (permalink / raw)
  To: Jeff Johnson, ath12k; +Cc: linux-wireless
In-Reply-To: <2d776c69-51d0-429f-b716-b5302d657047@oss.qualcomm.com>



On 6/30/2026 6:06 AM, Jeff Johnson wrote:
> On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
>> @@ -2781,9 +2781,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
>>  			goto out;
>>  
>>  		avail_rmem_size = resource_size(&res);
>> -		if (chunk->type == BDF_MEM_REGION_TYPE) {
>> +		if (chunk->type == BDF_MEM_REGION_TYPE ||
>> +		    chunk->type == HOST_DDR_REGION_TYPE) {
>>  			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
>> -			res.start += ab->hw_params->bdf_addr_offset;
>> +			avail_rmem_size -= offset;
>> +			res.start += ab->hw_params->bdf_addr_offset + offset;
>> +			offset += chunk->size;
> 
> avail_rmem_size is size_t (unsigned).
> If bdf_addr_offset + offset >= resource_size(&res) (e.g., DT
> misconfiguration), the subtraction silently wraps to a huge value, the
> avail_rmem_size < chunk->size guard passes incorrectly, and ioremap proceeds
> out-of-bounds.
> 
> So seems there should be a test to sanitize the DT values.
> 

Sure, I will address this in the next version.

>>  		}
>>  
>>  		if (avail_rmem_size < chunk->size) {
> 


^ permalink raw reply

* Re: [PATCH 2/2] wifi: ath12k: skip unknown direct buffer ring module IDs
From: Nazar Mokrynskyi @ 2026-06-30  3:52 UTC (permalink / raw)
  To: Jeff Johnson, ath12k; +Cc: linux-wireless
In-Reply-To: <07a1e340-cfdf-4027-861e-8f2a940bd21c@mokrynskyi.com>

Anything else I can do to help upstream some version of these patches?
I've been running them for another 1.5 months with no issues.

Sincerely, Nazar Mokrynskyi
github.com/nazar-pc

11.05.26 23:10, Nazar Mokrynskyi:
> 11.05.26 22:02, Jeff Johnson:
>> On 5/5/2026 10:24 AM, Nazar Mokrynskyi wrote:
>>> The firmware may advertise direct buffer ring capabilities for module
>>> IDs beyond what the driver currently knows about (WMI_DIRECT_BUF_MAX).
>>> This happens with newer firmware versions that support additional ring
>>> types not yet implemented in the driver.
>> What "newer firmware version" are you using that has this issue?
>>
>> Can you share the "Skipping unknown direct buf ring module id" logs from your
>> modified driver?
> ID is the same as in the original warning:
>
> [   10.611560] ath12k_pci 0000:01:00.0: Invalid module id 2
> [   10.616467] ath12k_pci 0000:01:00.0: failed to parse tlv -22
>
> The firmware according to system logs (all this info is provided in [PATCH 0/2] email):
>
> [    7.688137] ath12k_pci 0000:01:00.0: fw_version 0x160484db fw_build_timestamp 2025-12-09 20:09 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>
> This is running on OpenWRT 25.12, which uses 6.12.74 kernel with modules backported from 6.18.7 kernel:
> [    0.000000] Linux version 6.12.74 (builder@buildhost) (x86_64-openwrt-linux-musl-gcc (OpenWrt GCC 14.3.0 r32802-f505120278) 14.3.0, GNU ld (GNU Binutils) 2.44) #0 SMP Wed Mar 25 20:09:53 2026
> [    6.997293] Loading modules backported from Linux version v6.18.7-0-g5dfbc5357
> [    6.999210] Backport generated by backports.git c8a37ce
>
>>> The current code treats an unknown module_id as a fatal error, returning
>>> -EINVAL and tearing down the entire driver initialization. This is
>>> incorrect: the driver only needs to set up rings for types it uses
>>> (SPECTRAL=0, CFR=1) and can safely ignore capability advertisements for
>>> unknown types.
>>>
>>> Change the unknown module_id handling to skip the entry with a debug
>>> message rather than failing, allowing initialization to proceed.
>>>
>>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>>>
>>> Signed-off-by: Nazar Mokrynskyi <nazar@mokrynskyi.com>
>>> ---
>>>  drivers/net/wireless/ath/ath12k/wmi.c | 12 ++++--------
>>>  1 file changed, 4 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
>>> index 484fdd3b1..0e776a8d8 100644
>>> --- a/drivers/net/wireless/ath/ath12k/wmi.c
>>> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
>>> @@ -4814,10 +4814,10 @@ static int ath12k_wmi_dma_ring_caps(struct ath12k_base *ab,
>>>  	dir_buff_caps = ab->db_caps;
>>>  	for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) {
>>>  		if (le32_to_cpu(dma_caps[i].module_id) >= WMI_DIRECT_BUF_MAX) {
>>> -			ath12k_warn(ab, "Invalid module id %d\n",
>>> -				    le32_to_cpu(dma_caps[i].module_id));
>>> -			ret = -EINVAL;
>>> -			goto free_dir_buff;
>>> +			ath12k_dbg(ab, ATH12K_DBG_WMI,
>>> +				   "Skipping unknown direct buf ring module id %d\n",
>>> +				   le32_to_cpu(dma_caps[i].module_id));
>>> +			continue;
>> by continuing you don't populate the dir_buff_caps[i] information below,
>> leaving that record with zeroed data from the initial allocation. Does other
>> code correctly handle that?
>>
>> would it be better to have a separate count of the number of dir_buff_caps
>> records that are actually filled, and then update
>> dma_caps_parse->n_dma_ring_caps to match once the parsing has completed?
> I'm very far from kernel development, let alone ath12k driver specifically.
> The patch is provided to better showcase the problems I had.
> If there is a better way to address it, I'd really appreciate if someone more knowledgeable could take over, I just hope this is helpful.
>
> With these changes QCN9274 runs an access point with over 3 weeks uptime as of right now.
> That is not necessary the proof of anything, but it does seem to work in practice so far.
>>>  		}
>>>  
>>>  		dir_buff_caps[i].id = le32_to_cpu(dma_caps[i].module_id);
>>> @@ -4829,10 +4829,6 @@ static int ath12k_wmi_dma_ring_caps(struct ath12k_base *ab,
>>>  	}
>>>  
>>>  	return 0;
>>> -
>>> -free_dir_buff:
>>> -	ath12k_wmi_free_dbring_caps(ab);
>>> -	return ret;
>>>  }
>>>  
>>>  static void

^ permalink raw reply

* [PATCH] wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop
From: Fan Wu @ 2026-06-30  3:31 UTC (permalink / raw)
  To: Jes.Sorensen; +Cc: kvalo, linux-wireless, linux-kernel, stable, Fan Wu

rtl8xxxu arms rx_urb_wq from the RX completion path:
rtl8xxxu_rx_complete() hands the URB to rtl8xxxu_queue_rx_urb(), which
queues it on rx_urb_pending_list and, once the list grows past
RTL8XXXU_RX_URB_PENDING_WATER, schedules rx_urb_wq.  The worker
rtl8xxxu_rx_urb_work() drains rx_urb_pending_list, recovers priv through
container_of, and resubmits each URB through rtl8xxxu_submit_rx_urb(),
which anchors it on rx_anchor and dereferences priv->udev.

rtl8xxxu_stop() cancels the sibling work items (c2hcmd_work, ra_watchdog,
update_beacon_work) but never cancels rx_urb_wq, so a worker armed during
the last burst of RX traffic can run rtl8xxxu_rx_urb_work() after
rtl8xxxu_disconnect() has called ieee80211_free_hw(), which frees priv,
producing a use-after-free.  The window opens under active RX traffic
(pending count above the watermark) followed by a disconnect.

There are two teardown races to close:

  * rtl8xxxu_queue_rx_urb() decided whether to enqueue under rx_urb_lock
    but called schedule_work() after dropping the lock.  A completion
    that observed shutdown == false and released the lock could then call
    schedule_work() after rtl8xxxu_stop() had set shutdown and
    cancel_work_sync() had already returned, arming the worker to run
    after the teardown.  Move schedule_work() under the same !shutdown
    branch so the arming decision is atomic with the shutdown check.

  * rtl8xxxu_rx_urb_work() anchors every URB it drained back onto
    rx_anchor through rtl8xxxu_submit_rx_urb().  A worker still running
    when usb_kill_anchored_urbs(&priv->rx_anchor) returned would submit a
    URB that escaped the kill.  In rtl8xxxu_stop(), call
    cancel_work_sync(&priv->rx_urb_wq) before the kill so the worker is
    drained first.

After priv->shutdown is set under rx_urb_lock, completions can no longer
queue rx_urb_wq. cancel_work_sync() then drains the last queued or running
worker, and the following usb_kill_anchored_urbs() kills the URBs it may
have submitted.

rtl8xxxu_disconnect() is covered because ieee80211_unregister_hw()
guarantees .stop() runs for a live interface before ieee80211_free_hw()
frees priv.  The probe error path needs no cancel: rx_urb_wq is
INIT_WORK()'d there but cannot have been scheduled, since no URB is
submitted before ieee80211_register_hw() succeeds.

This bug was found by static analysis.

Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
Cc: stable@vger.kernel.org
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
---
 drivers/net/wireless/realtek/rtl8xxxu/core.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index c06ad064f37c..b447ce78ff05 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -5792,14 +5792,19 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
 {
 	struct sk_buff *skb;
 	unsigned long flags;
-	int pending = 0;
 
 	spin_lock_irqsave(&priv->rx_urb_lock, flags);
 
 	if (!priv->shutdown) {
 		list_add_tail(&rx_urb->list, &priv->rx_urb_pending_list);
 		priv->rx_urb_pending_count++;
-		pending = priv->rx_urb_pending_count;
+		/*
+		 * Arm the worker under rx_urb_lock so this is atomic with the
+		 * shutdown check: moving it out of the lock would let a
+		 * completion arm the work after rtl8xxxu_stop() canceled it.
+		 */
+		if (priv->rx_urb_pending_count > RTL8XXXU_RX_URB_PENDING_WATER)
+			schedule_work(&priv->rx_urb_wq);
 	} else {
 		skb = (struct sk_buff *)rx_urb->urb.context;
 		dev_kfree_skb_irq(skb);
@@ -5807,9 +5812,6 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
 	}
 
 	spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
-
-	if (pending > RTL8XXXU_RX_URB_PENDING_WATER)
-		schedule_work(&priv->rx_urb_wq);
 }
 
 static void rtl8xxxu_rx_urb_work(struct work_struct *work)
@@ -7461,6 +7463,13 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw, bool suspend)
 	priv->shutdown = true;
 	spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
 
+	/*
+	 * Cancel before killing rx_anchor: the worker re-anchors every URB
+	 * it drained via rtl8xxxu_submit_rx_urb(), so a worker still running
+	 * after the kill could submit a URB that escapes it.
+	 */
+	cancel_work_sync(&priv->rx_urb_wq);
+
 	usb_kill_anchored_urbs(&priv->rx_anchor);
 	usb_kill_anchored_urbs(&priv->tx_anchor);
 	if (priv->usb_interrupts)
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/2] dt-bindings: wireless: ath12k: drop qcom,ath12k-calibration-variant
From: Andrew LaMarche @ 2026-06-30  1:14 UTC (permalink / raw)
  To: Jeff Johnson
  Cc: linux-wireless, ath12k, linux-kernel, Andrew LaMarche,
	Ernest Van Hoecke
In-Reply-To: <20260630011413.1424654-1-andrewjlamarche@gmail.com>

The ath12k-wsi binding documentation describes using the
generation-specific qcom,ath12k-calibration-variant binding as well as
the generation-agnostic qcom,calibration-variant binding to load
board-specific calibration data from the device tree. However, the
driver never implemented either of these.

Given that no devices currently supported use
qcom,ath12k-calibration-variant and the previous patch implements
qcom,calibration-variant, drop the generation-specific version from the
binding to prevent future confusion.

Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
---
 .../devicetree/bindings/net/wireless/qcom,ath12k-wsi.yaml  | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-wsi.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-wsi.yaml
index 589960144fe1..fa64c8aa56f5 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-wsi.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-wsi.yaml
@@ -58,13 +58,6 @@ properties:
       String to uniquely identify variant of the calibration data for designs
       with colliding bus and device ids
 
-  qcom,ath12k-calibration-variant:
-    $ref: /schemas/types.yaml#/definitions/string
-    deprecated: true
-    description:
-      String to uniquely identify variant of the calibration data for designs
-      with colliding bus and device ids
-
   qcom,wsi-controller:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 1/2] wifi: ath12k: support calibration-variant from device tree
From: Andrew LaMarche @ 2026-06-30  1:14 UTC (permalink / raw)
  To: Jeff Johnson
  Cc: linux-wireless, ath12k, linux-kernel, Andrew LaMarche,
	Ernest Van Hoecke

ath10k and ath11k support reading calibration variants from the device
tree to locate the correct Board Description File (BDF). The ath12k-wsi
binding already describes using qcom,calibration-variant but it is not
implemented in the driver.

Many ath12k designs expose all the radios under a single phy, each of
which typically require a separate BDF. Without this, the radios may not
come up or will not be calibrated correctly.

Fix this by parsing the device tree for the generation-agnostic
qcom,calibration-variant. This allows the driver to properly select,
read and apply the correct BDF.

Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
---
Changes in v2:
- Drop ath12k-specific binding qcom,ath12k-calibration-variant in favor
  of generation agnostic qcom,calibration-variant.
- Link to v1: https://lore.kernel.org/all/20260131003222.2011259-1-andrewjlamarche@gmail.com
---
 drivers/net/wireless/ath/ath12k/core.c | 22 ++++++++++++++++++++++
 drivers/net/wireless/ath/ath12k/qmi.c  |  4 ++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 742d4fd1b598..52c28864c63c 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -812,6 +812,28 @@ int ath12k_core_check_smbios(struct ath12k_base *ab)
 	return 0;
 }
 
+int ath12k_core_check_dt(struct ath12k_base *ab)
+{
+	size_t max_len = sizeof(ab->qmi.target.bdf_ext);
+	const char *variant = NULL;
+	struct device_node *node;
+
+	node = ab->dev->of_node;
+	if (!node)
+		return -ENOENT;
+
+	of_property_read_string(node, "qcom,calibration-variant",
+			&variant);
+	if (!variant)
+		return -ENODATA;
+
+	if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
+		ath12k_dbg(ab, ATH12K_DBG_BOOT,
+				"bdf variant string is longer than the buffer can accommodate (variant: %s)\n", variant);
+
+	return 0;
+}
+
 static int ath12k_core_soc_create(struct ath12k_base *ab)
 {
 	int ret;
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..3cf39ae06fd3 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -2945,6 +2945,10 @@ int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
 	if (r)
 		ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
 
+	r = ath12k_core_check_dt(ab);
+	if (r)
+		ath12k_dbg(ab, ATH12K_DBG_QMI, "DT bdf variant name not set.\n");
+
 	r = ath12k_acpi_start(ab);
 	if (r)
 		/* ACPI is optional so continue in case of an error */
-- 
2.43.0


^ permalink raw reply related

* RE: rtw89: RTL8852BE P2P-device iftype and STA+P2P interface combination
From: Ping-Ke Shih @ 2026-06-30  0:50 UTC (permalink / raw)
  To: Doug Brewer; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <CAG0V13Qfp+eVCR6NjQJydN-fL8tus_EyJCWGQqQxTkKA9ZXBFQ@mail.gmail.com>

Doug Brewer <brewer.doug@gmail.com> wrote:
> On Mon, Jun 29, 2026 at 10:10 AM Ping-Ke Shih <pkshih@realtek.com> wrote:
> >
> > Doug Brewer wrote:
> > > Hi,
> > >
> > > I'm experimenting with Wi-Fi Display (Miracast sink) concurrent with an
> > > STA connection on an RTL8852BE (PCIe) using the mainline rtw89 driver
> > > (kernel 6.18.37).
> > >
> > > iw phy reports:
> > > Supported interface modes:
> > >    * managed, AP, P2P-client, P2P-GO
> > >    (no P2P-device)
> > > interface combinations are not supported
> > >
> > > In practice this blocks the standard P2P flow: there is no P2P-device
> > > iftype for a dedicated discovery context, and no advertised interface
> > > combination for managed + P2P-client coexistence.
> > >
> > > My questions:
> > > 1. is P2P-device iftype support planned for rtw89 on RTL885x? Is there a
> > >     known technical blocker, or is it simply not yet implemented?
> >
> > We are planning to add P2P-device iftype. It needs to consider the cases of
> > channel context, conditions of power save, and etc. It will take some time.
> >
> > I think it would be okay that you use STA interface to do P2P negotiation,
> > and then create P2P-client or P2P-GO iftype then.
> >
> > > 2. would advertising a managed + P2P-client interface combination
> > >     (single channel) be feasible on the current rtw89?
> >
> > This is a SCC which is supported.
> >
> > > 3. is MCC (#channels > 1) on the roadmap, or considered out of scope?
> >
> > Current support MCC as well. However, we are cooking new firmware to support
> > hw_scan with two operation channels -- which doesn't matter if you don't need
> > to do scan when MCC is operating.
> 
> Thanks for the suggestion. I tried using the STA interface for P2P
> negotiation, and wanted to share what I found.
> 
> With the STA connected (2.4GHz ch11) and an active p2p_connect, a
> wpa_supplicant -dd trace shows GO negotiation getting fairly far:
> 
> Peer's GO-NEG Request is received
> send the GO-NEG Response on ch11, peer ACKs it (TX ack=1)
> State goes GO_NEG -> CONNECT
> then time out waiting for the GO-NEG Confirm, status=-1
> 
> I select ch11 as the P2P operating channel (same as STA, SCC), while
> the peer's operating preference is 5GHz ch149. It looks like after we TX
> the Response, the radio doesn't stay on ch11 to listen for the Confirm,
> so the frame is missed -- presumably because the single radio is serving
> the STA connection.

So, peer doesn't stay ch11 to complete he negotiation, right?

What is the peer device you are using? Can you setup another RTL8852BE?
I suggest running simple scenario first to dig cause.

1. two peers make P2P group without any STA connection
2. RTL8852BE with a STA connection, and peer without connection. 

> 
> Aalso tested with the STA on 5GHz (ch149); the result is the same
> GO-NEG Confirm timeout.
> 
> Is this the channel-context issue that P2P-device iftype will address?
> And with the current driver, is there any way to keep the P2P listen
> context on the operating channel during GO negotiation while STA is up?

Before P2P negotiation completion, there is only one channel context.
The second interface (GC or GO) is created when the P2P role is decided
by P2P negotiation. 

You need to check supplicant log about channels on both peers. I think
remain-on-channel is the method supplicant switch channel to send
negotiation frames and to stay on listen channel. 

> 
> (FWIW, passing an explicit freq= to p2p_connect is rejected with FAIL,
> whether or not it matches the STA channel.)

Not sure why. In our side, it seems work.


I'd share a pair of wpa_supplicant .conf and wpa_cli commands we are testing
for reference.

Peer 1:
ctrl_interface=/var/run/wpa_supplicant
 
network={
        ssid="ap_x"
        key_mgmt=NONE
 
}
 
update_config=1
device_name=my_p2p
manufacturer=Realtek
model_name=RTW_STA
model_number=WLAN_CU
serial_number=12345
device_type=1-0050F204-1
os_version=01020300
config_methods=virtual_display virtual_push_button keypad
p2p_listen_reg_class=81
p2p_listen_channel=1
p2p_oper_reg_class=81
p2p_oper_channel=1
p2p_no_group_iface=1


wpa_supplicant -i wlan0 -c p2p.conf
wpa_cli
> p2p_find
> p2p_connect $SUT_MAC_ADDR pbc (freq=xxxx go_intent=15)


Peer 2:
ctrl_interface=/var/run/wpa_supplicant
update_config=1
device_name=my_p2p
manufacturer=Realtek
model_name=RTW_STA
model_number=WLAN_CU
serial_number=12345
device_type=1-0050F204-1
os_version=01020300
config_methods=virtual_display virtual_push_button keypad
p2p_listen_reg_class=81
p2p_listen_channel=1
p2p_oper_reg_class=81
p2p_oper_channel=1
p2p_no_group_iface=1

wpa_supplicant -i wlan0 -c p2p.conf
wpa_cli
> p2p_find
> p2p_connect $DUT_MAC_ADDR pbc (freq=xxxx go_intent=1)

Regards
Ping-Ke



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox