From mboxrd@z Thu Jan 1 00:00:00 1970 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 E99CE2BF3F4 for ; Wed, 24 Jun 2026 11:12:18 +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=1782299540; cv=none; b=kxvb2RD5agl0YsN/Bh6/b20LRY+JEngfSobA3Q5Xyxo3wLSILJAhUEstQt4mVdMANC3/DKC3nb+TY4uiRNfJTBRJMVS15DEDnz0SaaX1fD8+xSDdDzDwkV0R2FLQWDW+o+TsPYLJQI29+9+nR6hdL5ewn1b6Ccq7ygzWPtGPnYk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782299540; c=relaxed/simple; bh=zww7f4sFzsfUZ30J7VOgNS8sQF0fjHN+eCJz+LiNUos=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=OynSGAIDq9Ms6yPdnvNlM/Xw+fB/83GTT2aMF7+b6E9nRsdJXT/joY4fQgEr+nYHTOaVcsDZxKAV7h7Yk1QkG9fSQj+L1yh1hmk48XrOqoPxLcirNq0Jg98UTtS2oTXl1P+I+PzMsanh/JPSsafSif22fXVLIosOSBAy6DspRTM= 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=iWvVR8SZ; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=PywZ7x4j; 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="iWvVR8SZ"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="PywZ7x4j" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65OANUnJ3167315 for ; Wed, 24 Jun 2026 11:12:17 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= IlkzB21BQLyGO2BKUaCWrS3HNTUhTdWcAGomTPerZl8=; b=iWvVR8SZgE1JCi+S d5urdJGSckjzVsGa+aw8Blmn1E6YH5FBINGp4hdv84i+sz+DoFzOOpHQuh/mlNDb G8/bBTppdvA9XXwbxizS+fUpLqI0uFmFXctKjlu1BadytT3BIC906f7gcMBtxKQI IAg5KJb+22J0FdISa6lsz8eaYpitPL2eUHZJpoEqu5MUifphEqxDj360wsUWh6/2 OVfVlgmbWTCaae//EC/sBF2tyEoOQEtWWR9MvBCNw792KSHI8wcoCRMB2Ib2LHbr 9jxguqn8QNQ/vcwPlH26YOh7Xzj1wdZDD6KeFK2xoQlgJ2a9f7r4BbBKnaUPMDkQ Qb16cg== Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4f0996h94v-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 24 Jun 2026 11:12:17 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2c7ef28ce24so1459855ad.1 for ; Wed, 24 Jun 2026 04:12:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782299536; x=1782904336; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=IlkzB21BQLyGO2BKUaCWrS3HNTUhTdWcAGomTPerZl8=; b=PywZ7x4jrR9Hhflgpwg4dxrCSdEIrH8rfovxxz3FI001pgDT/aOikxzFFGfgpfSOCe bTHg811NBgEcYC+ZdfKJaxBJmKcLMpRtP/9Vv0bjKKrqKS9pX3kdA2F7a7l7yzsxV4r6 tpVDzWwSlQZHcTw+bOOcmQIcBQBVBC5Fk4CGGeYX85prSUY0XC6O5BB0U/LMy3GFevzC 0fxS9k1y7kG9nziutye4i6A8njHbkeRJaPfIHHJdRkkJCHifH+Lib5LeIG792IsvTRGs Kh6qHH+0+fdZw8BTHzUyatBDufDu/ctklUMDSyTP2gVH2/3R0kxOmznBWFsYMek2SyJX 6bjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782299536; x=1782904336; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IlkzB21BQLyGO2BKUaCWrS3HNTUhTdWcAGomTPerZl8=; b=QRv0Jtpb5uk6dmWWwF4RPiA1MTH0s5pyW2LhIgCjWdKxdqZOzkV3FIwZn9k5JtP8M0 jYAbeOaXuvmhyqOfzMRLQnYfPZzQEM/9XDBeB2xCTFkjpGPw60F+oj1x4zSQ8k9snRMj 9HMc23e8jVHsbiK5tKVTU+RMyUbH3cGYQrOYrIupSEdCWVmdROR8QTi7rq7TVOXDRnHU DzWYkQspihKvFlvQ0kMN7uQa3MtDt9ZDKPYR/k2D1aeI7uYk3S0kjjHCUpySuSASFZnc WyUSSzGg9ancGRhZ2kCdThLhvLBPW6XCFeHkG5dpEKO/TKrYSRXe/IZ5Y+erQiZrneKy Bthw== X-Forwarded-Encrypted: i=1; AHgh+RpotVd7jUUZlFo6mknfUDQz/5hOWcHWTszmtM4xZbQOno9SkWW2QmSJbhwsRRz5tG911fVwe+sNC6aKFXA=@vger.kernel.org X-Gm-Message-State: AOJu0YyzCoLTTP67o7Qpl1m9mXBiRyacC/vYOmrAip09LUytyNXpL8MP 07sQeCUkRHSm0uM+K6ulDS/zOSznhEgkGUjFFA/b6pXd8Tnbs2PU3+FsC+Wk+9n8VaqYuWXEVHV TOQSSXiMeAgpYartImCB5/xybFODbd+sWiPHXrASGGfZ/EN+R9wp/DYLz5QR14J5SXao= X-Gm-Gg: AfdE7cknTU+FA1qMNITJfMugPtxpGeVbuU2+FQagTxXRfTnCENz8VLCIDT679UpP1bt DDzcu7WNpd9G+2TpanJFIEvQ0OYGr+r3gdh8UPFVx4C07E+tjGguaSsF2ACNFh6XbsCivlfqVOl k7guTGh1I1WY9sE6WMZ9V5o8II+T234n2pKRGYwpQ3z52I4L/qp/hmthjVARl8dnDls8OQVD0PL X9eNKW0UnwLdDtOhT1w1fUpbGxUEFHDgN9FR1sBkIyj1pM08OoGRGzRMi8bstdaCntw+dg12Sdg g7lKiRjEYxSJZlTR1LWVIFj4Mqel4UkhyBounkaQSbOauuP0TZe7Y/KFxuk3GJgn88BNHLPS7Q8 sXXrPWEs5YYBI1hyNKXpYc4kSl4kNw1lT3ry4Rekn X-Received: by 2002:a17:902:ebc3:b0:2bf:dd8b:7cd with SMTP id d9443c01a7336-2c7c75c4046mr75507125ad.10.1782299536195; Wed, 24 Jun 2026 04:12:16 -0700 (PDT) X-Received: by 2002:a17:902:ebc3:b0:2bf:dd8b:7cd with SMTP id d9443c01a7336-2c7c75c4046mr75506755ad.10.1782299535537; Wed, 24 Jun 2026 04:12:15 -0700 (PDT) Received: from [10.217.219.124] ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c743bfdc97sm160971055ad.65.2026.06.24.04.12.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 24 Jun 2026 04:12:15 -0700 (PDT) Message-ID: <9f0c465e-f9ef-4511-97dc-e3ccb0347151@oss.qualcomm.com> Date: Wed, 24 Jun 2026 16:42:12 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v4 3/3] bus: mhi: ep: clients: Add loopback driver for data path testing To: Manivannan Sadhasivam Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Krishna Chaitanya Chundru References: <20260622-loopback_mhi-v4-0-782b3a0f2eef@oss.qualcomm.com> <20260622-loopback_mhi-v4-3-782b3a0f2eef@oss.qualcomm.com> Content-Language: en-US From: Sumit Kumar In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Proofpoint-GUID: 7nNmI9j5gjj_926stP-PVTVGbyAgsztC X-Proofpoint-ORIG-GUID: 7nNmI9j5gjj_926stP-PVTVGbyAgsztC X-Proofpoint-Spam-Info: AW1haW4tMjYwNjI0MDA5MyBTYWx0ZWRfX49OoDEXxYqbf kpvFipda60kplcfxBbN+A8btLHJRW5AKRe/iODiYs5gjcULsGYalL2mCyk1gUKof2xsixa/uoi7 dPbW8GTbQUImKYrKQcB/I/ltiOaZHKk= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjI0MDA5MyBTYWx0ZWRfX0Huuu/KufsU2 OBR/bhVLkpdOubv2IdCUhRfoSVxgG4QqtyMFG9fYhizJVW41gsgi+ch3+ugLjXaSZVZgdEW2lU2 /6neZSOxiewLU6z0pYOghOwa8tGKbbt+u3s9XPkSWudZqwAEceyk5lYlIJRL3IIS8cVtYBZb7nw /ALmwhLdInhP0FvZNj5tSkuiHH5u16NrjNpW0XseigJLGSSdKNNe8DIWW6U5q1EqZQQiz9PTif9 f6axlUfRnoSpfw9rklRyjWf0Q6ksQ3WsCdDW0JCSn8lQcm+WqgKY5eVK7g2j6D5QLuu4V6DjZBA bm00e3Zk++ldUu/SY2YF+yPrMeD/6N9ifObOupjEVMvigPQfnthhVunQ1zKAPFCQdCSm0GAiCjM bINUJlGDuV0del1yfFX38iBF1MLBJmSYgjawUJw5Wi67qdgp9oVBKJuNatcNHdnXFb2DNZhkYbs qmXGQ5LbJjKNGy2ax0w== X-Authority-Analysis: v=2.4 cv=Tv/WQjXh c=1 sm=1 tr=0 ts=6a3bbb91 cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=DC1agn4tkaTvQTsFoT0A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=GvdueXVYPmCkWapjIL-Q:22 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-24_03,2026-06-23_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 bulkscore=0 adultscore=0 lowpriorityscore=0 impostorscore=0 spamscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606240093 On 6/23/2026 2:47 PM, Manivannan Sadhasivam wrote: > On Mon, Jun 22, 2026 at 10:39:17AM +0530, Sumit Kumar wrote: >> 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..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..05db91be6ffc5afe5a2022962410c96a7ec19962 >> --- /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; > s/loopback_wq/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 send the packet\n"); > 'Failed to queue buffer' > >> + 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; > Hmm. This seems similar to patch 1 race condition. But we do not have a EP > specific API to stop a channel and flush the wq like > mhi_ep_unprepare_from_transfer(). But you should add one and call it from > remove(). mhi_ep_driver_remove() already does this before calling mhi_drv->remove():        mutex_lock(&mhi_chan->lock);       mhi_chan->xfer_cb(mhi_dev, -ENOTCONN);       mhi_chan->state = MHI_CH_STATE_DISABLED;       mhi_chan->xfer_cb = NULL;       mutex_unlock(&mhi_chan->lock); So by the time mhi_ep_loopback_remove() is entered, both channels are already stopped and xfer_cb is NULL. A mhi_ep_unprepare_from_transfer() call from remove() would be redundant. The race with mhi_ep_read_completion() is handled by setting dev_set_drvdata(NULL) before destroy_workqueue(), combined with the NULL guard in ul_callback. Please correct me if i am missing something here. -Sumit > >> + >> + 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) >> + return; > Error log? > >> + >> + mhi_ep_lb_work = kmalloc(sizeof(*mhi_ep_lb_work), GFP_KERNEL); >> + if (!mhi_ep_lb_work) { >> + kfree(buf); > Same here. > >> + 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->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 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->loopback_wq = 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"); > nit: Remove fullstop at the end of error message. > >> + 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->loopback_wq); >> + dev_set_drvdata(&mhi_dev->dev, NULL); > As mentioned above, this should be dropped if you can ensure that xfer_cb() > won't be called. > > - Mani >