]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bus: mhi: host: Fix endianness of BHI vector table
authorAlexander Wilhelm <alexander.wilhelm@westermo.com>
Mon, 19 May 2025 14:58:37 +0000 (16:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:24:27 +0000 (16:24 +0200)
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
drivers/bus/mhi/host/internal.h

index c9dfb1a48ad6d69bb4fc4b689590e83788a4833d..aacaaadf8ca678d079f9c6daa35106a6596c5cb0 100644 (file)
@@ -30,8 +30,8 @@ void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
        unsigned int i;
 
        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");
@@ -376,8 +376,8 @@ static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
        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;
index df65bb17fdbad0a8d31fe9844d1e663ac655db8c..2fa5bbcc69fe5c62eca804f0422797f346be68f0 100644 (file)
@@ -263,8 +263,8 @@ struct mhi_ring_element {
 };
 
 struct bhi_vec_entry {
-       u64 dma_addr;
-       u64 size;
+       __le64 dma_addr;
+       __le64 size;
 };
 
 enum mhi_cmd_type {