lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAOiHx=nSEP=4s2xZuPtLEO43YDbkNEYzw6V11JbXG0H2iPn7Ag@mail.gmail.com>
Date: Tue, 28 Oct 2025 21:19:53 +0100
From: Jonas Gorski <jonas.gorski@...il.com>
To: Caleb James DeLisle <cjd@...ns.fr>
Cc: nbd@....name, lorenzo@...nel.org, ryder.lee@...iatek.com, 
	shayne.chen@...iatek.com, sean.wang@...iatek.com, matthias.bgg@...il.com, 
	angelogioacchino.delregno@...labora.com, linux-wireless@...r.kernel.org, 
	linux-kernel@...r.kernel.org, linux-mediatek@...ts.infradead.org
Subject: Re: [PATCH] wifi: mt76: mmio_(read|write)_copy byte swap when on Big Endian

Hi,

On Mon, Oct 27, 2025 at 6:19 PM Caleb James DeLisle <cjd@...ns.fr> wrote:
>
> When on a Big Endian machine, PCI swaps words to/from LE when
> reading/writing them. This presents a problem when we're trying
> to copy an opaque byte array such as firmware or encryption key.
>
> Byte-swapping during copy results in two swaps, but solves the
> problem.
>
> Fixes:
> mt76x2e 0000:02:00.0: ROM patch build: 20141115060606a
> mt76x2e 0000:02:00.0: Firmware Version: 0.0.00
> mt76x2e 0000:02:00.0: Build: 1
> mt76x2e 0000:02:00.0: Build Time: 201607111443____
> mt76x2e 0000:02:00.0: Firmware failed to start
> mt76x2e 0000:02:00.0: probe with driver mt76x2e failed with error -145
>
> Signed-off-by: Caleb James DeLisle <cjd@...ns.fr>
> ---
>  drivers/net/wireless/mediatek/mt76/mmio.c | 34 +++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c
> index cd2e9737c3bf..776dbaacc8a3 100644
> --- a/drivers/net/wireless/mediatek/mt76/mmio.c
> +++ b/drivers/net/wireless/mediatek/mt76/mmio.c
> @@ -30,15 +30,49 @@ static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
>         return val;
>  }
>
> +static void mt76_mmio_write_copy_portable(void __iomem *dst,
> +                                         const u8 *src, int len)
> +{
> +       __le32 val;
> +       int i = 0;
> +
> +       for (i = 0; i < ALIGN(len, 4); i += 4) {
> +               memcpy(&val, src + i, sizeof(val));
> +               writel(cpu_to_le32(val), dst + i);
> +       }
> +}
> +
>  static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset,
>                                  const void *data, int len)
>  {
> +       if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) {
> +               mt76_mmio_write_copy_portable(dev->mmio.regs + offset, data,
> +                                             len);
> +               return;
> +       }
>         __iowrite32_copy(dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4));

Maybe just replace this with memcpy_toio() which does no swapping at
all instead of double swapping on BE?

>  }
>
> +static void mt76_mmio_read_copy_portable(u8 *dst,
> +                                        const void __iomem *src, int len)
> +{
> +       u32 val;
> +       int i;
> +
> +       for (i = 0; i < ALIGN(len, 4); i += 4) {
> +               val = le32_to_cpu(readl(src + i));
> +               memcpy(dst + i, &val, sizeof(val));
> +       }
> +}
> +
>  static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset,
>                                 void *data, int len)
>  {
> +       if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) {
> +               mt76_mmio_read_copy_portable(data, dev->mmio.regs + offset,
> +                                            len);
> +               return;
> +       }
>         __ioread32_copy(data, dev->mmio.regs + offset, DIV_ROUND_UP(len, 4));

And memcpy_fromio() here.

Best regards,
Jonas

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