* [PATCH v4 01/12] net: qrtr: support getting new endpoint ids externally
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it Juha-Matti Tilli
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
This is originally based on a patch by Mihai Moldovan, that allowed
registering endpoint-specific data and getting endpoint ids by the
endpoint-specific data. Unfortunately, the old API did not support
freeing the ids, creating a memory leak if someone repeatedly unloads
and reloads kernel modules. Also, the old API had O(N) complexity where
N was the amount of leaked memory. Because the patch has been
extensively changed, I reset authorship.
So, the new patch version only supports getting ids externally, with the
idea being that MHI controller would know about its endpoint id.
I made sure getting new data ids is permissible while holding a
spinlock, since multiple threads may race to get the same id.
Originally-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
MAINTAINERS | 1 +
include/net/qrtr.h | 10 ++++++++++
net/qrtr/af_qrtr.c | 42 ++++++++++++++++++++++++++++++++++++------
net/qrtr/qrtr.h | 2 ++
4 files changed, 49 insertions(+), 6 deletions(-)
create mode 100644 include/net/qrtr.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 0b42e898f4d8e..491f09cb7939c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22506,6 +22506,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 0000000000000..762d60b03012e
--- /dev/null
+++ b/include/net/qrtr.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __NET_QRTR_H
+#define __NET_QRTR_H
+
+#include <linux/types.h>
+
+int qrtr_endpoint_get_data_id(u32 *endpoint_id);
+void qrtr_endpoint_free_data_id(u32 endpoint_id);
+
+#endif /* __NET_QRTR_H */
diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
index 7c50d32b11015..86a92e95e270f 100644
--- a/net/qrtr/af_qrtr.c
+++ b/net/qrtr/af_qrtr.c
@@ -11,6 +11,7 @@
#include <linux/wait.h>
#include <net/sock.h>
+#include <net/qrtr.h>
#include "qrtr.h"
@@ -753,8 +754,8 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt,
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
{
struct qrtr_node *node;
- u32 endpoint_id;
- int rc;
+ u32 endpoint_id = 0;
+ int rc = 0;
if (!ep || !ep->xmit)
return -EINVAL;
@@ -763,9 +764,18 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
if (!node)
return -ENOMEM;
- rc = xa_alloc_cyclic(&qrtr_endpoints, &endpoint_id, NULL,
- QRTR_ENDPOINT_RANGE, &next_endpoint_id,
- GFP_KERNEL);
+ if (ep->endpoint_data_id)
+ endpoint_id = ep->endpoint_data_id;
+
+ /*
+ * If we're registering an endpoint into smd or tun based qrtr,
+ * we don't have endpoint_data_id. Thus, allocate a new one.
+ */
+ if (!endpoint_id) {
+ rc = xa_alloc_cyclic(&qrtr_endpoints, &endpoint_id, NULL,
+ QRTR_ENDPOINT_RANGE, &next_endpoint_id,
+ GFP_KERNEL);
+ }
if (rc < 0)
goto free_node;
@@ -857,13 +867,33 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
qrtr_node_release(node);
- xa_erase(&qrtr_endpoints, endpoint_id);
+ if (ep->endpoint_data_id != endpoint_id)
+ xa_erase(&qrtr_endpoints, endpoint_id); // did allocate
ep->id = 0;
ep->node = NULL;
}
EXPORT_SYMBOL_GPL(qrtr_endpoint_unregister);
+int qrtr_endpoint_get_data_id(u32 *endpoint_id)
+{
+ int rc;
+
+ *endpoint_id = 0;
+ // GFP_ATOMIC to allow while holding spinlock
+ rc = xa_alloc_cyclic(&qrtr_endpoints, endpoint_id, NULL,
+ QRTR_ENDPOINT_RANGE, &next_endpoint_id,
+ GFP_ATOMIC);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(qrtr_endpoint_get_data_id);
+
+void qrtr_endpoint_free_data_id(u32 endpoint_id)
+{
+ xa_erase(&qrtr_endpoints, endpoint_id);
+}
+EXPORT_SYMBOL_GPL(qrtr_endpoint_free_data_id);
+
/* Lookup socket by port.
*
* Callers must release with qrtr_port_put()
diff --git a/net/qrtr/qrtr.h b/net/qrtr/qrtr.h
index affc24f426c64..45e38be0b2cb6 100644
--- a/net/qrtr/qrtr.h
+++ b/net/qrtr/qrtr.h
@@ -21,6 +21,7 @@ struct qrtr_node_lookup_helper {
/**
* struct qrtr_endpoint - endpoint handle
* @xmit: Callback for outgoing packets
+ * @endpoint_data_id: an already allocated id to be used instead of new alloc
*
* The socket buffer passed to the xmit function becomes owned by the endpoint
* driver. As such, when the driver is done with the buffer, it should
@@ -32,6 +33,7 @@ struct qrtr_endpoint {
struct qrtr_node *node;
struct qrtr_node_lookup_helper helper;
u32 id;
+ u32 endpoint_data_id;
};
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid);
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi Juha-Matti Tilli
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
It is slightly less than ideal to have MHI know about its QRTR endpoint
id, since MHI can be compiled in without QRTR. However, since many users
of MHI use QRTR, I was bold enough to edit the MHI controller data
structure. The only alternative to this editing is to have a hash table
or worse, an O(N) lookup list inside QRTR to turn MHI controller data
pointer to QRTR endpoint id. However, even in that case the QRTR
endpoint id needs to be freed when the MHI controller is freed, so it is
impossible to do this in a non-leaky way without editing MHI controller.
It's a good question whether the QRTR endpoint it should be stored to
mhi_controller or mhi_device. In most cases, it shouldn't matter, as two
PCIe ath11k/ath12k cards have two mhi_controllers. So, I followed the
original idea by Mihai Moldovan that mhi_controller has 1:1 relationship
to QRTR endpoint.
MHI controller needs a function pointer to actually free the QRTR
endpoint id, since MHI can be compiled in without QRTR, so the freeing
has to happen externally.
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/bus/mhi/host/init.c | 8 ++++++++
include/linux/mhi.h | 5 +++++
2 files changed, 13 insertions(+)
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index fd3050889412d..d96b099432640 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -947,6 +947,9 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
rwlock_init(&mhi_cntrl->pm_lock);
spin_lock_init(&mhi_cntrl->transition_lock);
spin_lock_init(&mhi_cntrl->wlock);
+ spin_lock_init(&mhi_cntrl->qrtr_endpoint_lock);
+ mhi_cntrl->qrtr_endpoint_id = 0;
+ mhi_cntrl->free_qrtr_endpoint_id = NULL;
INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker);
init_waitqueue_head(&mhi_cntrl->state_event);
@@ -1087,6 +1090,11 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
put_device(&mhi_dev->dev);
ida_free(&mhi_controller_ida, mhi_cntrl->index);
+
+ spin_lock(&mhi_cntrl->qrtr_endpoint_lock);
+ if (mhi_cntrl->free_qrtr_endpoint_id)
+ mhi_cntrl->free_qrtr_endpoint_id(mhi_cntrl);
+ spin_unlock(&mhi_cntrl->qrtr_endpoint_lock);
}
EXPORT_SYMBOL_GPL(mhi_unregister_controller);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 8616bacd8675d..d6d5c93e41cb0 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -361,6 +361,7 @@ struct mhi_controller_config {
* @st_worker: State transition worker
* @hiprio_wq: High priority workqueue for MHI work such as state transitions
* @state_event: State change event
+ * @qrtr_endpoint_id: The QRTR endpoint id associated with this MHI controller
* @status_cb: CB function to notify power states of the device (required)
* @wake_get: CB function to assert device wake (optional)
* @wake_put: CB function to de-assert device wake (optional)
@@ -373,6 +374,7 @@ struct mhi_controller_config {
* @write_reg: Write a MHI register via the physical link (required)
* @reset: Controller specific reset function (optional)
* @edl_trigger: CB function to trigger EDL mode (optional)
+ * @free_qrtr_endpoint_id: Function to free the QRTR endpoint id
* @buffer_len: Bounce buffer length
* @index: Index of the MHI controller instance
* @bounce_buf: Use of bounce buffer
@@ -440,6 +442,8 @@ struct mhi_controller {
struct work_struct st_worker;
struct workqueue_struct *hiprio_wq;
wait_queue_head_t state_event;
+ u32 qrtr_endpoint_id;
+ spinlock_t qrtr_endpoint_lock;
void (*status_cb)(struct mhi_controller *mhi_cntrl,
enum mhi_callback cb);
@@ -458,6 +462,7 @@ struct mhi_controller {
u32 val);
void (*reset)(struct mhi_controller *mhi_cntrl);
int (*edl_trigger)(struct mhi_controller *mhi_cntrl);
+ void (*free_qrtr_endpoint_id)(void *mhi_cntrl_void);
size_t buffer_len;
int index;
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Juha-Matti Tilli
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
MHI will use the mhi_controller data structure to store the QRTR
endpoint id, as explained previously.
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
net/qrtr/mhi.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 630ce0da060e5..41b58ab854725 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <net/sock.h>
+#include <net/qrtr.h>
#include "qrtr.h"
@@ -116,6 +117,17 @@ static ssize_t endpoint_show(struct device *dev,
static DEVICE_ATTR_RO(endpoint);
+static void qcom_mhi_qrtr_free_mhi_id(void *mhi_cntrl_void)
+{
+ struct mhi_controller *mhi_cntrl = mhi_cntrl_void;
+ u32 id = mhi_cntrl->qrtr_endpoint_id;
+
+ if (id != 0)
+ qrtr_endpoint_free_data_id(id);
+ mhi_cntrl->qrtr_endpoint_id = 0;
+ mhi_cntrl->free_qrtr_endpoint_id = NULL;
+}
+
static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
const struct mhi_device_id *id)
{
@@ -130,6 +142,23 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
qdev->dev = &mhi_dev->dev;
qdev->ep.xmit = qcom_mhi_qrtr_send;
+ spin_lock(&mhi_dev->mhi_cntrl->qrtr_endpoint_lock);
+ if (mhi_dev->mhi_cntrl->qrtr_endpoint_id) {
+ qdev->ep.endpoint_data_id =
+ mhi_dev->mhi_cntrl->qrtr_endpoint_id;
+ } else {
+ rc = qrtr_endpoint_get_data_id(&qdev->ep.endpoint_data_id);
+ if (rc) {
+ spin_unlock(&mhi_dev->mhi_cntrl->qrtr_endpoint_lock);
+ return -ENOMEM;
+ }
+ mhi_dev->mhi_cntrl->qrtr_endpoint_id =
+ qdev->ep.endpoint_data_id;
+ mhi_dev->mhi_cntrl->free_qrtr_endpoint_id =
+ qcom_mhi_qrtr_free_mhi_id;
+ }
+ spin_unlock(&mhi_dev->mhi_cntrl->qrtr_endpoint_lock);
+
dev_set_drvdata(&mhi_dev->dev, qdev);
/* start channels */
@@ -150,6 +179,9 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");
+ mhi_dev->mhi_cntrl->qrtr_endpoint_id = qdev->ep.id;
+ mhi_dev->mhi_cntrl->free_qrtr_endpoint_id = qcom_mhi_qrtr_free_mhi_id;
+
return 0;
err_unregister:
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (2 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Juha-Matti Tilli
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
Adding this allows us to easily supply an endpoint ID to bind on later
on when creating the socket.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
include/linux/soc/qcom/qmi.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h
index b9dcb437a0be5..c675d095df778 100644
--- a/include/linux/soc/qcom/qmi.h
+++ b/include/linux/soc/qcom/qmi.h
@@ -224,6 +224,7 @@ struct qmi_msg_handler {
* @txns: outstanding transactions
* @txn_lock: lock for modifications of @txns
* @handlers: list of handlers for incoming messages
+ * @endpoint_id: QRTR endpoint ID to bind on
*/
struct qmi_handle {
struct socket *sock;
@@ -247,6 +248,8 @@ struct qmi_handle {
struct mutex txn_lock;
const struct qmi_msg_handler *handlers;
+
+ u32 endpoint_id;
};
int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (3 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 06/12] wifi: ath11k: add QRTR endpoint ID hif feature Juha-Matti Tilli
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
For clients that already know the QRTR endpoint ID before actually
creating the QMI socket and set it in struct qmi_handle, optionally try
to bind to this QRTR endpoint ID when creating the socket.
This can fail, and qmi_sock_create will issue diagnostic messages, but
otherwise ignore the error.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/soc/qcom/qmi_interface.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c
index 16e2e24b60968..1550138a938d2 100644
--- a/drivers/soc/qcom/qmi_interface.c
+++ b/drivers/soc/qcom/qmi_interface.c
@@ -586,6 +586,7 @@ static struct socket *qmi_sock_create(struct qmi_handle *qmi,
struct sockaddr_qrtr *sq)
{
struct socket *sock;
+ const struct proto_ops *ops = NULL;
int ret;
ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
@@ -593,6 +594,33 @@ static struct socket *qmi_sock_create(struct qmi_handle *qmi,
if (ret < 0)
return ERR_PTR(ret);
+ ops = READ_ONCE(sock->ops);
+
+ if (!ops) {
+ pr_warn("sock->ops not available for QMI socket\n");
+ pr_warn("will not be able to bind to endpoint ID.\n");
+ /* N.B.: this error value will not be passed out. */
+ ret = -ENXIO;
+ }
+
+ if (!ret && !ops->setsockopt) {
+ pr_warn("ops->setsockopt not available for QMI socket\n");
+ pr_warn("will not be able to bind to endpoint ID.\n");
+ /* N.B.: this error value will not be passed out. */
+ ret = -ENXIO;
+ }
+
+ /* Only bind to a specific endpoint if a valid one was provided. */
+ if (!ret && qmi->endpoint_id) {
+ ret = ops->setsockopt(sock, SOL_QRTR, QRTR_BIND_ENDPOINT,
+ KERNEL_SOCKPTR(&qmi->endpoint_id),
+ sizeof(qmi->endpoint_id));
+
+ if (ret < 0)
+ pr_warn("binding to QRTR endpoint ID failed: %d\n",
+ ret);
+ }
+
ret = kernel_getsockname(sock, (struct sockaddr *)sq);
if (ret < 0) {
sock_release(sock);
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 06/12] wifi: ath11k: add QRTR endpoint ID hif feature
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (4 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 07/12] wifi: ath11k: stub QRTR endpoint ID fetching Juha-Matti Tilli
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
This will allow fetching the QRTR endpoint ID via hardware-specific
means.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath11k/hif.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
index 017fed1b4bd15..2f1634bb9b181 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 (*set_qrtr_endpoint_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_set_qrtr_endpoint_id(struct ath11k_base *ab)
+{
+ if (!ab->hif.ops->set_qrtr_endpoint_id)
+ return -EOPNOTSUPP;
+ else
+ return ab->hif.ops->set_qrtr_endpoint_id(ab);
+}
+
#endif /* _HIF_H_ */
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 07/12] wifi: ath11k: stub QRTR endpoint ID fetching
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (5 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 06/12] wifi: ath11k: add QRTR endpoint ID hif feature Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 08/12] wifi: ath11k: implement QRTR endpoint ID fetching for PCI Juha-Matti Tilli
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
QRTR endpoint ID fetching will currently not be available for AHB.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath11k/ahb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 27d01411b6e9c..1cd81d2ac1201 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -798,6 +798,11 @@ static int ath11k_ahb_hif_resume(struct ath11k_base *ab)
return 0;
}
+static int ath11k_ahb_set_qrtr_endpoint_id(struct ath11k_base *ab)
+{
+ return -EOPNOTSUPP;
+}
+
static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
.start = ath11k_ahb_start,
.stop = ath11k_ahb_stop,
@@ -811,6 +816,7 @@ static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
.power_up = ath11k_ahb_power_up,
.ce_irq_enable = ath11k_ahb_ce_irqs_enable,
.ce_irq_disable = ath11k_ahb_ce_irq_disable_sync,
+ .set_qrtr_endpoint_id = ath11k_ahb_set_qrtr_endpoint_id,
};
static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
@@ -830,6 +836,7 @@ static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
.resume = ath11k_ahb_hif_resume,
.ce_irq_enable = ath11k_pci_enable_ce_irqs_except_wake_irq,
.ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
+ .set_qrtr_endpoint_id = ath11k_ahb_set_qrtr_endpoint_id,
};
static int ath11k_core_get_rproc(struct ath11k_base *ab)
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 08/12] wifi: ath11k: implement QRTR endpoint ID fetching for PCI
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (6 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 07/12] wifi: ath11k: stub QRTR endpoint ID fetching Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 09/12] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_init_service Juha-Matti Tilli
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
QRTR endpoint ID fetching for PCIe devices will use MHI.
Originally-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath11k/mhi.c | 46 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/mhi.h | 1 +
drivers/net/wireless/ath/ath11k/pci.c | 1 +
3 files changed, 48 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index a6c9ff112c68f..755a57b6058a1 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -11,6 +11,8 @@
#include <linux/of_address.h>
#include <linux/ioport.h>
+#include <net/qrtr.h>
+
#include "core.h"
#include "debug.h"
#include "mhi.h"
@@ -502,3 +504,47 @@ void ath11k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic)
{
mhi_download_rddm_image(mhi_ctrl, in_panic);
}
+
+static void ath11k_mhi_qrtr_free_mhi_id(void *mhi_cntrl_void)
+{
+ struct mhi_controller *mhi_cntrl = mhi_cntrl_void;
+ u32 id = mhi_cntrl->qrtr_endpoint_id;
+
+ if (id != 0)
+ qrtr_endpoint_free_data_id(id);
+ mhi_cntrl->qrtr_endpoint_id = 0;
+ mhi_cntrl->free_qrtr_endpoint_id = NULL;
+}
+
+int ath11k_mhi_set_qrtr_endpoint_id(struct ath11k_base *ab)
+{
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+ struct ath11k_qmi *qmi = &ab->qmi;
+ int ret;
+
+ spin_lock(&ab_pci->mhi_ctrl->qrtr_endpoint_lock);
+
+ if (ab_pci->mhi_ctrl->qrtr_endpoint_id) {
+ qmi->handle.endpoint_id = ab_pci->mhi_ctrl->qrtr_endpoint_id;
+ } else {
+ ret = qrtr_endpoint_get_data_id(&qmi->handle.endpoint_id);
+ if (!ret) {
+ ab_pci->mhi_ctrl->qrtr_endpoint_id =
+ qmi->handle.endpoint_id;
+ ab_pci->mhi_ctrl->free_qrtr_endpoint_id =
+ ath11k_mhi_qrtr_free_mhi_id;
+ }
+ }
+
+ spin_unlock(&ab_pci->mhi_ctrl->qrtr_endpoint_lock);
+
+ ath11k_dbg(ab, ATH11K_DBG_PCI,
+ "queried mhi_ctrl QRTR endpoint ID: %u\n",
+ qmi->handle.endpoint_id);
+ if (ret) {
+ ath11k_warn(ab, "failed to query QRTR endpoint ID: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h
index 7e7561ce883cb..46a9c978b30d1 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.h
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
@@ -28,4 +28,5 @@ int ath11k_mhi_suspend(struct ath11k_pci *ar_pci);
int ath11k_mhi_resume(struct ath11k_pci *ar_pci);
void ath11k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic);
+int ath11k_mhi_set_qrtr_endpoint_id(struct ath11k_base *ab);
#endif
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index a163168f36176..56490a21964a3 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -918,6 +918,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
.ce_irq_enable = ath11k_pci_hif_ce_irq_enable,
.ce_irq_disable = ath11k_pci_hif_ce_irq_disable,
.get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx,
+ .set_qrtr_endpoint_id = ath11k_mhi_set_qrtr_endpoint_id,
#ifdef CONFIG_DEV_COREDUMP
.coredump_download = ath11k_pci_coredump_download,
#endif
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 09/12] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_init_service
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (7 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 08/12] wifi: ath11k: implement QRTR endpoint ID fetching for PCI Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 10/12] wifi: ath12k: add QRTR endpoint ID hif feature Juha-Matti Tilli
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
If possible, fetch the QRTR endpoint ID in ath11k_qmi_init_service, just
before calling qmi_handle_init, and make it available in the qmi_handle.
qmi_helpers will then automatically bind to this endpoint for us.
This finally allows using multiple ath11k-based cards with the same QRTR
node/port combination to work simultanenous (and, for that matter, at
all).
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Tested-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath11k/qmi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 7dc07339b9579..ee5effc113667 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -16,6 +16,7 @@
#include <linux/ioport.h>
#include <linux/firmware.h>
#include <linux/of_irq.h>
+#include <net/sock.h>
#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
#define HOST_CSTATE_BIT 0x04
@@ -3324,6 +3325,13 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
ab->qmi.ab = ab;
ab->qmi.target_mem_mode = ab->hw_params.fw_mem_mode;
+
+ ret = ath11k_set_qrtr_endpoint_id(ab);
+ if (ret) {
+ ath11k_warn(ab, "failed to set QRTR endpoint ID: %d\n", ret);
+ ath11k_warn(ab, "only one device per system will be supported\n");
+ }
+
ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
&ath11k_qmi_ops, ath11k_qmi_msg_handlers);
if (ret < 0) {
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 10/12] wifi: ath12k: add QRTR endpoint ID hif feature
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (8 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 09/12] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_init_service Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 11/12] wifi: ath12k: implement QRTR endpoint ID fetching for PCI Juha-Matti Tilli
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
This will allow fetching the QRTR endpoint ID via hardware-specific
means.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath12k/hif.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index 4de8667690e91..4591660519efb 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 (*set_qrtr_endpoint_id)(struct ath12k_base *ab);
};
static inline int ath12k_hif_map_service_to_pipe(struct ath12k_base *ab, u16 service_id,
@@ -162,4 +163,13 @@ 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_set_qrtr_endpoint_id(struct ath12k_base *ab)
+{
+ if (!ab->hif.ops->set_qrtr_endpoint_id)
+ return -EOPNOTSUPP;
+ else
+ return ab->hif.ops->set_qrtr_endpoint_id(ab);
+}
+
#endif /* ATH12K_HIF_H */
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 11/12] wifi: ath12k: implement QRTR endpoint ID fetching for PCI
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (9 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 10/12] wifi: ath12k: add QRTR endpoint ID hif feature Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-15 7:41 ` [PATCH v4 12/12] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_init_service Juha-Matti Tilli
2026-09-18 6:26 ` [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
QRTR endpoint ID fetching for PCIe devices will use MHI.
Originally-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath12k/mhi.c | 46 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/mhi.h | 3 ++
drivers/net/wireless/ath/ath12k/pci.c | 1 +
3 files changed, 50 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
index ee87f00bc5de9..3d0884e65939d 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.c
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
@@ -8,6 +8,8 @@
#include <linux/pci.h>
#include <linux/firmware.h>
+#include <net/qrtr.h>
+
#include "core.h"
#include "debug.h"
#include "mhi.h"
@@ -527,3 +529,47 @@ void ath12k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic)
{
mhi_download_rddm_image(mhi_ctrl, in_panic);
}
+
+static void ath12k_mhi_qrtr_free_mhi_id(void *mhi_cntrl_void)
+{
+ struct mhi_controller *mhi_cntrl = mhi_cntrl_void;
+ u32 id = mhi_cntrl->qrtr_endpoint_id;
+
+ if (id != 0)
+ qrtr_endpoint_free_data_id(id);
+ mhi_cntrl->qrtr_endpoint_id = 0;
+ mhi_cntrl->free_qrtr_endpoint_id = NULL;
+}
+
+int ath12k_mhi_set_qrtr_endpoint_id(struct ath12k_base *ab)
+{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+ struct ath12k_qmi *qmi = &ab->qmi;
+ int ret;
+
+ spin_lock(&ab_pci->mhi_ctrl->qrtr_endpoint_lock);
+
+ if (ab_pci->mhi_ctrl->qrtr_endpoint_id) {
+ qmi->handle.endpoint_id = ab_pci->mhi_ctrl->qrtr_endpoint_id;
+ } else {
+ ret = qrtr_endpoint_get_data_id(&qmi->handle.endpoint_id);
+ if (!ret) {
+ ab_pci->mhi_ctrl->qrtr_endpoint_id =
+ qmi->handle.endpoint_id;
+ ab_pci->mhi_ctrl->free_qrtr_endpoint_id =
+ ath12k_mhi_qrtr_free_mhi_id;
+ }
+ }
+
+ spin_unlock(&ab_pci->mhi_ctrl->qrtr_endpoint_lock);
+
+ ath12k_dbg(ab, ATH12K_DBG_PCI,
+ "queried mhi_ctrl QRTR endpoint ID: %u\n",
+ qmi->handle.endpoint_id);
+ if (ret) {
+ ath12k_warn(ab, "failed to query QRTR endpoint ID: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/ath12k/mhi.h b/drivers/net/wireless/ath/ath12k/mhi.h
index 3674326763858..3e692ce0b5108 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.h
+++ b/drivers/net/wireless/ath/ath12k/mhi.h
@@ -41,4 +41,7 @@ void ath12k_mhi_clear_vector(struct ath12k_base *ab);
void ath12k_mhi_suspend(struct ath12k_pci *ar_pci);
void ath12k_mhi_resume(struct ath12k_pci *ar_pci);
void ath12k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic);
+
+int ath12k_mhi_set_qrtr_endpoint_id(struct ath12k_base *ab);
+
#endif
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 6441927b53822..7b73672e5e8e4 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1508,6 +1508,7 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
.ce_irq_enable = ath12k_pci_hif_ce_irq_enable,
.ce_irq_disable = ath12k_pci_hif_ce_irq_disable,
.get_ce_msi_idx = ath12k_pci_get_ce_msi_idx,
+ .set_qrtr_endpoint_id = ath12k_mhi_set_qrtr_endpoint_id,
.panic_handler = ath12k_pci_panic_handler,
#ifdef CONFIG_ATH12K_COREDUMP
.coredump_download = ath12k_pci_coredump_download,
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 12/12] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_init_service
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (10 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 11/12] wifi: ath12k: implement QRTR endpoint ID fetching for PCI Juha-Matti Tilli
@ 2026-09-15 7:41 ` Juha-Matti Tilli
2026-09-18 6:26 ` [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-15 7:41 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Juha-Matti Tilli, Mihai Moldovan,
Denis Kenzior
From: Mihai Moldovan <ionic@ionic.de>
If possible, fetch the QRTR endpoint ID in ath12k_qmi_init_service, just
before calling qmi_handle_init, and make it available in the qmi_handle.
qmi_helpers will then automatically bind to this endpoint for us.
This finally allows using multiple ath12k-based cards with the same QRTR
node/port combination to work simultanenous (and, for that matter, at
all), including combinations of ath11k-based and ath12k-based cards.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Old-version-tested-by: Mihai Moldovan <ionic@ionic.de>
Old-version-tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@iki.fi>
---
drivers/net/wireless/ath/ath12k/qmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 50082505c882d..3611d0eff22b3 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -9,11 +9,13 @@
#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>
#include <linux/ioport.h>
#include <linux/of_reserved_mem.h>
+#include <net/sock.h>
#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
#define HOST_CSTATE_BIT 0x04
@@ -4075,6 +4077,13 @@ int ath12k_qmi_init_service(struct ath12k_base *ab)
ab->qmi.ab = ab;
ab->qmi.target_mem_mode = ab->target_mem_mode;
+
+ ret = ath12k_hif_set_qrtr_endpoint_id(ab);
+ if (ret) {
+ ath12k_warn(ab, "failed to set QRTR endpoint ID: %d\n", ret);
+ ath12k_warn(ab, "only one device per system will be supported\n");
+ }
+
ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
&ath12k_qmi_ops, ath12k_qmi_msg_handlers);
if (ret < 0) {
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system
2026-09-15 7:41 [PATCH v4 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (11 preceding siblings ...)
2026-09-15 7:41 ` [PATCH v4 12/12] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_init_service Juha-Matti Tilli
@ 2026-09-18 6:26 ` Juha-Matti Tilli
12 siblings, 0 replies; 14+ messages in thread
From: Juha-Matti Tilli @ 2026-09-18 6:26 UTC (permalink / raw)
To: ath11k, ath12k, mhi, linux-arm-msm, Manivannan Sadhasivam, Jeff Johnson
Cc: Jeff Hugo, Bjorn Andersson, Konrad Dybcio, Eric Dumazet,
Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S . Miller, Jakub Kicinski, Simon Horman, linux-kernel,
linux-wireless, netdev, Mihai Moldovan, Denis Kenzior
On Tue, Sep 15, 2026, at 10:41, Juha-Matti Tilli wrote:
> Hello,
>
> As you may well know, multiple identical ath11k and ath12k devices are
> not supported in a single Linux host because they use conflicting QRTR
> node IDs. Fortunately, Denis Kenzior created a patchset to support
> multiple QRTR endpoints with identical node IDs, and Mihai Moldovan
> refined it, after which I took over the patchset and refined it more.
>
> Mihai Moldovan also created a patchset for actually adding the support
> for this QRTR multi-endpoint feature to ath11k and ath12k drivers.
> Unfortunately, the code of Mihai was not merge-quality, since it leaked
> memory if you ran rmmod and modprobe inside a loop. Mihai mentioned this
> drawback, without providing an API for deleting endpoints or usage of
> such API in code that's responsible for freeing resources. Also Mihai's
> patchset had a race condition.
Hello,
Some positive news. There will be no next version, as Qualcomm is going
to provide a superior patchset that I tested. It's easier to backport,
cleaner design, fewer lines changed, has 1 author as opposed to 3, and
most importantly, it worked just fine on my 2x card setup.
Thus, I'm going to abandon this patchset.
BR, Juha-Matti
^ permalink raw reply [flat|nested] 14+ messages in thread