| From f471578e8b1a90623674433a01a8845110bc76ce Mon Sep 17 00:00:00 2001 |
| From: Alexander Wilhelm <alexander.wilhelm@westermo.com> |
| Date: Mon, 19 May 2025 16:58:37 +0200 |
| Subject: bus: mhi: host: Fix endianness of BHI vector table |
| |
| From: Alexander Wilhelm <alexander.wilhelm@westermo.com> |
| |
| commit f471578e8b1a90623674433a01a8845110bc76ce upstream. |
| |
| On big endian platform like PowerPC, the MHI bus (which is little endian) |
| does not start properly. The following example shows the error messages by |
| using QCN9274 WLAN device with ath12k driver: |
| |
| ath12k_pci 0001:01:00.0: BAR 0: assigned [mem 0xc00000000-0xc001fffff 64bit] |
| ath12k_pci 0001:01:00.0: MSI vectors: 1 |
| ath12k_pci 0001:01:00.0: Hardware name: qcn9274 hw2.0 |
| ath12k_pci 0001:01:00.0: failed to set mhi state: POWER_ON(2) |
| ath12k_pci 0001:01:00.0: failed to start mhi: -110 |
| ath12k_pci 0001:01:00.0: failed to power up :-110 |
| ath12k_pci 0001:01:00.0: failed to create soc core: -110 |
| ath12k_pci 0001:01:00.0: failed to init core: -110 |
| ath12k_pci: probe of 0001:01:00.0 failed with error -110 |
| |
| The issue seems to be with the incorrect DMA address/size used for |
| transferring the firmware image over BHI. So fix it by converting the DMA |
| address and size of the BHI vector table to little endian format before |
| sending them to the device. |
| |
| Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells") |
| Signed-off-by: Alexander Wilhelm <alexander.wilhelm@westermo.com> |
| [mani: added stable tag and reworded commit message] |
| Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> |
| Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com> |
| Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com> |
| Cc: stable@vger.kernel.org |
| Link: https://patch.msgid.link/20250519145837.958153-1-alexander.wilhelm@westermo.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/bus/mhi/host/boot.c | 8 ++++---- |
| drivers/bus/mhi/host/internal.h | 4 ++-- |
| 2 files changed, 6 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/bus/mhi/host/boot.c |
| +++ b/drivers/bus/mhi/host/boot.c |
| @@ -31,8 +31,8 @@ int mhi_rddm_prepare(struct mhi_controll |
| int ret; |
| |
| for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) { |
| - bhi_vec->dma_addr = mhi_buf->dma_addr; |
| - bhi_vec->size = mhi_buf->len; |
| + bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr); |
| + bhi_vec->size = cpu_to_le64(mhi_buf->len); |
| } |
| |
| dev_dbg(dev, "BHIe programming for RDDM\n"); |
| @@ -379,8 +379,8 @@ static void mhi_firmware_copy(struct mhi |
| while (remainder) { |
| to_cpy = min(remainder, mhi_buf->len); |
| memcpy(mhi_buf->buf, buf, to_cpy); |
| - bhi_vec->dma_addr = mhi_buf->dma_addr; |
| - bhi_vec->size = to_cpy; |
| + bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr); |
| + bhi_vec->size = cpu_to_le64(to_cpy); |
| |
| buf += to_cpy; |
| remainder -= to_cpy; |
| --- a/drivers/bus/mhi/host/internal.h |
| +++ b/drivers/bus/mhi/host/internal.h |
| @@ -31,8 +31,8 @@ struct mhi_ctxt { |
| }; |
| |
| struct bhi_vec_entry { |
| - u64 dma_addr; |
| - u64 size; |
| + __le64 dma_addr; |
| + __le64 size; |
| }; |
| |
| enum mhi_ch_state_type { |