[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