diff options
| author | wuyangyong <[email protected]> | 2011-10-14 09:18:11 +0000 |
|---|---|---|
| committer | wuyangyong <[email protected]> | 2011-10-14 09:18:11 +0000 |
| commit | 2d98e4990e19e45e1a9b7f1ada4557da57f78581 (patch) | |
| tree | cd29d988d77ff5a982dda14150bccd182fb5d0cd /bsp | |
| parent | 01a17f4f38e661875af3c2b86e5bc9924eaae84a (diff) | |
add lpc178x eth driver
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1765 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'bsp')
| -rw-r--r-- | bsp/lpc178x/drivers/SConscript | 13 | ||||
| -rw-r--r-- | bsp/lpc178x/drivers/emac.c | 521 | ||||
| -rw-r--r-- | bsp/lpc178x/drivers/emac.h | 295 |
3 files changed, 829 insertions, 0 deletions
diff --git a/bsp/lpc178x/drivers/SConscript b/bsp/lpc178x/drivers/SConscript index dbcec922cf..34fe4de75f 100644 --- a/bsp/lpc178x/drivers/SConscript +++ b/bsp/lpc178x/drivers/SConscript @@ -1,9 +1,22 @@ +import copy
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
+
+# remove no need file.
+if GetDepend('RT_USING_LWIP') == False:
+ src_need_remove = ['emac.c'] # need remove file list.
+ src_tmp = copy.copy(src)
+ count = 0
+ for i in range(0, len(src_tmp)):
+ s = str(src_tmp[i])
+ if s in src_need_remove:
+ src.pop(i-count)
+ count = count + 1
+
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
diff --git a/bsp/lpc178x/drivers/emac.c b/bsp/lpc178x/drivers/emac.c new file mode 100644 index 0000000000..06bf61693e --- /dev/null +++ b/bsp/lpc178x/drivers/emac.c @@ -0,0 +1,521 @@ +#include "LPC177x_8x.h"
+#include "lpc177x_8x_pinsel.h"
+#include "emac.h"
+
+#include <rtthread.h>
+#include "lwipopts.h"
+#include <netif/ethernetif.h>
+
+#define EMAC_PHY_AUTO 0
+#define EMAC_PHY_10MBIT 1
+#define EMAC_PHY_100MBIT 2
+
+#define MAX_ADDR_LEN 6
+struct lpc17xx_emac
+{
+ /* inherit from ethernet device */
+ struct eth_device parent;
+
+ rt_uint8_t phy_mode;
+
+ /* interface address info. */
+ rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
+};
+static struct lpc17xx_emac lpc17xx_emac_device;
+static struct rt_semaphore sem_slot, sem_lock;
+
+/* Local Function Prototypes */
+static void write_PHY (rt_uint32_t PhyReg, rt_uint32_t Value);
+static rt_uint16_t read_PHY (rt_uint8_t PhyReg) ;
+
+void ENET_IRQHandler(void)
+{
+ rt_uint32_t status;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ status = LPC_EMAC->IntStatus & LPC_EMAC->IntEnable;
+
+ /* Clear the interrupt. */
+ LPC_EMAC->IntClear = status;
+
+ if (status & INT_RX_DONE)
+ {
+ /* Disable EMAC RxDone interrupts. */
+ LPC_EMAC->IntEnable = INT_TX_DONE;
+
+ /* a frame has been received */
+ eth_device_ready(&(lpc17xx_emac_device.parent));
+ }
+ else if (status & INT_TX_DONE)
+ {
+ /* release one slot */
+ rt_sem_release(&sem_slot);
+ }
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+/* phy write */
+static void write_PHY (rt_uint32_t PhyReg, rt_uint32_t Value)
+{
+ unsigned int tout;
+
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MWTD = Value;
+
+ /* Wait utill operation completed */
+ tout = 0;
+ for (tout = 0; tout < MII_WR_TOUT; tout++)
+ {
+ if ((LPC_EMAC->MIND & MIND_BUSY) == 0)
+ {
+ break;
+ }
+ }
+}
+
+/* phy read */
+static rt_uint16_t read_PHY (rt_uint8_t PhyReg)
+{
+ rt_uint32_t tout;
+
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MCMD = MCMD_READ;
+
+ /* Wait until operation completed */
+ tout = 0;
+ for (tout = 0; tout < MII_RD_TOUT; tout++)
+ {
+ if ((LPC_EMAC->MIND & MIND_BUSY) == 0)
+ {
+ break;
+ }
+ }
+ LPC_EMAC->MCMD = 0;
+ return (LPC_EMAC->MRDD);
+}
+
+/* init rx descriptor */
+rt_inline void rx_descr_init (void)
+{
+ rt_uint32_t i;
+
+ for (i = 0; i < NUM_RX_FRAG; i++)
+ {
+ RX_DESC_PACKET(i) = RX_BUF(i);
+ RX_DESC_CTRL(i) = RCTRL_INT | (ETH_FRAG_SIZE-1);
+ RX_STAT_INFO(i) = 0;
+ RX_STAT_HASHCRC(i) = 0;
+ }
+
+ /* Set EMAC Receive Descriptor Registers. */
+ LPC_EMAC->RxDescriptor = RX_DESC_BASE;
+ LPC_EMAC->RxStatus = RX_STAT_BASE;
+ LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1;
+
+ /* Rx Descriptors Point to 0 */
+ LPC_EMAC->RxConsumeIndex = 0;
+}
+
+/* init tx descriptor */
+rt_inline void tx_descr_init (void)
+{
+ rt_uint32_t i;
+
+ for (i = 0; i < NUM_TX_FRAG; i++)
+ {
+ TX_DESC_PACKET(i) = TX_BUF(i);
+ TX_DESC_CTRL(i) = (1ul<<31) | (1ul<<30) | (1ul<<29) | (1ul<<28) | (1ul<<26) | (ETH_FRAG_SIZE-1);
+ TX_STAT_INFO(i) = 0;
+ }
+
+ /* Set EMAC Transmit Descriptor Registers. */
+ LPC_EMAC->TxDescriptor = TX_DESC_BASE;
+ LPC_EMAC->TxStatus = TX_STAT_BASE;
+ LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
+
+ /* Tx Descriptors Point to 0 */
+ LPC_EMAC->TxProduceIndex = 0;
+}
+
+/*
+TX_EN P1_4
+TXD0 P1_0
+TXD1 P1_1
+
+RXD0 P1_9
+RXD1 P1_10
+RX_ER P1_14
+CRS_DV P1_8
+
+MDC P1_16
+MDIO P1_17
+
+PHY_RESET P3_19
+REF_CLK P1_15
+*/
+static rt_err_t lpc17xx_emac_init(rt_device_t dev)
+{
+ /* Initialize the EMAC ethernet controller. */
+ rt_uint32_t regv, tout, id1, id2;
+
+ /* Power Up the EMAC controller. */
+ LPC_SC->PCONP |= (1UL<<30);
+
+ /* config RESET */
+ PINSEL_ConfigPin(3, 19, 0);
+ PINSEL_SetPinMode(3, 19, IOCON_MODE_PLAIN);
+ LPC_GPIO3->DIR |= 1<<19;
+ LPC_GPIO3->CLR = 1<<19;
+
+ /* Enable P1 Ethernet Pins. */
+ PINSEL_ConfigPin(1, 0, 1); /**< P1_0 ENET_TXD0 */
+ PINSEL_ConfigPin(1, 1, 1); /**< P1_1 ENET_TXD1 */
+ PINSEL_ConfigPin(1, 4, 1); /**< P1_4 ENET_TX_EN */
+ PINSEL_ConfigPin(1, 8, 1); /**< P1_8 ENET_CRS_DV */
+ PINSEL_ConfigPin(1, 9, 1); /**< P1_9 ENET_RXD0 */
+ PINSEL_ConfigPin(1, 10, 1); /**< P1_10 ENET_RXD1 */
+ PINSEL_ConfigPin(1, 14, 1); /**< P1_14 ENET_RX_ER */
+ PINSEL_ConfigPin(1, 15, 1); /**< P1_15 ENET_REF_CLK */
+ PINSEL_ConfigPin(1, 16, 1); /**< P1_16 ENET_MDC */
+ PINSEL_ConfigPin(1, 17, 1); /**< P1_17 ENET_MDIO */
+
+ LPC_GPIO3->SET = 1<<19;
+
+ /* Reset all EMAC internal modules. */
+ LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
+ MAC1_SIM_RES | MAC1_SOFT_RES;
+ LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;
+
+ /* A short delay after reset. */
+ for (tout = 100; tout; tout--);
+
+ /* Initialize MAC control registers. */
+ LPC_EMAC->MAC1 = MAC1_PASS_ALL;
+ LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
+ LPC_EMAC->MAXF = ETH_MAX_FLEN;
+ LPC_EMAC->CLRT = CLRT_DEF;
+ LPC_EMAC->IPGR = IPGR_DEF;
+
+ /* PCLK=18MHz, clock select=6, MDC=18/6=3MHz */
+ /* Enable Reduced MII interface. */
+ LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII;
+ for (tout = 100; tout; tout--);
+ LPC_EMAC->MCFG = MCFG_CLK_DIV20;
+
+ /* Enable Reduced MII interface. */
+ LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;
+
+ /* Reset Reduced MII Logic. */
+ LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
+ for (tout = 100; tout; tout--);
+ LPC_EMAC->SUPP = SUPP_SPEED;
+
+ /* Put the PHY in reset mode */
+ write_PHY (PHY_REG_BMCR, 0x8000);
+ for (tout = 1000; tout; tout--);
+
+// /* Wait for hardware reset to end. */
+// for (tout = 0; tout < 0x100000; tout++)
+// {
+// regv = read_PHY (PHY_REG_BMCR);
+// if (!(regv & 0x8000))
+// {
+// /* Reset complete */
+// break;
+// }
+// }
+// if (tout >= 0x100000)
+// {
+// rt_kprintf("reset failed\r\n");
+// return -RT_ERROR; /* reset failed */
+// }
+
+// /* Check if this is a DP83848C PHY. */
+// id1 = read_PHY (PHY_REG_IDR1);
+// id2 = read_PHY (PHY_REG_IDR2);
+//
+// if (((id1 << 16) | (id2 & 0xFFF0)) != DP83848C_ID)
+// return -RT_ERROR;
+
+ /* Configure the PHY device */
+ /* Configure the PHY device */
+ switch (lpc17xx_emac_device.phy_mode)
+ {
+ case EMAC_PHY_AUTO:
+ /* Use autonegotiation about the link speed. */
+ write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
+ /* Wait to complete Auto_Negotiation. */
+// for (tout = 0; tout < 0x100000; tout++)
+// {
+// regv = read_PHY (PHY_REG_BMSR);
+// if (regv & 0x0020)
+// {
+// /* Autonegotiation Complete. */
+// break;
+// }
+// }
+ break;
+ case EMAC_PHY_10MBIT:
+ /* Connect at 10MBit */
+ write_PHY (PHY_REG_BMCR, PHY_FULLD_10M);
+ break;
+ case EMAC_PHY_100MBIT:
+ /* Connect at 100MBit */
+ write_PHY (PHY_REG_BMCR, PHY_FULLD_100M);
+ break;
+ }
+ if (tout >= 0x100000) return -RT_ERROR; // auto_neg failed
+
+// /* Check the link status. */
+// for (tout = 0; tout < 0x10000; tout++)
+// {
+// regv = read_PHY (PHY_REG_STS);
+// if (regv & 0x0001)
+// {
+// /* Link is on. */
+// break;
+// }
+// }
+// if (tout >= 0x10000) return -RT_ERROR;
+
+ regv = 0x0004;
+ /* Configure Full/Half Duplex mode. */
+ if (regv & 0x0004)
+ {
+ /* Full duplex is enabled. */
+ LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
+ LPC_EMAC->Command |= CR_FULL_DUP;
+ LPC_EMAC->IPGT = IPGT_FULL_DUP;
+ }
+ else
+ {
+ /* Half duplex mode. */
+ LPC_EMAC->IPGT = IPGT_HALF_DUP;
+ }
+
+ /* Configure 100MBit/10MBit mode. */
+ if (regv & 0x0002)
+ {
+ /* 10MBit mode. */
+ LPC_EMAC->SUPP = 0;
+ }
+ else
+ {
+ /* 100MBit mode. */
+ LPC_EMAC->SUPP = SUPP_SPEED;
+ }
+
+ /* Set the Ethernet MAC Address registers */
+ LPC_EMAC->SA0 = (lpc17xx_emac_device.dev_addr[1]<<8) | lpc17xx_emac_device.dev_addr[0];
+ LPC_EMAC->SA1 = (lpc17xx_emac_device.dev_addr[3]<<8) | lpc17xx_emac_device.dev_addr[2];
+ LPC_EMAC->SA2 = (lpc17xx_emac_device.dev_addr[5]<<8) | lpc17xx_emac_device.dev_addr[4];
+
+ /* Initialize Tx and Rx DMA Descriptors */
+ rx_descr_init ();
+ tx_descr_init ();
+
+ /* Receive Broadcast and Perfect Match Packets */
+ LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;
+
+ /* Reset all interrupts */
+ LPC_EMAC->IntClear = 0xFFFF;
+
+ /* Enable EMAC interrupts. */
+ LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;
+
+ /* Enable receive and transmit mode of MAC Ethernet core */
+ LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN);
+ LPC_EMAC->MAC1 |= MAC1_REC_EN;
+
+ /* Enable the ENET Interrupt */
+ NVIC_EnableIRQ(ENET_IRQn);
+
+ return RT_EOK;
+}
+
+static rt_err_t lpc17xx_emac_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ return RT_EOK;
+}
+
+static rt_err_t lpc17xx_emac_close(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+static rt_size_t lpc17xx_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_size_t lpc17xx_emac_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_err_t lpc17xx_emac_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ switch (cmd)
+ {
+ case NIOCTL_GADDR:
+ /* get mac address */
+ if (args) rt_memcpy(args, lpc17xx_emac_device.dev_addr, 6);
+ else return -RT_ERROR;
+ break;
+
+ default :
+ break;
+ }
+
+ return RT_EOK;
+}
+
+/* EtherNet Device Interface */
+/* transmit packet. */
+rt_err_t lpc17xx_emac_tx( rt_device_t dev, struct pbuf* p)
+{
+ rt_uint32_t Index, IndexNext;
+ struct pbuf *q;
+ rt_uint8_t *ptr;
+
+ /* take a slot */
+ rt_sem_take(&sem_slot, RT_WAITING_FOREVER);
+
+ /* lock EMAC device */
+ rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+ /* get produce index */
+ Index = LPC_EMAC->TxProduceIndex;
+
+ /* calculate next index */
+ IndexNext = LPC_EMAC->TxProduceIndex + 1;
+ if(IndexNext > LPC_EMAC->TxDescriptorNumber)
+ IndexNext = 0;
+
+ /* copy data to tx buffer */
+ q = p;
+ ptr = (rt_uint8_t*)TX_BUF(Index);
+ while (q)
+ {
+ memcpy(ptr, q->payload, q->len);
+ ptr += q->len;
+ q = q->next;
+ }
+
+ TX_DESC_CTRL(Index) &= ~0x7ff;
+ TX_DESC_CTRL(Index) |= (p->tot_len - 1) & 0x7ff;
+
+ /* change index to the next */
+ LPC_EMAC->TxProduceIndex = IndexNext;
+
+ /* unlock EMAC device */
+ rt_sem_release(&sem_lock);
+
+ return RT_EOK;
+}
+
+/* reception packet. */
+struct pbuf *lpc17xx_emac_rx(rt_device_t dev)
+{
+ struct pbuf* p;
+ rt_uint32_t size;
+ rt_uint32_t Index;
+
+ /* init p pointer */
+ p = RT_NULL;
+
+ /* lock EMAC device */
+ rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+ Index = LPC_EMAC->RxConsumeIndex;
+ if(Index != LPC_EMAC->RxProduceIndex)
+ {
+ size = (RX_STAT_INFO(Index) & 0x7ff)+1;
+ if (size > ETH_FRAG_SIZE) size = ETH_FRAG_SIZE;
+
+ /* allocate buffer */
+ p = pbuf_alloc(PBUF_LINK, size, PBUF_RAM);
+ if (p != RT_NULL)
+ {
+ struct pbuf* q;
+ rt_uint8_t *ptr;
+
+ ptr = (rt_uint8_t*)RX_BUF(Index);
+ for (q = p; q != RT_NULL; q= q->next)
+ {
+ memcpy(q->payload, ptr, q->len);
+ ptr += q->len;
+ }
+ }
+
+ /* move Index to the next */
+ if(++Index > LPC_EMAC->RxDescriptorNumber)
+ Index = 0;
+
+ /* set consume index */
+ LPC_EMAC->RxConsumeIndex = Index;
+ }
+ else
+ {
+ /* Enable RxDone interrupt */
+ LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;
+ }
+
+ /* unlock EMAC device */
+ rt_sem_release(&sem_lock);
+
+ return p;
+}
+
+void lpc17xx_emac_hw_init(void)
+{
+ rt_sem_init(&sem_slot, "tx_slot", NUM_TX_FRAG, RT_IPC_FLAG_FIFO);
+ rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+
+ /* set autonegotiation mode */
+ lpc17xx_emac_device.phy_mode = EMAC_PHY_AUTO;
+
+ // OUI 00-60-37 NXP Semiconductors
+ lpc17xx_emac_device.dev_addr[0] = 0x00;
+ lpc17xx_emac_device.dev_addr[1] = 0x60;
+ lpc17xx_emac_device.dev_addr[2] = 0x37;
+ /* set mac address: (only for test) */
+ lpc17xx_emac_device.dev_addr[3] = 0xA2;
+ lpc17xx_emac_device.dev_addr[4] = 0x45;
+ lpc17xx_emac_device.dev_addr[5] = 0x5E;
+
+ lpc17xx_emac_device.parent.parent.init = lpc17xx_emac_init;
+ lpc17xx_emac_device.parent.parent.open = lpc17xx_emac_open;
+ lpc17xx_emac_device.parent.parent.close = lpc17xx_emac_close;
+ lpc17xx_emac_device.parent.parent.read = lpc17xx_emac_read;
+ lpc17xx_emac_device.parent.parent.write = lpc17xx_emac_write;
+ lpc17xx_emac_device.parent.parent.control = lpc17xx_emac_control;
+ lpc17xx_emac_device.parent.parent.user_data = RT_NULL;
+
+ lpc17xx_emac_device.parent.eth_rx = lpc17xx_emac_rx;
+ lpc17xx_emac_device.parent.eth_tx = lpc17xx_emac_tx;
+
+ eth_device_init(&(lpc17xx_emac_device.parent), "e0");
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void emac_dump()
+{
+// rt_kprintf("IntCount : %d\n", intcount);
+ rt_kprintf("Status : %08x\n", LPC_EMAC->Status);
+ rt_kprintf("Command : %08x\n", LPC_EMAC->Command);
+ rt_kprintf("RxStatus : %08x\n", LPC_EMAC->RxStatus);
+ rt_kprintf("TxStatus : %08x\n", LPC_EMAC->TxStatus);
+ rt_kprintf("IntEnable: %08x\n", LPC_EMAC->IntEnable);
+ rt_kprintf("IntStatus: %08x\n", LPC_EMAC->IntStatus);
+}
+FINSH_FUNCTION_EXPORT(emac_dump, dump emac register);
+#endif
+
diff --git a/bsp/lpc178x/drivers/emac.h b/bsp/lpc178x/drivers/emac.h new file mode 100644 index 0000000000..f7199ddfed --- /dev/null +++ b/bsp/lpc178x/drivers/emac.h @@ -0,0 +1,295 @@ +#ifndef __LPC17XX_EMAC_H
+#define __LPC17XX_EMAC_H
+
+#include "LPC177x_8x.h"
+
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
+#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */
+#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */
+#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */
+
+#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
+
+/* EMAC variables located in 16K Ethernet SRAM */
+#define RX_DESC_BASE 0x20000000
+#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*8)
+#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*8)
+#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*8)
+#define RX_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*4)
+#define TX_BUF_BASE (RX_BUF_BASE + NUM_RX_FRAG*ETH_FRAG_SIZE)
+
+/* RX and TX descriptor and status definitions. */
+#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i))
+#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
+#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i))
+#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
+#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i))
+#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
+#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i))
+#define RX_BUF(i) (RX_BUF_BASE + ETH_FRAG_SIZE*i)
+#define TX_BUF(i) (TX_BUF_BASE + ETH_FRAG_SIZE*i)
+
+/* MAC Configuration Register 1 */
+#define MAC1_REC_EN 0x00000001 /* Receive Enable */
+#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
+#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */
+#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */
+#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */
+#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */
+#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */
+#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */
+#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */
+#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */
+#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */
+
+/* MAC Configuration Register 2 */
+#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */
+#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */
+#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */
+#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */
+#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */
+#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */
+#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */
+#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */
+#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */
+#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */
+#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */
+#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */
+#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */
+
+/* Back-to-Back Inter-Packet-Gap Register */
+#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */
+#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */
+
+/* Non Back-to-Back Inter-Packet-Gap Register */
+#define IPGR_DEF 0x00000012 /* Recommended value */
+
+/* Collision Window/Retry Register */
+#define CLRT_DEF 0x0000370F /* Default value */
+
+/* PHY Support Register */
+#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */
+#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */
+
+/* Test Register */
+#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */
+#define TEST_TST_PAUSE 0x00000002 /* Test Pause */
+#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */
+
+/* MII Management Configuration Register */
+#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
+#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
+#define MCFG_CLK_SEL 0x0000001C /* Clock Select Mask */
+#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
+
+#define MCFG_CLK_DIV4 0x00000000 /* MDC = hclk / 4 */
+#define MCFG_CLK_DIV6 0x00000008 /* MDC = hclk / 6 */
+#define MCFG_CLK_DIV8 0x0000000C /* MDC = hclk / 8 */
+#define MCFG_CLK_DIV10 0x00000010 /* MDC = hclk / 10 */
+#define MCFG_CLK_DIV14 0x00000014 /* MDC = hclk / 14 */
+#define MCFG_CLK_DIV20 0x00000018 /* MDC = hclk / 20 */
+#define MCFG_CLK_DIV28 0x0000001C /* MDC = hclk / 28 */
+
+
+/* MII Management Command Register */
+#define MCMD_READ 0x00000001 /* MII Read */
+#define MCMD_SCAN 0x00000002 /* MII Scan continuously */
+
+#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */
+#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */
+
+/* MII Management Address Register */
+#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */
+#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */
+
+/* MII Management Indicators Register */
+#define MIND_BUSY 0x00000001 /* MII is Busy */
+#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */
+#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */
+#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */
+
+/* Command Register */
+#define CR_RX_EN 0x00000001 /* Enable Receive */
+#define CR_TX_EN 0x00000002 /* Enable Transmit */
+#define CR_REG_RES 0x00000008 /* Reset Host Registers */
+#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */
+#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */
+#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */
+#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */
+#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */
+#define CR_RMII 0x00000200 /* Reduced MII Interface */
+#define CR_FULL_DUP 0x00000400 /* Full Duplex */
+
+/* Status Register */
+#define SR_RX_EN 0x00000001 /* Enable Receive */
+#define SR_TX_EN 0x00000002 /* Enable Transmit */
+
+/* Transmit Status Vector 0 Register */
+#define TSV0_CRC_ERR 0x00000001 /* CRC error */
+#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */
+#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */
+#define TSV0_DONE 0x00000008 /* Tramsmission Completed */
+#define TSV0_MCAST 0x00000010 /* Multicast Destination */
+#define TSV0_BCAST 0x00000020 /* Broadcast Destination */
+#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */
+#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */
+#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */
+#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */
+#define TSV0_GIANT 0x00000400 /* Giant Frame */
+#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */
+#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */
+#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */
+#define TSV0_PAUSE 0x20000000 /* Pause Frame */
+#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */
+#define TSV0_VLAN 0x80000000 /* VLAN Frame */
+
+/* Transmit Status Vector 1 Register */
+#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */
+#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */
+
+/* Receive Status Vector Register */
+#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */
+#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */
+#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */
+#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */
+#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */
+#define RSV_CRC_ERR 0x00100000 /* CRC Error */
+#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */
+#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */
+#define RSV_REC_OK 0x00800000 /* Frame Received OK */
+#define RSV_MCAST 0x01000000 /* Multicast Frame */
+#define RSV_BCAST 0x02000000 /* Broadcast Frame */
+#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */
+#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */
+#define RSV_PAUSE 0x10000000 /* Pause Frame */
+#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */
+#define RSV_VLAN 0x40000000 /* VLAN Frame */
+
+/* Flow Control Counter Register */
+#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */
+#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */
+
+/* Flow Control Status Register */
+#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */
+
+/* Receive Filter Control Register */
+#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */
+#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */
+#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */
+#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */
+#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/
+#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */
+#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */
+#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */
+
+/* Receive Filter WoL Status/Clear Registers */
+#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */
+#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */
+#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */
+#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */
+#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */
+#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */
+#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */
+#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */
+
+/* Interrupt Status/Enable/Clear/Set Registers */
+#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */
+#define INT_RX_ERR 0x00000002 /* Receive Error */
+#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */
+#define INT_RX_DONE 0x00000008 /* Receive Done */
+#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */
+#define INT_TX_ERR 0x00000020 /* Transmit Error */
+#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */
+#define INT_TX_DONE 0x00000080 /* Transmit Done */
+#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */
+#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */
+
+/* Power Down Register */
+#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */
+
+/* RX Descriptor Control Word */
+#define RCTRL_SIZE 0x000007FF /* Buffer size mask */
+#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */
+
+/* RX Status Hash CRC Word */
+#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */
+#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */
+
+/* RX Status Information Word */
+#define RINFO_SIZE 0x000007FF /* Data size in bytes */
+#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */
+#define RINFO_VLAN 0x00080000 /* VLAN Frame */
+#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */
+#define RINFO_MCAST 0x00200000 /* Multicast Frame */
+#define RINFO_BCAST 0x00400000 /* Broadcast Frame */
+#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */
+#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */
+#define RINFO_LEN_ERR 0x02000000 /* Length Error */
+#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */
+#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */
+#define RINFO_OVERRUN 0x10000000 /* Receive overrun */
+#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */
+#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */
+#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
+
+#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \
+ RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
+
+/* TX Descriptor Control Word */
+#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */
+#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */
+#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */
+#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */
+#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */
+#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */
+#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */
+
+/* TX Status Information Word */
+#define TINFO_COL_CNT 0x01E00000 /* Collision Count */
+#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */
+#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */
+#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */
+#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */
+#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */
+#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */
+#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
+
+/* ENET Device Revision ID */
+#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */
+
+/* DP83848C PHY Registers */
+#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */
+#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */
+#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */
+#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */
+#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */
+#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */
+#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */
+#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */
+
+/* PHY Extended Registers */
+#define PHY_REG_STS 0x10 /* Status Register */
+#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */
+#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */
+#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */
+#define PHY_REG_RECR 0x15 /* Receive Error Counter */
+#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */
+#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */
+#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */
+#define PHY_REG_PHYCR 0x19 /* PHY Control Register */
+#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */
+#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */
+#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */
+
+#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */
+#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */
+#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */
+#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */
+#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
+
+#define DP83848C_DEF_ADR 0x0F00 /* Default PHY device address */
+#define DP83848C_ID 0x20005C90 /* PHY Identifier */
+
+void lpc17xx_emac_hw_init(void);
+
+#endif
|
