[DONOTMERGE] [NOTEVENRFC] [PATCH 11/11] wifi: ath12k: bind to QRTR endpoint ID in ath12k_qmi_ops_new_server
Mihai Moldovan
ionic at ionic.de
Mon Nov 4 23:06:25 PST 2024
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 at 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
More information about the ath11k
mailing list