From nobody Sun Feb 8 07:58:45 2026 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 EBBA032D0D3; Thu, 18 Dec 2025 16:51:48 +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=1766076709; cv=none; b=pbfNZVweR02hE9eMPGmkXmx7/b8Uj/FyfttKwACMz0gQi/yH+FS+DFuzz4EX8It+yjycz2FOvgLDBRtxe53jo7sou4LbdKJ4uT0HxjkitaQMkte+ax0jZRicDICNoKB+ICkzxEd6wFTboihhs0B3qS1VvC4IouW+NmfBBL/ANEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766076709; c=relaxed/simple; bh=YxHTWrJYc+g6iLoPGlsZLRmW365iCw1itGiu1ndEaZ8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eUCzR+EdNP5LacmNYcqrmdITM1XGYdhUqN8V2j/0//yLu+33X65boAPXOIE5bSRdqTjVJWQ18bw7DshlHomxhWJqFUHyV6uRJ4CMgK5kMty8VFYhah6dn3IOb5klvPEBWEUGweuldmDfCv7b8kB/xRvu3DhFg6FQnGmTdsrY6Gk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ww2a8fBE; 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="Ww2a8fBE" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7040DC116D0; Thu, 18 Dec 2025 16:51:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1766076708; bh=YxHTWrJYc+g6iLoPGlsZLRmW365iCw1itGiu1ndEaZ8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Ww2a8fBErtSdtBizbRqB+LuKC5HOn3LkHX4qKZyZH2JqaQgpJD9ypPKyWaqBG9LYj ITcU3rKgugE9iP/l9I41hhHongq9aH3FwgybYfLbF56cSJdbm2iEu4B6fW0qifXqMd qrK5Ntp1pDGAcW+VyKImzHWI+XGcTkHoQ2NdKQo+nGusj6tcKS8Pvzx4hD94iitNdO GpAcMoQmb+Rmdqx+sAfUWbmu3iLREAOK1o0E7IQ1hsqWAkkplTkjqC0PvSdvFVobGk 1Rs4atKXhngYIWjc2ehm9eqLXPgubcaMnMqZ8l9ExQIV8CIupGUV4kdemIb6yLuuAZ rkmgJvFvonJxA== 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 5EEA7D6E2B2; Thu, 18 Dec 2025 16:51:48 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Thu, 18 Dec 2025 22:21:44 +0530 Subject: [PATCH v2 1/2] net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels 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: <20251218-qrtr-fix-v2-1-c7499bfcfbe0@oss.qualcomm.com> References: <20251218-qrtr-fix-v2-0-c7499bfcfbe0@oss.qualcomm.com> In-Reply-To: <20251218-qrtr-fix-v2-0-c7499bfcfbe0@oss.qualcomm.com> To: Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam , Jeff Johnson , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Greg Kroah-Hartman , Loic Poulain , Maxim Kochetkov Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, ath12k@lists.infradead.org, netdev@vger.kernel.org, Bjorn Andersson , Johan Hovold , Chris Lew , Manivannan Sadhasivam , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=20271; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=WL+sdUsNc6R2lsvJYk7eg1/QItYMInVMp9bpp60qYvo=; b=owGbwMvMwMUYOl/w2b+J574ynlZLYsh0MVS6H5HkaxJf0a8bvjflmfOBqy6PbsuaR2z77i42e 8b7JLZNnYzGLAyMXAyyYoos6UudtRo9Tt9YEqE+HWYQKxPIFAYuTgGYSNZD9n92S5wNAsrnm6sc fZitvdD2aLxt7+LklMuHd7tKJP1i1u2UYjmdNF9V3SPg41/Lc9vmzZrFu9e/7YJxbJ2GMfvvlG7 lnyz/vXoM/hUEaE9va/3DMevD6xjBWbsjwq2Xr74j25v38J/7sVO1Zue+dv5PKYsxkNp5zcreZf f6O2fDv2eE9zby/cs8fy4mIiQjY6mXok1Q2Jd2qZaUtoP/jgs3F53eOMHRVcfZrk94+cqjPapXl NPFts3cEbTrqffeHeoeGfvit4S5mMmG6xd1Sd9Y81EsUvOvw42Vu47/YRA0P5sXW+HGqxf1t5u5 W6Oxv9CI692phl/6dpoaMf1zp8w3jTDksqpgfHM9NnQ3AA== 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 MHI stack offers the 'auto_queue' feature, which allows the MHI stack to auto queue the buffers for the RX path (DL channel). Though this feature simplifies the client driver design, it introduces race between the client drivers and the MHI stack. For instance, with auto_queue, the 'dl_callback' for the DL channel may get called before the client driver is fully probed. This means, by the time the dl_callback gets called, the client driver's structures might not be initialized, leading to NULL ptr dereference. Currently, the drivers have to workaround this issue by initializing the internal structures before calling mhi_prepare_for_transfer_autoqueue(). But even so, there is a chance that the client driver's internal code path may call the MHI queue APIs before mhi_prepare_for_transfer_autoqueue() is called, leading to similar NULL ptr dereference. This issue has been reported on the Qcom X1E80100 CRD machines affecting boot. So to properly fix all these races, drop the MHI 'auto_queue' feature altogether and let the client driver (QRTR) manage the RX buffers manually. In the QRTR driver, queue the RX buffers based on the ring length during probe and recycle the buffers in 'dl_callback' once they are consumed. This also warrants removing the setting of 'auto_queue' flag from controller drivers. Currently, this 'auto_queue' feature is only enabled for IPCR DL channel. So only the QRTR client driver requires the modification. Fixes: 227fee5fc99e ("bus: mhi: core: Add an API for auto queueing buffers = for DL channel") Fixes: 68a838b84eff ("net: qrtr: start MHI channel after endpoit creation") Reported-by: Johan Hovold Closes: https://lore.kernel.org/linux-arm-msm/ZyTtVdkCCES0lkl4@hovoldconsul= ting.com Suggested-by: Chris Lew Acked-by: Jeff Johnson # drivers/net/wireless/ath/... Cc: stable@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Acked-by: Jeff Hugo Acked-by: Paolo Abeni Reviewed-by: Jeff Hugo Reviewed-by: Loic Poulain Tested-by: Abel Vesa --- drivers/accel/qaic/mhi_controller.c | 44 ---------------------- drivers/bus/mhi/host/pci_generic.c | 20 +--------- drivers/net/wireless/ath/ath11k/mhi.c | 4 -- drivers/net/wireless/ath/ath12k/mhi.c | 4 -- net/qrtr/mhi.c | 69 +++++++++++++++++++++++++++++--= ---- 5 files changed, 60 insertions(+), 81 deletions(-) diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_c= ontroller.c index 13a14c6c6168..4d787f77ce41 100644 --- a/drivers/accel/qaic/mhi_controller.c +++ b/drivers/accel/qaic/mhi_controller.c @@ -39,7 +39,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -55,7 +54,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -71,7 +69,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -87,7 +84,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -103,7 +99,6 @@ static const struct mhi_channel_config aic100_channels[]= =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -119,7 +114,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -135,7 +129,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -151,7 +144,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -167,7 +159,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -183,7 +174,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -199,7 +189,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -215,7 +204,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -231,7 +219,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -247,7 +234,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -263,7 +249,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -279,7 +264,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -295,7 +279,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -311,7 +294,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -327,7 +309,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -343,7 +324,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -359,7 +339,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -375,7 +354,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -391,7 +369,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -407,7 +384,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -423,7 +399,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -439,7 +414,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, .wake_capable =3D false, }, }; @@ -458,7 +432,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -474,7 +447,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -490,7 +462,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -506,7 +477,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -522,7 +492,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -538,7 +507,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -554,7 +522,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -570,7 +537,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -586,7 +552,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -602,7 +567,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -618,7 +582,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -634,7 +597,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -650,7 +612,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -666,7 +627,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -682,7 +642,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -698,7 +657,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -714,7 +672,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -730,7 +687,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, .wake_capable =3D false, }, }; diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_= generic.c index e3bc737313a2..0884a384b77f 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -94,22 +94,6 @@ struct mhi_pci_dev_info { .doorbell_mode_switch =3D false, \ } =20 -#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring= ) \ - { \ - .num =3D ch_num, \ - .name =3D ch_name, \ - .num_elements =3D el_count, \ - .event_ring =3D ev_ring, \ - .dir =3D DMA_FROM_DEVICE, \ - .ee_mask =3D BIT(MHI_EE_AMSS), \ - .pollcfg =3D 0, \ - .doorbell =3D MHI_DB_BRST_DISABLE, \ - .lpm_notify =3D false, \ - .offload_channel =3D false, \ - .doorbell_mode_switch =3D false, \ - .auto_queue =3D true, \ - } - #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ { \ .num_elements =3D el_count, \ @@ -329,7 +313,7 @@ static const struct mhi_channel_config modem_qcom_v1_mh= i_channels[] =3D { MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0), MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2), @@ -762,7 +746,7 @@ static const struct mhi_channel_config mhi_telit_fn980_= hw_v1_channels[] =3D { MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2), }; diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/a= th/ath11k/mhi.c index acd76e9392d3..d2c44f7f9b62 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -34,7 +34,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qca6390[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -48,7 +47,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qca6390[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 @@ -99,7 +97,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qcn9074[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -113,7 +110,6 @@ static const struct mhi_channel_config ath11k_mhi_chann= els_qcn9074[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/a= th/ath12k/mhi.c index 08f44baf182a..2dbdb95ae7be 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -31,7 +31,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_qcn9274[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -45,7 +44,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_qcn9274[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 @@ -96,7 +94,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_wcn7850[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -110,7 +107,6 @@ static const struct mhi_channel_config ath12k_mhi_chann= els_wcn7850[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 69f53625a049..80e341d2f8a4 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -24,13 +24,25 @@ static void qcom_mhi_qrtr_dl_callback(struct mhi_device= *mhi_dev, struct qrtr_mhi_dev *qdev =3D dev_get_drvdata(&mhi_dev->dev); int rc; =20 - if (!qdev || mhi_res->transaction_status) + if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status = !=3D -ENOTCONN)) return; =20 + /* Channel got reset. So just free the buffer */ + if (mhi_res->transaction_status =3D=3D -ENOTCONN) { + devm_kfree(&mhi_dev->dev, mhi_res->buf_addr); + return; + } + rc =3D qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, mhi_res->bytes_xferd); if (rc =3D=3D -EINVAL) dev_err(qdev->dev, "invalid ipcrouter packet\n"); + + /* Done with the buffer, now recycle it for future use */ + rc =3D mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr, + mhi_dev->mhi_cntrl->buffer_len, MHI_EOT); + if (rc) + dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc); } =20 /* From QRTR to MHI */ @@ -72,6 +84,29 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, = struct sk_buff *skb) return rc; } =20 +static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev) +{ + u32 free_desc; + void *buf; + int ret; + + free_desc =3D mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE); + while (free_desc--) { + buf =3D devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_= KERNEL); + if (!buf) + return -ENOMEM; + + ret =3D mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl-= >buffer_len, + MHI_EOT); + if (ret) { + dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret); + return ret; + } + } + + return 0; +} + static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { @@ -87,20 +122,30 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_= dev, qdev->ep.xmit =3D qcom_mhi_qrtr_send; =20 dev_set_drvdata(&mhi_dev->dev, qdev); - rc =3D qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); - if (rc) - return rc; =20 /* start channels */ - rc =3D mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) { - qrtr_endpoint_unregister(&qdev->ep); + rc =3D mhi_prepare_for_transfer(mhi_dev); + if (rc) return rc; - } + + rc =3D qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); + if (rc) + goto err_unprepare; + + rc =3D qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); + if (rc) + goto err_unregister; =20 dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); =20 return 0; + +err_unregister: + qrtr_endpoint_unregister(&qdev->ep); +err_unprepare: + mhi_unprepare_from_transfer(mhi_dev); + + return rc; } =20 static void qcom_mhi_qrtr_remove(struct mhi_device *mhi_dev) @@ -151,11 +196,13 @@ static int __maybe_unused qcom_mhi_qrtr_pm_resume_ear= ly(struct device *dev) if (state =3D=3D MHI_STATE_M3) return 0; =20 - rc =3D mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) + rc =3D mhi_prepare_for_transfer(mhi_dev); + if (rc) { dev_err(dev, "failed to prepare for autoqueue transfer %d\n", rc); + return rc; + } =20 - return rc; + return qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); } =20 static const struct dev_pm_ops qcom_mhi_qrtr_pm_ops =3D { --=20 2.48.1 From nobody Sun Feb 8 07:58:45 2026 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 4E4732E266C; Thu, 18 Dec 2025 16:51:48 +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=1766076709; cv=none; b=t7crKT2x1tzd5FYYisX1agj02TwVJa9Wfzy8B6tLh7C49NYu4+ahHGi08mIrm3o5quGIj/Ul5UtHgesifhZZv9eHRkOftEeJ7G935hi4QsQbasK7RtPC44+eBdmfh4K75Nu2Zzoo/4vIGTC5yfhmBj8bYLexFhgJ3igaw+aJvIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766076709; c=relaxed/simple; bh=Q/8GpnfrMmlE2LL5HbEze0rIAQlIeIt7hlwv5Pmh084=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dP9wuH2slp5SXoEOihmJ0ilrigVU06/heyD3xGEF7pMPzsCBqb11P+b6pdUShmeZwtfZNQaKphqNjWdKR6kLXyQZvxWuz5f8lGALeElikkFM/dPcqRz979pyh2ujqPEj67iA24tbkDPOnLMJAqgK4/wTDc2d9f57oyjV3ZMOT8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N0qN6hm1; 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="N0qN6hm1" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7F6EAC116C6; Thu, 18 Dec 2025 16:51:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1766076708; bh=Q/8GpnfrMmlE2LL5HbEze0rIAQlIeIt7hlwv5Pmh084=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=N0qN6hm1RGtoVjHjBA5EV4109msEzFilC9TbhPOkhg9Jzdqs1G+JcfwlQ+e2kBx9C Gnfe8rYL7dMkmLnW5JNe7EFP8tMO/wFX2+BHXWC5kqa/g/jPlXgAlDR0T7ENmuhhTd xaJZrNzYSG/ZhnpU/I/hEvFeSdxerg0p5cBo3t+3xkp8qu6bEx8z62xiHmkkj0jVZc 1URpJ/BOATsROzK/GWPXnXYQJ1rpwQPikjlbZs57k1sdC16BCmDrd+qrypz4Nm2alh GXWzNYVJUWVStJkwH3EgC5fK/qPWpHJ2DnPJEoC/K/QD7JJuHCo1amsuha5wwn7Aow B654/jmZCED+A== 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 70CAAD6E2B3; Thu, 18 Dec 2025 16:51:48 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Thu, 18 Dec 2025 22:21:45 +0530 Subject: [PATCH v2 2/2] bus: mhi: host: Drop the auto_queue support 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: <20251218-qrtr-fix-v2-2-c7499bfcfbe0@oss.qualcomm.com> References: <20251218-qrtr-fix-v2-0-c7499bfcfbe0@oss.qualcomm.com> In-Reply-To: <20251218-qrtr-fix-v2-0-c7499bfcfbe0@oss.qualcomm.com> To: Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam , Jeff Johnson , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Greg Kroah-Hartman , Loic Poulain , Maxim Kochetkov Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, ath12k@lists.infradead.org, netdev@vger.kernel.org, Bjorn Andersson , Johan Hovold , Chris Lew , Manivannan Sadhasivam X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7811; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=999FZ005VmQ50ugtoGwa60OjoIrDOfJs9J4slqZv21E=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBpRDEiiTdzAY4ft40HzRS/ezsIRLSoNZ/RbJzA/ Z5McmZxO5eJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaUQxIgAKCRBVnxHm/pHO 9a0UB/47xAE0KkVsOsPKTNJuunouZCvnWWk7FUl9ISg4FYtiwi1wGkGHjRbrzqY6JlbI4vqSNvb 1mJ3w1xwTz1jCDmkOTZRiTJG1CtAaOMPfq3UTtDIKmcDGgvHXAR1/hBoW5uHxc0Di20efsj6aFt Zw+zsLIOxAwW3V7Zlzw5Uwcz7Q0rT0T0IOs4tAO5MeBpddib2JG9qYSKC2rmeUM71YSk9kJXGJ3 mTJxu6kLeu1gbv+qbwEp+tAqc4W2zm+GW0rEi+HaLuavVkjsDuDDWt3IrNdSWGnqARAvHk2vfOp 8BfRqhXE4Mw4D6hQzkmrwOnUTVSOvYO+aj1GrIToOwVsn/NT 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 Now that the only user of the 'auto_queue' feature, (QRTR) has been converted to manage the buffers on its own, drop the code related to it. Reviewed-by: Loic Poulain Signed-off-by: Manivannan Sadhasivam Reviewed-by: Jeff Hugo --- drivers/bus/mhi/host/init.c | 10 ----- drivers/bus/mhi/host/internal.h | 3 -- drivers/bus/mhi/host/main.c | 81 +------------------------------------= ---- include/linux/mhi.h | 14 ------- 4 files changed, 2 insertions(+), 106 deletions(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 099be8dd1900..b020a6489c07 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -841,18 +841,8 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cnt= rl, mhi_chan->lpm_notify =3D ch_cfg->lpm_notify; mhi_chan->offload_ch =3D ch_cfg->offload_channel; mhi_chan->db_cfg.reset_req =3D ch_cfg->doorbell_mode_switch; - mhi_chan->pre_alloc =3D ch_cfg->auto_queue; mhi_chan->wake_capable =3D ch_cfg->wake_capable; =20 - /* - * If MHI host allocates buffers, then the channel direction - * should be DMA_FROM_DEVICE - */ - if (mhi_chan->pre_alloc && mhi_chan->dir !=3D DMA_FROM_DEVICE) { - dev_err(dev, "Invalid channel configuration\n"); - goto error_chan_cfg; - } - /* * Bi-directional and direction less channel must be an * offload channel diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 7937bb1f742c..7b0ee5e3a12d 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -286,7 +286,6 @@ struct mhi_chan { bool lpm_notify; bool configured; bool offload_ch; - bool pre_alloc; bool wake_capable; }; =20 @@ -389,8 +388,6 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, struct image_info *img_info); void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); =20 -/* Automatically allocate and queue inbound buffers */ -#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 861551274319..53c0ffe30070 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -664,23 +664,6 @@ static int parse_xfer_event(struct mhi_controller *mhi= _cntrl, mhi_cntrl->runtime_put(mhi_cntrl); } =20 - /* - * Recycle the buffer if buffer is pre-allocated, - * if there is an error, not much we can do apart - * from dropping the packet - */ - if (mhi_chan->pre_alloc) { - if (mhi_queue_buf(mhi_chan->mhi_dev, - mhi_chan->dir, - buf_info->cb_buf, - buf_info->len, MHI_EOT)) { - dev_err(dev, - "Error recycling buffer for chan:%d\n", - mhi_chan->chan); - kfree(buf_info->cb_buf); - } - } - read_lock_bh(&mhi_chan->lock); } break; @@ -1177,17 +1160,12 @@ static int mhi_queue(struct mhi_device *mhi_dev, st= ruct mhi_buf_info *buf_info, int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir, struct sk_buff *skb, size_t len, enum mhi_flags mflags) { - struct mhi_chan *mhi_chan =3D (dir =3D=3D DMA_TO_DEVICE) ? mhi_dev->ul_ch= an : - mhi_dev->dl_chan; struct mhi_buf_info buf_info =3D { }; =20 buf_info.v_addr =3D skb->data; buf_info.cb_buf =3D skb; buf_info.len =3D len; =20 - if (unlikely(mhi_chan->pre_alloc)) - return -EINVAL; - return mhi_queue(mhi_dev, &buf_info, dir, mflags); } EXPORT_SYMBOL_GPL(mhi_queue_skb); @@ -1472,45 +1450,6 @@ static int mhi_prepare_channel(struct mhi_controller= *mhi_cntrl, if (ret) goto error_pm_state; =20 - if (mhi_chan->dir =3D=3D DMA_FROM_DEVICE) - mhi_chan->pre_alloc =3D !!(flags & MHI_CH_INBOUND_ALLOC_BUFS); - - /* Pre-allocate buffer for xfer ring */ - if (mhi_chan->pre_alloc) { - int nr_el =3D get_nr_avail_ring_elements(mhi_cntrl, - &mhi_chan->tre_ring); - size_t len =3D mhi_cntrl->buffer_len; - - while (nr_el--) { - void *buf; - struct mhi_buf_info info =3D { }; - - buf =3D kmalloc(len, GFP_KERNEL); - if (!buf) { - ret =3D -ENOMEM; - goto error_pre_alloc; - } - - /* Prepare transfer descriptors */ - info.v_addr =3D buf; - info.cb_buf =3D buf; - info.len =3D len; - ret =3D mhi_gen_tre(mhi_cntrl, mhi_chan, &info, MHI_EOT); - if (ret) { - kfree(buf); - goto error_pre_alloc; - } - } - - read_lock_bh(&mhi_cntrl->pm_lock); - if (MHI_DB_ACCESS_VALID(mhi_cntrl)) { - read_lock_irq(&mhi_chan->lock); - mhi_ring_chan_db(mhi_cntrl, mhi_chan); - read_unlock_irq(&mhi_chan->lock); - } - read_unlock_bh(&mhi_cntrl->pm_lock); - } - mutex_unlock(&mhi_chan->mutex); =20 return 0; @@ -1522,12 +1461,6 @@ static int mhi_prepare_channel(struct mhi_controller= *mhi_cntrl, error_init_chan: mutex_unlock(&mhi_chan->mutex); =20 - return ret; - -error_pre_alloc: - mutex_unlock(&mhi_chan->mutex); - mhi_unprepare_channel(mhi_cntrl, mhi_chan); - return ret; } =20 @@ -1600,12 +1533,8 @@ static void mhi_reset_data_chan(struct mhi_controlle= r *mhi_cntrl, mhi_del_ring_element(mhi_cntrl, buf_ring); mhi_del_ring_element(mhi_cntrl, tre_ring); =20 - if (mhi_chan->pre_alloc) { - kfree(buf_info->cb_buf); - } else { - result.buf_addr =3D buf_info->cb_buf; - mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); - } + result.buf_addr =3D buf_info->cb_buf; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); } } =20 @@ -1666,12 +1595,6 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_= dev) } EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer); =20 -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev) -{ - return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS); -} -EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue); - void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl =3D mhi_dev->mhi_cntrl; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index dd372b0123a6..88ccb3e14f48 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -215,7 +215,6 @@ enum mhi_db_brst_mode { * @lpm_notify: The channel master requires low power mode notifications * @offload_channel: The client manages the channel completely * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transiti= on - * @auto_queue: Framework will automatically queue buffers for DL traffic * @wake-capable: Channel capable of waking up the system */ struct mhi_channel_config { @@ -232,7 +231,6 @@ struct mhi_channel_config { bool lpm_notify; bool offload_channel; bool doorbell_mode_switch; - bool auto_queue; bool wake_capable; }; =20 @@ -743,18 +741,6 @@ void mhi_device_put(struct mhi_device *mhi_dev); */ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev); =20 -/** - * mhi_prepare_for_transfer_autoqueue - Setup UL and DL channels with auto= queue - * buffers for DL traffic - * @mhi_dev: Device associated with the channels - * - * Allocate and initialize the channel context and also issue the START ch= annel - * command to both channels. Channels can be started only if both host and - * device execution environments match and channels are in a DISABLED stat= e. - * The MHI core will automatically allocate and queue buffers for the DL t= raffic. - */ -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev); - /** * mhi_unprepare_from_transfer - Reset UL and DL channels for data transfe= r. * Issue the RESET channel command and let t= he --=20 2.48.1