From mboxrd@z Thu Jan 1 00:00:00 1970 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 281EC3F3279 for ; Mon, 17 Aug 2026 10:14:49 +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=1786961698; cv=none; b=VN3l8IJa9+HrEfUxucrQITYeW2leJMi1kK2zfSZCV1ViC2VvuhQ8DnAmOZole/ZuA/5USGwKaG7D75hAr/OQW+JlUSUAH8QcT6zQtvDywYsZPcBIrFXxfIoHl/f0M2M6gCajFbmDYVG00FtO57KUOGnAL6rZFKjpQTO/Y/nEybE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961698; c=relaxed/simple; bh=XoQxJJ4G4Dr0ttKF9Uej+JnGlrI6hRsCj0OAR11OKhY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MmUyKewGZ5P9oSO2A2uNRJUqtuVKzPq/q7pJoYoyv2ioyK5CeQolD7xyC6zNaonIwXJ8GlkQAIJRKwU3RSrW9a6NZnWhuxS3Ssv8Ccw7XupnpWLx9xIh5hfYni4A+8u1JYLbNrhNeahMMqzVh8VfGWs5Ltj9jo1oBURaTfUph5Q= 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=lMDBHQLm; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=exiyTiCv; 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="lMDBHQLm"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="exiyTiCv" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9dfXt2470492 for ; Mon, 17 Aug 2026 10:14:49 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= dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=lMDBHQLmNyAMV7LZ ibaz7TogGOvP8C0SOFc4gJ8XLNL5l9Pu+gXOUPgdfJW//riKYXc1v62LBruxC5uh bT7j1wGo6s1bIkd2dGrDwPnUwRNmm1z6SsjqFCSuHw4WES8G8CZKLo2LttjCVC4P Yx6RSvqx5ncDmpIqLntqzHp5DJAJsb3GFDmZK+EWgLrFTU4yuvymyAaaA5Qa5BSB NF0htXkJGTQaNSgNJaWqxDJH77i+9VDvqkvNKBlOks5uYdBYj3jjmGv77713ukO0 W9kzYkN8b5AXVcaQ2TbF6QUV0XEXxzGRMzkiq/ZFxIAYuzWevOIAMS8Bhj7h+1ok TFO2qg== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3wm7rpv8-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:14:49 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-3950b1371a7so2777907a91.2 for ; Mon, 17 Aug 2026 03:14:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786961688; x=1787566488; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=exiyTiCvOi4AYYbmz197q3S60pleLGwCr52KImp4E9gJKvswFzDsbCqi9ySAI2G1EG gr5MIzDGDSYN1Qq5JuFgvChvZhhjKh0IfP2XjZA6Qscv0n8WuQiiNiOLr2c+YbIbW/T5 jF4szFDRGh7X2In1hdm7ly5dlkOdt0p6ZMjMwNcj/2XnbpOnMeZZeNDG/Wx+T6SowOD8 x0zq3UrwwH7wGfYyF97aTjfwBUtdYNWyk6HlmhKYRbeLSgjz53VW4h5Cea9WIpFBZGOp a8QtV1Of6t/+sREdbllKhSMsA77D+6elRX6IVOZWH90NmC0bW29Ov9+7vZtISooM5vy2 Mmmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786961688; x=1787566488; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=T+4SlIZ0XOfna22CMNaoJBKJHWMVzvgLFpIwgoUhJR8Vs1ArOk1byBYyjw3HAME9zF g1sVl83whsl6M9rrEC27r7UDRXT8kHHRfpA9RU+f+PXTyFzd4BAvg7xj1coyCe2f7AlX LdUZSZngMBDfc7WdYGGZeGsik1L+zHYQ7GngWXRpoppHCWk+Ffd8ES9PgsYkGOeDqKXP VaaHTa9q2hziO6d+wy/GQ2M5zSy4grbDAH6/+s0CK3AB+FxW6pdrFFvgB5dA6yvABvN3 bX0bTjFnn2RxYI4eneCYfuqGFX6zU0Q2RFqa/oGVjaGBf8PqPolv9JdHOAvi0rNCgwf+ 79cw== X-Forwarded-Encrypted: i=1; AHgh+Rrs8JmuZtRcrWj+DkCPEML7ebvpJ6RNU/4WpDSEFy+mwVHoZXBu0ituiVm1fQZpYt7yDfQFUPPVAUgT/hQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwUGxT3ZGHjV+1jZnnVO4DN+1I/8P1h5AVQPVMZ0NpxUa0sj4mU k9vzAGgPQpO0lqEqAXUJKKfMq4byEs3jLXI+r2NxRNZhWgHpqzbNj+u7n3HS+kDIjsFw/774uuU h1s9RcsPQZ7mel9jdUzUzXROu566zLvxIXY2WjxnnsrFJxC9PCwSLWLYqflCoBc8+y4Z/VYMs3X I= X-Gm-Gg: AR+sD11OLw1DReAwq4BBoLLIPp6pGmCxcI3UMYCUjmGJ4CKXlDVYMtjZXWdMQGd/0rf G5HzaeVtGxfNyOWue6wulw86w6FIRFRVprThm8Zvzs8LHo3qJ2EQE083yHSKC9ZAVzLmKkIwWqV Fv3tcfaWgyjKKHuDwqZoPjD4N/8+mswEogK3cR8vtJFK1AgJBcpKnTUU/KY4VaJ3r6Xh4nx0N6o DxtdMoGLxL7cOVUVCaicgKKOMO+WdO8C15Q+ydIvhdbTx/sZPWsd3I80tf/ppX1zQRvmP9wdI3f EufzK3U5vEOHDn8WP3YktlbARhW31LuEakNOZPzuaI7/jf5LZdnarkQpp5PK8/huNK5xD9yAdny VUu/t9MgCCGsTNjJuw1+apkoCXQ== X-Received: by 2002:a17:90b:1a87:b0:38e:57a3:f218 with SMTP id 98e67ed59e1d1-3933b956294mr24198935a91.13.1786961688426; Mon, 17 Aug 2026 03:14:48 -0700 (PDT) X-Received: by 2002:a17:90b:1a87:b0:38e:57a3:f218 with SMTP id 98e67ed59e1d1-3933b956294mr24198874a91.13.1786961687867; Mon, 17 Aug 2026 03:14:47 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3954d3d2adcsm1744315a91.17.2026.08.17.03.14.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:14:47 -0700 (PDT) From: Sumit Kumar Date: Mon, 17 Aug 2026 15:44:36 +0530 Subject: [PATCH v5 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: 7bit Message-Id: <20260817-loopback_mhi-v5-3-50efc7360b7f@oss.qualcomm.com> References: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> In-Reply-To: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> To: Manivannan Sadhasivam , Jeff Hugo 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=1786961675; l=7186; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=XoQxJJ4G4Dr0ttKF9Uej+JnGlrI6hRsCj0OAR11OKhY=; b=6lYGLte404UZocgwzJBcKpkiCEszoNVkI0+J2liHJMXrXMFxi9/XCW9WX0+3hPCgfG7r/uzLw DXGl81ZwcK3Cn5S7/s3MiV3bO5GioGST8Hp7E/n6AsA3eh6AJx7DFS1 X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-GUID: HIofiggv23HSWLkuGZmP-IN4hR-gDAQl X-Proofpoint-ORIG-GUID: HIofiggv23HSWLkuGZmP-IN4hR-gDAQl X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfXz2yLIzRpEa1A rhzPNGIzqm/lBKVqImTwNhfLpxqRUmUv6vDjAJegjWE1A/UJctPB2pQMC3aWEJ8iehYn2Y+te8R MwQ/fpl/H+QOriVYBskEPXswmy9l2+cHtrOxHy1uYzKTuPxXYR2z6WgPsKzlczbLmxggfx9GA8f xh7HhQM5imnX1LJscVqPAu62/NTYBhVOPUbx6HzqdFWRdW9r1IpLe5YElRurm1genuPulUhpolF F3CMJoiBfvHeymI6C6aZQ3EGmy1Fu/MffPQNBvdzlizTMCsreMWLzdE4xQkPkEbyw7GiFd4mG9m sb70a8okJk555jwqxvp3Gsul0DmG51l2XwsRvv6M0HHcMWsIiIfgsngvUA/qOx/qHk+srZIA1ly WLnh/o97YEfrNnrhBhhuJtSC362hItMleC6s8f1d1KzSbUcARRzZliuFfqNLxVI+stxHhM3ZeM8 mc3F8GcyD1f4zrwhYsw== X-Authority-Analysis: v=2.4 cv=YqM/gYYX c=1 sm=1 tr=0 ts=6a82df19 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=F9PWhn0UeK7EsyOwsFYA:9 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfX+Le7YweEeDb/ qvUoGZQESup/iOkyG4cHOiamWEYRcEpwEefMfPF3xvb70GoPJj0mHMae6kJ+qVUJFuD5UWNqQNa 5FQhUVjHMjrPL/PCtapHzHZ3kCAKypE= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 impostorscore=0 suspectscore=0 adultscore=0 clxscore=1015 bulkscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170075 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 | 130 ++++++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+) diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig index 90ab3b040672e0f04181d4802e3062afcc7cf782..9edb81b39890e093a51138465a4d7705767eafa5 100644 --- a/drivers/bus/mhi/ep/Kconfig +++ b/drivers/bus/mhi/ep/Kconfig @@ -8,3 +8,5 @@ config MHI_BUS_EP 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..ab36ef2a40ab8174e5ddae44a3e6ccb8eb31168d 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o mhi_ep-y := main.o mmio.o ring.o sm.o +obj-y += clients/ diff --git a/drivers/bus/mhi/ep/clients/Kconfig b/drivers/bus/mhi/ep/clients/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4cf27184058ca2be020885b6f57b4cc44b5054b6 --- /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/clients/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..71dc91cc63b02592b177cf66db6090748c0653a6 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_EP_LOOPBACK) += mhi_ep_loopback.o +mhi_ep_loopback-y += loopback.o diff --git a/drivers/bus/mhi/ep/clients/loopback.c b/drivers/bus/mhi/ep/clients/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..18a92d6a40e0f7de277d155cdb5495d14a60c19d --- /dev/null +++ b/drivers/bus/mhi/ep/clients/loopback.c @@ -0,0 +1,130 @@ +// 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 *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 = container_of(work, + struct mhi_ep_loopback_work, work); + int ret; + + ret = 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 queue buffer: %d\n", ret); + 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 = 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 = kmemdup(mhi_res->buf_addr, mhi_res->bytes_xferd, GFP_KERNEL); + if (!buf) { + dev_err(&mhi_dev->dev, "Failed to allocate loopback buffer\n"); + return; + } + + mhi_ep_lb_work = kmalloc(sizeof(*mhi_ep_lb_work), GFP_KERNEL); + if (!mhi_ep_lb_work) { + dev_err(&mhi_dev->dev, "Failed to allocate loopback work\n"); + kfree(buf); + return; + } + + INIT_WORK(&mhi_ep_lb_work->work, mhi_ep_loopback_work_handler); + mhi_ep_lb_work->mdev = mhi_dev; + mhi_ep_lb_work->buf = buf; + mhi_ep_lb_work->len = mhi_res->bytes_xferd; + + queue_work(mhi_ep_lb->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 struct mhi_device_id *id) +{ + struct mhi_ep_loopback *mhi_ep_lb; + + mhi_ep_lb = devm_kzalloc(&mhi_dev->dev, sizeof(*mhi_ep_lb), GFP_KERNEL); + if (!mhi_ep_lb) + return -ENOMEM; + + mhi_ep_lb->wq = alloc_ordered_workqueue("mhi_ep_loopback", WQ_MEM_RECLAIM); + if (!mhi_ep_lb->wq) { + dev_err(&mhi_dev->dev, "Failed to create workqueue\n"); + return -ENOMEM; + } + + mhi_ep_lb->mdev = 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 = dev_get_drvdata(&mhi_dev->dev); + + destroy_workqueue(mhi_ep_lb->wq); +} + +static const struct mhi_device_id mhi_ep_loopback_id_table[] = { + { .chan = "LOOPBACK"}, + {} +}; +MODULE_DEVICE_TABLE(mhi, mhi_ep_loopback_id_table); + +static struct mhi_ep_driver mhi_ep_loopback_driver = { + .probe = mhi_ep_loopback_probe, + .remove = mhi_ep_loopback_remove, + .dl_xfer_cb = mhi_ep_loopback_dl_callback, + .ul_xfer_cb = mhi_ep_loopback_ul_callback, + .id_table = mhi_ep_loopback_id_table, + .driver = { + .name = "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"); -- 2.34.1