The device that Aspeed uses is basically Faraday FTGMAC100, but with
some differences here and there. Since I don't have access to a properly
implemented FTGMAC100 though, I can't really test it and so I don't
feel comfortable claiming compatibility, even though I reused a lot of
FTGMAC100 driver code.

Signed-off-by: Maxim Sloyko <max...@google.com>
---

 drivers/net/Kconfig   |   8 +
 drivers/net/Makefile  |   1 +
 drivers/net/ast_nic.c | 584 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ast_nic.h | 198 +++++++++++++++++
 4 files changed, 791 insertions(+)
 create mode 100644 drivers/net/ast_nic.c
 create mode 100644 drivers/net/ast_nic.h

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 70e36611ea..6de8b35d9f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -208,4 +208,12 @@ config GMAC_ROCKCHIP
          This driver provides Rockchip SoCs network support based on the
          Synopsys Designware driver.
 
+config AST_NIC
+       bool "Support Aspeed ast2500/ast2400 NIC"
+       depends on DM_ETH
+       help
+         This driver provides support for ast2500/ast2400 network devices.
+         It uses Driver Model and so can support multiple devices on the same 
SoC.
+         The device itself is basically a variation of Faraday FTGMAC100.
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 2493a48b88..792bebb9cc 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_FSL_MEMAC) += fm/memac_phy.o
 obj-$(CONFIG_VSC9953) += vsc9953.o
 obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
 obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
