* [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices
@ 2026-09-21 11:23 Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 1/4] net: qrtr: Allow the host QRTR to assign a unique node id Manivannan Sadhasivam via B4 Relay
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-09-21 11:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo,
Manivannan Sadhasivam
Hi,
This series reworks the QRTR driver to add support for using identical MHI
endpoint devices at the same time. Currently, QRTR driver has a limitation on
using more than one identical MHI endpoint devices like QCS6490 or any Qcom
Endpoint device making use of QRTR at the same time. Because of the fact that
these devices will have the identical QRTR node id, they cannot be used at the
same time, on the same host machine.
This limitation is a blocker for running upstream kernel on devices like Qcom
based routers as they often have multiple identical WLAN Endpoint devices
connected to the Router SoC.
This series supersedes the following 2 series from Juha:
https://lore.kernel.org/all/20260915054207.2513877-1-juha-matti.tilli@iki.fi
https://lore.kernel.org/all/20260915074135.2567411-1-juha-matti.tilli@iki.fi
Compared to the series from Juha, this series simplifies the multi-endpoint
support by computing a unique node id for each MHI endpoint and uses it for the
internal QRTR book keeping. This ensures that even if the MHI endpoint devices
have same node ids, the host QRTR will always use a unique node id for each one
of them.
More details can be found in the individual patches.
Testing
=======
Juha tested this series on multi ath11k setup by backporting this series to
6.6.156 kernel. I'd appreciate a formal tested-by tag from Juha and other folks
CCed to this series.
Merge Strategy
==============
Since both QRTR and ath drivers are falling under the networking tree, the whole
series can be merged through netdev tree.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
Changes in v2:
- Rebased on top of net-next/main
- Used READ/WRITE_ONCE for reading/writing ep_nid
- Link to v1: https://patch.msgid.link/20260918-qrtr-multi-ep-v1-0-8a06caa368d3@oss.qualcomm.com
---
Manivannan Sadhasivam (4):
net: qrtr: Allow the host QRTR to assign a unique node id
net: qrtr: Assign unique node id for MHI endpoints
wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver
wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
MAINTAINERS | 1 +
drivers/net/wireless/ath/ath11k/hif.h | 9 ++++++
drivers/net/wireless/ath/ath11k/pci.c | 9 ++++++
drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++
drivers/net/wireless/ath/ath12k/hif.h | 9 ++++++
drivers/net/wireless/ath/ath12k/pci.c | 9 ++++++
drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++
include/net/qrtr.h | 21 ++++++++++++
net/qrtr/af_qrtr.c | 61 +++++++++++++++++++++++++++++++----
net/qrtr/mhi.c | 4 ++-
10 files changed, 136 insertions(+), 8 deletions(-)
---
base-commit: 8830e65ed46de41f849eefb8ba227d4852c460f6
change-id: 20260918-qrtr-multi-ep-c27c2bc54ee1
Best regards,
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/4] net: qrtr: Allow the host QRTR to assign a unique node id
2026-09-21 11:23 [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices Manivannan Sadhasivam via B4 Relay
@ 2026-09-21 11:23 ` Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 2/4] net: qrtr: Assign unique node id for MHI endpoints Manivannan Sadhasivam via B4 Relay
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-09-21 11:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Currently, QRTR identifies each remote node by the value of the
'src_node_id' field in the received packet and uses the node id as the key
to store the node to the internal 'qrtr_nodes' radix tree.
But this approach comes with a limitation. When more than one remote node
share the same id, then QRTR can only add the first node to the radix tree
and has to drop the successive nodes with the same node id as the 'key' in
radix tree has to be unique. This prevents connecting identical Qcom PCIe
WLAN devices to a single host at the same time.
To fix this limitation, allow the host QRTR to use the node id (nid)
received from the endpoint driver during qrtr_endpoint_register() as the
unique node id and use it as the 'key' for the internal radix tree. Also,
store the received 'src_id' in a new 'qrtr_node->ep_nid' field and replace
the 'ep_nid' with the unique 'nid' in the QRTR control packets if both
differ i.e., an endpoint driver has passed a unique 'nid' during
qrtr_endpoint_register(). To maintain symmetry, replace the 'nid' with the
'ep_nid' while sending the packet back to the remote node if both differ.
Currently, all QRTR endpoint drivers pass 'QRTR_EP_NID_AUTO' as the 'nid'
during qrtr_endpoint_register(). So 'ep_nid' and 'nid' are same and the
functionality is not changed.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
net/qrtr/af_qrtr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 54 insertions(+), 7 deletions(-)
diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
index 78347c937af7..ad62f3caede8 100644
--- a/net/qrtr/af_qrtr.c
+++ b/net/qrtr/af_qrtr.c
@@ -118,7 +118,8 @@ static DEFINE_XARRAY_ALLOC(qrtr_ports);
* @ep_lock: lock for endpoint management and callbacks
* @ep: endpoint
* @ref: reference count for node
- * @nid: node id
+ * @nid: node id assigned by the host QRTR
+ * @ep_nid: endpoint's own node id as received
* @qrtr_tx_flow: xarray of qrtr_tx_flow, keyed by node << 32 | port
* @qrtr_tx_lock: lock for qrtr_tx_flow inserts
* @hello_sent: hello packet send successful
@@ -131,6 +132,7 @@ struct qrtr_node {
struct qrtr_endpoint *ep;
struct kref ref;
unsigned int nid;
+ unsigned int ep_nid;
struct xarray qrtr_tx_flow;
struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */
@@ -347,6 +349,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
{
struct qrtr_hdr_v1 *hdr;
size_t len = skb->len;
+ unsigned int dst_node;
int rc, confirm_rx;
mutex_lock(&node->ep_lock);
@@ -369,10 +372,14 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
hdr->src_node_id = cpu_to_le32(from->sq_node);
hdr->src_port_id = cpu_to_le32(from->sq_port);
if (to->sq_port == QRTR_PORT_CTRL) {
- hdr->dst_node_id = cpu_to_le32(READ_ONCE(node->nid));
+ hdr->dst_node_id = cpu_to_le32(READ_ONCE(node->ep_nid));
hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
} else {
- hdr->dst_node_id = cpu_to_le32(to->sq_node);
+ /* Put back the endpoint's own node id */
+ dst_node = to->sq_node;
+ if (dst_node == READ_ONCE(node->nid))
+ dst_node = node->ep_nid;
+ hdr->dst_node_id = cpu_to_le32(dst_node);
hdr->dst_port_id = cpu_to_le32(to->sq_port);
}
@@ -441,6 +448,32 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid)
spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
}
+/* Replace the node id in the control packet with 'node->nid', if both are
+ * different.
+ */
+static void qrtr_node_rewrite_ctrl(struct qrtr_node *node, unsigned int type,
+ struct sk_buff *skb)
+{
+ struct qrtr_ctrl_pkt *pkt;
+ __le32 *nid;
+
+ if (node->nid == node->ep_nid)
+ return;
+
+ if (skb->len < sizeof(*pkt))
+ return;
+
+ pkt = (struct qrtr_ctrl_pkt *)skb->data;
+ if (type == QRTR_TYPE_DEL_CLIENT)
+ nid = &pkt->client.node;
+ else
+ nid = &pkt->server.node;
+
+ /* Rewrite only the endpoint's node id, not those of bridged nodes */
+ if (le32_to_cpu(*nid) == node->ep_nid)
+ *nid = cpu_to_le32(node->nid);
+}
+
/**
* qrtr_endpoint_post() - post incoming data
* @ep: endpoint handle
@@ -531,16 +564,29 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
skb_put_data(skb, data + hdrlen, size);
- qrtr_node_assign(node, cb->src_node);
+ if (node->ep_nid == QRTR_EP_NID_AUTO)
+ WRITE_ONCE(node->ep_nid, cb->src_node);
+
+ if (node->nid == QRTR_EP_NID_AUTO || node->nid == cb->src_node)
+ qrtr_node_assign(node, cb->src_node);
if (cb->type == QRTR_TYPE_NEW_SERVER) {
/* Remote node endpoint can bridge other distant nodes */
- const struct qrtr_ctrl_pkt *pkt;
+ const struct qrtr_ctrl_pkt *pkt = data + hdrlen;
+ unsigned int server_node = le32_to_cpu(pkt->server.node);
- pkt = data + hdrlen;
- qrtr_node_assign(node, le32_to_cpu(pkt->server.node));
+ if (server_node != node->ep_nid)
+ qrtr_node_assign(node, server_node);
}
+ if (cb->src_node == node->ep_nid)
+ cb->src_node = node->nid;
+
+ if (cb->type == QRTR_TYPE_NEW_SERVER ||
+ cb->type == QRTR_TYPE_DEL_SERVER ||
+ cb->type == QRTR_TYPE_DEL_CLIENT)
+ qrtr_node_rewrite_ctrl(node, cb->type, skb);
+
if (cb->type == QRTR_TYPE_RESUME_TX) {
qrtr_tx_resume(node, skb);
} else {
@@ -646,6 +692,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
mutex_init(&node->ep_lock);
skb_queue_head_init(&node->rx_queue);
node->nid = QRTR_EP_NID_AUTO;
+ node->ep_nid = QRTR_EP_NID_AUTO;
node->ep = ep;
node->hello_sent = false;
--
2.43.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/4] net: qrtr: Assign unique node id for MHI endpoints
2026-09-21 11:23 [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 1/4] net: qrtr: Allow the host QRTR to assign a unique node id Manivannan Sadhasivam via B4 Relay
@ 2026-09-21 11:23 ` Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 4/4] wifi: ath12k: " Manivannan Sadhasivam via B4 Relay
3 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-09-21 11:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Now that the QRTR driver allows using the unique node id for each device,
which is different from the node id received from the remote node, compute
a unique node id using a new API, qrtr_host_node_id().
This API takes the 'index' parameter and adds it to QRTR_NODE_HOST_BASE,
whose value is outside of the node id range used by the remote nodes (0 to
0xffff).
Finally, call the new API from MHI endpoint driver by passing the MHI
controller index as the parameter. The MHI controller index is unique for
each controller, thereby for each MHI endpoint device.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
MAINTAINERS | 1 +
include/net/qrtr.h | 21 +++++++++++++++++++++
net/qrtr/mhi.c | 4 +++-
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index df8ab9b82402..9c8bb086be28 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22511,6 +22511,7 @@ QUALCOMM IPC ROUTER (QRTR) DRIVER
M: Manivannan Sadhasivam <mani@kernel.org>
L: linux-arm-msm@vger.kernel.org
S: Maintained
+F: include/net/qrtr.h
F: include/trace/events/qrtr.h
F: include/uapi/linux/qrtr.h
F: net/qrtr/
diff --git a/include/net/qrtr.h b/include/net/qrtr.h
new file mode 100644
index 000000000000..745d51b4a6ba
--- /dev/null
+++ b/include/net/qrtr.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _NET_QRTR_H
+#define _NET_QRTR_H
+
+#include <linux/types.h>
+
+/* The offset is chosen carefully to not collide with the node ids allocated by
+ * the remote nodes. All the remote nodes use node ids in range 0 to 0xffff.
+ */
+#define QRTR_NODE_HOST_BASE 0x10000u
+
+/* Compute host node id from a per-device index. The index must be unique
+ * among the host assigned endpoints and smaller than QRTR_NODE_HOST_BASE.
+ */
+static inline unsigned int qrtr_host_node_id(unsigned int index)
+{
+ return QRTR_NODE_HOST_BASE + index;
+}
+
+#endif /* _NET_QRTR_H */
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 3990da1a65dc..c920ab61f848 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -6,6 +6,7 @@
#include <linux/mhi.h>
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <net/qrtr.h>
#include <net/sock.h>
#include "qrtr.h"
@@ -127,7 +128,8 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
if (rc)
return rc;
- rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
+ rc = qrtr_endpoint_register(&qdev->ep,
+ qrtr_host_node_id(mhi_dev->mhi_cntrl->index));
if (rc)
goto err_unprepare;
--
2.43.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 1/4] net: qrtr: Allow the host QRTR to assign a unique node id Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 2/4] net: qrtr: Assign unique node id for MHI endpoints Manivannan Sadhasivam via B4 Relay
@ 2026-09-21 11:23 ` Manivannan Sadhasivam via B4 Relay
2026-09-21 16:28 ` Juha-Matti Tilli
2026-09-22 11:02 ` Vasanthakumar Thiagarajan
2026-09-21 11:23 ` [PATCH v2 4/4] wifi: ath12k: " Manivannan Sadhasivam via B4 Relay
3 siblings, 2 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-09-21 11:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
When two identical ath11k PCIe devices are connected to the same host, both
advertise the WLFW service with the same service and instance id. The QMI
lookup reports both servers to each device, so a device may connect to the
firmware running on the other device.
But now, QRTR provides each MHI endpoint a unique node id which is
different from the node id announced by the device. So use the same id to
pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
the node id derived from the MHI controller index and zero for transports
that do not assign one. In the new_server callback, skip any service whose
node id does not match. A node id of zero disables the check, so transports
that do not assign one keep their current behavior.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath11k/hif.h | 9 +++++++++
drivers/net/wireless/ath/ath11k/pci.c | 9 +++++++++
drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++++
3 files changed, 28 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
index 017fed1b4bd1..0da9025c7ed8 100644
--- a/drivers/net/wireless/ath/ath11k/hif.h
+++ b/drivers/net/wireless/ath/ath11k/hif.h
@@ -32,6 +32,7 @@ struct ath11k_hif_ops {
void (*ce_irq_disable)(struct ath11k_base *ab);
void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
void (*coredump_download)(struct ath11k_base *ab);
+ int (*get_qrtr_node_id)(struct ath11k_base *ab);
};
static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
@@ -159,4 +160,12 @@ static inline void ath11k_hif_coredump_download(struct ath11k_base *ab)
ab->hif.ops->coredump_download(ab);
}
+static inline int ath11k_hif_get_qrtr_node_id(struct ath11k_base *ab)
+{
+ if (!ab->hif.ops->get_qrtr_node_id)
+ return 0;
+
+ return ab->hif.ops->get_qrtr_node_id(ab);
+}
+
#endif /* _HIF_H_ */
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index a163168f3617..4d327b5cc98a 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -10,6 +10,7 @@
#include <linux/of.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
+#include <net/qrtr.h>
#include "pci.h"
#include "core.h"
@@ -900,6 +901,13 @@ static int ath11k_pci_start(struct ath11k_base *ab)
return 0;
}
+static int ath11k_pci_get_qrtr_node_id(struct ath11k_base *ab)
+{
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
+ return qrtr_host_node_id(ab_pci->mhi_ctrl->index);
+}
+
static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
.start = ath11k_pci_start,
.stop = ath11k_pcic_stop,
@@ -921,6 +929,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
#ifdef CONFIG_DEV_COREDUMP
.coredump_download = ath11k_pci_coredump_download,
#endif
+ .get_qrtr_node_id = ath11k_pci_get_qrtr_node_id,
};
static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 7dc07339b957..dadf78f30b89 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -3170,8 +3170,18 @@ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
struct ath11k_base *ab = qmi->ab;
struct sockaddr_qrtr *sq = &qmi->sq;
+ int node_id;
int ret;
+ /* Identical devices advertise the same QMI services, so connect only to
+ * the QMI server on this device's node. A node id of 0 means the
+ * transport has not assigned a unique node id, so accept the server
+ * unfiltered.
+ */
+ node_id = ath11k_hif_get_qrtr_node_id(ab);
+ if (node_id && service->node != node_id)
+ return 0;
+
sq->sq_family = AF_QIPCRTR;
sq->sq_node = service->node;
sq->sq_port = service->port;
--
2.43.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 4/4] wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices Manivannan Sadhasivam via B4 Relay
` (2 preceding siblings ...)
2026-09-21 11:23 ` [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver Manivannan Sadhasivam via B4 Relay
@ 2026-09-21 11:23 ` Manivannan Sadhasivam via B4 Relay
2026-09-22 11:05 ` Vasanthakumar Thiagarajan
2026-09-22 11:43 ` Juha-Matti Tilli
3 siblings, 2 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-09-21 11:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
When two identical ath12k PCIe devices are connected to the same host, both
advertise the WLFW service with the same service and instance id. The QMI
lookup reports both servers to each device, so a device may connect to the
firmware running on the other device.
But now, QRTR provides each MHI endpoint a unique node id which is
different from the node id announced by the device. So use the same id to
pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
the node id derived from the MHI controller index and zero for transports
that do not assign one. In the new_server callback, skip any service whose
node id does not match. A node id of zero disables the check, so transports
that do not assign one keep their current behavior.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/hif.h | 9 +++++++++
drivers/net/wireless/ath/ath12k/pci.c | 9 +++++++++
drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++++++
3 files changed, 29 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index 4de8667690e9..be9c070cf716 100644
--- a/drivers/net/wireless/ath/ath12k/hif.h
+++ b/drivers/net/wireless/ath/ath12k/hif.h
@@ -32,6 +32,7 @@ struct ath12k_hif_ops {
void (*get_ce_msi_idx)(struct ath12k_base *ab, u32 ce_id, u32 *msi_idx);
int (*panic_handler)(struct ath12k_base *ab);
void (*coredump_download)(struct ath12k_base *ab);
+ int (*get_qrtr_node_id)(struct ath12k_base *ab);
};
static inline int ath12k_hif_map_service_to_pipe(struct ath12k_base *ab, u16 service_id,
@@ -162,4 +163,12 @@ static inline void ath12k_hif_coredump_download(struct ath12k_base *ab)
if (ab->hif.ops->coredump_download)
ab->hif.ops->coredump_download(ab);
}
+
+static inline int ath12k_hif_get_qrtr_node_id(struct ath12k_base *ab)
+{
+ if (!ab->hif.ops->get_qrtr_node_id)
+ return 0;
+
+ return ab->hif.ops->get_qrtr_node_id(ab);
+}
#endif /* ATH12K_HIF_H */
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 6441927b5382..2b1b122bbb3b 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
+#include <net/qrtr.h>
#include "pci.h"
#include "core.h"
@@ -1491,6 +1492,13 @@ static int ath12k_pci_panic_handler(struct ath12k_base *ab)
return NOTIFY_OK;
}
+static int ath12k_pci_get_qrtr_node_id(struct ath12k_base *ab)
+{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+
+ return qrtr_host_node_id(ab_pci->mhi_ctrl->index);
+}
+
static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
.start = ath12k_pci_start,
.stop = ath12k_pci_stop,
@@ -1512,6 +1520,7 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
#ifdef CONFIG_ATH12K_COREDUMP
.coredump_download = ath12k_pci_coredump_download,
#endif
+ .get_qrtr_node_id = ath12k_pci_get_qrtr_node_id,
};
static enum ath12k_device_family
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 280e50a1f31d..22b8cbbbf4f4 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -9,6 +9,7 @@
#include "qmi.h"
#include "core.h"
#include "debug.h"
+#include "hif.h"
#include <linux/of.h>
#include <linux/firmware.h>
#include <linux/of_address.h>
@@ -3940,8 +3941,18 @@ static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
struct ath12k_base *ab = qmi->ab;
struct sockaddr_qrtr *sq = &qmi->sq;
+ int node_id;
int ret;
+ /* Identical devices advertise the same QMI services, so connect only to
+ * the QMI server on this device's node. A node id of 0 means the
+ * transport has not assigned a unique node id, so accept the server
+ * unfiltered.
+ */
+ node_id = ath12k_hif_get_qrtr_node_id(ab);
+ if (node_id && service->node != node_id)
+ return 0;
+
sq->sq_family = AF_QIPCRTR;
sq->sq_node = service->node;
sq->sq_port = service->port;
--
2.43.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 ` [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver Manivannan Sadhasivam via B4 Relay
@ 2026-09-21 16:28 ` Juha-Matti Tilli
2026-09-22 11:02 ` Vasanthakumar Thiagarajan
1 sibling, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-21 16:28 UTC (permalink / raw)
To: Manivannan Sadhasivam, Manivannan Sadhasivam, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Jeff Hugo
On Mon, Sep 21, 2026, at 14:23, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> When two identical ath11k PCIe devices are connected to the same host, both
> advertise the WLFW service with the same service and instance id. The QMI
> lookup reports both servers to each device, so a device may connect to the
> firmware running on the other device.
>
> But now, QRTR provides each MHI endpoint a unique node id which is
> different from the node id announced by the device. So use the same id to
> pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> the node id derived from the MHI controller index and zero for transports
> that do not assign one. In the new_server callback, skip any service whose
> node id does not match. A node id of zero disables the check, so transports
> that do not assign one keep their current behavior.
Tested-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
Tested-on: 2x WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1
That's from the new rebased patches, v2, applied with git am.
Again, I picked the entire QRTR from net-next/main after your changes,
and backported the ath11k and ath12k changes to 6.6.157 kernel. The
conflicts in ath11k and ath12k are really simple to resolve. The QRTR is
better to take as-is, as it's a large and substantially modified piece
of code, and backporting could risk different behavior.
Unfortunately, it seems I'm locked to 6.6 kernel until I manage to boot
a newer kernel. I tested 6.12 series and my perfectly valid gzipped
initrd ext2 file system is recognised as gzipped, but mounting the root
from /dev/ram0 fails due to -EBUSY. Why this happens with 6.12.x but not
6.6.157 is a mystery to me. Prompting two AI models didn't help, they
keep on just repeating the same useless points. So I have to resort to
heavier weapons, printk and maybe even git bisect.
So, because 6.6 kernel in our CPU doesn't work with ath12k due to lack
of interrupts and I can't boot a newer kernel yet, you'll have to either
find someone with two ath12k cards, or just accept to test the ath12k
change with a single card and hope for the best.
My understanding is that 6.12 would support just 1 interrupt in ath12k.
If I could only boot it, that is.
BR, Juha-Matti
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 ` [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver Manivannan Sadhasivam via B4 Relay
2026-09-21 16:28 ` Juha-Matti Tilli
@ 2026-09-22 11:02 ` Vasanthakumar Thiagarajan
2026-09-22 13:27 ` Manivannan Sadhasivam
1 sibling, 1 reply; 12+ messages in thread
From: Vasanthakumar Thiagarajan @ 2026-09-22 11:02 UTC (permalink / raw)
To: manivannan.sadhasivam, Manivannan Sadhasivam, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo
On 9/21/2026 4:53 PM, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> When two identical ath11k PCIe devices are connected to the same host, both
> advertise the WLFW service with the same service and instance id. The QMI
> lookup reports both servers to each device, so a device may connect to the
> firmware running on the other device.
>
> But now, QRTR provides each MHI endpoint a unique node id which is
> different from the node id announced by the device. So use the same id to
> pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> the node id derived from the MHI controller index and zero for transports
> that do not assign one. In the new_server callback, skip any service whose
> node id does not match. A node id of zero disables the check, so transports
> that do not assign one keep their current behavior.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/net/wireless/ath/ath11k/hif.h | 9 +++++++++
> drivers/net/wireless/ath/ath11k/pci.c | 9 +++++++++
> drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++++
> 3 files changed, 28 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
> index 017fed1b4bd1..0da9025c7ed8 100644
> --- a/drivers/net/wireless/ath/ath11k/hif.h
> +++ b/drivers/net/wireless/ath/ath11k/hif.h
> @@ -32,6 +32,7 @@ struct ath11k_hif_ops {
> void (*ce_irq_disable)(struct ath11k_base *ab);
> void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
> void (*coredump_download)(struct ath11k_base *ab);
> + int (*get_qrtr_node_id)(struct ath11k_base *ab);
> };
>
> static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
> @@ -159,4 +160,12 @@ static inline void ath11k_hif_coredump_download(struct ath11k_base *ab)
> ab->hif.ops->coredump_download(ab);
> }
>
> +static inline int ath11k_hif_get_qrtr_node_id(struct ath11k_base *ab)
> +{
> + if (!ab->hif.ops->get_qrtr_node_id)
> + return 0;
> +
> + return ab->hif.ops->get_qrtr_node_id(ab);
> +}
> +
> #endif /* _HIF_H_ */
> diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
> index a163168f3617..4d327b5cc98a 100644
> --- a/drivers/net/wireless/ath/ath11k/pci.c
> +++ b/drivers/net/wireless/ath/ath11k/pci.c
> @@ -10,6 +10,7 @@
> #include <linux/of.h>
> #include <linux/time.h>
> #include <linux/vmalloc.h>
> +#include <net/qrtr.h>
>
> #include "pci.h"
> #include "core.h"
> @@ -900,6 +901,13 @@ static int ath11k_pci_start(struct ath11k_base *ab)
> return 0;
> }
>
> +static int ath11k_pci_get_qrtr_node_id(struct ath11k_base *ab)
> +{
> + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
> +
> + return qrtr_host_node_id(ab_pci->mhi_ctrl->index);
nit: since qrtr_host_node_id() returns node_id in unsigned int,
may be maintain that in the return type of the callers as well.
Mostly harmless as it is unlikely that node_id is allocated with
an extremely high id. Either way is fine with me. Same applicable
for ath12k patch as well.
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/4] wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 ` [PATCH v2 4/4] wifi: ath12k: " Manivannan Sadhasivam via B4 Relay
@ 2026-09-22 11:05 ` Vasanthakumar Thiagarajan
2026-09-22 11:43 ` Juha-Matti Tilli
1 sibling, 0 replies; 12+ messages in thread
From: Vasanthakumar Thiagarajan @ 2026-09-22 11:05 UTC (permalink / raw)
To: manivannan.sadhasivam, Manivannan Sadhasivam, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Juha-Matti Tilli, Jeff Hugo
On 9/21/2026 4:53 PM, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> When two identical ath12k PCIe devices are connected to the same host, both
> advertise the WLFW service with the same service and instance id. The QMI
> lookup reports both servers to each device, so a device may connect to the
> firmware running on the other device.
>
> But now, QRTR provides each MHI endpoint a unique node id which is
> different from the node id announced by the device. So use the same id to
> pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> the node id derived from the MHI controller index and zero for transports
> that do not assign one. In the new_server callback, skip any service whose
> node id does not match. A node id of zero disables the check, so transports
> that do not assign one keep their current behavior.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/4] wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
2026-09-21 11:23 ` [PATCH v2 4/4] wifi: ath12k: " Manivannan Sadhasivam via B4 Relay
2026-09-22 11:05 ` Vasanthakumar Thiagarajan
@ 2026-09-22 11:43 ` Juha-Matti Tilli
2026-09-22 13:30 ` Manivannan Sadhasivam
1 sibling, 1 reply; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-22 11:43 UTC (permalink / raw)
To: Manivannan Sadhasivam, Manivannan Sadhasivam, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jeff Johnson
Cc: linux-arm-msm, netdev, linux-kernel, linux-wireless, ath11k,
ath12k, Bjorn Andersson, Chris Lew, Deepak Kumar Singh,
Raj Kumar Bhagat, Jeff Hugo
On Mon, Sep 21, 2026, at 14:23, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> When two identical ath12k PCIe devices are connected to the same host, both
> advertise the WLFW service with the same service and instance id. The QMI
> lookup reports both servers to each device, so a device may connect to the
> firmware running on the other device.
>
> But now, QRTR provides each MHI endpoint a unique node id which is
> different from the node id announced by the device. So use the same id to
> pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> the node id derived from the MHI controller index and zero for transports
> that do not assign one. In the new_server callback, skip any service whose
> node id does not match. A node id of zero disables the check, so transports
> that do not assign one keep their current behavior.
Tested-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
Tested-on: 2x WCN7850 hw2.0 WLAN.IOE_HMT.1.1-00018-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1
Tested-on: 1x WCN6855 ath11k + 1x WCN7850 ath12k
I'm having some issues with regdb on ath12k cards so I had to test using
the low-frequency 2.4GHz channels. I tried updating linux-firmware to
20260810 to match my 6.12.110+multi-QRTR kernel, didn't help. The error
is:
ath12k_pci 0001:01:00.0: No reg rules available
ath12k_pci 0001:01:00.0: failed to extract regulatory info from received event
------------[ cut here ]------------
WARNING: CPU: 0 PID: 12 at /drivers/net/wireless/ath/ath12k/wmi.c:5841 ath12k_reg_chan_list_event+0x171/0x1e0 [ath12k]
Modules linked in: xt_gmmark(O) xt_bemark(O) w24e2identificator(O) qrtr_mhi ath12k mhi qmi_helpers mac80211 libarc4 cfg80211
CPU: 0 UID: 0 PID: 12 Comm: kworker/u8:0 Tainted: G O 6.12.110-yocto-standard-gec77603762c7 #1
Tainted: [O]=OOT_MODULE
Hardware name: Freescale LS1021A
Workqueue: ath12k_qmi_driver_event ath12k_qmi_driver_event_work [ath12k]
Call trace:
unwind_backtrace from show_stack+0xb/0xc
show_stack from dump_stack_lvl+0x35/0x40
dump_stack_lvl from __warn+0xaf/0xb0
__warn from warn_slowpath_fmt+0xe5/0xe8
warn_slowpath_fmt from ath12k_reg_chan_list_event+0x171/0x1e0 [ath12k]
ath12k_reg_chan_list_event [ath12k] from ath12k_wmi_op_rx+0x219/0xc08 [ath12k]
ath12k_wmi_op_rx [ath12k] from ath12k_htc_rx_completion_handler+0x215/0x2d4 [ath12k]
ath12k_htc_rx_completion_handler [ath12k] from ath12k_ce_recv_process_cb+0x149/0x198 [ath12k]
ath12k_ce_recv_process_cb [ath12k] from ath12k_pci_ce_tasklet+0x13/0x28 [ath12k]
ath12k_pci_ce_tasklet [ath12k] from tasklet_action_common+0x87/0xa8
tasklet_action_common from handle_softirqs+0xbf/0x1b4
handle_softirqs from irq_exit+0x55/0x78
irq_exit from call_with_stack+0xd/0x10
---[ end trace 0000000000000000 ]---
This error happens with 2x ath12k and 1x ath12k 1x ath11k too.
But, the dual ath12k setup works, and the errors are entirely different
than what QRTR node id clash does.
So, I believe the patch works.
BR, Juha-Matti
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver
2026-09-22 11:02 ` Vasanthakumar Thiagarajan
@ 2026-09-22 13:27 ` Manivannan Sadhasivam
0 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-22 13:27 UTC (permalink / raw)
To: Vasanthakumar Thiagarajan
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Jeff Johnson, linux-arm-msm, netdev, linux-kernel,
linux-wireless, ath11k, ath12k, Bjorn Andersson, Chris Lew,
Deepak Kumar Singh, Raj Kumar Bhagat, Juha-Matti Tilli,
Jeff Hugo
On Tue, Sep 22, 2026 at 04:32:07PM +0530, Vasanthakumar Thiagarajan wrote:
>
>
> On 9/21/2026 4:53 PM, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > When two identical ath11k PCIe devices are connected to the same host, both
> > advertise the WLFW service with the same service and instance id. The QMI
> > lookup reports both servers to each device, so a device may connect to the
> > firmware running on the other device.
> >
> > But now, QRTR provides each MHI endpoint a unique node id which is
> > different from the node id announced by the device. So use the same id to
> > pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> > the node id derived from the MHI controller index and zero for transports
> > that do not assign one. In the new_server callback, skip any service whose
> > node id does not match. A node id of zero disables the check, so transports
> > that do not assign one keep their current behavior.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> > drivers/net/wireless/ath/ath11k/hif.h | 9 +++++++++
> > drivers/net/wireless/ath/ath11k/pci.c | 9 +++++++++
> > drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++++
> > 3 files changed, 28 insertions(+)
> >
> > diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
> > index 017fed1b4bd1..0da9025c7ed8 100644
> > --- a/drivers/net/wireless/ath/ath11k/hif.h
> > +++ b/drivers/net/wireless/ath/ath11k/hif.h
> > @@ -32,6 +32,7 @@ struct ath11k_hif_ops {
> > void (*ce_irq_disable)(struct ath11k_base *ab);
> > void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
> > void (*coredump_download)(struct ath11k_base *ab);
> > + int (*get_qrtr_node_id)(struct ath11k_base *ab);
> > };
> > static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
> > @@ -159,4 +160,12 @@ static inline void ath11k_hif_coredump_download(struct ath11k_base *ab)
> > ab->hif.ops->coredump_download(ab);
> > }
> > +static inline int ath11k_hif_get_qrtr_node_id(struct ath11k_base *ab)
> > +{
> > + if (!ab->hif.ops->get_qrtr_node_id)
> > + return 0;
> > +
> > + return ab->hif.ops->get_qrtr_node_id(ab);
> > +}
> > +
> > #endif /* _HIF_H_ */
> > diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
> > index a163168f3617..4d327b5cc98a 100644
> > --- a/drivers/net/wireless/ath/ath11k/pci.c
> > +++ b/drivers/net/wireless/ath/ath11k/pci.c
> > @@ -10,6 +10,7 @@
> > #include <linux/of.h>
> > #include <linux/time.h>
> > #include <linux/vmalloc.h>
> > +#include <net/qrtr.h>
> > #include "pci.h"
> > #include "core.h"
> > @@ -900,6 +901,13 @@ static int ath11k_pci_start(struct ath11k_base *ab)
> > return 0;
> > }
> > +static int ath11k_pci_get_qrtr_node_id(struct ath11k_base *ab)
> > +{
> > + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
> > +
> > + return qrtr_host_node_id(ab_pci->mhi_ctrl->index);
>
> nit: since qrtr_host_node_id() returns node_id in unsigned int,
> may be maintain that in the return type of the callers as well.
> Mostly harmless as it is unlikely that node_id is allocated with
> an extremely high id. Either way is fine with me. Same applicable
> for ath12k patch as well.
>
Thanks for spotting it. For the sake of correctness, it makes sense to use same
type everywhere. I'll fix it in next version.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/4] wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
2026-09-22 11:43 ` Juha-Matti Tilli
@ 2026-09-22 13:30 ` Manivannan Sadhasivam
2026-09-22 14:53 ` Juha-Matti Tilli
0 siblings, 1 reply; 12+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-22 13:30 UTC (permalink / raw)
To: Juha-Matti Tilli
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Jeff Johnson, linux-arm-msm, netdev, linux-kernel,
linux-wireless, ath11k, ath12k, Bjorn Andersson, Chris Lew,
Deepak Kumar Singh, Raj Kumar Bhagat, Jeff Hugo
On Tue, Sep 22, 2026 at 02:43:05PM +0300, Juha-Matti Tilli wrote:
> On Mon, Sep 21, 2026, at 14:23, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > When two identical ath12k PCIe devices are connected to the same host, both
> > advertise the WLFW service with the same service and instance id. The QMI
> > lookup reports both servers to each device, so a device may connect to the
> > firmware running on the other device.
> >
> > But now, QRTR provides each MHI endpoint a unique node id which is
> > different from the node id announced by the device. So use the same id to
> > pick the correct server. Add a get_qrtr_node_id() HIF callback that returns
> > the node id derived from the MHI controller index and zero for transports
> > that do not assign one. In the new_server callback, skip any service whose
> > node id does not match. A node id of zero disables the check, so transports
> > that do not assign one keep their current behavior.
>
> Tested-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
> Tested-on: 2x WCN7850 hw2.0 WLAN.IOE_HMT.1.1-00018-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1
> Tested-on: 1x WCN6855 ath11k + 1x WCN7850 ath12k
>
> I'm having some issues with regdb on ath12k cards so I had to test using
> the low-frequency 2.4GHz channels. I tried updating linux-firmware to
> 20260810 to match my 6.12.110+multi-QRTR kernel, didn't help. The error
> is:
>
> ath12k_pci 0001:01:00.0: No reg rules available
> ath12k_pci 0001:01:00.0: failed to extract regulatory info from received event
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 12 at /drivers/net/wireless/ath/ath12k/wmi.c:5841 ath12k_reg_chan_list_event+0x171/0x1e0 [ath12k]
> Modules linked in: xt_gmmark(O) xt_bemark(O) w24e2identificator(O) qrtr_mhi ath12k mhi qmi_helpers mac80211 libarc4 cfg80211
> CPU: 0 UID: 0 PID: 12 Comm: kworker/u8:0 Tainted: G O 6.12.110-yocto-standard-gec77603762c7 #1
> Tainted: [O]=OOT_MODULE
> Hardware name: Freescale LS1021A
> Workqueue: ath12k_qmi_driver_event ath12k_qmi_driver_event_work [ath12k]
> Call trace:
> unwind_backtrace from show_stack+0xb/0xc
> show_stack from dump_stack_lvl+0x35/0x40
> dump_stack_lvl from __warn+0xaf/0xb0
> __warn from warn_slowpath_fmt+0xe5/0xe8
> warn_slowpath_fmt from ath12k_reg_chan_list_event+0x171/0x1e0 [ath12k]
> ath12k_reg_chan_list_event [ath12k] from ath12k_wmi_op_rx+0x219/0xc08 [ath12k]
> ath12k_wmi_op_rx [ath12k] from ath12k_htc_rx_completion_handler+0x215/0x2d4 [ath12k]
> ath12k_htc_rx_completion_handler [ath12k] from ath12k_ce_recv_process_cb+0x149/0x198 [ath12k]
> ath12k_ce_recv_process_cb [ath12k] from ath12k_pci_ce_tasklet+0x13/0x28 [ath12k]
> ath12k_pci_ce_tasklet [ath12k] from tasklet_action_common+0x87/0xa8
> tasklet_action_common from handle_softirqs+0xbf/0x1b4
> handle_softirqs from irq_exit+0x55/0x78
> irq_exit from call_with_stack+0xd/0x10
> ---[ end trace 0000000000000000 ]---
>
> This error happens with 2x ath12k and 1x ath12k 1x ath11k too.
>
> But, the dual ath12k setup works, and the errors are entirely different
> than what QRTR node id clash does.
>
> So, I believe the patch works.
>
Thanks a lot for testing. I asked our WLAN team member to test this series on
multi-ath12k setup and found one issue with QRTR_TYPE_RESUME_TX. After fixing
it, multi-ath12k setup works fine.
I'll submit v3 with that fix. Please give it a shot on this setup, one final
time :) Appreciate your help here.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/4] wifi: ath12k: Connect to the QMI server belonging to the device owned by this driver
2026-09-22 13:30 ` Manivannan Sadhasivam
@ 2026-09-22 14:53 ` Juha-Matti Tilli
0 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-22 14:53 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Jeff Johnson, linux-arm-msm, netdev, linux-kernel,
linux-wireless, ath11k, ath12k, Bjorn Andersson, Chris Lew,
Deepak Kumar Singh, Raj Kumar Bhagat, Jeff Hugo
On Tue, Sep 22, 2026, at 16:30, Manivannan Sadhasivam wrote:
> On Tue, Sep 22, 2026 at 02:43:05PM +0300, Juha-Matti Tilli wrote:
> > So, I believe the patch works.
>
> Thanks a lot for testing. I asked our WLAN team member to test this series on
> multi-ath12k setup and found one issue with QRTR_TYPE_RESUME_TX. After fixing
> it, multi-ath12k setup works fine.
>
> I'll submit v3 with that fix. Please give it a shot on this setup, one final
> time :) Appreciate your help here.
Is this issue perhaps related to this (2x ath12k):
ath12k_pci 0001:01:00.0: dp_tx: failed to find the peer with peer_id 2
I managed to switch to 6.18.53 kernel and now the regulatory DB issue
is gone, but I'm getting this repeatedly to dmesg.
Yet, despite this issue, I see the network and data flows (with v2).
Also the other card gives:
ath12k_pci 0000:01:00.0: failed to pull fw stats: -71
ath12k_pci 0000:01:00.0: time out while waiting for get fw stats
...but it's lacking antennas so could be related to that.
BR, Juha-Matti
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-22 14:54 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 11:23 [PATCH v2 0/4] net: qrtr: Add support for using identical MHI endpoint devices Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 1/4] net: qrtr: Allow the host QRTR to assign a unique node id Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 2/4] net: qrtr: Assign unique node id for MHI endpoints Manivannan Sadhasivam via B4 Relay
2026-09-21 11:23 ` [PATCH v2 3/4] wifi: ath11k: Connect to the QMI server belonging to the device owned by this driver Manivannan Sadhasivam via B4 Relay
2026-09-21 16:28 ` Juha-Matti Tilli
2026-09-22 11:02 ` Vasanthakumar Thiagarajan
2026-09-22 13:27 ` Manivannan Sadhasivam
2026-09-21 11:23 ` [PATCH v2 4/4] wifi: ath12k: " Manivannan Sadhasivam via B4 Relay
2026-09-22 11:05 ` Vasanthakumar Thiagarajan
2026-09-22 11:43 ` Juha-Matti Tilli
2026-09-22 13:30 ` Manivannan Sadhasivam
2026-09-22 14:53 ` Juha-Matti Tilli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®