[PATCH net-next 1/2] net: axienet: make the 64b addresable DMA depends on 64b archectures
Andy Chiu
andy.chiu at sifive.com
Mon Jun 13 01:18:25 PDT 2022
Reviewed-by: Greentime Hu <greentime.hu at sifive.com>
On Mon, Jun 13, 2022 at 11:45 AM Andy Chiu <andy.chiu at sifive.com> wrote:
>
> Currently it is not safe to config the IP as 64-bit addressable on 32-bit
> archectures, which cannot perform a double-word store on its descriptor
> pointers. The pointer is 64-bit wide if the IP is configured as 64-bit,
> and the device would process the partially updated pointer on some
> states if the pointer was updated via two store-words. To prevent such
> condition, we force a probe fail if we discover that the IP has 64-bit
> capability but it is not running on a 64-Bit kernel.
>
> This is a series of patch (1/2). The next patch must be applied in order
> to make 64b DMA safe on 64b archectures.
>
> Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
> Reported-by: Max Hsu <max.hsu at sifive.com>
> ---
> drivers/net/ethernet/xilinx/xilinx_axienet.h | 36 +++++++++++++++++++
> .../net/ethernet/xilinx/xilinx_axienet_main.c | 28 +++------------
> 2 files changed, 40 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
> index 4225efbeda3d..6c95676ba172 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
> @@ -547,6 +547,42 @@ static inline void axienet_iow(struct axienet_local *lp, off_t offset,
> iowrite32(value, lp->regs + offset);
> }
>
> +/**
> + * axienet_dma_out32 - Memory mapped Axi DMA register write.
> + * @lp: Pointer to axienet local structure
> + * @reg: Address offset from the base address of the Axi DMA core
> + * @value: Value to be written into the Axi DMA register
> + *
> + * This function writes the desired value into the corresponding Axi DMA
> + * register.
> + */
> +
> +static inline void axienet_dma_out32(struct axienet_local *lp,
> + off_t reg, u32 value)
> +{
> + iowrite32(value, lp->dma_regs + reg);
> +}
> +
> +#ifdef CONFIG_64BIT
> +static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
> + dma_addr_t addr)
> +{
> + axienet_dma_out32(lp, reg, lower_32_bits(addr));
> +
> + if (lp->features & XAE_FEATURE_DMA_64BIT)
> + axienet_dma_out32(lp, reg + 4, upper_32_bits(addr));
> +}
> +
> +#else /* CONFIG_64BIT */
> +
> +static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
> + dma_addr_t addr)
> +{
> + axienet_dma_out32(lp, reg, lower_32_bits(addr));
> +}
> +
> +#endif /* CONFIG_64BIT */
> +
> /* Function prototypes visible in xilinx_axienet_mdio.c for other files */
> int axienet_mdio_enable(struct axienet_local *lp);
> void axienet_mdio_disable(struct axienet_local *lp);
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index 93c9f305bba4..fa7bcd2c1892 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -133,30 +133,6 @@ static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg)
> return ioread32(lp->dma_regs + reg);
> }
>
> -/**
> - * axienet_dma_out32 - Memory mapped Axi DMA register write.
> - * @lp: Pointer to axienet local structure
> - * @reg: Address offset from the base address of the Axi DMA core
> - * @value: Value to be written into the Axi DMA register
> - *
> - * This function writes the desired value into the corresponding Axi DMA
> - * register.
> - */
> -static inline void axienet_dma_out32(struct axienet_local *lp,
> - off_t reg, u32 value)
> -{
> - iowrite32(value, lp->dma_regs + reg);
> -}
> -
> -static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
> - dma_addr_t addr)
> -{
> - axienet_dma_out32(lp, reg, lower_32_bits(addr));
> -
> - if (lp->features & XAE_FEATURE_DMA_64BIT)
> - axienet_dma_out32(lp, reg + 4, upper_32_bits(addr));
> -}
> -
> static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr,
> struct axidma_bd *desc)
> {
> @@ -2061,6 +2037,10 @@ static int axienet_probe(struct platform_device *pdev)
> iowrite32(0x0, desc);
> }
> }
> + if (!IS_ENABLED(CONFIG_64BIT) && lp->features & XAE_FEATURE_DMA_64BIT) {
> + dev_err(&pdev->dev, "64-bit addressable DMA is not compatible with 32-bit archecture\n");
> + goto cleanup_clk;
> + }
>
> ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width));
> if (ret) {
> --
> 2.36.0
>
More information about the linux-arm-kernel
mailing list