[PATCH 16/17] aspeed: Add AST2500/AST2400 compatible NIC Driver
Maxim Sloyko
maxims at google.com
Fri Mar 17 08:36:23 AEDT 2017
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 <maxims at 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 <ratbert at faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macpaul at 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 <ratbert at faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macpaul at 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
More information about the openbmc
mailing list