* [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system
@ 2024-11-05 7:06 Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 01/11] bus: mhi: host: add QRTR endpoint ID to mhi_device Mihai Moldovan
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
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@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@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 auxillary data in the QRTR
socket and bound to for client sockets, which will automatically filter
mssages from other endpoints and also make sure that messages clients
send 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 only way I found to communicate endpoint IDs between QRTR and the
drivers is to use MHI as the common layer utilized by both systems.
Since QRTR is using MHI as one underlying bus system, we can extend
struct mhi_device with a qrtr_endpoint_id field, initialize this to zero
(which is an invalid QRTR endpoint ID), have QRTR go through an
mhi_dev->mhi_cntrl->mhi_dev chain to select the MHI controller of the
device it is currently initializing for, save the newly assigned
endpoint ID to the MHI controller's mhi_device structure and do the same
for our device drivers ath1{1,2}k for fetching the endpoint ID QRTR
associated with the MHI controller.
This is not only incredibly ugly, because it essentially is a weird
pseudo-IPC implementation using the MHI bus device data space as a
communication platform, it comes short because of multiple issues:
- The timing is critical. Since QRTR assigns endpoint IDs, clients can
not query them before QRTR has been initialized for a specific
device.
- We would actually like to know the QRTR endpoint ID beforehand and
bind to it BEFORE creating the QRTR/QMI socket, to not receive
messages from other endpoints we are not interested in or send
messages to wrong endpoints! But since there is no central registry
for endpoint IDs, we cannot blindly assign just any ID from clients,
and even if we could, the current architecture relies on QRTR doing
it.
- We should not use struct mhi_device to handle QRTR data. Obviously.
- We are assuming that each device we are handling has a unique MHI
controller associated with it, and also only one. This might not at
all be true...
Personally, I am not comfortable with the patch set in its current form.
While it does fix the initial problem, it is not elegant in any way, and
I am aware of other issues, like not being able to unload the qrtr
module once it has been used (refcount only drops down to 2, even though
there is nothing still using it). I have not debugged this yet, and this
issue might have been introduced by Denis's changes, but I would not
find it hard to believe that my changes introduced a subtle refcount
increase that I am not aware of either.
Even with these issues, this patch set might be useful in the future and
it proves that multiple devices can work in one machine.
[0] https://patch.msgid.link/20230111170033.32454-1-kvalo@kernel.org
[1] https://patch.msgid.link/20241018181842.1368394-1-denkenz@gmail.com
Mihai Moldovan (11):
bus: mhi: host: add QRTR endpoint ID to mhi_device
net: qrtr: mhi: pass endpoint ID to MHI device on init
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 for AHB
wifi: ath11k: implement QRTR endpoint ID fetching for PCI
wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_ops_new_server
wifi: ath12k: add QRTR endpoint ID hif feature
wifi: ath12k: implement QRTR endpoint ID fetching for PCI
wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server
drivers/bus/mhi/host/init.c | 1 +
drivers/bus/mhi/host/main.c | 64 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/ahb.c | 7 +++
drivers/net/wireless/ath/ath11k/hif.h | 8 ++++
drivers/net/wireless/ath/ath11k/mhi.c | 17 +++++++
drivers/net/wireless/ath/ath11k/mhi.h | 1 +
drivers/net/wireless/ath/ath11k/pci.c | 1 +
drivers/net/wireless/ath/ath11k/qmi.c | 50 +++++++++++++++++++++
drivers/net/wireless/ath/ath11k/qmi.h | 1 +
drivers/net/wireless/ath/ath12k/hif.h | 9 ++++
drivers/net/wireless/ath/ath12k/mhi.c | 17 +++++++
drivers/net/wireless/ath/ath12k/mhi.h | 2 +
drivers/net/wireless/ath/ath12k/pci.c | 1 +
drivers/net/wireless/ath/ath12k/qmi.c | 49 ++++++++++++++++++++
drivers/net/wireless/ath/ath12k/qmi.h | 1 +
drivers/soc/qcom/qmi_interface.c | 28 ++++++++++++
include/linux/mhi.h | 20 +++++++++
include/linux/soc/qcom/qmi.h | 3 ++
net/qrtr/mhi.c | 4 ++
19 files changed, 284 insertions(+)
--
2.45.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 01/11] bus: mhi: host: add QRTR endpoint ID to mhi_device
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 02/11] net: qrtr: mhi: pass endpoint ID to MHI device on init Mihai Moldovan
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
We need a way to communicate between QMI clients (e.g., ath11k and
ath12k) and QRTR internals.
Unfortunately, clients are on the "wrong" side of a socket and cannot
really extract QRTR data easily, and, to make matters worse, not at all
until the socket is properly connected. Further complicating the matter
is that multiple clients can be connected to the same server socket, so
even if we would add additional control message support for fetching the
data we are interested in, there is no way for the QRTR system to know
what endpoint ID the client is actually interested in.
However, MHI and its data is a central place that essentially connects
both sides. Both the QRTR subsystem and QMI clients have access to MHI
devices, so we will employ a really ugly IPC scheme in which QRTR will
write the endpoint ID associated with an MHI (controller) device to
mhi_dev->mhi_cntrl->mhi_dev->qrtr_endpoint_id once the endpoint ID
initialization has happened for a specific MHI device, and clients can
then fetch this data at a later time by also going through
mhi_dev->mhi_cntrl->mhi_dev->qrtr_endpoint_id.
This is incredibly ugly. It also certainly is not the correct way to do
this. It is also racy, because clients need to fetch the QRTR endpoint
ID after QRTR has actually initialized it, or they will just see a value
of zero (which is an illegal endpoint ID, so at least we have some sort
of guard for this uglyness).
I just was not able to come up with any other idea that would actually
work.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Depends-on: 25a7151cdc98 ("net: qrtr: ns: support multiple endpoints")
Link: https://patch.msgid.link/20241018181842.1368394-1-denkenz@gmail.com
---
drivers/bus/mhi/host/init.c | 1 +
drivers/bus/mhi/host/main.c | 64 +++++++++++++++++++++++++++++++++++++
include/linux/mhi.h | 20 ++++++++++++
3 files changed, 85 insertions(+)
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index a9b1f8beee7b..b35e722b0802 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -1262,6 +1262,7 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl)
mhi_dev->mhi_cntrl = mhi_cntrl;
mhi_dev->dev_wake = 0;
+ mhi_dev->qrtr_endpoint_id = 0;
return mhi_dev;
}
diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c
index 4de75674f193..c774e941fbb7 100644
--- a/drivers/bus/mhi/host/main.c
+++ b/drivers/bus/mhi/host/main.c
@@ -1707,3 +1707,67 @@ int mhi_get_channel_doorbell_offset(struct mhi_controller *mhi_cntrl, u32 *chdb_
return 0;
}
EXPORT_SYMBOL_GPL(mhi_get_channel_doorbell_offset);
+
+
+int mhi_set_qrtr_endpoint_id(struct mhi_device *mhi_dev, u32 qrtr_endpoint_id)
+{
+ struct mhi_controller *mhi_cntrl = NULL;
+ struct mhi_device *mhi_cntrl_dev = NULL;
+ struct device *dev = NULL;
+
+ if (!mhi_dev)
+ return -ENODEV;
+
+ mhi_cntrl = mhi_dev->mhi_cntrl;
+
+ if (!mhi_cntrl)
+ return -ENODEV;
+
+ mhi_cntrl_dev = mhi_cntrl->mhi_dev;
+
+ if (!mhi_cntrl_dev)
+ return -ENODEV;
+
+ dev = &mhi_cntrl_dev->dev;
+
+ if (dev)
+ dev_dbg(dev, "setting qrtr_endpoint_id = %u for mhi_dev->mhi_cntrl->mhi_dev = %p", qrtr_endpoint_id, mhi_cntrl_dev);
+
+ mhi_cntrl_dev->qrtr_endpoint_id = qrtr_endpoint_id;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mhi_set_qrtr_endpoint_id);
+
+int mhi_get_qrtr_endpoint_id(struct mhi_device *mhi_dev, u32 *qrtr_endpoint_id)
+{
+ struct mhi_controller *mhi_cntrl = NULL;
+ struct mhi_device *mhi_cntrl_dev = NULL;
+ struct device *dev = NULL;
+
+ if (!qrtr_endpoint_id)
+ return -EINVAL;
+
+ if (!mhi_dev)
+ return -ENODEV;
+
+ mhi_cntrl = mhi_dev->mhi_cntrl;
+
+ if (!mhi_cntrl)
+ return -ENODEV;
+
+ mhi_cntrl_dev = mhi_cntrl->mhi_dev;
+
+ if (!mhi_cntrl_dev)
+ return -ENODEV;
+
+ WRITE_ONCE(*qrtr_endpoint_id, mhi_cntrl_dev->qrtr_endpoint_id);
+
+ dev = &mhi_cntrl_dev->dev;
+
+ if (dev)
+ dev_dbg(dev, "queried qrtr_endpoint_id = %u for mhi_dev->mhi_ctrl->mhi_dev = %p", *qrtr_endpoint_id, mhi_cntrl_dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mhi_get_qrtr_endpoint_id);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 059dc94d20bb..2262be3ee5b1 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -462,6 +462,7 @@ struct mhi_controller {
* @ul_chan_id: MHI channel id for UL transfer
* @dl_chan_id: MHI channel id for DL transfer
* @dev_wake: Device wakeup counter
+ * @qrtr_endpoint_id: endpoint ID associated with QRTR
*/
struct mhi_device {
const struct mhi_device_id *id;
@@ -474,6 +475,7 @@ struct mhi_device {
int ul_chan_id;
int dl_chan_id;
u32 dev_wake;
+ u32 qrtr_endpoint_id;
};
/**
@@ -827,4 +829,22 @@ bool mhi_queue_is_full(struct mhi_device *mhi_dev, enum dma_data_direction dir);
*/
int mhi_get_channel_doorbell_offset(struct mhi_controller *mhi_cntrl, u32 *chdb_offset);
+/**
+ * mhi_set_qrtr_endpoint_id - Sets supplied QRTR endpoint ID
+ * @mhi_dev: Device to set the QRTR endpoint ID for
+ * @qrtr_endpoint_id: ID to set
+ *
+ * Return: 0 if setting data succeeded, a negative error code otherwise
+ */
+int mhi_set_qrtr_endpoint_id(struct mhi_device *mhi_dev, u32 qrtr_endpoint_id);
+
+/**
+ * mhi_get_qrtr_endpoint_id - Gets QRTR endpoint ID for specified MHI device
+ * @mhi_dev: Device to get the QRTR endpoint ID for
+ * @qrtr_endpoint_id: pointer to save the QRTR endpoint ID to
+ *
+ * Return: 0 if fetching data succeeded, a negative error code otherwise
+ */
+int mhi_get_qrtr_endpoint_id(struct mhi_device *mhi_dev, u32 *qrtr_endpoint_id);
+
#endif /* _MHI_H_ */
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 02/11] net: qrtr: mhi: pass endpoint ID to MHI device on init
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 01/11] bus: mhi: host: add QRTR endpoint ID to mhi_device Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 03/11] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Mihai Moldovan
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
This is the simple QRTR part of the ugly endpoint ID "IPC" hack.
On initialization, which is currently only implemented for the MHI
backend, the endpoint ID is written to the MHI device's MHI controller.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
net/qrtr/mhi.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 9a23c888e234..942b65a494e2 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -104,6 +104,10 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
if (device_create_file(&mhi_dev->dev, &dev_attr_endpoint) < 0)
dev_err(qdev->dev, "Failed to create endpoint attribute\n");
+ /* Pass endpoint ID to mhi_dev. */
+ dev_dbg(qdev->dev, "setting qdev->ep.id = %u as qrtr_endpoint_id for mhi_dev = %p\n", qdev->ep.id, mhi_dev);
+ mhi_set_qrtr_endpoint_id(mhi_dev, qdev->ep.id);
+
/* start channels */
rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
if (rc) {
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 03/11] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 01/11] bus: mhi: host: add QRTR endpoint ID to mhi_device Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 02/11] net: qrtr: mhi: pass endpoint ID to MHI device on init Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 04/11] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Mihai Moldovan
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
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>
---
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 469e02d2aa0d..77743c855762 100644
--- a/include/linux/soc/qcom/qmi.h
+++ b/include/linux/soc/qcom/qmi.h
@@ -212,6 +212,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;
@@ -235,6 +236,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.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 04/11] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (2 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 03/11] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 05/11] wifi: ath11k: add QRTR endpoint ID hif feature Mihai Moldovan
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
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>
---
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 bb98b06e87f8..893e5a6accd9 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, 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, 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 requested, but "
+ "operation failed: %d\n", ret);
+ }
+
ret = kernel_getsockname(sock, (struct sockaddr *)sq);
if (ret < 0) {
sock_release(sock);
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 05/11] wifi: ath11k: add QRTR endpoint ID hif feature
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (3 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 04/11] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 06/11] wifi: ath11k: stub QRTR endpoint ID fetching for AHB Mihai Moldovan
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
This will allow fetching the QRTR endpoint ID via hardware-specific
means.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
drivers/net/wireless/ath/ath11k/hif.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
index 674ff772b181..22324fe59d48 100644
--- a/drivers/net/wireless/ath/ath11k/hif.h
+++ b/drivers/net/wireless/ath/ath11k/hif.h
@@ -31,6 +31,7 @@ struct ath11k_hif_ops {
void (*ce_irq_enable)(struct ath11k_base *ab);
void (*ce_irq_disable)(struct ath11k_base *ab);
void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
+ int (*set_qrtr_endpoint_id)(struct ath11k_base *ab);
};
static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
@@ -146,4 +147,11 @@ static inline void ath11k_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
*msi_data_idx = ce_id;
}
+static inline int ath11k_set_qrtr_endpoint_id(struct ath11k_base *ab)
+{
+ if (!ab->hif.ops->set_qrtr_endpoint_id)
+ return -ENOSYS;
+ else
+ return ab->hif.ops->set_qrtr_endpoint_id(ab);
+}
#endif /* _HIF_H_ */
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 06/11] wifi: ath11k: stub QRTR endpoint ID fetching for AHB
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (4 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 05/11] wifi: ath11k: add QRTR endpoint ID hif feature Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 07/11] wifi: ath11k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
QRTR endpoint ID fetching will currently not be available for AHB.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
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 916402ad06b8..19c958b04b7a 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -773,6 +773,7 @@ static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
.map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
.power_down = ath11k_ahb_power_down,
.power_up = ath11k_ahb_power_up,
+ .set_qrtr_endpoint_id = ath11k_ahb_set_qrtr_endpoint_id,
};
static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
@@ -792,6 +793,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)
@@ -1312,6 +1314,11 @@ static void ath11k_ahb_shutdown(struct platform_device *pdev)
ath11k_ahb_free_resources(ab);
}
+static ath11k_ahb_set_qrtr_endpoint_id(struct ath11k_base *ab)
+{
+ return -ENOSYS;
+}
+
static struct platform_driver ath11k_ahb_driver = {
.driver = {
.name = "ath11k",
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 07/11] wifi: ath11k: implement QRTR endpoint ID fetching for PCI
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (5 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 06/11] wifi: ath11k: stub QRTR endpoint ID fetching for AHB Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 08/11] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_ops_new_server Mihai Moldovan
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
QRTR endpoint ID fetching for PCIe devices will use MHI.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
drivers/net/wireless/ath/ath11k/mhi.c | 17 +++++++++++++++++
drivers/net/wireless/ath/ath11k/mhi.h | 1 +
drivers/net/wireless/ath/ath11k/pci.c | 1 +
3 files changed, 19 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index 6974a551883f..5af02802c3b0 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -490,3 +490,20 @@ int ath11k_mhi_resume(struct ath11k_pci *ab_pci)
return 0;
}
+
+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;
+
+ /* Pass endpoint ID up for QMI usage. */
+ ret = mhi_get_qrtr_endpoint_id(ab_pci->mhi_ctrl->mhi_dev, &qmi->handle.endpoint_id);
+ ath11k_dbg(ab, ATH11K_DBG_PCI, "queried mhi_device 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 a682aad52fc5..84465fb5d5da 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.h
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
@@ -27,4 +27,5 @@ void ath11k_mhi_clear_vector(struct ath11k_base *ab);
int ath11k_mhi_suspend(struct ath11k_pci *ar_pci);
int ath11k_mhi_resume(struct ath11k_pci *ar_pci);
+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 18248b8e5b93..fd3664c8ff8b 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -744,6 +744,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,
};
static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor)
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 08/11] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_ops_new_server
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (6 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 07/11] wifi: ath11k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 09/11] wifi: ath12k: add QRTR endpoint ID hif feature Mihai Moldovan
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
If possible, fetch the QRTR endpoint ID in ath11k_qmi_ops_new_server,
which should be late enough for all initializations to already have
happened, and bind to this endpoint ID if fetching it worked.
This finally allows using multiple ath11k-based cards with the same QRTR
node/port combination to work simultanenous (and, for that matter, at
all).
Caveat: it would be better to actually bind to the correct QRTR endpoint
ID right at socket creation time (i.e., when qmi_handle_init is called).
However, we cannot do this, because the socket creation is the part that
actually kicks off qrtr-mhi probing and initialization.
ath11k_qmi_ops_new_server is "early enough" in that it should work
mostly fine, but obviously, there is a time in which messages for other
endpoints can be coming in as well before we actually bound to the
endpoint ID we are interested in.
Unfortunately, I have no idea how to avoid this and properly get the
QRTR endpoint ID before actually creating the socket.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1
---
drivers/net/wireless/ath/ath11k/qmi.c | 50 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/qmi.h | 1 +
2 files changed, 51 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 7a22483b35cd..4c88e04362bc 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -15,6 +15,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
@@ -3164,6 +3165,23 @@ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
struct sockaddr_qrtr *sq = &qmi->sq;
int ret;
+ ret = ath11k_set_qrtr_endpoint_id(ab);
+ if (ret)
+ ath11k_warn(ab, "failed to set QRTR endpoint ID: %d\n", ret);
+ else {
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "trying to bind qrtr endpoint...\n");
+ ret = ath11k_qmi_bind_endpoint_id(ab);
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "bound bind qrtr endpoint...\n");
+
+ if (ret)
+ ath11k_warn(ab, "failed to bind to QRTR endpoint ID: "
+ "%d\n", ret);
+ }
+
+ if (ret)
+ ath11k_warn(ab, "continuing without, but only one device per "
+ "system will be supported\n");
+
sq->sq_family = AF_QIPCRTR;
sq->sq_node = service->node;
sq->sq_port = service->port;
@@ -3355,3 +3373,35 @@ void ath11k_qmi_free_resource(struct ath11k_base *ab)
ath11k_qmi_free_target_mem_chunk(ab);
ath11k_qmi_m3_free(ab);
}
+
+int ath11k_qmi_bind_endpoint_id(struct ath11k_base *ab)
+{
+ struct ath11k_qmi *qmi = NULL;
+ struct qmi_handle *handle = NULL;
+ const struct proto_ops *ops = NULL;
+ int ret;
+
+ if (!ab)
+ return -EINVAL;
+
+ qmi = &ab->qmi;
+ handle = &qmi->handle;
+
+ if (!handle->sock)
+ return -ENODEV;
+
+ ops = READ_ONCE(handle->sock->ops);
+
+ if (!ops)
+ return -ENODEV;
+
+ if (!ops->setsockopt)
+ return -ENXIO;
+
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "calling ops->setsockopt...\n");
+ ret = ops->setsockopt(handle->sock, SOL_QRTR, QRTR_BIND_ENDPOINT,
+ KERNEL_SOCKPTR(&handle->endpoint_id),
+ sizeof(handle->endpoint_id));
+
+ return ret;
+}
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index 7e06d100af57..35361f844874 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -518,5 +518,6 @@ void ath11k_qmi_deinit_service(struct ath11k_base *ab);
int ath11k_qmi_init_service(struct ath11k_base *ab);
void ath11k_qmi_free_resource(struct ath11k_base *ab);
int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab);
+int ath11k_qmi_bind_endpoint_id(struct ath11k_base *ab);
#endif
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 09/11] wifi: ath12k: add QRTR endpoint ID hif feature
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (7 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 08/11] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_ops_new_server Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 10/11] wifi: ath12k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 11/11] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server Mihai Moldovan
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
This will allow fetching the QRTR endpoint ID via hardware-specific
means.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
drivers/net/wireless/ath/ath12k/hif.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index e8840fab6061..c00234ec64c1 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,12 @@ static inline void ath12k_hif_coredump_download(struct ath12k_base *ab)
if (ab->hif.ops->coredump_download)
ab->hif.ops->coredump_download(ab);
}
+
+static inline int ath12k_hif_set_qrtr_endpoint_id(struct ath12k_base *ab)
+{
+ if (!ab->hif.ops->set_qrtr_endpoint_id)
+ return -ENOSYS;
+ else
+ return ab->hif.ops->set_qrtr_endpoint_id(ab);
+}
#endif /* ATH12K_HIF_H */
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 10/11] wifi: ath12k: implement QRTR endpoint ID fetching for PCI
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (8 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 09/11] wifi: ath12k: add QRTR endpoint ID hif feature Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 11/11] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server Mihai Moldovan
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
QRTR endpoint ID fetching for PCIe devices will use MHI.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
---
drivers/net/wireless/ath/ath12k/mhi.c | 17 +++++++++++++++++
drivers/net/wireless/ath/ath12k/mhi.h | 2 ++
drivers/net/wireless/ath/ath12k/pci.c | 1 +
3 files changed, 20 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
index 2f6d14382ed7..30b3efc283b9 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.c
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
@@ -654,3 +654,20 @@ void ath12k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic)
{
mhi_download_rddm_image(mhi_ctrl, in_panic);
}
+
+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;
+
+ /* Pass endpoint ID up for QMI usage. */
+ ret = mhi_get_qrtr_endpoint_id(ab_pci->mhi_ctrl->mhi_dev, &qmi->handle.endpoint_id);
+ ath12k_dbg(ab, ATH12K_DBG_PCI, "queried mhi_device 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 7358b8477536..c4e00c1747c8 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.h
+++ b/drivers/net/wireless/ath/ath12k/mhi.h
@@ -44,4 +44,6 @@ 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 cf907550e6a4..3d65c64d1b31 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1514,6 +1514,7 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
#ifdef CONFIG_ATH12K_COREDUMP
.coredump_download = ath12k_pci_coredump_download,
#endif
+ .set_qrtr_endpoint_id = ath12k_mhi_set_qrtr_endpoint_id,
};
static
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [DONOTMERGE] [NOTEVENRFC] [PATCH 11/11] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
` (9 preceding siblings ...)
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 10/11] wifi: ath12k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
@ 2024-11-05 7:06 ` Mihai Moldovan
10 siblings, 0 replies; 12+ messages in thread
From: Mihai Moldovan @ 2024-11-05 7:06 UTC (permalink / raw)
To: ath11k; +Cc: Mihai Moldovan
If possible, fetch the QRTR endpoint ID in ath12k_qmi_ops_new_server,
which should be late enough for all initializations to already have
happened, and bind to this endpoint ID if fetching it worked.
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.
Caveat: it would be better to actually bind to the correct QRTR endpoint
ID right at socket creation time (i.e., when qmi_handle_init is called).
However, we cannot do this, because the socket creation is the part that
actually kicks off qrtr-mhi probing and initialization.
ath12k_qmi_ops_new_server is "early enough" in that it should work
mostly fine, but obviously, there is a time in which messages for other
endpoints can be coming in as well before we actually bound to the
endpoint ID we are interested in.
Unfortunately, I have no idea how to avoid this and properly get the
QRTR endpoint ID before actually creating the socket.
Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
---
drivers/net/wireless/ath/ath12k/qmi.c | 49 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/qmi.h | 1 +
2 files changed, 50 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index d2d9d03c7a28..96bc0a3cb86f 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -9,8 +9,10 @@
#include "qmi.h"
#include "core.h"
#include "debug.h"
+#include "hif.h"
#include <linux/of.h>
#include <linux/firmware.h>
+#include <net/sock.h>
#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
#define HOST_CSTATE_BIT 0x04
@@ -3264,6 +3266,21 @@ static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
struct sockaddr_qrtr *sq = &qmi->sq;
int ret;
+ ret = ath12k_hif_set_qrtr_endpoint_id(ab);
+ if (ret)
+ ath12k_warn(ab, "failed to set QRTR endpoint ID: %d\n", ret);
+ else {
+ ret = ath12k_qmi_bind_endpoint_id(ab);
+
+ if (ret)
+ ath12k_warn(ab, "failed to bind to QRTR endpoint ID: "
+ "%d\n", ret);
+ }
+
+ if (ret)
+ ath12k_warn(ab, "continuing without, but only one device per "
+ "system will be supported\n");
+
sq->sq_family = AF_QIPCRTR;
sq->sq_node = service->node;
sq->sq_port = service->port;
@@ -3414,3 +3431,35 @@ void ath12k_qmi_free_resource(struct ath12k_base *ab)
ath12k_qmi_free_target_mem_chunk(ab);
ath12k_qmi_m3_free(ab);
}
+
+int ath12k_qmi_bind_endpoint_id(struct ath12k_base *ab)
+{
+ struct ath12k_qmi *qmi = NULL;
+ struct qmi_handle *handle = NULL;
+ const struct proto_ops *ops = NULL;
+ int ret;
+
+ if (!ab)
+ return -EINVAL;
+
+ qmi = &ab->qmi;
+ handle = &qmi->handle;
+
+ if (!handle->sock)
+ return -ENODEV;
+
+ ops = READ_ONCE(handle->sock->ops);
+
+ if (!ops)
+ return -ENODEV;
+
+ if (!ops->setsockopt)
+ return -ENXIO;
+
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "calling ops->setsockopt...\n");
+ ret = ops->setsockopt(handle->sock, SOL_QRTR, QRTR_BIND_ENDPOINT,
+ KERNEL_SOCKPTR(&handle->endpoint_id),
+ sizeof(handle->endpoint_id));
+
+ return ret;
+}
diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
index 0dfcbd8cb59b..6358f75475cf 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.h
+++ b/drivers/net/wireless/ath/ath12k/qmi.h
@@ -600,5 +600,6 @@ void ath12k_qmi_firmware_stop(struct ath12k_base *ab);
void ath12k_qmi_deinit_service(struct ath12k_base *ab);
int ath12k_qmi_init_service(struct ath12k_base *ab);
void ath12k_qmi_free_resource(struct ath12k_base *ab);
+int ath12k_qmi_bind_endpoint_id(struct ath12k_base *ab);
#endif
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-11-05 8:16 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-05 7:06 [DONOTMERGE] [NOTEVENRFC] [PATCH 00/11] ath1{1,2}k: support multiple PCI devices in one system Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 01/11] bus: mhi: host: add QRTR endpoint ID to mhi_device Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 02/11] net: qrtr: mhi: pass endpoint ID to MHI device on init Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 03/11] soc: qcom: qmi_helpers: add QRTR endpoint ID to qmi_handle Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 04/11] soc: qcom: qmi_helpers: optionally bind to QRTR endpoint ID in qmi_sock_create Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 05/11] wifi: ath11k: add QRTR endpoint ID hif feature Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 06/11] wifi: ath11k: stub QRTR endpoint ID fetching for AHB Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 07/11] wifi: ath11k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 08/11] wifi: ath11k: bind to QRTR endpoint ID in ath11k_qmi_ops_new_server Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 09/11] wifi: ath12k: add QRTR endpoint ID hif feature Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 10/11] wifi: ath12k: implement QRTR endpoint ID fetching for PCI Mihai Moldovan
2024-11-05 7:06 ` [DONOTMERGE] [NOTEVENRFC] [PATCH 11/11] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server Mihai Moldovan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox