From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD0F443CE6A; Tue, 22 Sep 2026 13:42:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790084524; cv=none; b=nhi3cTaUo3MxFgPJVhHMYZ7ks4/AXMht2eEwnl77yfxc16XS6UBK2DoOTk4CdmKKcn/pSRUnKuQtR69Ox1XRoP2AAKL2bQKUY6gqzN+S0TxPChm0HX4vhlk7IKVsphtLnB6cxEN7UWfxWRF9F7MbmRDzjKCMHxrqyzh1oq7WCyU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790084524; c=relaxed/simple; bh=ui+TXvwrceC03rroE/Q4o0li/haNQJon38ShWlc2EVE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZiBQhzexD6H3PZq+L2bFSiImS7nkdoroGGrUIkqF5b+oxbXWNLzXQZdOeYYYQN9Sgamgb87Gh+R8c0o87HXAOkXBUef08eReCHRcMo2bkAv6rS6EaGIQa3Jc8q5spE+6PzY/S9vYfkx1P3c3G23LgFWDsT0S0nREXv0PY5R7B8M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=G6K2V3hf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="G6K2V3hf" Received: by smtp.kernel.org (Postfix) with ESMTPS id A14E2C2BCFA; Tue, 22 Sep 2026 13:42:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1790084524; bh=ui+TXvwrceC03rroE/Q4o0li/haNQJon38ShWlc2EVE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=G6K2V3hfxV8r+6ZtFmtnLu4ih7IPQs+y1XyytoQWBKS6m600IsltVrhtwrCBheq2I qUGX4r7XtKZKalpluawZjWH4qA3vmSnhGjF07qGWXHxxzqq+bWPFAo5w11YxWj9gmQ uVUHXJPfNrIYjD/bYxui47zSYqInlcy0a8E7EEfWVgb/kBd9Xd0qExY+zTai3lC8O/ BQcccDntbL7pixs++cJwDag5HVo1kBLwt1kGxcBwc9PZ35i6y/zulJcz8UtvS4WrNU gTv0XqFIwh/tQftlYhAb2IHmr5qkEUf3RlNKgIQFgLbYkTGZ1uyS0QTBB9xj7TAp1w j9122tpLF1C3w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A37CC98304; Tue, 22 Sep 2026 13:42:04 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Tue, 22 Sep 2026 15:41:45 +0200 Subject: [PATCH v3 1/4] net: qrtr: Allow the host QRTR to assign a unique node id Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260922-qrtr-multi-ep-v3-1-c00831e88957@oss.qualcomm.com> References: <20260922-qrtr-multi-ep-v3-0-c00831e88957@oss.qualcomm.com> In-Reply-To: <20260922-qrtr-multi-ep-v3-0-c00831e88957@oss.qualcomm.com> To: Manivannan Sadhasivam , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jeff Johnson Cc: linux-arm-msm@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, ath12k@lists.infradead.org, Bjorn Andersson , Chris Lew , Deepak Kumar Singh , Raj Kumar Bhagat , Juha-Matti Tilli , Jeff Hugo , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5742; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=SBSrI+qlLmBFZ+dE+vFKRI0DdSkol2nyOzoeOTlj9jg=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBqsoWpbuOyoQKV02+GoxJrFYPlSGJH68jOs7wMr CDEg/wp0rSJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCarKFqQAKCRBVnxHm/pHO 9RcNB/9Imo5XHaW0CoxAo1arRjZkVC9Pi5NdmD5TJnnRtZtHPqJukKAgUq+T1QMDJODb9T4jQRI l1HYvNzc0DY5/RtMUbmyhv8150KdgqfHDZgSL5laDLOLSitqRXvR+Xu9PeND9KOdMb75JY1H7cn ix7DaTI9v/5ViUY39bUs3cpiLeEaSBRxU68SJieioxEzQBp4PqX6Se/r7FC+qBHZNpesj+l+ZWJ Nuc15UcBm3gzpQ05Nr3X3T9nQc06uVuyyOYxBlL9Tt4uxtVnDRmNmAg4/tugcW/dTC2EauUEuNI 4u72wA8v1E398uOzTvT0FwX1FyGRVXBYLyIPMS6fzA/4EkBs X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam Currently, QRTR identifies each remote node by the value of the 'src_node_id' field in the received packet and uses the node id as the key to store the node to the internal 'qrtr_nodes' radix tree. But this approach comes with a limitation. When more than one remote node share the same id, then QRTR can only add the first node to the radix tree and has to drop the successive nodes with the same node id as the 'key' in radix tree has to be unique. This prevents connecting identical Qcom PCIe WLAN devices to a single host at the same time. To fix this limitation, allow the host QRTR to use the node id (nid) received from the endpoint driver during qrtr_endpoint_register() as the unique node id and use it as the 'key' for the internal radix tree. Also, store the received 'src_id' in a new 'qrtr_node->ep_nid' field and replace the 'ep_nid' with the unique 'nid' in the QRTR control packets if both differ i.e., an endpoint driver has passed a unique 'nid' during qrtr_endpoint_register(). To maintain symmetry, replace the 'nid' with the 'ep_nid' while sending the packet back to the remote node if both differ. Currently, all QRTR endpoint drivers pass 'QRTR_EP_NID_AUTO' as the 'nid' during qrtr_endpoint_register(). So 'ep_nid' and 'nid' are same and the functionality is not changed. Signed-off-by: Manivannan Sadhasivam --- net/qrtr/af_qrtr.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c index 78347c937af7..6387b85a7a2c 100644 --- a/net/qrtr/af_qrtr.c +++ b/net/qrtr/af_qrtr.c @@ -118,7 +118,8 @@ static DEFINE_XARRAY_ALLOC(qrtr_ports); * @ep_lock: lock for endpoint management and callbacks * @ep: endpoint * @ref: reference count for node - * @nid: node id + * @nid: node id assigned by the host QRTR + * @ep_nid: endpoint's own node id as received * @qrtr_tx_flow: xarray of qrtr_tx_flow, keyed by node << 32 | port * @qrtr_tx_lock: lock for qrtr_tx_flow inserts * @hello_sent: hello packet send successful @@ -131,6 +132,7 @@ struct qrtr_node { struct qrtr_endpoint *ep; struct kref ref; unsigned int nid; + unsigned int ep_nid; struct xarray qrtr_tx_flow; struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */ @@ -347,6 +349,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, { struct qrtr_hdr_v1 *hdr; size_t len = skb->len; + unsigned int dst_node; int rc, confirm_rx; mutex_lock(&node->ep_lock); @@ -369,10 +372,14 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, hdr->src_node_id = cpu_to_le32(from->sq_node); hdr->src_port_id = cpu_to_le32(from->sq_port); if (to->sq_port == QRTR_PORT_CTRL) { - hdr->dst_node_id = cpu_to_le32(READ_ONCE(node->nid)); + hdr->dst_node_id = cpu_to_le32(READ_ONCE(node->ep_nid)); hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL); } else { - hdr->dst_node_id = cpu_to_le32(to->sq_node); + /* Put back the endpoint's own node id */ + dst_node = to->sq_node; + if (dst_node == READ_ONCE(node->nid)) + dst_node = node->ep_nid; + hdr->dst_node_id = cpu_to_le32(dst_node); hdr->dst_port_id = cpu_to_le32(to->sq_port); } @@ -441,6 +448,32 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid) spin_unlock_irqrestore(&qrtr_nodes_lock, flags); } +/* Replace the node id in the control packet with 'node->nid', if both are + * different. + */ +static void qrtr_node_rewrite_ctrl(struct qrtr_node *node, unsigned int type, + struct sk_buff *skb) +{ + struct qrtr_ctrl_pkt *pkt; + __le32 *nid; + + if (node->nid == node->ep_nid) + return; + + if (skb->len < sizeof(*pkt)) + return; + + pkt = (struct qrtr_ctrl_pkt *)skb->data; + if (type == QRTR_TYPE_DEL_CLIENT || type == QRTR_TYPE_RESUME_TX) + nid = &pkt->client.node; + else + nid = &pkt->server.node; + + /* Rewrite only the endpoint's node id, not those of bridged nodes */ + if (le32_to_cpu(*nid) == node->ep_nid) + *nid = cpu_to_le32(node->nid); +} + /** * qrtr_endpoint_post() - post incoming data * @ep: endpoint handle @@ -531,16 +564,30 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) skb_put_data(skb, data + hdrlen, size); - qrtr_node_assign(node, cb->src_node); + if (node->ep_nid == QRTR_EP_NID_AUTO) + WRITE_ONCE(node->ep_nid, cb->src_node); + + if (node->nid == QRTR_EP_NID_AUTO || node->nid == cb->src_node) + qrtr_node_assign(node, cb->src_node); if (cb->type == QRTR_TYPE_NEW_SERVER) { /* Remote node endpoint can bridge other distant nodes */ - const struct qrtr_ctrl_pkt *pkt; + const struct qrtr_ctrl_pkt *pkt = data + hdrlen; + unsigned int server_node = le32_to_cpu(pkt->server.node); - pkt = data + hdrlen; - qrtr_node_assign(node, le32_to_cpu(pkt->server.node)); + if (server_node != node->ep_nid) + qrtr_node_assign(node, server_node); } + if (cb->src_node == node->ep_nid) + cb->src_node = node->nid; + + if (cb->type == QRTR_TYPE_NEW_SERVER || + cb->type == QRTR_TYPE_DEL_SERVER || + cb->type == QRTR_TYPE_DEL_CLIENT || + cb->type == QRTR_TYPE_RESUME_TX) + qrtr_node_rewrite_ctrl(node, cb->type, skb); + if (cb->type == QRTR_TYPE_RESUME_TX) { qrtr_tx_resume(node, skb); } else { @@ -646,6 +693,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) mutex_init(&node->ep_lock); skb_queue_head_init(&node->rx_queue); node->nid = QRTR_EP_NID_AUTO; + node->ep_nid = QRTR_EP_NID_AUTO; node->ep = ep; node->hello_sent = false; -- 2.43.0