• Anssi Hannula's avatar
    net: xilinx_emaclite: fix freezes due to unordered I/O · acf138f1
    Anssi Hannula authored
    The xilinx_emaclite uses __raw_writel and __raw_readl for register
    accesses. Those functions do not imply any kind of memory barriers and
    they may be reordered.
    
    The driver does not seem to take that into account, though, and the
    driver does not satisfy the ordering requirements of the hardware.
    For clear examples, see xemaclite_mdio_write() and xemaclite_mdio_read()
    which try to set MDIO address before initiating the transaction.
    
    I'm seeing system freezes with the driver with GCC 5.4 and current
    Linux kernels on Zynq-7000 SoC immediately when trying to use the
    interface.
    
    In commit 123c1407 ("net: emaclite: Do not use microblaze and ppc
    IO functions") the driver was switched from non-generic
    in_be32/out_be32 (memory barriers, big endian) to
    __raw_readl/__raw_writel (no memory barriers, native endian), so
    apparently the device follows system endianness and the driver was
    originally written with the assumption of memory barriers.
    
    Rather than try to hunt for each case of missing barrier, just switch
    the driver to use iowrite32/ioread32/iowrite32be/ioread32be depending
    on endianness instead.
    
    Tested on little-endian Zynq-7000 ARM SoC FPGA.
    Signed-off-by: default avatarAnssi Hannula <anssi.hannula@bitwise.fi>
    Fixes: 123c1407 ("net: emaclite: Do not use microblaze and ppc IO
    functions")
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    acf138f1
xilinx_emaclite.c 36.3 KB