summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-06-05 18:10:41 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2008-06-06 09:30:47 +0200
commit3f73e61600f8fce0b6fa02e9a82124c1c89937c7 (patch)
treee48eb078ccd6637c4534b69dca7ec11ab15dfb51 /drivers/net
parent5fef327aaf7ede78f8a9644e70ed18ba0bfda673 (diff)
downloadbarebox-3f73e61600f8fce0b6fa02e9a82124c1c89937c7.tar.gz
barebox-3f73e61600f8fce0b6fa02e9a82124c1c89937c7.tar.xz
add macb ethernet driver
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig5
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/macb.c477
-rw-r--r--drivers/net/macb.h269
4 files changed, 752 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 372f02dc12..05514d7c6a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -57,6 +57,11 @@ config DRIVER_NET_IMX27
depends on ARCH_IMX27
select MIIPHY
+config DRIVER_NET_MACB
+ bool "macb Ethernet driver"
+ depends on ARCH_AT91SAM9
+ select MIIPHY
+
config DRIVER_NET_TAP
bool "tap Ethernet driver"
depends on LINUX
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index cc48a27e52..6dc38b8d83 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_DRIVER_NET_NETX) += netx_eth.o
obj-$(CONFIG_DRIVER_NET_AT91_ETHER) += at91_ether.o
obj-$(CONFIG_DRIVER_NET_MPC5200) += fec_mpc5200.o
obj-$(CONFIG_DRIVER_NET_IMX27) += fec_imx27.o
+obj-$(CONFIG_DRIVER_NET_MACB) += macb.o
obj-$(CONFIG_DRIVER_NET_TAP) += tap.o
obj-$(CONFIG_MIIPHY) += miiphy.o
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
new file mode 100644
index 0000000000..c56b722eb8
--- /dev/null
+++ b/drivers/net/macb.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <common.h>
+
+/*
+ * The u-boot networking stack is a little weird. It seems like the
+ * networking core allocates receive buffers up front without any
+ * regard to the hardware that's supposed to actually receive those
+ * packets.
+ *
+ * The MACB receives packets into 128-byte receive buffers, so the
+ * buffers allocated by the core isn't very practical to use. We'll
+ * allocate our own, but we need one such buffer in case a packet
+ * wraps around the DMA ring so that we have to copy it.
+ *
+ * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific
+ * configuration header. This way, the core allocates one RX buffer
+ * and one TX buffer, each of which can hold a ethernet packet of
+ * maximum size.
+ *
+ * For some reason, the networking core unconditionally specifies a
+ * 32-byte packet "alignment" (which really should be called
+ * "padding"). MACB shouldn't need that, but we'll refrain from any
+ * core modifications here...
+ */
+
+#include <net.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <init.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+
+#include "macb.h"
+
+#define barrier() asm volatile("" ::: "memory")
+
+#define CFG_MACB_RX_BUFFER_SIZE 4096
+#define CFG_MACB_RX_RING_SIZE (CFG_MACB_RX_BUFFER_SIZE / 128)
+#define CFG_MACB_TX_TIMEOUT 1000
+#define CFG_MACB_AUTONEG_TIMEOUT 5000000
+
+struct macb_dma_desc {
+ u32 addr;
+ u32 ctrl;
+};
+
+#define RXADDR_USED 0x00000001
+#define RXADDR_WRAP 0x00000002
+
+#define RXBUF_FRMLEN_MASK 0x00000fff
+#define RXBUF_FRAME_START 0x00004000
+#define RXBUF_FRAME_END 0x00008000
+#define RXBUF_TYPEID_MATCH 0x00400000
+#define RXBUF_ADDR4_MATCH 0x00800000
+#define RXBUF_ADDR3_MATCH 0x01000000
+#define RXBUF_ADDR2_MATCH 0x02000000
+#define RXBUF_ADDR1_MATCH 0x04000000
+#define RXBUF_BROADCAST 0x80000000
+
+#define TXBUF_FRMLEN_MASK 0x000007ff
+#define TXBUF_FRAME_END 0x00008000
+#define TXBUF_NOCRC 0x00010000
+#define TXBUF_EXHAUSTED 0x08000000
+#define TXBUF_UNDERRUN 0x10000000
+#define TXBUF_MAXRETRY 0x20000000
+#define TXBUF_WRAP 0x40000000
+#define TXBUF_USED 0x80000000
+
+struct macb_device {
+ void *regs;
+
+ unsigned int rx_tail;
+ unsigned int tx_tail;
+
+ void *rx_buffer;
+ void *tx_buffer;
+ struct macb_dma_desc *rx_ring;
+ struct macb_dma_desc *tx_ring;
+
+ const struct device *dev;
+ struct eth_device netdev;
+ unsigned short phy_addr;
+
+ struct miiphy_device miiphy;
+};
+
+static int macb_send(struct eth_device *edev, void *packet,
+ int length)
+{
+ struct macb_device *macb = edev->priv;
+ unsigned long ctrl;
+
+ debug("%s\n", __func__);
+
+ ctrl = length & TXBUF_FRMLEN_MASK;
+ ctrl |= TXBUF_FRAME_END | TXBUF_WRAP;
+
+ macb->tx_ring[0].ctrl = ctrl;
+ macb->tx_ring[0].addr = (ulong)packet;
+ barrier();
+ writel(MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART), macb->regs + MACB_NCR);
+
+ if (ctrl & TXBUF_UNDERRUN)
+ printf("TX underrun\n");
+ if (ctrl & TXBUF_EXHAUSTED)
+ printf("TX buffers exhausted in mid frame\n");
+
+ /* No one cares anyway */
+ return 0;
+}
+
+static void reclaim_rx_buffers(struct macb_device *macb,
+ unsigned int new_tail)
+{
+ unsigned int i;
+
+ debug("%s\n", __func__);
+
+ i = macb->rx_tail;
+ while (i > new_tail) {
+ macb->rx_ring[i].addr &= ~RXADDR_USED;
+ i++;
+ if (i > CFG_MACB_RX_RING_SIZE)
+ i = 0;
+ }
+
+ while (i < new_tail) {
+ macb->rx_ring[i].addr &= ~RXADDR_USED;
+ i++;
+ }
+
+ barrier();
+ macb->rx_tail = new_tail;
+}
+
+static int macb_recv(struct eth_device *edev)
+{
+ struct macb_device *macb = edev->priv;
+ unsigned int rx_tail = macb->rx_tail;
+ void *buffer;
+ int length;
+ int wrapped = 0;
+ u32 status;
+
+// printf("%s\n", __func__);
+
+ for (;;) {
+ if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+ return -1;
+
+ status = macb->rx_ring[rx_tail].ctrl;
+ if (status & RXBUF_FRAME_START) {
+ if (rx_tail != macb->rx_tail)
+ reclaim_rx_buffers(macb, rx_tail);
+ wrapped = 0;
+ }
+
+ if (status & RXBUF_FRAME_END) {
+ buffer = macb->rx_buffer + 128 * macb->rx_tail;
+ length = status & RXBUF_FRMLEN_MASK;
+ if (wrapped) {
+ unsigned int headlen, taillen;
+
+ headlen = 128 * (CFG_MACB_RX_RING_SIZE
+ - macb->rx_tail);
+ taillen = length - headlen;
+ memcpy((void *)NetRxPackets[0],
+ buffer, headlen);
+ memcpy((void *)NetRxPackets[0] + headlen,
+ macb->rx_buffer, taillen);
+ buffer = (void *)NetRxPackets[0];
+ }
+
+ NetReceive(buffer, length);
+ if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
+ rx_tail = 0;
+ reclaim_rx_buffers(macb, rx_tail);
+ } else {
+ if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
+ wrapped = 1;
+ rx_tail = 0;
+ }
+ }
+ barrier();
+ }
+
+ return 0;
+}
+
+static int macb_open(struct eth_device *edev)
+{
+ struct macb_device *macb = edev->priv;
+ int duplex = 1, speed = 1;
+ u32 ncfgr;
+
+ debug("%s\n", __func__);
+
+ miiphy_wait_aneg(&macb->miiphy);
+ miiphy_print_status(&macb->miiphy);
+
+ ncfgr = readl(macb->regs + MACB_NCFGR);
+ ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+ if (speed)
+ ncfgr |= MACB_BIT(SPD);
+ if (duplex)
+ ncfgr |= MACB_BIT(FD);
+ writel(ncfgr, macb->regs + MACB_NCFGR);
+
+ return 0;
+}
+
+static int macb_init(struct eth_device *edev)
+{
+ struct macb_device *macb = edev->priv;
+ unsigned long paddr;
+ int i;
+
+ debug("%s\n", __func__);
+
+ /*
+ * macb_halt should have been called at some point before now,
+ * so we'll assume the controller is idle.
+ */
+
+ /* initialize DMA descriptors */
+ paddr = (ulong)macb->rx_buffer;
+ for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
+ if (i == (CFG_MACB_RX_RING_SIZE - 1))
+ paddr |= RXADDR_WRAP;
+ macb->rx_ring[i].addr = paddr;
+ macb->rx_ring[i].ctrl = 0;
+ paddr += 128;
+ }
+
+ macb->tx_ring[0].addr = 0;
+ macb->tx_ring[0].ctrl = TXBUF_USED | TXBUF_WRAP;
+
+ macb->rx_tail = macb->tx_tail = 0;
+
+ writel((ulong)macb->rx_ring, macb->regs + MACB_RBQP);
+ writel((ulong)macb->tx_ring, macb->regs + MACB_TBQP);
+
+ /* choose RMII or MII mode. This depends on the board */
+#define CONFIG_RMII
+#define CONFIG_AT91SAM9260
+
+#ifdef CONFIG_RMII
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260)
+ writel(MACB_BIT(RMII) | MACB_BIT(CLKEN), macb->regs + MACB_USRIO);
+#else
+ writel(0, macb->regs + MACB_USRIO);
+#endif
+#else
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260)
+ writel(MACB_BIT(CLKEN), macb->regs + MACB_USRIO);
+#else
+ writel(MACB_BIT(MII), macb->regs + MACB_USRIO);
+#endif
+#endif /* CONFIG_RMII */
+
+ /* Enable TX and RX */
+ writel(MACB_BIT(TE) | MACB_BIT(RE), macb->regs + MACB_NCR);
+
+ return 0;
+}
+
+static void macb_halt(struct eth_device *edev)
+{
+ struct macb_device *macb = edev->priv;
+ u32 ncr, tsr;
+
+ /* Halt the controller and wait for any ongoing transmission to end. */
+ ncr = readl(macb->regs + MACB_NCR);
+ ncr |= MACB_BIT(THALT);
+ writel(ncr, macb->regs + MACB_NCR);
+
+ do {
+ tsr = readl(macb->regs + MACB_TSR);
+ } while (tsr & MACB_BIT(TGO));
+
+ /* Disable TX and RX, and clear statistics */
+ writel(MACB_BIT(CLRSTAT), macb->regs + MACB_NCR);
+}
+
+static int macb_phy_read(struct miiphy_device *mdev, uint8_t addr,
+ uint8_t reg, uint16_t * value)
+{
+ struct eth_device *edev = mdev->edev;
+ struct macb_device *macb = edev->priv;
+
+ unsigned long netctl;
+ unsigned long netstat;
+ unsigned long frame;
+ int iflag;
+
+ debug("%s\n", __func__);
+
+ iflag = disable_interrupts();
+ netctl = readl(macb->regs + MACB_NCR);
+ netctl |= MACB_BIT(MPE);
+ writel(netctl, macb->regs + MACB_NCR);
+ if (iflag)
+ enable_interrupts();
+
+ frame = (MACB_BF(SOF, 1)
+ | MACB_BF(RW, 2)
+ | MACB_BF(PHYA, addr)
+ | MACB_BF(REGA, reg)
+ | MACB_BF(CODE, 2));
+ writel(frame, macb->regs + MACB_MAN);
+
+ do {
+ netstat = readl(macb->regs + MACB_NSR);
+ } while (!(netstat & MACB_BIT(IDLE)));
+
+ frame = readl(macb->regs + MACB_MAN);
+ *value = MACB_BFEXT(DATA, frame);
+
+ iflag = disable_interrupts();
+ netctl = readl(macb->regs + MACB_NCR);
+ netctl &= ~MACB_BIT(MPE);
+ writel(netctl, macb->regs + MACB_NCR);
+ if (iflag)
+ enable_interrupts();
+
+ return 0;
+}
+
+static int macb_phy_write(struct miiphy_device *mdev, uint8_t addr,
+ uint8_t reg, uint16_t value)
+{
+ struct eth_device *edev = mdev->edev;
+ struct macb_device *macb = edev->priv;
+ unsigned long netctl;
+ unsigned long netstat;
+ unsigned long frame;
+ int iflag;
+
+ debug("%s\n", __func__);
+
+ iflag = disable_interrupts();
+ netctl = readl(macb->regs + MACB_NCR);
+ netctl |= MACB_BIT(MPE);
+ writel(netctl, macb->regs + MACB_NCR);
+ if (iflag)
+ enable_interrupts();
+
+ frame = (MACB_BF(SOF, 1)
+ | MACB_BF(RW, 1)
+ | MACB_BF(PHYA, addr)
+ | MACB_BF(REGA, reg)
+ | MACB_BF(CODE, 2)
+ | MACB_BF(DATA, value));
+ writel(frame, macb->regs + MACB_MAN);
+
+ do {
+ netstat = readl(macb->regs + MACB_NSR);
+ } while (!(netstat & MACB_BIT(IDLE)));
+
+ iflag = disable_interrupts();
+ netctl = readl(macb->regs + MACB_NCR);
+ netctl &= ~MACB_BIT(MPE);
+ writel(netctl, macb->regs + MACB_NCR);
+ if (iflag)
+ enable_interrupts();
+
+ return 0;
+}
+
+static int macb_get_ethaddr(struct eth_device *edev, unsigned char *adr)
+{
+ debug("%s\n", __func__);
+
+ return -1;
+}
+
+static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr)
+{
+ struct macb_device *macb = edev->priv;
+
+ debug("%s\n", __func__);
+
+ /* set hardware address */
+
+ writel(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24, macb->regs + MACB_SA1B);
+ writel(adr[4] | adr[5] << 8, macb->regs + MACB_SA1T);
+
+ return 0;
+}
+
+static int macb_probe(struct device_d *dev)
+{
+ struct eth_device *edev;
+ struct macb_device *macb;
+ unsigned long macb_hz;
+ u32 ncfgr;
+
+ edev = xzalloc(sizeof(struct eth_device) + sizeof(struct macb_device));
+ dev->type_data = edev;
+ edev->dev = dev;
+ edev->priv = (struct macb_device *)(edev + 1);
+ macb = edev->priv;
+
+ edev->init = macb_init;
+ edev->open = macb_open;
+ edev->send = macb_send;
+ edev->recv = macb_recv;
+ edev->halt = macb_halt;
+ edev->get_ethaddr = macb_get_ethaddr;
+ edev->set_ethaddr = macb_set_ethaddr;
+
+ macb->miiphy.read = macb_phy_read;
+ macb->miiphy.write = macb_phy_write;
+ macb->miiphy.address = 0;
+ macb->miiphy.flags = 0;
+ macb->miiphy.edev = edev;
+
+ macb->rx_buffer = xmalloc(CFG_MACB_RX_BUFFER_SIZE);
+ macb->rx_ring = xmalloc(CFG_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
+ macb->tx_ring = xmalloc(sizeof(struct macb_dma_desc));
+
+ macb->regs = (void *)dev->map_base;
+ macb->phy_addr = 0; /* FIXME */
+
+ /*
+ * Do some basic initialization so that we at least can talk
+ * to the PHY
+ */
+ macb_hz = get_macb_pclk_rate(0);
+ if (macb_hz < 20000000)
+ ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
+ else if (macb_hz < 40000000)
+ ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
+ else if (macb_hz < 80000000)
+ ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
+ else
+ ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
+
+ writel(ncfgr, macb->regs + MACB_NCFGR);
+
+ miiphy_register(&macb->miiphy);
+ eth_register(edev);
+
+ return 0;
+}
+
+static struct driver_d macb_driver = {
+ .name = "macb",
+ .probe = macb_probe,
+ .type = DEVICE_TYPE_ETHER,
+};
+
+static int macb_driver_init(void)
+{
+ register_driver(&macb_driver);
+ return 0;
+}
+
+device_initcall(macb_driver_init);
+
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
new file mode 100644
index 0000000000..8b6d2e7787
--- /dev/null
+++ b/drivers/net/macb.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __DRIVERS_MACB_H__
+#define __DRIVERS_MACB_H__
+
+/* MACB register offsets */
+#define MACB_NCR 0x0000
+#define MACB_NCFGR 0x0004
+#define MACB_NSR 0x0008
+#define MACB_TSR 0x0014
+#define MACB_RBQP 0x0018
+#define MACB_TBQP 0x001c
+#define MACB_RSR 0x0020
+#define MACB_ISR 0x0024
+#define MACB_IER 0x0028
+#define MACB_IDR 0x002c
+#define MACB_IMR 0x0030
+#define MACB_MAN 0x0034
+#define MACB_PTR 0x0038
+#define MACB_PFR 0x003c
+#define MACB_FTO 0x0040
+#define MACB_SCF 0x0044
+#define MACB_MCF 0x0048
+#define MACB_FRO 0x004c
+#define MACB_FCSE 0x0050
+#define MACB_ALE 0x0054
+#define MACB_DTF 0x0058
+#define MACB_LCOL 0x005c
+#define MACB_EXCOL 0x0060
+#define MACB_TUND 0x0064
+#define MACB_CSE 0x0068
+#define MACB_RRE 0x006c
+#define MACB_ROVR 0x0070
+#define MACB_RSE 0x0074
+#define MACB_ELE 0x0078
+#define MACB_RJA 0x007c
+#define MACB_USF 0x0080
+#define MACB_STE 0x0084
+#define MACB_RLE 0x0088
+#define MACB_TPF 0x008c
+#define MACB_HRB 0x0090
+#define MACB_HRT 0x0094
+#define MACB_SA1B 0x0098
+#define MACB_SA1T 0x009c
+#define MACB_SA2B 0x00a0
+#define MACB_SA2T 0x00a4
+#define MACB_SA3B 0x00a8
+#define MACB_SA3T 0x00ac
+#define MACB_SA4B 0x00b0
+#define MACB_SA4T 0x00b4
+#define MACB_TID 0x00b8
+#define MACB_TPQ 0x00bc
+#define MACB_USRIO 0x00c0
+#define MACB_WOL 0x00c4
+
+/* Bitfields in NCR */
+#define MACB_LB_OFFSET 0
+#define MACB_LB_SIZE 1
+#define MACB_LLB_OFFSET 1
+#define MACB_LLB_SIZE 1
+#define MACB_RE_OFFSET 2
+#define MACB_RE_SIZE 1
+#define MACB_TE_OFFSET 3
+#define MACB_TE_SIZE 1
+#define MACB_MPE_OFFSET 4
+#define MACB_MPE_SIZE 1
+#define MACB_CLRSTAT_OFFSET 5
+#define MACB_CLRSTAT_SIZE 1
+#define MACB_INCSTAT_OFFSET 6
+#define MACB_INCSTAT_SIZE 1
+#define MACB_WESTAT_OFFSET 7
+#define MACB_WESTAT_SIZE 1
+#define MACB_BP_OFFSET 8
+#define MACB_BP_SIZE 1
+#define MACB_TSTART_OFFSET 9
+#define MACB_TSTART_SIZE 1
+#define MACB_THALT_OFFSET 10
+#define MACB_THALT_SIZE 1
+#define MACB_NCR_TPF_OFFSET 11
+#define MACB_NCR_TPF_SIZE 1
+#define MACB_TZQ_OFFSET 12
+#define MACB_TZQ_SIZE 1
+
+/* Bitfields in NCFGR */
+#define MACB_SPD_OFFSET 0
+#define MACB_SPD_SIZE 1
+#define MACB_FD_OFFSET 1
+#define MACB_FD_SIZE 1
+#define MACB_BIT_RATE_OFFSET 2
+#define MACB_BIT_RATE_SIZE 1
+#define MACB_JFRAME_OFFSET 3
+#define MACB_JFRAME_SIZE 1
+#define MACB_CAF_OFFSET 4
+#define MACB_CAF_SIZE 1
+#define MACB_NBC_OFFSET 5
+#define MACB_NBC_SIZE 1
+#define MACB_NCFGR_MTI_OFFSET 6
+#define MACB_NCFGR_MTI_SIZE 1
+#define MACB_UNI_OFFSET 7
+#define MACB_UNI_SIZE 1
+#define MACB_BIG_OFFSET 8
+#define MACB_BIG_SIZE 1
+#define MACB_EAE_OFFSET 9
+#define MACB_EAE_SIZE 1
+#define MACB_CLK_OFFSET 10
+#define MACB_CLK_SIZE 2
+#define MACB_RTY_OFFSET 12
+#define MACB_RTY_SIZE 1
+#define MACB_PAE_OFFSET 13
+#define MACB_PAE_SIZE 1
+#define MACB_RBOF_OFFSET 14
+#define MACB_RBOF_SIZE 2
+#define MACB_RLCE_OFFSET 16
+#define MACB_RLCE_SIZE 1
+#define MACB_DRFCS_OFFSET 17
+#define MACB_DRFCS_SIZE 1
+#define MACB_EFRHD_OFFSET 18
+#define MACB_EFRHD_SIZE 1
+#define MACB_IRXFCS_OFFSET 19
+#define MACB_IRXFCS_SIZE 1
+
+/* Bitfields in NSR */
+#define MACB_NSR_LINK_OFFSET 0
+#define MACB_NSR_LINK_SIZE 1
+#define MACB_MDIO_OFFSET 1
+#define MACB_MDIO_SIZE 1
+#define MACB_IDLE_OFFSET 2
+#define MACB_IDLE_SIZE 1
+
+/* Bitfields in TSR */
+#define MACB_UBR_OFFSET 0
+#define MACB_UBR_SIZE 1
+#define MACB_COL_OFFSET 1
+#define MACB_COL_SIZE 1
+#define MACB_TSR_RLE_OFFSET 2
+#define MACB_TSR_RLE_SIZE 1
+#define MACB_TGO_OFFSET 3
+#define MACB_TGO_SIZE 1
+#define MACB_BEX_OFFSET 4
+#define MACB_BEX_SIZE 1
+#define MACB_COMP_OFFSET 5
+#define MACB_COMP_SIZE 1
+#define MACB_UND_OFFSET 6
+#define MACB_UND_SIZE 1
+
+/* Bitfields in RSR */
+#define MACB_BNA_OFFSET 0
+#define MACB_BNA_SIZE 1
+#define MACB_REC_OFFSET 1
+#define MACB_REC_SIZE 1
+#define MACB_OVR_OFFSET 2
+#define MACB_OVR_SIZE 1
+
+/* Bitfields in ISR/IER/IDR/IMR */
+#define MACB_MFD_OFFSET 0
+#define MACB_MFD_SIZE 1
+#define MACB_RCOMP_OFFSET 1
+#define MACB_RCOMP_SIZE 1
+#define MACB_RXUBR_OFFSET 2
+#define MACB_RXUBR_SIZE 1
+#define MACB_TXUBR_OFFSET 3
+#define MACB_TXUBR_SIZE 1
+#define MACB_ISR_TUND_OFFSET 4
+#define MACB_ISR_TUND_SIZE 1
+#define MACB_ISR_RLE_OFFSET 5
+#define MACB_ISR_RLE_SIZE 1
+#define MACB_TXERR_OFFSET 6
+#define MACB_TXERR_SIZE 1
+#define MACB_TCOMP_OFFSET 7
+#define MACB_TCOMP_SIZE 1
+#define MACB_ISR_LINK_OFFSET 9
+#define MACB_ISR_LINK_SIZE 1
+#define MACB_ISR_ROVR_OFFSET 10
+#define MACB_ISR_ROVR_SIZE 1
+#define MACB_HRESP_OFFSET 11
+#define MACB_HRESP_SIZE 1
+#define MACB_PFR_OFFSET 12
+#define MACB_PFR_SIZE 1
+#define MACB_PTZ_OFFSET 13
+#define MACB_PTZ_SIZE 1
+
+/* Bitfields in MAN */
+#define MACB_DATA_OFFSET 0
+#define MACB_DATA_SIZE 16
+#define MACB_CODE_OFFSET 16
+#define MACB_CODE_SIZE 2
+#define MACB_REGA_OFFSET 18
+#define MACB_REGA_SIZE 5
+#define MACB_PHYA_OFFSET 23
+#define MACB_PHYA_SIZE 5
+#define MACB_RW_OFFSET 28
+#define MACB_RW_SIZE 2
+#define MACB_SOF_OFFSET 30
+#define MACB_SOF_SIZE 2
+
+/* Bitfields in USRIO */
+#define MACB_MII_OFFSET 0
+#define MACB_MII_SIZE 1
+#define MACB_EAM_OFFSET 1
+#define MACB_EAM_SIZE 1
+#define MACB_TX_PAUSE_OFFSET 2
+#define MACB_TX_PAUSE_SIZE 1
+#define MACB_TX_PAUSE_ZERO_OFFSET 3
+#define MACB_TX_PAUSE_ZERO_SIZE 1
+
+/* Bitfields in USRIO (AT91) */
+#define MACB_RMII_OFFSET 0
+#define MACB_RMII_SIZE 1
+#define MACB_CLKEN_OFFSET 1
+#define MACB_CLKEN_SIZE 1
+
+/* Bitfields in WOL */
+#define MACB_IP_OFFSET 0
+#define MACB_IP_SIZE 16
+#define MACB_MAG_OFFSET 16
+#define MACB_MAG_SIZE 1
+#define MACB_ARP_OFFSET 17
+#define MACB_ARP_SIZE 1
+#define MACB_SA1_OFFSET 18
+#define MACB_SA1_SIZE 1
+#define MACB_WOL_MTI_OFFSET 19
+#define MACB_WOL_MTI_SIZE 1
+
+/* Constants for CLK */
+#define MACB_CLK_DIV8 0
+#define MACB_CLK_DIV16 1
+#define MACB_CLK_DIV32 2
+#define MACB_CLK_DIV64 3
+
+/* Constants for MAN register */
+#define MACB_MAN_SOF 1
+#define MACB_MAN_WRITE 1
+#define MACB_MAN_READ 2
+#define MACB_MAN_CODE 2
+
+/* Bit manipulation macros */
+#define MACB_BIT(name) \
+ (1 << MACB_##name##_OFFSET)
+#define MACB_BF(name,value) \
+ (((value) & ((1 << MACB_##name##_SIZE) - 1)) \
+ << MACB_##name##_OFFSET)
+#define MACB_BFEXT(name,value)\
+ (((value) >> MACB_##name##_OFFSET) \
+ & ((1 << MACB_##name##_SIZE) - 1))
+#define MACB_BFINS(name,value,old) \
+ (((old) & ~(((1 << MACB_##name##_SIZE) - 1) \
+ << MACB_##name##_OFFSET)) \
+ | MACB_BF(name,value))
+
+#endif /* __DRIVERS_MACB_H__ */