diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2008-06-05 18:10:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2008-06-06 09:30:47 +0200 |
commit | 3f73e61600f8fce0b6fa02e9a82124c1c89937c7 (patch) | |
tree | e48eb078ccd6637c4534b69dca7ec11ab15dfb51 /drivers/net | |
parent | 5fef327aaf7ede78f8a9644e70ed18ba0bfda673 (diff) | |
download | barebox-3f73e61600f8fce0b6fa02e9a82124c1c89937c7.tar.gz barebox-3f73e61600f8fce0b6fa02e9a82124c1c89937c7.tar.xz |
add macb ethernet driver
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 5 | ||||
-rw-r--r-- | drivers/net/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/macb.c | 477 | ||||
-rw-r--r-- | drivers/net/macb.h | 269 |
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__ */ |