* [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system
@ 2026-09-08 9:31 Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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.
Since Mihai has been busy recently and the previous iteration of this
patchset is nearly 2 years old, I decided to "steal" the patchset from
him since he said he doesn't care who eventually implements this, as
long as it "just works". I am willing to give the responsibility of this
patchset back to Mihai if he so wants.
I reverted back to the approach where MHI knows the QRTR endpoint id.
This is somewhat ugly, but really the only way resources can be freed
(unless you resort to some kind of reference counting which would be
doable in kernel, or garbage-collection which wouldn't be doable). It
does create some extra memory usage in the mhi_controller data
structure, but a large fraction of the time, the data there is useful,
since a large fraction of MHI devices actually use QRTR. So this is not
as bad as making every PCI device know its QRTR endpoint ID (which a
vast majority don't have), even though MHI can be compiled in without
QRTR so we have to do the freeing via a function pointer.
I think the code is mostly merge-quality now. It does require the QRTR
multi-endpoint support, such as this v6 (I'm soon going to post v7 --
note that in v6 one intermediate commit doesn't compile on 32-bit
although the tip of the branch does compile):
https://msgid.link/all/20260901131934.225991-1-juha-matti.tilli@iki.fi
I tested it on dual ath11k setup, but more testers would be good. If you
only have a single ath11k card, your testing is useful too ("given
enough races, all race conditions are shallow").
Link to Github if you don't want to apply patches manually from mails:
https://github.com/jmtilli/linux/tree/athnext_multi_qrtr_v7_multi_ath11k_ath12k_v3
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218480
Mihai mentioned in Bugzilla in comment 21 that there was a hardware
crash he couldn't reproduce and he believed it's a race condition. I
could reproduce it in older Mihai's patchset version by treating -EEXIST
as an error, which indeed points to it being a race condition. I believe
the source was qrtr_endpoint_id_get_or_assign that tried to get an ID
and then assign an ID if it couldn't get one, while not holding a
spinlock. In my newest patchset, my belief is this race condition is
gone (the entire offending function is gone), but any kind of review
about thread-safety of my code would be good input.
Original description:
ath11k and ath12k suffer from a long-standing issue that is partly
caused by the QRTR implementation, which only supports one device per
node/port combination and partly caused by the fact that the
QMI instance ID of the devices are statically set to 1.
P Praneesh <quic_ppranees at quicinc.com> submitted a patch[0] that fixes
this issue generating a unique QMI instance ID based on the PCI bus data
for the device and passing that information to the QMI subsystem and the
device's firmware via a special PCI register.
However, it quickly turned out that this approach works for the hardware
he tested, but fails for other ath11k-based devices, including the
popular QCA6930, since its firmware just ignores the special register
being used.
Since we need QMI (and, for matter, QRTR) to work for the initial
firmware upload, this approach will not work generically.
Fortunately, Denis Kenzior <denkenz at gmail.com> cooked up a patch set for
QRTR[1] that introduces the concept of endpoint IDs, which are
dynamically allocated and can be used to distinguish different devices
even though they use the same node/port combination. Using this patch
set, endpoint IDs can be reported as part of auxiliary data in the QRTR
socket and bound to for client sockets, which will automatically filter
messages from other endpoints and also make sure that client messages
are routed to the correct endpoint.
This looked promising, and with that functionality, the only challenge
is to find out the correct endpoint IDs and bind to them in drivers to
finally support multiple devices in a generic way.
This patch set implements exactly that, and it WORKSFORME, but
unfortunately it turns out that "the only challenge" is very difficult
to overcome due to the socket-based architecture.
ath1{1,2}k and QRTR are at opposite sides of the socket, with QRTR
assigning endpoint IDs and ath1{1,2}k needing a way to fetch and operate
on them.
The endpoint reporting feature in QRTR is not helpful in this case,
because drivers do not generally know which endpoint belongs to the
device they currently handle (i.e., there is no central registry) and
even if we were to snoop on the socket and take the first endpoint ID we
are unaware of, this might not be the correct one, because it might be
in use by a different driver for instance, or correspond to a different
device.
The first iteration of this patch set[2] extended struct mhi_device with
a qrtr_endpoint_id field that was initialized to zero and populated by
the QRTR MHI driver as soon as it was loaded. Drivers could then query
this field through an mhi_device->mhi_cntrl->mhi_device chain (if they
also use the MHI bus, of course). This, however, was an incredibly ugly
hack because QRTR data should not be part of MHI device structures in
the first place, timing is critical (drivers querying the endpoint ID
must do so after the QRTR MHI module initialized, which is typically
only the case after QRTR socket was created) and it was not possible to
query or pre-assign an endpoint ID before creating a socket and directly
bind to it (which might lead to races such as seeing messages over the
socket that are not meant for the endpoint ID drivers are actually
interested in).
Since that was not elegant at all, and due to the other mentioned
issues, this iteration uses a different approach: endpoint IDs can now
be associated with (private) backend endpoint-specific data, which
allows us to identify which endpoint ID is being used with what backend,
and additionally new API is introduced so that other parts in the kernel
can either get an endpoint ID for given endpoint-specific data or even
attach endpoint-specific data to a new endpoint ID generated by the QRTR
driver. The QRTR system will try to use endpoint-specific data if
possible, but falls back to generating endpoint IDs without
endpoint-specific data (as in, NULL pointer) if that did not work.
Crucially, the endpoint-specific data pointer is used as an opaque void
pointer and at most compared with data stored in the endpoints XArray.
In the QRTR MHI backend, we use the MHI controller's structure pointer
as endpoint-specific data, and since the MHI controller is also the bus
master and responsible for the physical link, clients (drivers) can
pre-register an endpoint ID for their MHI controllers and directly tell
QMI to bind to the endpoint ID at socket creation time.
The QRTR SMD backend uses its rpmsg_device pointer and the TUN backend
uses the inode pointer as their respective endpoint-specific data
pointers.
This approach is cleaner and works better, because it is not prone to
races (although it requires coordination between QRTR backends and
clients/drivers because both must use the same endpoint-specific data
for the scheme to work).
There are, however, also issues with this approach:
- Any kernel part can generate an unlimited number of endpoint IDs
with arbitrary pointers. The amount of endpoint IDs that can be
tracked is limited, though, so there is potential for exhaustion of ID
space.
- Since previously endpoint IDs were only generated by the QRTR
subsystem, there was no need to use any kind of life cycle management
for the endpoint IDs: they were created at node creation time and
also deleted at node deletion time. Since other subsystems can now
create endpoint IDs, it would probably be good to have a way to
reclaim created but unused endpoint IDs. No such implementation is
provided here.
- Multiple PCI/MHI devices will work, but no AHB + PCI/MHI interaction
has been tested. Since PCI/MHI devices bind to their endpoint ID,
these will likely work, but the AHB devices might still see messages
for all endpoints and fail to work correctly. AHB devices seem to be
using QMI and thus also QRTR, but without a specific QRTR backend
driver (going through REMOTEPROC instead?), so this approach might
not be viable for AHB devices.
I am much more comfortable with this patch set, even if it has some
rough edges and might not fix the situation for AHB devices.
[0] https://patch.msgid.link/20230111170033.32454-1-kvalo@kernel.org
[1] https://patch.msgid.link/20241018181842.1368394-1-denkenz@gmail.com
[2] https://msgid.link/cover.1730790058.git.ionic@ionic.de
v3:
- rebase against current ath-next
- solved a major memory leak
- replaced O(N) algorithm by O(1) where N is the leaked memory
- solved all known race condition issues
- Link to v2: https://msgid.link/cover.1732506261.git.ionic@ionic.de
v2: code and metadata cleanup (checkpatch.pl), no functional changes
BR, Juha-Matti
Juha-Matti Tilli (5):
net: qrtr: support getting new endpoint ids externally
bus: mhi: allow mhi to know about its qrtr endpoint id and free it
net: qrtr: mhi: register new qrtr endpoint id for mhi
wifi: ath11k: implement QRTR endpoint ID fetching for PCI
wifi: ath12k: implement QRTR endpoint ID fetching for PCI
Mihai Moldovan (7):
soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in
qmi_sock_create
wifi: ath11k: add QRTR endpoint ID hif feature
wifi: ath11k: stub QRTR endpoint ID fetching
wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_init_service
wifi: ath12k: add QRTR endpoint ID hif feature
wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_init_service
MAINTAINERS | 1 +
drivers/bus/mhi/host/init.c | 8 +++++
drivers/net/wireless/ath/ath11k/ahb.c | 7 ++++
drivers/net/wireless/ath/ath11k/hif.h | 9 ++++++
drivers/net/wireless/ath/ath11k/mhi.c | 46 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/mhi.h | 1 +
drivers/net/wireless/ath/ath11k/pci.c | 1 +
drivers/net/wireless/ath/ath11k/qmi.c | 8 +++++
drivers/net/wireless/ath/ath12k/hif.h | 10 ++++++
drivers/net/wireless/ath/ath12k/mhi.c | 46 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/mhi.h | 3 ++
drivers/net/wireless/ath/ath12k/pci.c | 1 +
drivers/net/wireless/ath/ath12k/qmi.c | 9 ++++++
drivers/soc/qcom/qmi_interface.c | 28 ++++++++++++++++
include/linux/mhi.h | 5 +++
include/linux/soc/qcom/qmi.h | 3 ++
include/net/qrtr.h | 10 ++++++
net/qrtr/af_qrtr.c | 42 ++++++++++++++++++++----
net/qrtr/mhi.c | 31 ++++++++++++++++++
net/qrtr/qrtr.h | 5 +++
20 files changed, 268 insertions(+), 6 deletions(-)
create mode 100644 include/net/qrtr.h
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 01/12] net: qrtr: support getting new endpoint ids externally
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it Juha-Matti Tilli
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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 | 5 +++++
4 files changed, 52 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..86c9b4e724d7e 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);
@@ -47,4 +49,7 @@ void qrtr_ns_remove(void);
int qrtr_msg_get_endpoint(struct msghdr *msg, u32 *out_endpoint_id);
void qrtr_sock_set_report_endpoint(struct sock *sk);
+int qrtr_endpoint_get_data_id(u32 *endpoint_id);
+void qrtr_endpoint_free_data_id(u32 endpoint_id);
+
#endif
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi Juha-Matti Tilli
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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] 12+ messages in thread
* [PATCH v3 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Juha-Matti Tilli
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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 | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 630ce0da060e5..60d85f126bca5 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -116,6 +116,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 +141,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 +178,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] 12+ messages in thread
* [PATCH v3 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (2 preceding siblings ...)
2026-09-08 9:31 ` [PATCH v3 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Juha-Matti Tilli
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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] 12+ messages in thread
* [PATCH v3 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (3 preceding siblings ...)
2026-09-08 9:31 ` [PATCH v3 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 06/12] wifi: ath11k: add QRTR endpoint ID hif feature Juha-Matti Tilli
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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] 12+ messages in thread
* [PATCH v3 06/12] wifi: ath11k: add QRTR endpoint ID hif feature
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (4 preceding siblings ...)
2026-09-08 9:31 ` [PATCH v3 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 07/12] wifi: ath11k: stub QRTR endpoint ID fetching Juha-Matti Tilli
` (2 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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] 12+ messages in thread
* [PATCH v3 07/12] wifi: ath11k: stub QRTR endpoint ID fetching
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (5 preceding siblings ...)
2026-09-08 9:31 ` [PATCH v3 06/12] wifi: ath11k: add QRTR endpoint ID hif feature Juha-Matti Tilli
@ 2026-09-08 9:31 ` Juha-Matti Tilli
2026-09-08 9:44 ` [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-11 19:15 ` Jeff Johnson
8 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:31 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
Juha-Matti Tilli, linux-wireless, linux-arm-msm, netdev,
linux-kernel
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] 12+ messages in thread
* Re: [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (6 preceding siblings ...)
2026-09-08 9:31 ` [PATCH v3 07/12] wifi: ath11k: stub QRTR endpoint ID fetching Juha-Matti Tilli
@ 2026-09-08 9:44 ` Juha-Matti Tilli
2026-09-11 19:19 ` Jeff Johnson
2026-09-11 19:15 ` Jeff Johnson
8 siblings, 1 reply; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-08 9:44 UTC (permalink / raw)
To: ath11k, ath12k, Kalle Valo, Jeff Johnson, Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
linux-wireless, linux-arm-msm, netdev, linux-kernel
On Tue, Sep 8, 2026, at 12:31, Juha-Matti Tilli wrote:
> 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.
Hello,
I am incredibly sorry by messing up the threading. git-send-email said:
4.7.1 Error: too many recipients from 83.150.90.33
...and failed at the patch id 8/12.
So I thought retrying from where it failed would be safe. But that
broke the threading.
The next time, I'll increase the waiting time between subsequent mails.
Links to mails missed from the thread:
https://lore.kernel.org/all/20260908093437.2493698-1-juha-matti.tilli@iki.fi/
https://lore.kernel.org/all/20260908093437.2493698-2-juha-matti.tilli@iki.fi/
https://lore.kernel.org/all/20260908093437.2493698-3-juha-matti.tilli@iki.fi/
https://lore.kernel.org/all/20260908093437.2493698-4-juha-matti.tilli@iki.fi/
https://lore.kernel.org/all/20260908093437.2493698-5-juha-matti.tilli@iki.fi/
BR, Juha-Matti
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
` (7 preceding siblings ...)
2026-09-08 9:44 ` [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
@ 2026-09-11 19:15 ` Jeff Johnson
2026-09-12 7:58 ` Juha-Matti Tilli
8 siblings, 1 reply; 12+ messages in thread
From: Jeff Johnson @ 2026-09-11 19:15 UTC (permalink / raw)
To: Juha-Matti Tilli, ath11k, ath12k, Kalle Valo, Jeff Johnson,
Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
linux-wireless, linux-arm-msm, netdev, linux-kernel
On 9/8/2026 2:31 AM, 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.
>
> Since Mihai has been busy recently and the previous iteration of this
> patchset is nearly 2 years old, I decided to "steal" the patchset from
> him since he said he doesn't care who eventually implements this, as
> long as it "just works". I am willing to give the responsibility of this
> patchset back to Mihai if he so wants.
>
> I reverted back to the approach where MHI knows the QRTR endpoint id.
> This is somewhat ugly, but really the only way resources can be freed
> (unless you resort to some kind of reference counting which would be
> doable in kernel, or garbage-collection which wouldn't be doable). It
> does create some extra memory usage in the mhi_controller data
> structure, but a large fraction of the time, the data there is useful,
> since a large fraction of MHI devices actually use QRTR. So this is not
> as bad as making every PCI device know its QRTR endpoint ID (which a
> vast majority don't have), even though MHI can be compiled in without
> QRTR so we have to do the freeing via a function pointer.
>
> I think the code is mostly merge-quality now. It does require the QRTR
> multi-endpoint support, such as this v6 (I'm soon going to post v7 --
> note that in v6 one intermediate commit doesn't compile on 32-bit
> although the tip of the branch does compile):
>
> https://msgid.link/all/20260901131934.225991-1-juha-matti.tilli@iki.fi
>
> I tested it on dual ath11k setup, but more testers would be good. If you
> only have a single ath11k card, your testing is useful too ("given
> enough races, all race conditions are shallow").
>
> Link to Github if you don't want to apply patches manually from mails:
>
> https://github.com/jmtilli/linux/tree/athnext_multi_qrtr_v7_multi_ath11k_ath12k_v3
>
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218480
>
> Mihai mentioned in Bugzilla in comment 21 that there was a hardware
> crash he couldn't reproduce and he believed it's a race condition. I
> could reproduce it in older Mihai's patchset version by treating -EEXIST
> as an error, which indeed points to it being a race condition. I believe
> the source was qrtr_endpoint_id_get_or_assign that tried to get an ID
> and then assign an ID if it couldn't get one, while not holding a
> spinlock. In my newest patchset, my belief is this race condition is
> gone (the entire offending function is gone), but any kind of review
> about thread-safety of my code would be good input.
>
> Original description:
>
> ath11k and ath12k suffer from a long-standing issue that is partly
> caused by the QRTR implementation, which only supports one device per
> node/port combination and partly caused by the fact that the
> QMI instance ID of the devices are statically set to 1.
>
> P Praneesh <quic_ppranees at quicinc.com> submitted a patch[0] that fixes
> this issue generating a unique QMI instance ID based on the PCI bus data
> for the device and passing that information to the QMI subsystem and the
> device's firmware via a special PCI register.
>
> However, it quickly turned out that this approach works for the hardware
> he tested, but fails for other ath11k-based devices, including the
> popular QCA6930, since its firmware just ignores the special register
> being used.
>
> Since we need QMI (and, for matter, QRTR) to work for the initial
> firmware upload, this approach will not work generically.
>
> Fortunately, Denis Kenzior <denkenz at gmail.com> cooked up a patch set for
> QRTR[1] that introduces the concept of endpoint IDs, which are
> dynamically allocated and can be used to distinguish different devices
> even though they use the same node/port combination. Using this patch
> set, endpoint IDs can be reported as part of auxiliary data in the QRTR
> socket and bound to for client sockets, which will automatically filter
> messages from other endpoints and also make sure that client messages
> are routed to the correct endpoint.
>
> This looked promising, and with that functionality, the only challenge
> is to find out the correct endpoint IDs and bind to them in drivers to
> finally support multiple devices in a generic way.
>
> This patch set implements exactly that, and it WORKSFORME, but
> unfortunately it turns out that "the only challenge" is very difficult
> to overcome due to the socket-based architecture.
>
> ath1{1,2}k and QRTR are at opposite sides of the socket, with QRTR
> assigning endpoint IDs and ath1{1,2}k needing a way to fetch and operate
> on them.
>
> The endpoint reporting feature in QRTR is not helpful in this case,
> because drivers do not generally know which endpoint belongs to the
> device they currently handle (i.e., there is no central registry) and
> even if we were to snoop on the socket and take the first endpoint ID we
> are unaware of, this might not be the correct one, because it might be
> in use by a different driver for instance, or correspond to a different
> device.
>
> The first iteration of this patch set[2] extended struct mhi_device with
> a qrtr_endpoint_id field that was initialized to zero and populated by
> the QRTR MHI driver as soon as it was loaded. Drivers could then query
> this field through an mhi_device->mhi_cntrl->mhi_device chain (if they
> also use the MHI bus, of course). This, however, was an incredibly ugly
> hack because QRTR data should not be part of MHI device structures in
> the first place, timing is critical (drivers querying the endpoint ID
> must do so after the QRTR MHI module initialized, which is typically
> only the case after QRTR socket was created) and it was not possible to
> query or pre-assign an endpoint ID before creating a socket and directly
> bind to it (which might lead to races such as seeing messages over the
> socket that are not meant for the endpoint ID drivers are actually
> interested in).
>
> Since that was not elegant at all, and due to the other mentioned
> issues, this iteration uses a different approach: endpoint IDs can now
> be associated with (private) backend endpoint-specific data, which
> allows us to identify which endpoint ID is being used with what backend,
> and additionally new API is introduced so that other parts in the kernel
> can either get an endpoint ID for given endpoint-specific data or even
> attach endpoint-specific data to a new endpoint ID generated by the QRTR
> driver. The QRTR system will try to use endpoint-specific data if
> possible, but falls back to generating endpoint IDs without
> endpoint-specific data (as in, NULL pointer) if that did not work.
>
> Crucially, the endpoint-specific data pointer is used as an opaque void
> pointer and at most compared with data stored in the endpoints XArray.
>
> In the QRTR MHI backend, we use the MHI controller's structure pointer
> as endpoint-specific data, and since the MHI controller is also the bus
> master and responsible for the physical link, clients (drivers) can
> pre-register an endpoint ID for their MHI controllers and directly tell
> QMI to bind to the endpoint ID at socket creation time.
>
> The QRTR SMD backend uses its rpmsg_device pointer and the TUN backend
> uses the inode pointer as their respective endpoint-specific data
> pointers.
>
> This approach is cleaner and works better, because it is not prone to
> races (although it requires coordination between QRTR backends and
> clients/drivers because both must use the same endpoint-specific data
> for the scheme to work).
>
> There are, however, also issues with this approach:
> - Any kernel part can generate an unlimited number of endpoint IDs
> with arbitrary pointers. The amount of endpoint IDs that can be
> tracked is limited, though, so there is potential for exhaustion of ID
> space.
> - Since previously endpoint IDs were only generated by the QRTR
> subsystem, there was no need to use any kind of life cycle management
> for the endpoint IDs: they were created at node creation time and
> also deleted at node deletion time. Since other subsystems can now
> create endpoint IDs, it would probably be good to have a way to
> reclaim created but unused endpoint IDs. No such implementation is
> provided here.
> - Multiple PCI/MHI devices will work, but no AHB + PCI/MHI interaction
> has been tested. Since PCI/MHI devices bind to their endpoint ID,
> these will likely work, but the AHB devices might still see messages
> for all endpoints and fail to work correctly. AHB devices seem to be
> using QMI and thus also QRTR, but without a specific QRTR backend
> driver (going through REMOTEPROC instead?), so this approach might
> not be viable for AHB devices.
>
> I am much more comfortable with this patch set, even if it has some
> rough edges and might not fix the situation for AHB devices.
>
> [0] https://patch.msgid.link/20230111170033.32454-1-kvalo@kernel.org
> [1] https://patch.msgid.link/20241018181842.1368394-1-denkenz@gmail.com
> [2] https://msgid.link/cover.1730790058.git.ionic@ionic.de
>
> v3:
> - rebase against current ath-next
> - solved a major memory leak
> - replaced O(N) algorithm by O(1) where N is the leaked memory
> - solved all known race condition issues
> - Link to v2: https://msgid.link/cover.1732506261.git.ionic@ionic.de
>
> v2: code and metadata cleanup (checkpatch.pl), no functional changes
>
> BR, Juha-Matti
>
> Juha-Matti Tilli (5):
> net: qrtr: support getting new endpoint ids externally
> bus: mhi: allow mhi to know about its qrtr endpoint id and free it
> net: qrtr: mhi: register new qrtr endpoint id for mhi
> wifi: ath11k: implement QRTR endpoint ID fetching for PCI
> wifi: ath12k: implement QRTR endpoint ID fetching for PCI
>
> Mihai Moldovan (7):
> soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
> soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in
> qmi_sock_create
> wifi: ath11k: add QRTR endpoint ID hif feature
> wifi: ath11k: stub QRTR endpoint ID fetching
> wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_init_service
> wifi: ath12k: add QRTR endpoint ID hif feature
> wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_init_service
>
> MAINTAINERS | 1 +
> drivers/bus/mhi/host/init.c | 8 +++++
> drivers/net/wireless/ath/ath11k/ahb.c | 7 ++++
> drivers/net/wireless/ath/ath11k/hif.h | 9 ++++++
> drivers/net/wireless/ath/ath11k/mhi.c | 46 +++++++++++++++++++++++++++
> drivers/net/wireless/ath/ath11k/mhi.h | 1 +
> drivers/net/wireless/ath/ath11k/pci.c | 1 +
> drivers/net/wireless/ath/ath11k/qmi.c | 8 +++++
> drivers/net/wireless/ath/ath12k/hif.h | 10 ++++++
> drivers/net/wireless/ath/ath12k/mhi.c | 46 +++++++++++++++++++++++++++
> drivers/net/wireless/ath/ath12k/mhi.h | 3 ++
> drivers/net/wireless/ath/ath12k/pci.c | 1 +
> drivers/net/wireless/ath/ath12k/qmi.c | 9 ++++++
> drivers/soc/qcom/qmi_interface.c | 28 ++++++++++++++++
> include/linux/mhi.h | 5 +++
> include/linux/soc/qcom/qmi.h | 3 ++
> include/net/qrtr.h | 10 ++++++
> net/qrtr/af_qrtr.c | 42 ++++++++++++++++++++----
> net/qrtr/mhi.c | 31 ++++++++++++++++++
> net/qrtr/qrtr.h | 5 +++
> 20 files changed, 268 insertions(+), 6 deletions(-)
> create mode 100644 include/net/qrtr.h
>
How are you populating the list of recipients for your e-mail?
You are including folks no longer involved in kernel development, but more
importantly, you are using an obsolete e-mail address for the MHI maintainer
(Mani). I've replaced his address in my reply.
Please make sure to use scripts/get_maintainer.pl to get an accurate list of
recipients.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system
2026-09-08 9:44 ` [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
@ 2026-09-11 19:19 ` Jeff Johnson
0 siblings, 0 replies; 12+ messages in thread
From: Jeff Johnson @ 2026-09-11 19:19 UTC (permalink / raw)
To: Juha-Matti Tilli, ath11k, ath12k, Kalle Valo, Jeff Johnson,
Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
linux-wireless, linux-arm-msm, netdev, linux-kernel
On 9/8/2026 2:44 AM, Juha-Matti Tilli wrote:
> On Tue, Sep 8, 2026, at 12:31, Juha-Matti Tilli wrote:
>> 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.
>
> Hello,
>
> I am incredibly sorry by messing up the threading. git-send-email said:
>
> 4.7.1 Error: too many recipients from 83.150.90.33
>
> ...and failed at the patch id 8/12.
>
> So I thought retrying from where it failed would be safe. But that
> broke the threading.
>
> The next time, I'll increase the waiting time between subsequent mails.
>
> Links to mails missed from the thread:
>
> https://lore.kernel.org/all/20260908093437.2493698-1-juha-matti.tilli@iki.fi/
> https://lore.kernel.org/all/20260908093437.2493698-2-juha-matti.tilli@iki.fi/
> https://lore.kernel.org/all/20260908093437.2493698-3-juha-matti.tilli@iki.fi/
> https://lore.kernel.org/all/20260908093437.2493698-4-juha-matti.tilli@iki.fi/
> https://lore.kernel.org/all/20260908093437.2493698-5-juha-matti.tilli@iki.fi/
>
> BR, Juha-Matti
Unfortunately this prevents many automations from processing your series,
including mine which utilizes 'b4'
* b4 am -3 -S 20260908093145.2492666-1-juha-matti.tilli@iki.fi
Grabbing thread from
lore.kernel.org/all/20260908093145.2492666-1-juha-matti.tilli@iki.fi/t.mbox.gz
Analyzing 10 messages in the thread
Looking for additional code-review trailers on lore.kernel.org
Analyzing 44 code-review messages
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v3 1/12] net: qrtr: support getting new endpoint ids externally
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 2/12] bus: mhi: allow mhi to know about its qrtr endpoint id and
free it
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 3/12] net: qrtr: mhi: register new qrtr endpoint id for mhi
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 4/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 5/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint
ID in qmi_sock_create
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 6/12] wifi: ath11k: add QRTR endpoint ID hif feature
✓ Signed: DKIM/iki.fi
✓ [PATCH v3 7/12] wifi: ath11k: stub QRTR endpoint ID fetching
✓ Signed: DKIM/iki.fi
ERROR: missing [8/12]!
ERROR: missing [9/12]!
ERROR: missing [10/12]!
ERROR: missing [11/12]!
ERROR: missing [12/12]!
---
Total patches: 7
WARNING: cannot prepare 3-way (series incomplete)
---
WARNING: Thread incomplete!
So I cannot evaluate your series.
/jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system
2026-09-11 19:15 ` Jeff Johnson
@ 2026-09-12 7:58 ` Juha-Matti Tilli
0 siblings, 0 replies; 12+ messages in thread
From: Juha-Matti Tilli @ 2026-09-12 7:58 UTC (permalink / raw)
To: Jeff Johnson, ath11k, ath12k, Kalle Valo, Jeff Johnson,
Manivannan Sadhasivam
Cc: Bjorn Andersson, Konrad Dybcio, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Mihai Moldovan,
linux-wireless, linux-arm-msm, netdev, linux-kernel
On Fri, Sep 11, 2026, at 22:15, Jeff Johnson wrote:
> On 9/8/2026 2:31 AM, 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.
> >
> > [snip]
>
> How are you populating the list of recipients for your e-mail?
>
> You are including folks no longer involved in kernel development, but more
> importantly, you are using an obsolete e-mail address for the MHI maintainer
> (Mani). I've replaced his address in my reply.
>
> Please make sure to use scripts/get_maintainer.pl to get an accurate list of
> recipients.
Hello,
I will post a new patchset without messed-up threading later. The e-mail
list was populated from Mihai's patchset from 2024, and I indeed noticed
that Mani's e-mail address was old, which would have been fixed in the
next version anyway. I will also do an estimate of how recently the
recipients have been doing kernel development, based on the Linux kernel
commit history, and what kind of development they have done (in what
subsystems), and remove addresses that haven't been part of relevant
kernel subsystem development recently (except maybe Denis and Mihai
could be listed as the patches were originally theirs). Of course,
get_maintainer.pl result will be included.
I will also join the modified recipient lists of Denis's patchset and
Mihai's patchset, as they are related to each other, and Mihai's patches
require Denis's patches.
I hope that with these modifications, the patchsets could be taken into
consideration and review.
At least my git send-email settings and changed SMTP server settings
should prevent the previous mistake in the next series, and if not, now
I know --in-reply-to and --no-thread. Also shorter CC list will make SMTP
server limits less likely.
BR, Juha-Matti
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-12 7:59 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-08 9:31 [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 01/12] net: qrtr: support getting new endpoint ids externally Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 02/12] bus: mhi: allow mhi to know about its qrtr endpoint id and free it Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 03/12] net: qrtr: mhi: register new qrtr endpoint id for mhi Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 04/12] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 05/12] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 06/12] wifi: ath11k: add QRTR endpoint ID hif feature Juha-Matti Tilli
2026-09-08 9:31 ` [PATCH v3 07/12] wifi: ath11k: stub QRTR endpoint ID fetching Juha-Matti Tilli
2026-09-08 9:44 ` [PATCH v3 00/12] ath1{1,2}k: support multiple PCI devices in one system Juha-Matti Tilli
2026-09-11 19:19 ` Jeff Johnson
2026-09-11 19:15 ` Jeff Johnson
2026-09-12 7:58 ` 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®