All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ramon Fried <rfried.dev@gmail.com>
To: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Cc: U-Boot Mailing List <u-boot@lists.denx.de>,
	Joe Hershberger <joe.hershberger@ni.com>,
	 Michal Simek <monstr@monstr.eu>, git <git@xilinx.com>,
	somaashokreddy@gmail.com, Alessandro Temil <atemil@waymo.com>
Subject: Re: [PATCH 2/2] net: xilinx: axi_emac: Add support for 10G/25G AXI ethernet
Date: Sun, 27 Jun 2021 23:01:27 +0300	[thread overview]
Message-ID: <CAGi-RUKcawGBZ4KdmKbZvzUtiNKYLo10zaKQ1K74=cKhb362DQ@mail.gmail.com> (raw)
In-Reply-To: <20210624063441.24072-3-ashok.reddy.soma@xilinx.com>

On Thu, Jun 24, 2021 at 9:35 AM Ashok Reddy Soma
<ashok.reddy.soma@xilinx.com> wrote:
>
> Add support for 10G/25G (XXV) high speed ethernet. This Makes use of
> the exiting AXI DMA, similar to 1G.
>
> Signed-off-by: Alessandro Temil <atemil@waymo.com>
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
> ---
>
>  drivers/net/xilinx_axi_emac.c | 162 +++++++++++++++++++++++++---------
>  1 file changed, 118 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
> index cfc6082475..2ec76d0f52 100644
> --- a/drivers/net/xilinx_axi_emac.c
> +++ b/drivers/net/xilinx_axi_emac.c
> @@ -1,5 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
> + * Copyright (C) 2021 Waymo LLC
>   * Copyright (C) 2011 Michal Simek <monstr@monstr.eu>
>   * Copyright (C) 2011 PetaLogix
>   * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
> @@ -73,9 +74,22 @@ DECLARE_GLOBAL_DATA_PTR;
>  #define XAXIDMA_BD_CTRL_TXSOF_MASK     0x08000000 /* First tx packet */
>  #define XAXIDMA_BD_CTRL_TXEOF_MASK     0x04000000 /* Last tx packet */
>
> -#define DMAALIGN       128
> +/* Bitmasks for XXV Ethernet MAC */
> +#define XXV_TC_TX_MASK         0x00000001
> +#define XXV_TC_FCS_MASK                0x00000002
> +#define XXV_RCW1_RX_MASK       0x00000001
> +#define XXV_RCW1_FCS_MASK      0x00000002
> +
> +#define DMAALIGN               128
> +#define XXV_MIN_PKT_SIZE       60
>
>  static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN)));
> +static u8 txminframe[XXV_MIN_PKT_SIZE] __attribute((aligned(DMAALIGN)));
> +
> +enum emac_variant {
> +       EMAC_1G = 0,
> +       EMAC_10G_25G = 1,
> +};
>
>  /* Reflect dma offsets */
>  struct axidma_reg {
> @@ -95,6 +109,7 @@ struct axidma_plat {
>         int phyaddr;
>         u8 eth_hasnobuf;
>         int phy_of_handle;
> +       enum emac_variant mactype;
>  };
>
>  /* Private driver structures */
> @@ -108,6 +123,7 @@ struct axidma_priv {
>         struct mii_dev *bus;
>         u8 eth_hasnobuf;
>         int phy_of_handle;
> +       enum emac_variant mactype;
>  };
>
>  /* BD descriptors */
> @@ -154,6 +170,14 @@ struct axi_regs {
>         u32 uaw1; /* 0x704: Unicast address word 1 */
>  };
>
> +struct xxv_axi_regs {
> +       u32 gt_reset;   /* 0x0 */
> +       u32 reserved[2];
> +       u32 tc;         /* 0xC: Tx Configuration */
> +       u32 reserved2;
> +       u32 rcw1;       /* 0x14: Rx Configuration Word 1 */
> +};
> +
>  /* Use MII register 1 (MII status register) to detect PHY */
>  #define PHY_DETECT_REG  1
>
> @@ -385,6 +409,18 @@ static void axiemac_stop(struct udevice *dev)
>         debug("axiemac: Halted\n");
>  }
>
> +static int xxv_axi_ethernet_init(struct axidma_priv *priv)
> +{
> +       struct xxv_axi_regs *regs = (struct xxv_axi_regs *)priv->iobase;
> +
> +       writel(readl(&regs->rcw1) | XXV_RCW1_FCS_MASK, &regs->rcw1);
> +       writel(readl(&regs->tc) | XXV_TC_FCS_MASK, &regs->tc);
> +       writel(readl(&regs->tc) | XXV_TC_TX_MASK, &regs->tc);
> +       writel(readl(&regs->rcw1) | XXV_RCW1_RX_MASK, &regs->rcw1);
> +
> +       return 0;
> +}
> +
>  static int axi_ethernet_init(struct axidma_priv *priv)
>  {
>         struct axi_regs *regs = priv->iobase;
> @@ -440,6 +476,9 @@ static int axiemac_write_hwaddr(struct udevice *dev)
>         struct axidma_priv *priv = dev_get_priv(dev);
>         struct axi_regs *regs = priv->iobase;
>
> +       if (priv->mactype != EMAC_1G)
> +               return 0;
> +
>         /* Set the MAC address */
>         int val = ((pdata->enetaddr[3] << 24) | (pdata->enetaddr[2] << 16) |
>                 (pdata->enetaddr[1] << 8) | (pdata->enetaddr[0]));
> @@ -477,7 +516,6 @@ static void axi_dma_init(struct axidma_priv *priv)
>  static int axiemac_start(struct udevice *dev)
>  {
>         struct axidma_priv *priv = dev_get_priv(dev);
> -       struct axi_regs *regs = priv->iobase;
>         u32 temp;
>
>         debug("axiemac: Init started\n");
> @@ -490,8 +528,13 @@ static int axiemac_start(struct udevice *dev)
>         axi_dma_init(priv);
>
>         /* Initialize AxiEthernet hardware. */
> -       if (axi_ethernet_init(priv))
> -               return -1;
> +       if (priv->mactype == EMAC_1G) {
> +               if (axi_ethernet_init(priv))
> +                       return -1;
> +       } else {
> +               if (xxv_axi_ethernet_init(priv))
> +                       return -1;
> +       }
>
>         /* Disable all RX interrupts before RxBD space setup */
>         temp = readl(&priv->dmarx->control);
> @@ -525,15 +568,25 @@ static int axiemac_start(struct udevice *dev)
>         /* Rx BD is ready - start */
>         axienet_dma_write(&rx_bd, &priv->dmarx->tail);
>
> -       /* Enable TX */
> -       writel(XAE_TC_TX_MASK, &regs->tc);
> -       /* Enable RX */
> -       writel(XAE_RCW1_RX_MASK, &regs->rcw1);
> +       if (priv->mactype == EMAC_1G) {
> +               struct axi_regs *regs = priv->iobase;
> +               /* Enable TX */
> +               writel(XAE_TC_TX_MASK, &regs->tc);
> +               /* Enable RX */
> +               writel(XAE_RCW1_RX_MASK, &regs->rcw1);
> +
> +               /* PHY setup */
> +               if (!setup_phy(dev)) {
> +                       axiemac_stop(dev);
> +                       return -1;
> +               }
> +       } else {
> +               struct xxv_axi_regs *regs = (struct xxv_axi_regs *)priv->iobase;
> +               /* Enable TX */
> +               writel(readl(&regs->tc) | XXV_TC_TX_MASK, &regs->tc);
>
> -       /* PHY setup */
> -       if (!setup_phy(dev)) {
> -               axiemac_stop(dev);
> -               return -1;
> +               /* Enable RX */
> +               writel(readl(&regs->rcw1) | XXV_RCW1_RX_MASK, &regs->rcw1);
>         }
>
>         debug("axiemac: Init complete\n");
> @@ -548,6 +601,14 @@ static int axiemac_send(struct udevice *dev, void *ptr, int len)
>         if (len > PKTSIZE_ALIGN)
>                 len = PKTSIZE_ALIGN;
>
> +       /* If size is less than min packet size, pad to min size */
> +       if (priv->mactype == EMAC_10G_25G && len < XXV_MIN_PKT_SIZE) {
> +               memset(txminframe, 0, XXV_MIN_PKT_SIZE);
> +               memcpy(txminframe, ptr, len);
> +               len = XXV_MIN_PKT_SIZE;
> +               ptr = txminframe;
> +       }
> +
>         /* Flush packet to main memory to be trasfered by DMA */
>         flush_cache((phys_addr_t)ptr, len);
>
> @@ -632,7 +693,7 @@ static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp)
>         temp = readl(&priv->dmarx->control);
>         temp &= ~XAXIDMA_IRQ_ALL_MASK;
>         writel(temp, &priv->dmarx->control);
> -       if (!priv->eth_hasnobuf)
> +       if (!priv->eth_hasnobuf  && priv->mactype == EMAC_1G)
>                 length = rx_bd.app4 & 0xFFFF; /* max length mask */
>         else
>                 length = rx_bd.status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
> @@ -709,21 +770,25 @@ static int axi_emac_probe(struct udevice *dev)
>         priv->dmatx = plat->dmatx;
>         /* RX channel offset is 0x30 */
>         priv->dmarx = (struct axidma_reg *)((phys_addr_t)priv->dmatx + 0x30);
> -       priv->eth_hasnobuf = plat->eth_hasnobuf;
> -       priv->phyaddr = plat->phyaddr;
> -       priv->phy_of_handle = plat->phy_of_handle;
> -       priv->interface = pdata->phy_interface;
> +       priv->mactype = plat->mactype;
> +
> +       if (priv->mactype == EMAC_1G) {
> +               priv->eth_hasnobuf = plat->eth_hasnobuf;
> +               priv->phyaddr = plat->phyaddr;
> +               priv->phy_of_handle = plat->phy_of_handle;
> +               priv->interface = pdata->phy_interface;
>
> -       priv->bus = mdio_alloc();
> -       priv->bus->read = axiemac_miiphy_read;
> -       priv->bus->write = axiemac_miiphy_write;
> -       priv->bus->priv = priv;
> +               priv->bus = mdio_alloc();
> +               priv->bus->read = axiemac_miiphy_read;
> +               priv->bus->write = axiemac_miiphy_write;
> +               priv->bus->priv = priv;
>
> -       ret = mdio_register_seq(priv->bus, dev_seq(dev));
> -       if (ret)
> -               return ret;
> +               ret = mdio_register_seq(priv->bus, dev_seq(dev));
> +               if (ret)
> +                       return ret;
>
> -       axiemac_phy_init(dev);
> +               axiemac_phy_init(dev);
> +       }
>
>         return 0;
>  }
> @@ -732,9 +797,11 @@ static int axi_emac_remove(struct udevice *dev)
>  {
>         struct axidma_priv *priv = dev_get_priv(dev);
>
> -       free(priv->phydev);
> -       mdio_unregister(priv->bus);
> -       mdio_free(priv->bus);
> +       if (priv->mactype == EMAC_1G) {
> +               free(priv->phydev);
> +               mdio_unregister(priv->bus);
> +               mdio_free(priv->bus);
> +       }
>
>         return 0;
>  }
> @@ -757,6 +824,7 @@ static int axi_emac_of_to_plat(struct udevice *dev)
>         const char *phy_mode;
>
>         pdata->iobase = dev_read_addr(dev);
> +       plat->mactype = dev_get_driver_data(dev);
>
>         offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
>                                        "axistream-connected");
> @@ -771,24 +839,29 @@ static int axi_emac_of_to_plat(struct udevice *dev)
>                 return -EINVAL;
>         }
>
> -       plat->phyaddr = -1;
> +       if (plat->mactype == EMAC_1G) {
> +               plat->phyaddr = -1;
>
> -       offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle");
> -       if (offset > 0) {
> -               plat->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
> -               plat->phy_of_handle = offset;
> -       }
> +               offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
> +                                              "phy-handle");
> +               if (offset > 0) {
> +                       plat->phyaddr = fdtdec_get_int(gd->fdt_blob, offset,
> +                                                      "reg", -1);
> +                       plat->phy_of_handle = offset;
> +               }
>
> -       phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
> -       if (phy_mode)
> -               pdata->phy_interface = phy_get_interface_by_name(phy_mode);
> -       if (pdata->phy_interface == -1) {
> -               printf("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
> -               return -EINVAL;
> -       }
> +               phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
> +               if (phy_mode)
> +                       pdata->phy_interface = phy_get_interface_by_name(phy_mode);
> +               if (pdata->phy_interface == -1) {
> +                       printf("%s: Invalid PHY interface '%s'\n", __func__,
> +                              phy_mode);
> +                       return -EINVAL;
> +               }
>
> -       plat->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, node,
> -                                            "xlnx,eth-hasnobuf");
> +               plat->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, node,
> +                                                    "xlnx,eth-hasnobuf");
> +       }
>
>         printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)pdata->iobase,
>                plat->phyaddr, phy_string_for_interface(pdata->phy_interface));
> @@ -797,7 +870,8 @@ static int axi_emac_of_to_plat(struct udevice *dev)
>  }
>
>  static const struct udevice_id axi_emac_ids[] = {
> -       { .compatible = "xlnx,axi-ethernet-1.00.a" },
> +       { .compatible = "xlnx,axi-ethernet-1.00.a", .data = (uintptr_t)EMAC_1G },
> +       { .compatible = "xlnx,xxv-ethernet-1.0", .data = (uintptr_t)EMAC_10G_25G },
>         { }
>  };
>
> --
> 2.17.1
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

  reply	other threads:[~2021-06-27 20:01 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-24  6:34 [PATCH 0/2] Add support for 10G/25G to AXI emac driver Ashok Reddy Soma
2021-06-24  6:34 ` [PATCH 1/2] net: xilinx: axi_emac: Cleanup of of_to_plat() Ashok Reddy Soma
2021-06-27 20:00   ` Ramon Fried
2021-06-24  6:34 ` [PATCH 2/2] net: xilinx: axi_emac: Add support for 10G/25G AXI ethernet Ashok Reddy Soma
2021-06-27 20:01   ` Ramon Fried [this message]
2021-06-28  7:07 ` [PATCH 0/2] Add support for 10G/25G to AXI emac driver Michal Simek
2021-06-28 17:13   ` Ramon Fried
2021-06-29  4:30     ` Ashok Reddy Soma
2021-06-29  5:17       ` Ramon Fried

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAGi-RUKcawGBZ4KdmKbZvzUtiNKYLo10zaKQ1K74=cKhb362DQ@mail.gmail.com' \
    --to=rfried.dev@gmail.com \
    --cc=ashok.reddy.soma@xilinx.com \
    --cc=atemil@waymo.com \
    --cc=git@xilinx.com \
    --cc=joe.hershberger@ni.com \
    --cc=monstr@monstr.eu \
    --cc=somaashokreddy@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.