From nobody Thu Jul 2 12:39:45 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 123E5355F42 for ; Mon, 22 Jun 2026 05:09:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104967; cv=none; b=XFod8pBTIgcsvAO8RSpG3Xwba3UeRNTIt0OK6/sS9ZgcGEZR8VzzCp/DHl/sToC6ClWv6my5FyUy7X9zpW2tbuO/O1fNU9ko2vfxpwK5WhasDvEZJ+PhvhNoEm7EoMoISUqnmb2PVmr0Gv5CVHZnX4a8ss0czfff3+xkotDyFkA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104967; c=relaxed/simple; bh=BdTN6n1LHqnGXFJg35aSQS7P/2dFr0YrfLiu5hnpr10=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UoO73cJJRTKlyGwi6c+CIJ1CVOQtta3ONi0UO1YLuYopqPtpgUcnXdLOltkavLyxDZ52g1rT4yH8HJqbYl7k7qa6APrK4RWOl23FbQ6lYDscfjmQ6OD+LGgQDPXPZH8z5pbyyO7N3/GiZc2p+DZtMSn7Ukg4OOjHjT8fkyZfqXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=FSfhJYyM; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Xb7MsoT7; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="FSfhJYyM"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Xb7MsoT7" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65M59MBI3800818 for ; Mon, 22 Jun 2026 05:09:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= tm04REIlapwuSniGf9i7oLt52QuGZ4tIkTb9qieRbGk=; b=FSfhJYyMf63lnyE6 EOi/vjMMf8xcoA8K5XGfTIBtkv1Wx0AgWn/xUEUEJiy11GHOsph8bUBX2v86YLHa nW/2UdliCjkxNCylfYja1o55zxhzcNN8U40kANLPzFJL54bv3YL+ofBtpISH0+QZ WijKYHpPkswUd40+FuaY3KFhdgwpdeJqbvSuAVFLEAsDizxawtl885JhwTSFAz8e ajX0bFxc4u7KTZHDeYNHK6B2p/PDFvOST2+s03PbRklMOM/aiEPfilMSiC4KysRV sSrv0euySl0CwjWg61uZBcmFmD246L7uTuQ4RSZe3cLGydk4nI2Kh2xzbLW7zvwN fpK3ZQ== Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ewm1k4nvt-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 22 Jun 2026 05:09:25 +0000 (GMT) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-8423f424d5bso2756290b3a.3 for ; Sun, 21 Jun 2026 22:09:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782104964; x=1782709764; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=tm04REIlapwuSniGf9i7oLt52QuGZ4tIkTb9qieRbGk=; b=Xb7MsoT7zqaK+AT66VheKhdYDu2gIbuG9IljYPN86MUJT+jD6+B0nb8I8FQJhl82UF avdl5n8trrjvmV5OxYSEUqXmDVh8vRwI+aAZL6bIgfcpiWqATrqTeUlzUtfAf3j1+qOe JrIFB8M8wbkYG2Mklxg5ynEVR0C7pIqIgxf6ZL8jA1jvw3oAxm7k00A+sPPRZZU14sVD yiVjf/4//cycyHSsikSxOJCRWzx0ahEfSeY5nvUmAOkA9ORgfIeiPMGpPvEoCvr84aD/ 1SkVZPDiX+Y6VsFGddd79I7yfu4vuqBlaOOX7dkf3tKouEFfvzXafwvWROo0uSqt9nZa f0oA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782104964; x=1782709764; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=tm04REIlapwuSniGf9i7oLt52QuGZ4tIkTb9qieRbGk=; b=Um8umGQmCBTnOYxMOZ8DlxisfGlWVZU2YIGDf1lm/e6/PvOf0yqJUD67HFHr45MyrI B5PAlaLW0nCGsyOBsS+IdMuVqeiH8Ktjs3wQFSVxvb9bcPK9DwfRl7h3esWWx0E7ymvN L8LVS+ezz8waMVGGnZr41k3BJxMn6M8m5R2aPPBWzuTa0ptrKM1In6qYK9R8HwgV8ABx Znvo1lq746biTBX35JX0Y5Hhx9DA5Bt7LVUe8x/JjWK7F9udaGZw44x8+iKPo7Vpskvj nXr+O4LhyaQyD0L/mW30IQXylfe5sDL8MOrAJYGMjND/tr/TWJQ/pRfI8bKwfYsAEtZF lu/g== X-Forwarded-Encrypted: i=1; AFNElJ/z+g+NEjWz5mSCn0zwsR/yZXK/B6LanEf6G6CGUbMqDxSHNGLOofdHj0+6VrnMd5Fgr3YfFgUSh0q8B2M=@vger.kernel.org X-Gm-Message-State: AOJu0YwCIATYFi7+FnIB9sxEd9wGk8qUEM3S8iCVIIOdSO/JKHwQxPRT SYLj9bd5y6HeF4/C5I05+kx9N7lFKXmqMRd9gI3G5geJxSXJz3BzEfYb1sgQoidLgAR76RBPQ9B qhkvr2zC8cXE4BItyn3j3jxnD9CH37Lnn+mQ6b8rdRfO45NccxHB/dQAldGnMjPzcQYWWM+NfJB g= X-Gm-Gg: AfdE7cnxfDBNWG7z85XaWw7XUcNSjwmOKCe0+ZbP1hWSWisKG3/9C4yN3I5+TZIXOlI aJkJXAgnt4m0NY47LjNM6OEitau+g2+G4h33+7DARQRBLLEaDiP9EOCLqzT27zSqwo5lPWjByU7 I6U5YKUN4AbMnqcusYGiiLdLzXP2zhle8Yt9ZlEn0ENmrgRTFbDSb3K5doUZq4asFZx53Bs7ea0 3O/mOf+QNZAfsEzGnrq5Vhw79BEUA2iqf+pMousTfj5RGddkND9+W0hLrVa2ssdB0vUeOQOnJMM e8s5r0bQgBEwNFDROjnzi8gBBmYZWJ9+T2BTH5OhtUQGbpAfcpxJ3i2UmhG22nhjbdWp3PiJyb2 unkxV2YSUYFb9qQ2uM8ybJaqr0UAeVjY0EuJe X-Received: by 2002:a05:6a00:a257:b0:842:7fc8:eba with SMTP id d2e1a72fcca58-845507bbd87mr13932985b3a.11.1782104964090; Sun, 21 Jun 2026 22:09:24 -0700 (PDT) X-Received: by 2002:a05:6a00:a257:b0:842:7fc8:eba with SMTP id d2e1a72fcca58-845507bbd87mr13932936b3a.11.1782104963441; Sun, 21 Jun 2026 22:09:23 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84564d6c5dbsm5905996b3a.12.2026.06.21.22.09.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 21 Jun 2026 22:09:23 -0700 (PDT) From: Sumit Kumar Date: Mon, 22 Jun 2026 10:39:15 +0530 Subject: [PATCH v4 1/3] bus: mhi: host: clients: Add loopback driver with sysfs interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260622-loopback_mhi-v4-1-782b3a0f2eef@oss.qualcomm.com> References: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> In-Reply-To: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> To: Manivannan Sadhasivam Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar , Krishna Chaitanya Chundru X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1782104957; l=15316; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=BdTN6n1LHqnGXFJg35aSQS7P/2dFr0YrfLiu5hnpr10=; b=QJFo24XXEE5QiV2oTS/j2hjFZKsjb+haxeahP2zqwi/mI6laPcHH3cZFFgNVhd37Ui9GFGO2k 1p7qUVjwhPgDvMkXPE9Wh8vV7D0TBqFi8aqCJJYxoM397yBP9OaGm3L X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-GUID: noRd1btAYycXnrTgUp8hli5Xsx0y_D7Q X-Proofpoint-Spam-Info: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfX4XOIq/lZ01Bl EVgVJhZcBUPwydlLjZUSdfZSoi0M80ch0VNQ5xT4PllOxqRWGmnJYcegU88mbGYw0qN6zaHHsr4 zcd3tlvrUSmTy+uGaB0QuVtNLLDdOis= X-Authority-Analysis: v=2.4 cv=T6S8ifKQ c=1 sm=1 tr=0 ts=6a38c385 cx=c_pps a=WW5sKcV1LcKqjgzy2JUPuA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=fr5qSj5IhElrMRFVs5kA:9 a=QEXdDO2ut3YA:10 a=OpyuDcXvxspvyRM73sMx:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfX+cZawtYJFOgQ EBcIjQmXHIGrb0sHN5Lz0ZrVLsRZV5SJONmIsdL9gaxgebXp5mi+rWUlol1kvfoBe0Eb/R6MApp 7BZVLEWjkF0bZABa56lr/aJmTwQUSwcswpgIjp72Cfc56bFEzyMRLCrYEksVLhHcx7Z5FF1t0Mc NyCCRRG6p6XiRu8Ur6iI0jzTMi6JcAb2JZmT/yDnorIFPNBFCnmc9vAUNFsgtZAAti/8CYopEmy lE2mmO8Sa/lvYSJs98Dz7u8D7qECByAFZAe/SAN9vnwtjWBQUZwRHgy10nOYGn4vJx8dC0XqI2A wU4Xr7euMQEwVm2TtB6GIn7dlFFlCEsPrjRjaBBT8UYxOhKfoL+3WpQRKLsLeVi8NgJTPxU2w1I yQRkcO60T/JutYfLIHFJzsLtNOaJgg4VySV+1KlM9MUnjzSCbQDCqtuOGYg2urFBxyxJcW+4oLG vlfaUOb+qPHxabP5fug== X-Proofpoint-ORIG-GUID: noRd1btAYycXnrTgUp8hli5Xsx0y_D7Q X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-22_01,2026-06-18_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 malwarescore=0 adultscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 spamscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606220047 The MHI specification defines a LOOPBACK channel. The endpoint firmware echoes back whatever the host sends on this channel. Without a host-side driver, there is no way to exercise this channel to validate MHI data path integrity between host and endpoint. Add a host-side loopback driver that binds to the LOOPBACK channel and expose a sysfs interface for data path testing. The sysfs interface allows users to configure TRE buffer size and count, trigger a loopback test, and read the result. Co-developed-by: Krishna Chaitanya Chundru Signed-off-by: Krishna Chaitanya Chundru Signed-off-by: Sumit Kumar --- .../ABI/testing/sysfs-bus-mhi-devices-loopback | 51 ++++ MAINTAINERS | 1 + drivers/bus/mhi/host/Kconfig | 1 + drivers/bus/mhi/host/Makefile | 1 + drivers/bus/mhi/host/clients/Kconfig | 17 ++ drivers/bus/mhi/host/clients/Makefile | 2 + drivers/bus/mhi/host/clients/loopback.c | 329 +++++++++++++++++= ++++ 7 files changed, 402 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback b/Doc= umentation/ABI/testing/sysfs-bus-mhi-devices-loopback new file mode 100644 index 0000000000000000000000000000000000000000..3bd770747799a3341a23903cc1a= 108e650e915b8 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback @@ -0,0 +1,51 @@ +What: /sys/bus/mhi/devices/mhi_LOOPBACK/tre_size +Date: April 2026 +KernelVersion: 7.1 +Contact: mhi@lists.linux.dev +Description: + (RW) Size of each Transfer Ring Element (TRE) buffer in bytes + used for the loopback test. Valid range is 1 to the value + reported by max_tre_size. Default value is 32 bytes. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/max_tre_size +Date: April 2026 +KernelVersion: 7.1 +Contact: mhi@lists.linux.dev +Description: + (RO) Maximum allowed TRE size in bytes. Reading this file + returns the upper bound for the tre_size attribute. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/num_tre +Date: April 2026 +KernelVersion: 7.1 +Contact: mhi@lists.linux.dev +Description: + (RW) Number of Transfer Ring Elements (TREs) to use per + loopback test. Must be greater than zero and must not exceed + the channel ring capacity. Default value is 1. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/start +Date: April 2026 +KernelVersion: 7.1 +Contact: mhi@lists.linux.dev +Description: + (WO) Write any value to trigger a loopback test. The driver + sends random data to the endpoint using the configured tre_size + and num_tre parameters, waits for the endpoint to echo it back, + and verifies the received data matches what was sent. + + This is a blocking write that returns when the test completes + or times out after 5 seconds. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/status +Date: April 2026 +KernelVersion: 7.1 +Contact: mhi@lists.linux.dev +Description: + (RO) Result of the last loopback test. Returns one of: + "pass" - last test completed successfully + "fail" - last test failed + "not started" - no test has been run yet + + Reading this file while a test is in progress will block + until the test completes. diff --git a/MAINTAINERS b/MAINTAINERS index 6dcfbd11efef87927041f5cf58d70633dbb4b18d..ff12a6da48947ac853bc638359a= 7046fea85fc21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16441,6 +16441,7 @@ L: linux-arm-msm@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git F: Documentation/ABI/stable/sysfs-bus-mhi +F: Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback F: Documentation/mhi/ F: drivers/bus/mhi/ F: drivers/pci/endpoint/functions/pci-epf-mhi.c diff --git a/drivers/bus/mhi/host/Kconfig b/drivers/bus/mhi/host/Kconfig index da5cd0c9fc620ab595e742c422f1a22a2a84c7b9..627c57948235aa52348179ae8b2= d0826ebaed01e 100644 --- a/drivers/bus/mhi/host/Kconfig +++ b/drivers/bus/mhi/host/Kconfig @@ -29,3 +29,4 @@ config MHI_BUS_PCI_GENERIC This driver provides MHI PCI controller driver for devices such as Qualcomm SDX55 based PCIe modems. =20 +source "drivers/bus/mhi/host/clients/Kconfig" diff --git a/drivers/bus/mhi/host/Makefile b/drivers/bus/mhi/host/Makefile index 859c2f38451c669b3d3014c374b2b957c99a1cfe..2a16008aeb38127494782bbff4e= 1656428d2b776 100644 --- a/drivers/bus/mhi/host/Makefile +++ b/drivers/bus/mhi/host/Makefile @@ -4,3 +4,4 @@ mhi-$(CONFIG_MHI_BUS_DEBUG) +=3D debugfs.o =20 obj-$(CONFIG_MHI_BUS_PCI_GENERIC) +=3D mhi_pci_generic.o mhi_pci_generic-y +=3D pci_generic.o +obj-y +=3D clients/ diff --git a/drivers/bus/mhi/host/clients/Kconfig b/drivers/bus/mhi/host/cl= ients/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d1463c3e0df0da461c815afaec6= 23ba349b51dda --- /dev/null +++ b/drivers/bus/mhi/host/clients/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MHI_BUS_LOOPBACK + tristate "MHI LOOPBACK client driver" + depends on MHI_BUS + help + MHI LOOPBACK client driver that binds to the MHI LOOPBACK channel + as defined in the MHI specification. The LOOPBACK channel is + implemented by MHI-based devices (modems, WLAN) in the field, where + the endpoint firmware echoes back whatever the host sends. + + This driver exposes a sysfs interface for testing MHI data path + integrity between host and endpoint. Users can configure the TRE + size and count, trigger a loopback test, and read the result. + + To compile this driver as a module, choose M here. The module + will be called mhi_loopback. diff --git a/drivers/bus/mhi/host/clients/Makefile b/drivers/bus/mhi/host/c= lients/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3811b6928f42b38f94b1167941c= f3b0fe512d32b --- /dev/null +++ b/drivers/bus/mhi/host/clients/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_LOOPBACK) +=3D mhi_loopback.o +mhi_loopback-y +=3D loopback.o diff --git a/drivers/bus/mhi/host/clients/loopback.c b/drivers/bus/mhi/host= /clients/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..693691fff26dc8fa0d58931b98c= e5f287fbd5c3e --- /dev/null +++ b/drivers/bus/mhi/host/clients/loopback.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/* + * The MHI LOOPBACK channel is defined in the MHI specification and is + * implemented by MHI-based devices (modems, WLAN) already deployed in the + * field. The endpoint firmware echoes back whatever the host sends on this + * channel. This driver binds to the LOOPBACK channel and exposes a sysfs + * interface for testing MHI data path integrity between host and endpoint. + * The sysfs interface is stable ABI because the wire protocol is fixed by + * the endpoint firmware and cannot be changed. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MHI_LOOPBACK_DEFAULT_TRE_SIZE 32 +#define MHI_LOOPBACK_DEFAULT_NUM_TRE 1 +#define MHI_LOOPBACK_TIMEOUT_MS 5000 +#define MHI_LOOPBACK_MAX_TRE_SIZE (SZ_64K - 1) + +struct mhi_loopback { + struct mhi_device *mdev; + struct mutex lb_mutex; + struct completion comp; + atomic_t tres_pending; + const char *result; + u32 num_tre; + u32 tre_size; +}; + +static ssize_t tre_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + + if (!loopback) + return -ENODEV; + + return sysfs_emit(buf, "%u\n", loopback->tre_size); +} + +static ssize_t tre_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 val; + + if (!loopback) + return -ENODEV; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (val =3D=3D 0 || val > MHI_LOOPBACK_MAX_TRE_SIZE) + return -EINVAL; + + guard(mutex)(&loopback->lb_mutex); + loopback->tre_size =3D val; + + return count; +} +static DEVICE_ATTR_RW(tre_size); + +static ssize_t max_tre_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", MHI_LOOPBACK_MAX_TRE_SIZE); +} +static DEVICE_ATTR_RO(max_tre_size); + +static ssize_t num_tre_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + + if (!loopback) + return -ENODEV; + + return sysfs_emit(buf, "%u\n", loopback->num_tre); +} + +static ssize_t num_tre_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 val; + int el_num; + + if (!loopback) + return -ENODEV; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (val =3D=3D 0) + return -EINVAL; + + guard(mutex)(&loopback->lb_mutex); + + el_num =3D mhi_get_free_desc_count(loopback->mdev, DMA_TO_DEVICE); + if (val > el_num) { + dev_err(dev, "num_tre (%u) exceeds ring capacity (%d)\n", val, el_num); + return -EINVAL; + } + + loopback->num_tre =3D val; + + return count; +} +static DEVICE_ATTR_RW(num_tre); + +static ssize_t start_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 total_size, tre_count, tre_size; + int i; + + if (!loopback) + return -ENODEV; + + guard(mutex)(&loopback->lb_mutex); + + tre_size =3D loopback->tre_size; + tre_count =3D loopback->num_tre; + total_size =3D size_mul(tre_count, tre_size); + + if (total_size > KMALLOC_MAX_SIZE) + return -EINVAL; + + void *recv_buf __free(kfree) =3D kzalloc(total_size, GFP_KERNEL); + if (!recv_buf) + return -ENOMEM; + + void *send_buf __free(kfree) =3D kzalloc(total_size, GFP_KERNEL); + if (!send_buf) + return -ENOMEM; + + get_random_bytes(send_buf, total_size); + + atomic_set(&loopback->tres_pending, tre_count); + reinit_completion(&loopback->comp); + + for (i =3D 0; i < tre_count; i++) { + int ret =3D mhi_queue_buf(loopback->mdev, DMA_FROM_DEVICE, + recv_buf + (i * tre_size), tre_size, MHI_EOT); + if (ret) { + dev_err(dev, "Unable to queue read TRE %d: %d\n", i, ret); + loopback->result =3D "fail"; + if (atomic_sub_and_test(tre_count - i, &loopback->tres_pending)) + complete(&loopback->comp); + return ret; + } + } + + for (i =3D 0; i < tre_count - 1; i++) { + int ret =3D mhi_queue_buf(loopback->mdev, DMA_TO_DEVICE, + send_buf + (i * tre_size), tre_size, MHI_CHAIN); + if (ret) { + dev_err(dev, "Unable to queue send TRE %d: %d\n", i, ret); + loopback->result =3D "fail"; + return ret; + } + } + + int ret =3D mhi_queue_buf(loopback->mdev, DMA_TO_DEVICE, + send_buf + (i * tre_size), tre_size, MHI_EOT); + if (ret) { + dev_err(dev, "Unable to queue final TRE: %d\n", ret); + loopback->result =3D "fail"; + return ret; + } + + if (!wait_for_completion_timeout(&loopback->comp, + msecs_to_jiffies(MHI_LOOPBACK_TIMEOUT_MS))) { + dev_err(dev, "Loopback test timed out\n"); + loopback->result =3D "fail"; + return -ETIMEDOUT; + } + + if (memcmp(send_buf, recv_buf, total_size)) { + dev_err(dev, "Loopback data mismatch\n"); + loopback->result =3D "fail"; + return -EIO; + } + + loopback->result =3D "pass"; + + return count; +} +static DEVICE_ATTR_WO(start); + +static ssize_t status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + + if (!loopback) + return -ENODEV; + + guard(mutex)(&loopback->lb_mutex); + + return sysfs_emit(buf, "%s\n", loopback->result); +} +static DEVICE_ATTR_RO(status); + +static void mhi_loopback_dl_callback(struct mhi_device *mhi_dev, + struct mhi_result *mhi_res) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(&mhi_dev->dev); + + if (!loopback) + return; + + if (mhi_res->transaction_status && mhi_res->transaction_status !=3D -ENOT= CONN) + dev_err(&mhi_dev->dev, "DL callback error: status %d\n", + mhi_res->transaction_status); + + if (atomic_dec_and_test(&loopback->tres_pending)) + complete(&loopback->comp); +} + +static void mhi_loopback_ul_callback(struct mhi_device *mhi_dev, + struct mhi_result *mhi_res) +{ +} + +static struct attribute *mhi_loopback_attrs[] =3D { + &dev_attr_tre_size.attr, + &dev_attr_max_tre_size.attr, + &dev_attr_num_tre.attr, + &dev_attr_start.attr, + &dev_attr_status.attr, + NULL, +}; + +static const struct attribute_group mhi_loopback_group =3D { + .attrs =3D mhi_loopback_attrs, +}; + +static int mhi_loopback_probe(struct mhi_device *mhi_dev, + const struct mhi_device_id *id) +{ + struct mhi_loopback *loopback; + int rc; + + loopback =3D devm_kzalloc(&mhi_dev->dev, sizeof(*loopback), GFP_KERNEL); + if (!loopback) + return -ENOMEM; + + loopback->mdev =3D mhi_dev; + loopback->tre_size =3D MHI_LOOPBACK_DEFAULT_TRE_SIZE; + loopback->num_tre =3D MHI_LOOPBACK_DEFAULT_NUM_TRE; + loopback->result =3D "not started"; + + mutex_init(&loopback->lb_mutex); + init_completion(&loopback->comp); + + dev_set_drvdata(&mhi_dev->dev, loopback); + + rc =3D mhi_prepare_for_transfer(mhi_dev); + if (rc) { + dev_err(&mhi_dev->dev, "failed to prepare for transfers\n"); + return rc; + } + + rc =3D devm_device_add_group(&mhi_dev->dev, &mhi_loopback_group); + if (rc) { + dev_err(&mhi_dev->dev, "failed to create sysfs attributes\n"); + mhi_unprepare_from_transfer(mhi_dev); + } + + return rc; +} + +static void mhi_loopback_remove(struct mhi_device *mhi_dev) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(&mhi_dev->dev); + + complete(&loopback->comp); + + mutex_lock(&loopback->lb_mutex); + mutex_unlock(&loopback->lb_mutex); + + mhi_unprepare_from_transfer(mhi_dev); + dev_set_drvdata(&mhi_dev->dev, NULL); +} + +static const struct mhi_device_id mhi_loopback_id_table[] =3D { + { .chan =3D "LOOPBACK"}, + {} +}; +MODULE_DEVICE_TABLE(mhi, mhi_loopback_id_table); + +static struct mhi_driver mhi_loopback_driver =3D { + .probe =3D mhi_loopback_probe, + .remove =3D mhi_loopback_remove, + .dl_xfer_cb =3D mhi_loopback_dl_callback, + .ul_xfer_cb =3D mhi_loopback_ul_callback, + .id_table =3D mhi_loopback_id_table, + .driver =3D { + .name =3D "mhi_loopback", + }, +}; + +module_mhi_driver(mhi_loopback_driver); + +MODULE_AUTHOR("Krishna Chaitanya Chundru "); +MODULE_AUTHOR("Sumit Kumar "); +MODULE_DESCRIPTION("MHI Host Loopback Driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Thu Jul 2 12:39:45 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 A59F43546E2 for ; Mon, 22 Jun 2026 05:09:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104970; cv=none; b=mPu836jM911zHWnhkXMYPs/wZcyHMGDxhgFHiBvUxSaHWRDvvSbDpvroXrWYJyn/OdQ8ZyAEViDQEexxUtg56eXNhcLhAYhNL2YdmUYS+g7X4g/FsyqJCjW+pUamFr6IeUGjMEfqd6wFpp2QWdDzyZPAy04kkWnxoXng/ffIDWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104970; c=relaxed/simple; bh=gGfaQBQV4ve45W3l4vga1g6v8XiqE+OMpkXU/G8WWwU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=feeecgSxiwBVhkx65oN6f7El+Z4asYE1w5UeFqe2OLBYHwBz6fWgO4aO6kHwoaQRE7n8Ib+CtY/uPbqeSLlm4jIxIU/HyhbwDdEjbQHxdAmWsNE1DwMs1wdT6FoJL67OIxOnRfWoPT2AsiVfgE+NaKZzTSm2upvJEeLXdoyoius= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=hvRL0yEL; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=guvsO3tN; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="hvRL0yEL"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="guvsO3tN" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65M59BVW3786565 for ; Mon, 22 Jun 2026 05:09:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= rFRW4uvz7oIyfQLLlTaUlea6eRZCi9oGvqy2/uhqCNc=; b=hvRL0yELe8o/N2tO J9l/e+TBTR0BSS8yq8+ypjq9FklOyYMpl/yExOtjX4PWLjwDQ/MjtnZQL/N8cQhE oMdl7X+ORpcnCYlkLpz5EYkG8dwCwp4/G/rmYFx6JFpg63f+2tQSu4DNOoxhCZSY vJK/jNa8NDcD8Dk1Ub6eWJsyaa9G+DhWtTb7r+MRZM3p0RDPlkiwjj7JNEjOT4uZ WVjKsyt+nnNOqOeEFljezIJp5Byf+4hnbWoEiIRvEbhFE6vC1UVx7pDi8nTQtWU7 9FMGFkNA+XhnW+EN5B8FjFr8JxwRyv9am+kd25X3ws/ri/RQiJjzq3B4VkkRH7A5 1cEc+g== Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ewkmecpre-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 22 Jun 2026 05:09:27 +0000 (GMT) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-845319bb97bso3240561b3a.0 for ; Sun, 21 Jun 2026 22:09:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782104967; x=1782709767; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=rFRW4uvz7oIyfQLLlTaUlea6eRZCi9oGvqy2/uhqCNc=; b=guvsO3tNBBT+/dGGVzwu6Om2aHV1cjjRHegLGXpgUj2e/Ej4dCDShZN8vjV9uXlgTI K7vcenn4Equ0XqACpSeMQANijAcBIbwr97xK1Rl/Bv/aeVqz6FEv3LVc8hDGYo7wWnBo 68ZT/5q0C7msD5XGFwlBMSGbGyLyeTc0Qot6he++J0MJR9SmffUJSSzDxg1xqdRO4q8b eL60pCT/fcS1GcZu1uBd8tA6cNs7rRF0zl0GHuVXQ8AwJc1kbigDvUb1FmEiQsF7aqIj LBuTSfU4GZu2uLhEbxdDZNkhfNGqHe0xa34H1mEn9KQUw6+f+LinmIf5+eiGIizCHgqJ bv+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782104967; x=1782709767; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=rFRW4uvz7oIyfQLLlTaUlea6eRZCi9oGvqy2/uhqCNc=; b=LBHluR1S122rkhhpM4R7HqEmITR+mU/QeCLPJ6Un/Eaz6NnVi8WDChHBOfUicUTGxd uuxUT4HfTIWtCNNS5rTzjnNVG2hJ6M1x2Nnz8suvZ52HPsIvgl+Pq50zRni2//obGmPX 6VNEOes9QQp6zQz9cC8+3cC9pizdv6WwO9dFCh7drlbqJh0usMaXZ/ws58DbjtpbMzhW Q4Le+ESSnUUIax3jPhkC9qnJOC4jid0/Ri70IJ2Y/AvP6BSsWL+QEaSSAj10qEJ8tJkQ qU20CC4UT3DynTsI2MY5L8WogOa0OWT+NfGc1q/OR7eTVscSUWLTpFxWFRwWQSxpBIb4 hQNQ== X-Forwarded-Encrypted: i=1; AFNElJ8iDTbCwzLTic+/+lMmG5yecBUJNNThM15gs9JyHjGh0BWiefH3t3PBw2H9a/XdhQgyMV4Y2TIm8sxC7AE=@vger.kernel.org X-Gm-Message-State: AOJu0Yw7Xyh2L5pt6OAMWrzxz7MdUYJqnDGlavc+ixxcUnKBW42y/iZE x9q6BVXPpVNCJlLg+5KsZ6/4be5JMT9G0pSrsZhTgWAgSV3I1PQoYsBhSNG6W4WnCrCY+fOtivq yBnkvqdhtI/sqkRwj2AuxUdjTkcbHkH6jTaIqsRqH6u065m9XOjR+9eKAL7Fwy/dN1GvO56l9WH g= X-Gm-Gg: AfdE7cnEUQfZyS/7iRbnkaHrKWOLOiEoQ9qsUy5JnzTVkIq4uiFnvMcRHbG8u+l3Uza ST2nHf1mg1onwvKZoDvVZQItzrLjJfAERTDsL10n5D4FIhPAnuKryo86t1GKOZM6FJaP9+k6K8x pJ/PKL4nxOeWe29Fxmg8L+vLwefq6K6GBp4aawk6HWxw5y7r1ovbxms8q8zubZCzIRwUZEnJO7k 1eGUs0mHYc23M+gYYy3KBUlv8aO0RAdYuT/mIVXDwPJ5Vl/7YML2CNfZANsDqjPuUVnhTYpwn4J D1AP0QbLAXT45scUgk5uNPNWyb354lOwbihYHRUZeW/U20IcyMuYeMIzC+C/aNUciReLI6c1yOe TOEvftWzagsAILWQpl2buJcHl8741Fa3c8xDi X-Received: by 2002:a05:6a00:1307:b0:842:21f0:5113 with SMTP id d2e1a72fcca58-8455088e136mr13692116b3a.24.1782104967257; Sun, 21 Jun 2026 22:09:27 -0700 (PDT) X-Received: by 2002:a05:6a00:1307:b0:842:21f0:5113 with SMTP id d2e1a72fcca58-8455088e136mr13692050b3a.24.1782104965798; Sun, 21 Jun 2026 22:09:25 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84564d6c5dbsm5905996b3a.12.2026.06.21.22.09.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 21 Jun 2026 22:09:25 -0700 (PDT) From: Sumit Kumar Date: Mon, 22 Jun 2026 10:39:16 +0530 Subject: [PATCH v4 2/3] bus: mhi: ep: Add mhi_ep_queue_buf() API for raw buffer queuing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260622-loopback_mhi-v4-2-782b3a0f2eef@oss.qualcomm.com> References: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> In-Reply-To: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> To: Manivannan Sadhasivam Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1782104957; l=4444; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=gGfaQBQV4ve45W3l4vga1g6v8XiqE+OMpkXU/G8WWwU=; b=Inx12IRZtn+PGKi5C1sB8q4ewBGMbnrNj8GYASSzmUwR1k7xA3mbnVEG8aUXfV+Xod2ur6uq5 01H8HcJBDr8BFAzLvLBvrjsrtJTYRYlP8ncdGf4jBCr4NQ0tn5QOv4s X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfX0p3oGUoYhtEQ vzhJa+sY3sz3HvLO9/RaUSM9MI7KuUH8AdK9RvimgfpV4lqO0iBrPlHgRp8mV04VI+mYnU+6xYS 2wJpKIQN3PcNOOu16UzMiHJ6FMf6QOaAZBaEuhxtXjdTYRjhp+U9MLj9jpYo+ikONjeMND9IPnM jLrAhHnP0Iinv66OhVYeT9OyLJSJo+2Wu5W3G54JDD9aOLwprP859BTsAWFbNJ9hwNmJAKaTXww qfK+MjYRlRUtkxKtTdBx7gu23oTVDiQEDfnl+qK8phFy1LBTZ1OOUud7TtuCwoiDImEJQSaYp43 c4V06aGjRvQ/G1uUSeX5H6qfy+L/g8lXlDB32nuNOZqobx+dHPBbyZqT9KymEVoAQIPkMn7BbMn DO46xw4vgqqF3/HZWxe+rDqjBBLrXlGEB4XyHzb4UlI9X0wJebNnrKxogta7PePEiHqxhZHM3u+ KHDKcjoWrvVesbGR+Bg== X-Authority-Analysis: v=2.4 cv=MtFiLWae c=1 sm=1 tr=0 ts=6a38c388 cx=c_pps a=WW5sKcV1LcKqjgzy2JUPuA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=27Ti7_ZD70JoqEhemiIA:9 a=QEXdDO2ut3YA:10 a=OpyuDcXvxspvyRM73sMx:22 X-Proofpoint-GUID: MqvxTQq4-xTDhHlwUDan5n1vLguMbeVH X-Proofpoint-Spam-Info: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfX5Nx7fe/8WIX3 6X78+QFRQIU+TK4THa0A4piH0iHyi3rvqXtvHY9peMEHydiBdWfAlxGctam+z3cFuWQJQ6g2bFf VreZzcSWR2+5iVZAN0yMPCU2nuGlEzI= X-Proofpoint-ORIG-GUID: MqvxTQq4-xTDhHlwUDan5n1vLguMbeVH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-22_01,2026-06-18_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 bulkscore=0 clxscore=1015 phishscore=0 adultscore=0 spamscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606220047 Some MHI endpoint clients do not use socket buffers and need a way to queue raw buffers for DL transfers. Add mhi_ep_queue_buf() to support this use case. Refactor mhi_ep_queue_skb() to delegate to a new internal mhi_ep_queue() helper shared by both APIs, and rename mhi_ep_skb_completion() to mhi_ep_buf_completion() to reflect its broader use. Signed-off-by: Sumit Kumar --- drivers/bus/mhi/ep/main.c | 29 ++++++++++++++++++++--------- include/linux/mhi_ep.h | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index b3eafcf2a2c50d95e3efd3afb27038ecf55552a5..d44e1e54cfb4404b6589aab372e= 687db7492d3c3 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -516,7 +516,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *r= ing) return 0; } =20 -static void mhi_ep_skb_completion(struct mhi_ep_buf_info *buf_info) +static void mhi_ep_buf_completion(struct mhi_ep_buf_info *buf_info) { struct mhi_ep_device *mhi_dev =3D buf_info->mhi_dev; struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; @@ -544,22 +544,22 @@ static void mhi_ep_skb_completion(struct mhi_ep_buf_i= nfo *buf_info) =20 mhi_ep_ring_inc_index(ring); } - /* TODO: Handle partially formed TDs */ -int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) +static int mhi_ep_queue(struct mhi_ep_device *mhi_dev, void *buf, size_t l= en, + void *cb_buf) { struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; struct mhi_ep_chan *mhi_chan =3D mhi_dev->dl_chan; struct device *dev =3D &mhi_chan->mhi_dev->dev; struct mhi_ep_buf_info buf_info =3D {}; struct mhi_ring_element *el; - u32 buf_left, read_offset; + size_t buf_left, read_offset; struct mhi_ep_ring *ring; size_t tr_len; u32 tre_len; int ret; =20 - buf_left =3D skb->len; + buf_left =3D len; ring =3D &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; =20 mutex_lock(&mhi_chan->lock); @@ -582,13 +582,13 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, s= truct sk_buff *skb) tre_len =3D MHI_TRE_DATA_GET_LEN(el); =20 tr_len =3D min(buf_left, tre_len); - read_offset =3D skb->len - buf_left; + read_offset =3D len - buf_left; =20 - buf_info.dev_addr =3D skb->data + read_offset; + buf_info.dev_addr =3D buf + read_offset; buf_info.host_addr =3D MHI_TRE_DATA_GET_PTR(el); buf_info.size =3D tr_len; - buf_info.cb =3D mhi_ep_skb_completion; - buf_info.cb_buf =3D skb; + buf_info.cb =3D mhi_ep_buf_completion; + buf_info.cb_buf =3D cb_buf; buf_info.mhi_dev =3D mhi_dev; =20 /* @@ -627,8 +627,19 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, st= ruct sk_buff *skb) =20 return ret; } + +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) +{ + return mhi_ep_queue(mhi_dev, skb->data, skb->len, skb); +} EXPORT_SYMBOL_GPL(mhi_ep_queue_skb); =20 +int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len) +{ + return mhi_ep_queue(mhi_dev, buf, len, buf); +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_buf); + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 7b40fc8cbe77ab8419d167e89264b69a817b9fb1..59f796e56207aaf8be09edc9ba4= d1f59b665581f 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -302,4 +302,19 @@ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_d= ev, enum dma_data_directio */ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb); =20 +/** + * mhi_ep_queue_buf - Send buffer to host over MHI Endpoint + * @mhi_dev: Device associated with the DL channel + * @buf: Buffer to be queued. On success, ownership passes to the MHI stac= k; + * the caller must not free @buf until the DL transfer callback fires + * with result->buf_addr equal to @buf. On failure, the caller retai= ns + * ownership and must free @buf. + * Note: if @len spans multiple host DL TREs, the DL transfer callba= ck + * fires once per TRE, each time with result->buf_addr equal to @buf. + * @len: Size of the buffer + * + * Return: 0 if the buffer has been sent successfully, a negative error co= de otherwise. + */ +int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len); + #endif --=20 2.34.1 From nobody Thu Jul 2 12:39:45 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 6120E356754 for ; Mon, 22 Jun 2026 05:09:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104972; cv=none; b=Sq7N5jxRoRYt/zPIhMWQ72k8ik45XifLZWGrDpwoQDJv70Uttdu7Cg9IAR3X4fIQz37nbLxhumszSAJxjAM0v0WSu8skY1Zz3TVXEejMCfYA1MgYooPXBlBesUsainJ+CbNvd6GLRl+fNKoNQVzx/jk+oWW/e9vUMCtGoDGpBw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782104972; c=relaxed/simple; bh=yx64t4XAMHE0z7lDJmlBWupNmecgou3W14tKJ6zAt7A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UFQ0A7Rvq2SLx2JRZz+i6UrX3eW+YLXv9iJTE/4qWCtPhaM4gnmAdA0gvFIzd1flMOEz49lQu7H5cKBlhd0W6cEV8tY3z001HrlNN7zXKSCVINjxDzVllJnD/cxjYTleaoiGiOe0j6DVMN5vYF1hbwdSV6tpMdPFJh/7OgTai3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=L/zFe7t1; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=OXZI+LnE; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="L/zFe7t1"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="OXZI+LnE" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65LDtchB2498854 for ; Mon, 22 Jun 2026 05:09:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 2foTe9u0+0jA2F7WQbtMiKVUOBLINMVJce7lwxJmKq8=; b=L/zFe7t1p6n6oT+R jNS6Vvsgq2tlYpfx+f+vkimhpSpQhZ8828uKXkQX/hlZTWMgtTGemzYVvKnKxUht LrUAfovoTNWDjvR/qBg2aJlqsTwMjLlTwe6zKz05leEeKb4EM+TzyyXhoyy6wTPD w4gLzvKzI0Ma039fvuvNeNCjNcah2BTMQP/o/ZsFdesFqHAfR50K6xkoVi2XTJIC lwt3X4eKYjTTnbApG8ATBPC2DMqqlrMrciujhUa92ZUJGYrigps1cQC6cVtr0+rY 04KbiStJbYN2wjx3VQEUxkGDHQukClK5zjcub9DJ4zoJghyL0+Cp/I7sJb1TU8r6 MCf4kg== Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ewjexvvg7-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 22 Jun 2026 05:09:30 +0000 (GMT) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-842446a3851so2006860b3a.0 for ; Sun, 21 Jun 2026 22:09:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782104969; x=1782709769; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=2foTe9u0+0jA2F7WQbtMiKVUOBLINMVJce7lwxJmKq8=; b=OXZI+LnEuP0hkLNs39pq4KSUMaYU6UrGle9kOQOTkGpn/tLk4RJGTGQDbPITYsmAYD pPSWiIxuoh8s6qTjp3/N/kXQznDpNs8SMRdJZqemXS0eAY+/7e57uW1pYPTJQT/0gnOP ZuEV71/6yfyQsB0OCrLpubASPnmWFbdrPD7BQVUXb+NKoID3bN4oQ90RmNeWhEPElZph XsTsxDdprvSHhPR4R8u24865yEhOoWpW5g3ccza/TA7KWNqopbA4F1MftY310HwMY1gz viSgWxhCzm445b4u3T6XXFYDaRgqcjXUkSvN2G5HztIci5/aho4PaEUgxsTs5UV5Xvt1 C12g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782104969; x=1782709769; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=2foTe9u0+0jA2F7WQbtMiKVUOBLINMVJce7lwxJmKq8=; b=WRQ2MavTEgVtXuhQP+fZYbSx6kRzYbAOCMUMShH6wBYZIEdfgj57WfEiL10i9v2CCL mPJL8nWmUZAOKmz+IVmfaukHxxeGexHYCB+TXjDKs7Lrz/Z/FW7GKvUyKMakogXR5Hyc 0qXFIx6lIcGEMF0ix+uyU+h2lqnx+UZuxgandt8ldfctTHaxZVXQrP2UC9672H9lvTWL 5m/oE1pz1XwL/iejf3cKhOcDJDZnc9MO+DxjyiW8FAfnrq8CduTUFEbIuzuttHkLKItK kvuMjmqQ3GLQuIXtaUcEKpSN69DS7oqRo6EK3z+zcLcYHw+tpGNbe4cKUtk5cyfzBTUr p9GA== X-Forwarded-Encrypted: i=1; AFNElJ+3bJeyExDPXb5k6tZm5/C0IgekVqNWrmlxELHfLaTj6W+Gvb7mWxnjD9xqBqZg1fQgMtGZQrXxOj73c+Q=@vger.kernel.org X-Gm-Message-State: AOJu0YzmImt2XyIYKt3xepyk3UQrjPn5H31YNpfov9kJeIx9n4dpT4k0 YHUJgJuplscAi2dy4d85jgcboG4CgphMvOs98cNYIzY4zo9wbLqBIyWFOqsatWCM/VwZ/ELZyIq mC7d80rLGkO3l7BPBV8AZcKyNPP+iHApBdd7vNqcWHovnIv9VXarmNEUZXhfgZRb/ax6/SjJniw s= X-Gm-Gg: AfdE7cnjvAZWFeJH6oTToOgLB8l8KarGZDM2n13RlT7VVxyRvgW+VIOkPI24v5TKfUZ sK2Fya9yEiV4m7i1JS51r1Rt2y7S/F6b0mONEbwjZvgDDEVHJS1u6mKCc17RKK62KBNPHJDf3M0 2COlshLGCjRIXqE1S8YeeuHGxxYB9CU7bMHwoyjoKMWrB2wtI0xEq1vJfJ8bCacgqPtZAjg5Oxf U4V/bamV5e2+7HGzU2nhbZEKcuNKRxtyojSrdrQsW/YbFvhPkClSO2YXzNIZD9nh9+QjRmTgluK F0cnHbeQ3+pOG8nkBcTNLo8oTEiH0xBeut9iz0f1URMAIVNfmVipVoH5rSMLzhqy7lxg2kjCuN3 kEm469f3uCpisC8Y1L9QsF9l70kdOfItTlSbJ X-Received: by 2002:a05:6a00:94f6:b0:82f:2b0:2809 with SMTP id d2e1a72fcca58-8455077cc5fmr14048559b3a.1.1782104969184; Sun, 21 Jun 2026 22:09:29 -0700 (PDT) X-Received: by 2002:a05:6a00:94f6:b0:82f:2b0:2809 with SMTP id d2e1a72fcca58-8455077cc5fmr14048532b3a.1.1782104968497; Sun, 21 Jun 2026 22:09:28 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84564d6c5dbsm5905996b3a.12.2026.06.21.22.09.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 21 Jun 2026 22:09:28 -0700 (PDT) From: Sumit Kumar Date: Mon, 22 Jun 2026 10:39:17 +0530 Subject: [PATCH v4 3/3] bus: mhi: ep: clients: Add loopback driver for data path testing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260622-loopback_mhi-v4-3-782b3a0f2eef@oss.qualcomm.com> References: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> In-Reply-To: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> To: Manivannan Sadhasivam Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar , Krishna Chaitanya Chundru X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1782104957; l=7123; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=yx64t4XAMHE0z7lDJmlBWupNmecgou3W14tKJ6zAt7A=; b=gNhPY9LtEd/nPhg9yrSsepZfRkA6bDOBQOhFmG4SoIbgCwU7NJtVL1FUO7Ju0LBLLP7qsWCUA EBEWynyk9OaCYvUmMiFC+j0jpicmloeik9UeQbdJgeaG5Ab5jwTtqEI X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfXwbRvhcrWVNYE ObWsClEPL8NMAttr9J9WMQTamQ9jjY/xix8KA1DmmcD9DwFcUcJR1hnpqqUJ35BxVEwvQ911Vy/ l6N1Up+IJXQeUEvotgRCxnxlVMUuX+3cosnx3sSQ2B+yriup18ucU8p6Ct8jZYXGAbJK//9RMJo AyvHmGEjgLX27+mRQ11kwVwzxSxt+KGrLyPW2FYxFIpz/b9k/BYQ8iFY7Z083QvSq58MnHIQ06i MLKhzAzDfmQ9UjaGlhATmIs11LZAzCUFJo4MJuAgOoAFnzjwws48WF0HslGswWfZwoDQQIQ/Ult 8XDVI7SkaMC40Y0j0yARHpnvJgFQPp2AxoL8wYOqY7cLtNH/TSVTHTVFXFtKnfERjZr5eKQ0QvU d9agZ8A1ELDdFaXu910vyBEnzIbFJcHGe9Odfv/cfoXn8JrpvKVetZBzKrSCWrr9qnYao/vPYpL TGcLkO4Tiw/uAGwoDFA== X-Proofpoint-ORIG-GUID: fR-RbfF0f7LJZJBPzmW40SLEkzBcT-TB X-Proofpoint-Spam-Info: AW1haW4tMjYwNjIyMDA0NyBTYWx0ZWRfXzJWi8oJ3/w7B TQdUhcffCdFmw2FoUMr3C3Fe3s0KTQ4YFglqUCmZniDDZlaczTYaoi+ASZDkQCoiM2b+vn2Etul nwOmytSOrbuanL4x9d+WbstYN6sQR3g= X-Authority-Analysis: v=2.4 cv=YtA/gYYX c=1 sm=1 tr=0 ts=6a38c38a cx=c_pps a=m5Vt/hrsBiPMCU0y4gIsQw==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=F9PWhn0UeK7EsyOwsFYA:9 a=QEXdDO2ut3YA:10 a=IoOABgeZipijB_acs4fv:22 X-Proofpoint-GUID: fR-RbfF0f7LJZJBPzmW40SLEkzBcT-TB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-21_02,2026-06-18_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 phishscore=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0 impostorscore=0 adultscore=0 suspectscore=0 clxscore=1015 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606220047 When an MHI endpoint device runs Linux, there is no firmware to implement the LOOPBACK channel echo that real modem firmware provides. Without an endpoint-side driver, the host loopback test has no software echo partner and cannot exercise the full end-to-end MHI data path. Add an endpoint-side loopback driver that binds to the LOOPBACK channel and echoes received data back to the host. An ordered workqueue is used for asynchronous processing to preserve packet ordering. Together with the host-side loopback driver, this enables complete MHI data path validation for Linux-based endpoint devices. Co-developed-by: Krishna Chaitanya Chundru Signed-off-by: Krishna Chaitanya Chundru Signed-off-by: Sumit Kumar --- drivers/bus/mhi/ep/Kconfig | 2 + drivers/bus/mhi/ep/Makefile | 1 + drivers/bus/mhi/ep/clients/Kconfig | 16 +++++ drivers/bus/mhi/ep/clients/Makefile | 2 + drivers/bus/mhi/ep/clients/loopback.c | 128 ++++++++++++++++++++++++++++++= ++++ 5 files changed, 149 insertions(+) diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig index 90ab3b040672e0f04181d4802e3062afcc7cf782..9edb81b39890e093a51138465a4= d7705767eafa5 100644 --- a/drivers/bus/mhi/ep/Kconfig +++ b/drivers/bus/mhi/ep/Kconfig @@ -8,3 +8,5 @@ config MHI_BUS_EP =20 MHI_BUS_EP implements the MHI protocol for the endpoint devices, such as SDX55 modem connected to the host machine over PCIe. + +source "drivers/bus/mhi/ep/clients/Kconfig" diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index aad85f180b707fb997fcb541837eda9bbbb67437..ab36ef2a40ab8174e5ddae44a3e= 6ccb8eb31168d 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MHI_BUS_EP) +=3D mhi_ep.o mhi_ep-y :=3D main.o mmio.o ring.o sm.o +obj-y +=3D clients/ diff --git a/drivers/bus/mhi/ep/clients/Kconfig b/drivers/bus/mhi/ep/client= s/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4cf27184058ca2be020885b6f57= b4cc44b5054b6 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MHI_BUS_EP_LOOPBACK + tristate "MHI Endpoint LOOPBACK client driver" + depends on MHI_BUS_EP + help + MHI Endpoint LOOPBACK client driver that binds to the MHI LOOPBACK + channel as defined in the MHI specification. The LOOPBACK channel is + implemented by MHI-based endpoint devices (modems, WLAN) in the field, + where the endpoint firmware echoes back whatever the host sends. + + This driver receives data on the uplink channel and echoes it back on + the downlink channel for testing the MHI endpoint data path. + + To compile this driver as a module, choose M here. The module + will be called mhi_ep_loopback. diff --git a/drivers/bus/mhi/ep/clients/Makefile b/drivers/bus/mhi/ep/clien= ts/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..71dc91cc63b02592b177cf66db6= 090748c0653a6 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_EP_LOOPBACK) +=3D mhi_ep_loopback.o +mhi_ep_loopback-y +=3D loopback.o diff --git a/drivers/bus/mhi/ep/clients/loopback.c b/drivers/bus/mhi/ep/cli= ents/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..05db91be6ffc5afe5a202296241= 0c96a7ec19962 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/loopback.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +struct mhi_ep_loopback { + struct workqueue_struct *loopback_wq; + struct mhi_ep_device *mdev; +}; + +struct mhi_ep_loopback_work { + struct mhi_ep_device *mdev; + struct work_struct work; + void *buf; + size_t len; +}; + +static void mhi_ep_loopback_work_handler(struct work_struct *work) +{ + struct mhi_ep_loopback_work *mhi_ep_lb_work =3D container_of(work, + struct mhi_ep_loopback_work, work); + int ret; + + ret =3D mhi_ep_queue_buf(mhi_ep_lb_work->mdev, mhi_ep_lb_work->buf, + mhi_ep_lb_work->len); + if (ret) { + dev_err(&mhi_ep_lb_work->mdev->dev, "Failed to send the packet\n"); + kfree(mhi_ep_lb_work->buf); + } + + kfree(mhi_ep_lb_work); +} + +static void mhi_ep_loopback_ul_callback(struct mhi_ep_device *mhi_dev, + struct mhi_result *mhi_res) +{ + struct mhi_ep_loopback *mhi_ep_lb =3D dev_get_drvdata(&mhi_dev->dev); + struct mhi_ep_loopback_work *mhi_ep_lb_work; + void *buf; + + if (!mhi_ep_lb) + return; + + if (!mhi_res->transaction_status) { + if (!mhi_res->bytes_xferd) + return; + + buf =3D kmemdup(mhi_res->buf_addr, mhi_res->bytes_xferd, GFP_KERNEL); + if (!buf) + return; + + mhi_ep_lb_work =3D kmalloc(sizeof(*mhi_ep_lb_work), GFP_KERNEL); + if (!mhi_ep_lb_work) { + kfree(buf); + return; + } + + INIT_WORK(&mhi_ep_lb_work->work, mhi_ep_loopback_work_handler); + mhi_ep_lb_work->mdev =3D mhi_dev; + mhi_ep_lb_work->buf =3D buf; + mhi_ep_lb_work->len =3D mhi_res->bytes_xferd; + + queue_work(mhi_ep_lb->loopback_wq, &mhi_ep_lb_work->work); + } +} + +static void mhi_ep_loopback_dl_callback(struct mhi_ep_device *mhi_dev, + struct mhi_result *mhi_res) +{ + kfree(mhi_res->buf_addr); +} + +static int mhi_ep_loopback_probe(struct mhi_ep_device *mhi_dev, const stru= ct mhi_device_id *id) +{ + struct mhi_ep_loopback *mhi_ep_lb; + + mhi_ep_lb =3D devm_kzalloc(&mhi_dev->dev, sizeof(*mhi_ep_lb), GFP_KERNEL); + if (!mhi_ep_lb) + return -ENOMEM; + + mhi_ep_lb->loopback_wq =3D alloc_ordered_workqueue("mhi_ep_loopback", WQ_= MEM_RECLAIM); + if (!mhi_ep_lb->loopback_wq) { + dev_err(&mhi_dev->dev, "Failed to create workqueue.\n"); + return -ENOMEM; + } + + mhi_ep_lb->mdev =3D mhi_dev; + dev_set_drvdata(&mhi_dev->dev, mhi_ep_lb); + + return 0; +} + +static void mhi_ep_loopback_remove(struct mhi_ep_device *mhi_dev) +{ + struct mhi_ep_loopback *mhi_ep_lb =3D dev_get_drvdata(&mhi_dev->dev); + + destroy_workqueue(mhi_ep_lb->loopback_wq); + dev_set_drvdata(&mhi_dev->dev, NULL); +} + +static const struct mhi_device_id mhi_ep_loopback_id_table[] =3D { + { .chan =3D "LOOPBACK"}, + {} +}; +MODULE_DEVICE_TABLE(mhi, mhi_ep_loopback_id_table); + +static struct mhi_ep_driver mhi_ep_loopback_driver =3D { + .probe =3D mhi_ep_loopback_probe, + .remove =3D mhi_ep_loopback_remove, + .dl_xfer_cb =3D mhi_ep_loopback_dl_callback, + .ul_xfer_cb =3D mhi_ep_loopback_ul_callback, + .id_table =3D mhi_ep_loopback_id_table, + .driver =3D { + .name =3D "mhi_ep_loopback", + }, +}; + +module_mhi_ep_driver(mhi_ep_loopback_driver); + +MODULE_AUTHOR("Krishna Chaitanya Chundru "); +MODULE_AUTHOR("Sumit Kumar "); +MODULE_DESCRIPTION("MHI Endpoint Loopback driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1