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