+obj-$(CONFIG_AST_NIC) += ast_nic.o
diff --git a/drivers/net/ast_nic.c b/drivers/net/ast_nic.c
new file mode 100644
index 0000000000..881d20151c
--- /dev/null
+++ b/drivers/net/ast_nic.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratb...@faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macp...@andestech.com>
+ *
+ * Copyright 2017 Google Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/*
+ * This device is basically Faraday FTGMAC100, with some differences,
+ * which do not seem to be very big, but are in very random places, like
+ * some registers removed and completely different ones put in their place.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#include <miiphy.h>
+#endif
+#include <net.h>
+#include <asm/io.h>
+#include <linux/mii.h>
+#include "ast_nic.h"
+
+#define ETH_ZLEN       60
+#define RBSR_DEFAULT_VALUE     0x640
+
+#define PKTBUFSTX      4
+
+#define MAX_PHY_ADDR 32
+
+struct ast_nic_xdes {
+       u32 des[4];
+} __aligned(16);
+
+struct ast_nic_xdes ast_txdes[PKTBUFSTX];
+struct ast_nic_xdes ast_rxdes[PKTBUFSRX];
+
+struct ast_nic_priv {
+       struct ast_nic_xdes *txdes;
+       struct ast_nic_xdes *rxdes;
+       struct ast_nic_regs *regs;
+       int tx_index;
+       int rx_index;
+       int phy_addr;
+};
+
+static int ast_nic_ofdata_to_platdata(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       struct eth_pdata *platdata = dev_get_platdata(dev);
+
+       priv->regs = dev_get_addr_ptr(dev);
+       priv->txdes = ast_txdes;
+       priv->rxdes = ast_rxdes;
+       platdata->iobase = (phys_addr_t)priv->regs;
+
+       return 0;
+}
+
+static void ast_nic_reset(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+
+       setbits_le32(&priv->regs->maccr, MAC_MACCR_SW_RST);
+       while (readl(&priv->regs->maccr) & MAC_MACCR_SW_RST)
+               ;
+       /*
+        * Only needed for ast2400, for ast2500 this is the no-op,
+        * because the register is marked read-only.
+        */
+       setbits_le32(&priv->regs->fear0, MAC_FEAR_NEW_MD_IFACE);
+}
+
+static int ast_nic_phy_read(struct udevice *dev, int phy_addr,
+                           int regnum, u16 *value)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       int phycr;
+       int i;
+
+       phycr = MAC_PHYCR_FIRE | MAC_PHYCR_ST_22 | MAC_PHYCR_READ |
+           (phy_addr << MAC_PHYCR_PHYAD_SHIFT) |
+           (regnum << MAC_PHYCR_REGAD_SHIFT);
+
+       writel(phycr, &priv->regs->phycr);
+
+       for (i = 0; i < 10; i++) {
+               phycr = readl(&priv->regs->phycr);
+
+               if ((phycr & MAC_PHYCR_FIRE) == 0) {
+                       int data;
+
+                       data = readl(&priv->regs->phydata);
+                       *value = (data & MAC_PHYDATA_MIIRDATA_MASK) >>
+                           MAC_PHYDATA_MIIRDATA_SHIFT;
+
+                       return 0;
+               }
+
+               mdelay(10);
+       }
+
+       debug("mdio read timed out\n");
+       return -ETIMEDOUT;
+}
+
+static int ast_nic_phy_write(struct udevice *dev, int phy_addr,
+       int regnum, u16 value)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       int phycr;
+       int i;
+
+       phycr = (value << MAC_PHYDATA_MIIWDATA_SHIFT) |
+                       MAC_PHYCR_FIRE | MAC_PHYCR_ST_22 |
+                       MAC_PHYCR_WRITE |
+                       (phy_addr << MAC_PHYCR_PHYAD_SHIFT) |
+                       (regnum << MAC_PHYCR_REGAD_SHIFT);
+
+       writel(phycr, &priv->regs->phycr);
+
+       for (i = 0; i < 10; i++) {
+               phycr = readl(&priv->regs->phycr);
+
+               if ((phycr & MAC_PHYCR_FIRE) == 0) {
+                       debug("(phycr & MAC_PHYCR_MIIWR) == 0: phy_addr: %x\n",
+                             phy_addr);
+                       return 0;
+               }
+
+               mdelay(10);
+       }
+
+       debug("mdio write timed out\n");
+
+       return -ETIMEDOUT;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int ast_nic_reg_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+       struct udevice *dev = eth_get_dev_by_name(bus->name);
+       u16 value;
+
+       ast_nic_phy_read(dev, addr, reg, &value);
+
+       return value;
+}
+
+static int ast_nic_reg_write(struct mii_dev *bus, int addr, int devad, int reg,
+                            u16 value)
+{
+       struct udevice *dev = eth_get_dev_by_name(bus->name);
+
+       return ast_nic_phy_write(dev, addr, reg, value);
+}
+#endif
+
+static int ast_nic_probe(struct udevice *dev)
+{
+       struct clk mac_clk;
+       struct clk d2pll_clk;
+       int ret;
+
+       debug("%s()\n", __func__);
+
+       ret = clk_get_by_index(dev, 0, &mac_clk);
+       if (ret) {
+               debug("%s(): get_clk_by_index failed: %d\n", __func__, ret);
+               return ret;
+       }
+
+       clk_enable(&mac_clk);
+
+       ret = clk_get_by_index(dev, 1, &d2pll_clk);
+       if (ret) {
+               debug("%s(): get_clk_by_index failed: %d\n", __func__, ret);
+               return ret;
+       }
+
+       clk_enable(&d2pll_clk);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+       struct mii_dev *mdiodev = mdio_alloc();
+       if (!mdiodev)
+               return -ENOMEM;
+       strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
+       mdiodev->read = ast_nic_reg_read;
+       mdiodev->write = ast_nic_reg_write;
+
+       ret = mdio_register(mdiodev);
+       if (ret < 0)
+               return ret;
+#endif
+
+       ast_nic_reset(dev);
+
+       return 0;
+}
+
+static int ast_nic_phy_reset(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       int i;
+       u16 status, adv;
+
+       adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+
+       ast_nic_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv);
+
+       printf("%s: Starting autonegotiation...\n", dev->name);
+
+       ast_nic_phy_write(dev, priv->phy_addr,
+                         MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
+
+       for (i = 0; i < 1000; i++) {
+               ast_nic_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
+
+               if (status & BMSR_ANEGCOMPLETE)
+                       break;
+               mdelay(1);
+       }
+
+       if (status & BMSR_ANEGCOMPLETE) {
+               printf("%s: Autonegotiation complete\n", dev->name);
+       } else {
+               printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+                      dev->name, status);
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int ast_nic_phy_init(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       int phy_addr;
+       u16 phy_id, status, adv, lpa, stat_ge;
+       int media, speed, duplex;
+       int i;
+
+       /* Check if the PHY is up to snuff... */
+       for (phy_addr = 0; phy_addr < MAX_PHY_ADDR; phy_addr++) {
+               ast_nic_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id);
+
+               /*
+                * When it is unable to found PHY,
+                * the interface usually return 0xffff or 0x0000
+                */
+               if (phy_id != 0xffff && phy_id != 0x0) {
+                       debug("%s: found PHY at 0x%02x\n", dev->name, phy_addr);
+                       priv->phy_addr = phy_addr;
+                       break;
+               }
+       }
+
+       if (phy_id == 0xffff || phy_id == 0x0) {
+               debug("%s: no PHY present\n", dev->name);
+               return -ENODEV;
+       }
+
+       ast_nic_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
+
+       if (!(status & BMSR_LSTATUS)) {
+               /* Try to re-negotiate if we don't have link already. */
+               ast_nic_phy_reset(dev);
+
+               for (i = 0; i < 100000 / 100; i++) {
+                       ast_nic_phy_read(dev, priv->phy_addr,
+                                        MII_BMSR, &status);
+                       if (status & BMSR_LSTATUS)
+                               break;
+                       udelay(100);
+               }
+       }
+
+       if (!(status & BMSR_LSTATUS)) {
+               printf("%s: link down\n", dev->name);
+               return -ENOLINK;
+       }
+
+       /* 1000 Base-T Status Register */
+       ast_nic_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge);
+
+       speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF)
+                ? 1 : 0);
+
+       duplex = ((stat_ge & LPA_1000FULL)
+                 ? 1 : 0);
+
+       if (speed) {            /* Speed is 1000 */
+               debug("%s: link up, 1000bps %s-duplex\n",
+                     dev->name, duplex ? "full" : "half");
+               return 0;
+       }
+
+       ast_nic_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv);
+       ast_nic_phy_read(dev, priv->phy_addr, MII_LPA, &lpa);
+
+       media = mii_nway_result(lpa & adv);
+       speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0);
+       duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+       debug("%s: link up, %sMbps %s-duplex\n",
+             dev->name, speed ? "100" : "10", duplex ? "full" : "half");
+
+       return 0;
+}
+
+static int ast_nic_update_link_speed(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       u16 stat_fe;
+       u16 stat_ge;
+       u32 maccr;
+
+       /* 1000 Base-T Status Register */
+       ast_nic_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge);
+       ast_nic_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe);
+
+       if (!(stat_fe & BMSR_LSTATUS))  /* link status up? */
+               return -EIO;
+
+       /* read MAC control register and clear related bits */
+       maccr = readl(&priv->regs->maccr) &
+               ~(MAC_MACCR_GIGA_MODE |
+                 MAC_MACCR_FAST_MODE |
+                 MAC_MACCR_FULLDUP);
+
+       if (stat_ge & LPA_1000FULL) {
+               /* set gmac for 1000BaseTX and Full Duplex */
+               maccr |= MAC_MACCR_GIGA_MODE | MAC_MACCR_FULLDUP;
+       }
+
+       if (stat_ge & LPA_1000HALF) {
+               /* set gmac for 1000BaseTX and Half Duplex */
+               maccr |= MAC_MACCR_GIGA_MODE;
+       }
+
+       if (stat_fe & BMSR_100FULL) {
+               /* set MII for 100BaseTX and Full Duplex */
+               maccr |= MAC_MACCR_FAST_MODE | MAC_MACCR_FULLDUP;
+       }
+
+       if (stat_fe & BMSR_10FULL) {
+               /* set MII for 10BaseT and Full Duplex */
+               maccr |= MAC_MACCR_FULLDUP;
+       }
+
+       if (stat_fe & BMSR_100HALF) {
+               /* set MII for 100BaseTX and Half Duplex */
+               maccr |= MAC_MACCR_FAST_MODE;
+       }
+
+       if (stat_fe & BMSR_10HALF) {
+               /* set MII for 10BaseT and Half Duplex */
+               /* we have already clear these bits, do nothing */
+               ;
+       }
+
+       /* update MII config into maccr */
+       writel(maccr, &priv->regs->maccr);
+
+       return 0;
+}
+
+static int ast_nic_start(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       struct ast_nic_xdes *txdes = priv->txdes;
+       struct ast_nic_xdes *rxdes = priv->rxdes;
+       u32 maccr;
+       int i;
+
+       debug("%s()\n", __func__);
+
+       ast_nic_reset(dev);
+
+       /* disable all interrupts */
+       writel(0, &priv->regs->ier);
+
+       /* initialize descriptors */
+       priv->tx_index = 0;
+       priv->rx_index = 0;
+
+       txdes[PKTBUFSTX - 1].des[0]     = cpu_to_le32(MAC_TXDES0_EDOTR);
+       rxdes[PKTBUFSRX - 1].des[0]     = cpu_to_le32(MAC_RXDES0_EDORR);
+
+       for (i = 0; i < PKTBUFSTX; i++) {
+               /* TXBUF_BADR */
+               txdes[i].des[3] = 0;
+               txdes[i].des[1] = 0;
+       }
+
+       for (i = 0; i < PKTBUFSRX; i++) {
+               /* RXBUF_BADR */
+               rxdes[i].des[3] = (u32)net_rx_packets[i];
+
+               rxdes[i].des[0] &= ~MAC_RXDES0_RXPKT_RDY;
+       }
+
+       /* transmit ring */
+       writel((u32)txdes, &priv->regs->txr_badr);
+
+       /* receive ring */
+       writel((u32)rxdes, &priv->regs->rxr_badr);
+
+       /* poll receive descriptor automatically */
+       writel((1 << MAC_APTC_RXPOLL_CNT_SHIFT), &priv->regs->aptc);
+
+       /* config receive buffer size register */
+       writel(RBSR_DEFAULT_VALUE, &priv->regs->rbsr);
+
+       /* enable transmitter, receiver */
+       maccr = MAC_MACCR_TXMAC_EN |
+               MAC_MACCR_RXMAC_EN |
+               MAC_MACCR_TXDMA_EN |
+               MAC_MACCR_RXDMA_EN |
+               MAC_MACCR_FULLDUP |
+               MAC_MACCR_CRC_APD |
+               MAC_MACCR_RX_RUNT |
+               MAC_MACCR_RX_BROADPKT;
+
+       writel(maccr, &priv->regs->maccr);
+
+       ast_nic_phy_init(dev);
+
+       return ast_nic_update_link_speed(dev);
+}
+
+static void ast_nic_stop(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+
+       debug("%s()\n", __func__);
+
+       clrbits_le32(&priv->regs->maccr,
+                    MAC_MACCR_TXDMA_EN | MAC_MACCR_RXDMA_EN |
+                    MAC_MACCR_TXMAC_EN | MAC_MACCR_RXMAC_EN);
+}
+
+static int ast_nic_send(struct udevice *dev, void *packet, int length)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       struct ast_nic_xdes *curr_des = &priv->txdes[priv->tx_index];
+       unsigned long start;
+       unsigned long now;
+       unsigned long diff_time;
+
+       if (curr_des->des[0] & MAC_TXDES0_TXDMA_OWN) {
+               debug("%s(): no TX descriptor available\n", __func__);
+               return -EIO;
+       }
+
+       debug("%s(%x, %x)\n", __func__, (int)packet, length);
+
+       length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
+
+       /* initiate a transmit sequence */
+       curr_des->des[3] = (u32) packet;        /* TXBUF_BADR */
+
+       curr_des->des[0] &= MAC_TXDES0_EDOTR;
+
+       curr_des->des[0] |= (MAC_TXDES0_FTS |
+                            MAC_TXDES0_LTS |
+                            ((length << MAC_TXDES0_TXBUF_SIZE_SHIFT) &
+                             MAC_TXDES0_TXBUF_SIZE_MASK) |
+                            MAC_TXDES0_TXDMA_OWN);
+
+       /* start transmit */
+       writel(1, &priv->regs->txpd);
+       invalidate_dcache_range((u32) curr_des,
+                               (u32) curr_des + sizeof(*curr_des));
+
+       /* wait for transfer to succeed */
+       start = get_timer(0);
+
+       while (curr_des->des[0] & MAC_TXDES0_TXDMA_OWN) {
+               now = get_timer(0);
+               if (now < start)
+                       now += 0xffffffff;
+               diff_time = now - start;
+               if (diff_time >= 5000) {
+                       debug("%s(): timed out\n", __func__);
+                       return -ETIMEDOUT;
+               }
+       }
+
+       debug("%s(): packet sent\n", __func__);
+
+       priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
+
+       return 0;
+}
+
+static int ast_nic_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       struct ast_nic_xdes *curr_des;
+       unsigned short rxlen;
+
+       curr_des = &priv->rxdes[priv->rx_index];
+
+       invalidate_dcache_range((u32) curr_des,
+                               (u32) curr_des + sizeof(*curr_des));
+
+       if (!(curr_des->des[0] & MAC_RXDES0_RXPKT_RDY))
+               return -ENOMSG;
+
+       if (curr_des->des[0] & (MAC_RXDES0_RX_ERR |
+                               MAC_RXDES0_CRC_ERR |
+                               MAC_RXDES0_FTL |
+                               MAC_RXDES0_RUNT | MAC_RXDES0_RX_ODD_NB)) {
+               return -EIO;
+       }
+
+       rxlen =
+           (curr_des->des[0] >> MAC_RXDES0_VDBC_SHIFT) & MAC_RXDES0_VDBC_MASK;
+
+       debug("%s(): RX buffer %d, %x received\n",
+             __func__, priv->rx_index, rxlen);
+
+       invalidate_dcache_range((u32) curr_des->des[3],
+                               (u32) curr_des->des[3] + rxlen);
+
+       /* pass the packet up to the protocol layers. */
+       net_process_received_packet((void *)curr_des->des[3], rxlen);
+
+       curr_des->des[0] &= ~MAC_RXDES0_RXPKT_RDY;
+
+       priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
+
+       return 0;
+}
+
+static int ast_nic_write_hwaddr(struct udevice *dev)
+{
+       struct ast_nic_priv *priv = dev_get_priv(dev);
+       struct eth_pdata *platdata = dev_get_platdata(dev);
+       u32 madr, ladr;
+
+       debug("%s(%pM)\n", __func__, platdata->enetaddr);
+
+       madr = platdata->enetaddr[0] << 8 | platdata->enetaddr[1];
+       ladr = platdata->enetaddr[2] << 24 | platdata->enetaddr[3] << 16
+           | platdata->enetaddr[4] << 8 | platdata->enetaddr[5];
+
+       writel(madr, &priv->regs->mac_madr);
+       writel(ladr, &priv->regs->mac_ladr);
+
+       return 0;
+}
+
+static const struct eth_ops ast_nic_ops = {
+       .start = ast_nic_start,
+       .send = ast_nic_send,
+       .recv = ast_nic_recv,
+       .stop = ast_nic_stop,
+       .write_hwaddr = ast_nic_write_hwaddr,
+};
+
+static const struct udevice_id ast_nic_ids[] = {
+       { .compatible = "aspeed,ast2500-nic" },
+       { .compatible = "aspeed,ast2400-nic" },
+       { }
+};
+
+U_BOOT_DRIVER(ast_nic) = {
+       .name   = "ast_nic",
+       .id     = UCLASS_ETH,
+       .of_match = ast_nic_ids,
+       .probe  = ast_nic_probe,
+       .ops    = &ast_nic_ops,
+       .ofdata_to_platdata = ast_nic_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct ast_nic_priv),
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/ast_nic.h b/drivers/net/ast_nic.h
new file mode 100644
index 0000000000..0d4332bd95
--- /dev/null
+++ b/drivers/net/ast_nic.h
@@ -0,0 +1,198 @@
+/*
+ * (C) Copyright 2010 Faraday Technology
+ * Po-Yu Chuang <ratb...@faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macp...@andestech.com>
+ *
+ * Copyright 2017 Google Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __AST_NIC_H
+#define __AST_NIC_H
+
+struct ast_nic_regs {
+       u32     isr;            /* 0x00 */
+       u32     ier;            /* 0x04 */
+       u32     mac_madr;       /* 0x08 */
+       u32     mac_ladr;       /* 0x0c */
+       u32     maht0;          /* 0x10 */
+       u32     maht1;          /* 0x14 */
+       u32     txpd;           /* 0x18 */
+       u32     rxpd;           /* 0x1c */
+       u32     txr_badr;       /* 0x20 */
+       u32     rxr_badr;       /* 0x24 */
+       u32     hptxpd;         /* 0x28 */
+       u32     hptxpd_badr;    /* 0x2c */
+       u32     itc;            /* 0x30 */
+       u32     aptc;           /* 0x34 */
+       u32     dblac;          /* 0x38 */
+       u32     dmafifos;       /* 0x3c */
+       u32     fear0;          /* 0x40 */
+       u32     fear1;          /* 0x44 */
+       u32     tpafcr;         /* 0x48 */
+       u32     rbsr;           /* 0x4c */
+       u32     maccr;          /* 0x50 */
+       u32     macsr;          /* 0x54 */
+       u32     tm;             /* 0x58 */
+       u32     physts;         /* 0x5c */
+       u32     phycr;          /* 0x60 */
+       u32     phydata;        /* 0x64 */
+       u32     fcr;            /* 0x68 */
+       u32     bpr;            /* 0x6c */
+       u32     wolcr;          /* 0x70 */
+       u32     wolsr;          /* 0x74 */
+       u32     wfbm1m;         /* 0x78 */
+       u32     wfbm1l;         /* 0x7c */
+       u32     wfbm2m;         /* 0x80 */
+       u32     wfbm2l;         /* 0x84 */
+       u32     wfbm3m;         /* 0x88 */
+       u32     wfbm3l;         /* 0x8c */
+       u32     nptxr_ptr;      /* 0x90 */
+       u32     hptxr_ptr;      /* 0x94 */
+       u32     rxr_ptr;        /* 0x98 */
+       u32     resv3;          /* 0x9c */
+       u32     tx;             /* 0xa0 */
+       u32     tx_mcol_scol;   /* 0xa4 */
+       u32     tx_ecol_fail;   /* 0xa8 */
+       u32     tx_lcol_und;    /* 0xac */
+       u32     rx;             /* 0xb0 */
+       u32     rx_bc;          /* 0xb4 */
+       u32     rx_mc;          /* 0xb8 */
+       u32     rx_pf_aep;      /* 0xbc */
+       u32     rx_runt;        /* 0xc0 */
+       u32     rx_crcer_ftl;   /* 0xc4 */
+       u32     rx_col_lost;    /* 0xc8 */
+};
+
+/*
+ * Interrupt status register & interrupt enable register
+ */
+#define MAC_INT_RPKT_BUF               (1 << 0)
+#define MAC_INT_RPKT_FIFO              (1 << 1)
+#define MAC_INT_NO_RXBUF               (1 << 2)
+#define MAC_INT_RPKT_LOST              (1 << 3)
+#define MAC_INT_XPKT_ETH               (1 << 4)
+#define MAC_INT_XPKT_FIFO              (1 << 5)
+#define MAC_INT_NO_NPTXBUF     (1 << 6)
+#define MAC_INT_XPKT_LOST              (1 << 7)
+#define MAC_INT_AHB_ERR                (1 << 8)
+#define MAC_INT_PHYSTS_CHG     (1 << 9)
+#define MAC_INT_NO_HPTXBUF     (1 << 10)
+#define MAC_INT_PHY_CHG                (1 << 28)
+#define MAC_INT_PHY_TIMEOUT    (1 << 29)
+#define MAC_INT_FLAG_ACK               (1 << 30)
+#define MAC_INT_FLAG_REQ               (1 << 31)
+
+/*
+ * MAC control register
+ */
+#define MAC_MACCR_TXDMA_EN     (1 << 0)
+#define MAC_MACCR_RXDMA_EN     (1 << 1)
+#define MAC_MACCR_TXMAC_EN     (1 << 2)
+#define MAC_MACCR_RXMAC_EN     (1 << 3)
+#define MAC_MACCR_RM_VLAN              (1 << 4)
+#define MAC_MACCR_HPTXR_EN     (1 << 5)
+#define MAC_MACCR_LOOP_EN              (1 << 6)
+#define MAC_MACCR_ENRX_IN_HALFTX       (1 << 7)
+#define MAC_MACCR_FULLDUP              (1 << 8)
+#define MAC_MACCR_GIGA_MODE    (1 << 9)
+#define MAC_MACCR_CRC_APD              (1 << 10)
+#define MAC_MACCR_LOW_SEN              (1 << 11)
+#define MAC_MACCR_RX_RUNT              (1 << 12)
+#define MAC_MACCR_JUMBO_LF     (1 << 13)
+#define MAC_MACCR_RX_ALL               (1 << 14)
+#define MAC_MACCR_HT_MULTI_EN  (1 << 15)
+#define MAC_MACCR_RX_MULTIPKT  (1 << 16)
+#define MAC_MACCR_RX_BROADPKT  (1 << 17)
+#define MAC_MACCR_DISCARD_CRCERR       (1 << 18)
+#define MAC_MACCR_FAST_MODE    (1 << 19)
+#define MAC_MACCR_SW_RST               (1 << 31)
+
+/*
+ * Feature Enable Register
+ */
+#define MAC_FEAR_NEW_MD_IFACE          (1 << 31)
+#define MAC_FEAR_LOOPBACK                      (1 << 30)
+
+/*
+ * Automatic polling timer control register
+ */
+#define MAC_APTC_RXPOLL_CNT_SHIFT      0
+#define MAC_APTC_RXPOLL_CNT_MASK       0xf
+#define MAC_APTC_RXPOLL_TIME_SEL       (1 << 4)
+#define MAC_APTC_TXPOLL_CNT_SHIFT      8
+#define MAC_APTC_TXPOLL_CNT_MASK       (0xf << MAC_APTC_TXPOLL_CNT_SHIFT)
+#define MAC_APTC_TXPOLL_TIME_SEL       (1 << 12)
+
+/*
+ * Receive buffer size register
+ */
+#define MAC_RBSR_SIZE_MASK             0x3fff
+
+/*
+ * PHY control register
+ */
+#define MAC_PHYCR_FIRE         (1 << 15)
+#define MAC_PHYCR_ST_22                (1 << 12)
+#define MAC_PHYCR_WRITE                (1 << 10)
+#define MAC_PHYCR_READ         (2 << 10)
+#define MAC_PHYCR_PHYAD_SHIFT  5
+#define MAC_PHYCR_PHYAD_MASK   (0x1f << MAC_PHYCR_PHYAD_SHIFT)
+#define MAC_PHYCR_REGAD_SHIFT  0
+#define MAC_PHYCR_REGAD_MASK   (0x1f << MAC_PHYCR_REGAD_SHIFT)
+
+/*
+ * PHY data register
+ */
+#define MAC_PHYDATA_MIIRDATA_SHIFT     0
+#define MAC_PHYDATA_MIIRDATA_MASK      (0xffff << MAC_PHYDATA_MIIRDATA_SHIFT)
+#define MAC_PHYDATA_MIIWDATA_SHIFT     16
+#define MAC_PHYDATA_MIIWDATA_MASK      (0xffff << MAC_PHYDATA_MIIWDATA_SHIFT)
+
+#define MAC_TXDES0_TXBUF_SIZE_SHIFT    0
+#define MAC_TXDES0_TXBUF_SIZE_MASK     0x3fff
+#define MAC_TXDES0_CRC_ERR     (1 << 19)
+#define MAC_TXDES0_LTS         (1 << 28)
+#define MAC_TXDES0_FTS         (1 << 29)
+#define MAC_TXDES0_EDOTR               (1 << 30)
+#define MAC_TXDES0_TXDMA_OWN   (1 << 31)
+
+#define MAC_TXDES1_INS_VLANTAG (1 << 16)
+#define MAC_TXDES1_LLC         (1 << 22)
+#define MAC_TXDES1_TX2FIC              (1 << 30)
+#define MAC_TXDES1_TXIC                (1 << 31)
+
+#define MAC_RXDES0_VDBC_SHIFT  0
+#define MAC_RXDES0_VDBC_MASK   0x3fff
+#define MAC_RXDES0_MULTICAST   (1 << 16)
+#define MAC_RXDES0_BROADCAST   (1 << 17)
+#define MAC_RXDES0_RX_ERR              (1 << 18)
+#define MAC_RXDES0_CRC_ERR     (1 << 19)
+#define MAC_RXDES0_FTL         (1 << 20)
+#define MAC_RXDES0_RUNT                (1 << 21)
+#define MAC_RXDES0_RX_ODD_NB   (1 << 22)
+#define MAC_RXDES0_FIFO_FULL   (1 << 23)
+#define MAC_RXDES0_PAUSE_OPCODE        (1 << 24)
+#define MAC_RXDES0_PAUSE_FRAME (1 << 25)
+#define MAC_RXDES0_LRS         (1 << 28)
+#define MAC_RXDES0_FRS         (1 << 29)
+#define MAC_RXDES0_EDORR               (1 << 30)
+#define MAC_RXDES0_RXPKT_RDY   (1 << 31)
+
+#define MAC_RXDES1_VLANTAG_CI  0xffff
+#define MAC_RXDES1_PROT_MASK   (0x3 << 20)
+#define MAC_RXDES1_PROT_NONIP  (0x0 << 20)
+#define MAC_RXDES1_PROT_IP     (0x1 << 20)
+#define MAC_RXDES1_PROT_TCPIP  (0x2 << 20)
+#define MAC_RXDES1_PROT_UDPIP  (0x3 << 20)
+#define MAC_RXDES1_LLC         (1 << 22)
+#define MAC_RXDES1_DF          (1 << 23)
+#define MAC_RXDES1_VLANTAG_AVAIL       (1 << 24)
+#define MAC_RXDES1_TCP_CHKSUM_ERR      (1 << 25)
+#define MAC_RXDES1_UDP_CHKSUM_ERR      (1 << 26)
+#define MAC_RXDES1_IP_CHKSUM_ERR       (1 << 27)
+
+#endif  /* __AST_NIC_H */
-- 
2.12.0.367.g23dc2f6d3c-goog

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to