Переглянути джерело

add emac driver for at91sam9260

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1384 bbd45198-f89e-11dd-88c7-29a3b14d5316
luohui2320@gmail.com 14 роки тому
батько
коміт
fd963d847a

+ 686 - 0
bsp/at91sam9260/macb.c

@@ -0,0 +1,686 @@
+/*
+ * File      : macb.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-03-18     weety      first version
+ */
+
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+#include <at91sam926x.h>
+#include "macb.h"
+
+#define CONFIG_RMII
+
+#define MACB_RX_BUFFER_SIZE		4096*4
+#define MACB_RX_RING_SIZE		(MACB_RX_BUFFER_SIZE / 128)
+#define MACB_TX_RING_SIZE		16
+#define MACB_TX_TIMEOUT		1000
+#define MACB_AUTONEG_TIMEOUT	5000000	
+#define MACB_LINK_TIMEOUT	        500000  
+
+
+struct macb_dma_desc {
+	rt_uint32_t	addr;
+	rt_uint32_t	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
+
+#define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
+				 | MACB_BIT(ISR_ROVR))
+
+
+#define MAX_ADDR_LEN 6
+struct rt_macb_eth
+{
+	/* inherit from ethernet device */
+	struct eth_device parent;
+
+	void			*regs;
+
+	unsigned int		rx_tail;
+	unsigned int		tx_head;
+	unsigned int		tx_tail;
+
+	void			*rx_buffer;
+	void			*tx_buffer;
+	struct macb_dma_desc	*rx_ring;
+	struct macb_dma_desc	*tx_ring;
+
+	unsigned long		rx_buffer_dma;
+	unsigned long		rx_ring_dma;
+	unsigned long		tx_ring_dma;
+
+	/* interface address info. */
+	rt_uint8_t  dev_addr[MAX_ADDR_LEN];		/* hw address	*/
+	unsigned short		phy_addr;
+};
+static struct rt_macb_eth macb_device;
+static struct rt_semaphore sem_ack, sem_lock;
+
+static void udelay(rt_uint32_t us)
+{
+    rt_uint32_t len;
+    for (;us > 0; us --)
+        for (len = 0; len < 10; len++ );
+}
+
+static void rt_macb_isr(int irq)
+{
+	struct rt_macb_eth *macb = &macb_device;
+	rt_device_t dev = &(macb->parent.parent);
+	rt_uint32_t status, rsr, tsr;
+
+	//rt_kprintf("%s:irq enter\n", __func__);
+	status = macb_readl(macb, ISR);
+
+	while (status) {
+
+		if (status & MACB_RX_INT_FLAGS) {
+			//rt_kprintf("macb recv isr\n");
+			//macb_writel(macb, IDR, MACB_RX_INT_FLAGS);
+			rsr = macb_readl(macb, RSR);
+			macb_writel(macb, RSR, rsr);
+			/* a frame has been received */
+			eth_device_ready(&(macb_device.parent));
+		
+		}
+
+		if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
+			    MACB_BIT(ISR_RLE)))
+		{
+			//rt_kprintf("macb tx complete\n");
+			tsr = macb_readl(macb, TSR);
+			macb_writel(macb, TSR, tsr);
+			/* One packet sent complete */
+			rt_sem_release(&sem_ack);
+		}
+			//macb_tx(bp);
+
+		/*
+		 * Link change detection isn't possible with RMII, so we'll
+		 * add that if/when we get our hands on a full-blown MII PHY.
+		 */
+
+		if (status & MACB_BIT(HRESP)) {
+			/*
+			 * TODO: Reset the hardware, and maybe move the printk
+			 * to a lower-priority context as well (work queue?)
+			 */
+			rt_kprintf("%s: DMA bus error: HRESP not OK\n",
+			       dev->parent.name);
+		}
+
+		status = macb_readl(macb, ISR);
+	}
+
+
+}
+
+static void macb_mdio_write(struct rt_macb_eth *macb, rt_uint8_t reg, rt_uint16_t value)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 1)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2)
+		 | MACB_BF(DATA, value));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+}
+
+static rt_uint16_t macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 2)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	frame = macb_readl(macb, MAN);
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	return MACB_BFEXT(DATA, frame);
+}
+
+static void macb_phy_reset(rt_device_t dev)
+{
+	struct rt_macb_eth *macb = dev->user_data;;
+	int i;
+	rt_uint16_t status, adv;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	macb_mdio_write(macb, MII_ADVERTISE, adv);
+	rt_kprintf("%s: Starting autonegotiation...\n", dev->parent.name);
+	macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
+					 | BMCR_ANRESTART));
+
+	for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
+		status = macb_mdio_read(macb, MII_BMSR);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE)
+		rt_kprintf("%s: Autonegotiation complete\n", dev->parent.name);
+	else
+		rt_kprintf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       dev->parent.name, status);
+}
+
+
+static int macb_phy_init(rt_device_t dev)
+{
+	//struct eth_device *netdev = &macb->netdev;
+	struct rt_macb_eth *macb = dev->user_data;
+	rt_uint32_t ncfgr;
+	rt_uint16_t phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+
+	/* Check if the PHY is up to snuff... */
+	phy_id = macb_mdio_read(macb, MII_PHYSID1);
+	if (phy_id == 0xffff) {
+		rt_kprintf("%s: No PHY present\n", dev->parent.name);
+		return 0;
+	}
+
+	status = macb_mdio_read(macb, MII_BMSR);
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		macb_phy_reset(dev);
+
+		for (i = 0; i < MACB_LINK_TIMEOUT / 100; i++) {   //modified by luohui@2009-11-27 CFG_MACB_AUTONEG_TIMEOUT
+			status = macb_mdio_read(macb, MII_BMSR);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+
+	if (!(status & BMSR_LSTATUS)) {
+		rt_kprintf("%s: link down (status: 0x%04x)\n",
+		       dev->parent.name, status);
+		return 0;
+	} else {
+		adv = macb_mdio_read(macb, MII_ADVERTISE);
+		lpa = macb_mdio_read(macb, MII_LPA);
+		media = mii_nway_result(lpa & adv);
+		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+			 ? 1 : 0);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		rt_kprintf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+		       dev->parent.name,
+		       speed ? "100" : "10",
+		       duplex ? "full" : "half",
+		       lpa);
+
+		ncfgr = macb_readl(macb, NCFGR);
+		ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+		if (speed)
+			ncfgr |= MACB_BIT(SPD);
+		if (duplex)
+			ncfgr |= MACB_BIT(FD);
+		macb_writel(macb, NCFGR, ncfgr);
+		return 1;
+	}
+}
+
+/* RT-Thread Device Interface */
+/* initialize the interface */
+
+static rt_err_t rt_macb_init(rt_device_t dev)
+{
+	struct rt_macb_eth *macb = dev->user_data;
+	unsigned long paddr;
+	rt_uint32_t hwaddr_bottom;
+	rt_uint16_t hwaddr_top;
+	int i;
+
+	/*
+	 * macb_halt should have been called at some point before now,
+	 * so we'll assume the controller is idle.
+	 */
+
+	/* initialize DMA descriptors */
+	paddr = macb->rx_buffer_dma;
+	for (i = 0; i < MACB_RX_RING_SIZE; i++) {
+		if (i == (MACB_RX_RING_SIZE - 1))
+			paddr |= RXADDR_WRAP;
+		macb->rx_ring[i].addr = paddr;
+		macb->rx_ring[i].ctrl = 0;
+		paddr += 128;
+	}
+	for (i = 0; i < MACB_TX_RING_SIZE; i++) {
+		macb->tx_ring[i].addr = 0;
+		if (i == (MACB_TX_RING_SIZE - 1))
+			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
+		else
+			macb->tx_ring[i].ctrl = TXBUF_USED;
+	}
+	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
+
+	macb_writel(macb, RBQP, macb->rx_ring_dma);
+	macb_writel(macb, TBQP, macb->tx_ring_dma);
+	
+	/* set hardware address */
+	//hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
+	hwaddr_bottom = (*((rt_uint32_t *)macb->dev_addr));
+	macb_writel(macb, SA1B, hwaddr_bottom);
+	//hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
+	hwaddr_top = (*((rt_uint16_t *)(macb->dev_addr + 4)));
+	macb_writel(macb, SA1T, hwaddr_top);
+
+	
+	/* choose RMII or MII mode. This depends on the board */
+#ifdef CONFIG_RMII
+#if defined(CONFIG_AVR32)
+	macb_writel(macb, USRIO, 0);
+#else
+	macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
+#endif
+#else
+#if defined(CONFIG_AVR32)
+	macb_writel(macb, USRIO, MACB_BIT(MII));
+#else
+	macb_writel(macb, USRIO, MACB_BIT(CLKEN));
+#endif
+#endif /* CONFIG_RMII */
+
+	if (!macb_phy_init(dev))
+		return -RT_ERROR;
+
+	/* Enable TX and RX */
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(MPE));
+	
+	/* Enable interrupts */
+	macb_writel(macb, IER, (MACB_BIT(RCOMP)
+			      | MACB_BIT(RXUBR)
+			      | MACB_BIT(ISR_TUND)
+			      | MACB_BIT(ISR_RLE)
+			      | MACB_BIT(TXERR)
+			      | MACB_BIT(TCOMP)
+			      | MACB_BIT(ISR_ROVR)
+			      | MACB_BIT(HRESP)));
+	
+	/* instal interrupt */
+	rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, RT_NULL);
+	rt_hw_interrupt_umask(AT91SAM9260_ID_EMAC);
+	
+	return RT_EOK;
+}
+
+static rt_err_t rt_macb_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	return RT_EOK;
+}
+
+static rt_err_t rt_macb_close(rt_device_t dev)
+{
+	return RT_EOK;
+}
+
+static rt_size_t rt_macb_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 rt_macb_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 rt_macb_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	switch(cmd)
+	{
+	case NIOCTL_GADDR:
+		/* get mac address */
+		if(args) rt_memcpy(args, macb_device.dev_addr, 6);
+		else return -RT_ERROR;
+		break;
+
+	default :
+		break;
+	}
+
+	return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p)
+{
+	struct rt_macb_eth *macb = dev->user_data;
+	struct pbuf* q;
+	rt_uint32_t len;
+	rt_uint8_t* bufptr, *buf = RT_NULL;
+	unsigned long paddr, ctrl;
+	unsigned int tx_head = macb->tx_head;
+	int i;
+	
+	/* lock macb device */
+	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+	//rt_kprintf("macb tx enter, packetlen=%d\n", p->tot_len);
+	buf = rt_malloc(p->tot_len);
+	if (!buf) {
+		rt_kprintf("%s:alloc buf failed\n", __func__);
+		return NULL;
+	}
+	bufptr = buf;
+
+
+	for (q = p; q != NULL; q = q->next)
+	{
+		//len = q->len;
+		//paddr = (unsigned long)q->payload;
+		memcpy(bufptr, q->payload, q->len);
+		bufptr += q->len;
+
+		/* write data to device */
+		/*ctrl = len & TXBUF_FRMLEN_MASK;
+		ctrl |= TXBUF_FRAME_END;
+		if (tx_head == (MACB_TX_RING_SIZE - 1)) {
+			ctrl |= TXBUF_WRAP;
+			macb->tx_head = 0;
+		} else
+			macb->tx_head++;
+
+		macb->tx_ring[tx_head].ctrl = ctrl;
+		macb->tx_ring[tx_head].addr = paddr;
+		macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));*/
+		
+		/*
+		 * I guess this is necessary because the networking core may
+		 * re-use the transmit buffer as soon as we return...
+		 */
+		
+		
+	}
+
+	ctrl = p->tot_len & TXBUF_FRMLEN_MASK;
+	ctrl |= TXBUF_FRAME_END;
+	if (tx_head == (MACB_TX_RING_SIZE - 1)) {
+		ctrl |= TXBUF_WRAP;
+		macb->tx_head = 0;
+	} else
+		macb->tx_head++;
+
+	macb->tx_ring[tx_head].ctrl = ctrl;
+	macb->tx_ring[tx_head].addr = (rt_uint32_t)buf;
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
+	//rt_uint32_t netcr = macb_readl(macb, NCR); //e0: DMA bus error: HRESP not OK
+	//rt_kprintf("NCR = 0x%08x\n");
+	//macb_writel(macb, NCR, netcr | MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
+
+	
+	/* unlock macb device */
+	rt_sem_release(&sem_lock);
+
+	/* wait ack */
+	rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
+	rt_free(buf);
+	buf == RT_NULL;
+
+	return RT_EOK;
+}
+
+static void reclaim_rx_buffers(struct rt_macb_eth *macb,
+			       unsigned int new_tail)
+{
+	unsigned int i;
+
+	i = macb->rx_tail;
+	while (i > new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+		if (i > MACB_RX_RING_SIZE)
+			i = 0;
+	}
+
+	while (i < new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+	}
+
+	//barrier();
+	macb->rx_tail = new_tail;
+}
+
+/* reception packet. */
+struct pbuf *rt_macb_rx(rt_device_t dev)
+{
+	struct rt_macb_eth *macb = dev->user_data;
+	struct pbuf* p = RT_NULL;
+	rt_uint32_t len;
+	unsigned int rx_tail = macb->rx_tail;
+	void *buffer;
+	//int length;
+	int wrapped = 0;
+	rt_uint32_t status;
+
+	//rt_uint8_t* data;
+	struct pbuf* q;
+	rt_uint8_t *buf = RT_NULL;
+	//rt_kprintf("macb rx enter\n");
+	
+	/* lock macb device */
+	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+	//rt_kprintf("macb rx enter2\n");
+	
+	for (;;) {
+		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+			break;
+
+		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;
+			len = status & RXBUF_FRMLEN_MASK;
+			//rt_kprintf("%s:recv %d bytes\n", __func__, len);
+			p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
+			if (!p)
+			{
+				rt_kprintf("alloc pbuf failed\n");
+				break;
+			}
+			if (wrapped) {
+				unsigned int headlen, taillen;
+				buf = rt_malloc(len);
+				if (!buf)
+				{
+					rt_kprintf("%s:alloc memory failed\n", __func__);
+					pbuf_free(p);
+					p = RT_NULL;
+					break;
+				}
+
+				headlen = 128 * (MACB_RX_RING_SIZE
+						 - macb->rx_tail);
+				taillen = len - headlen;
+				memcpy((void *)buf,
+				       buffer, headlen);
+				memcpy((void *)buf + headlen,
+				       macb->rx_buffer, taillen);
+				buffer = (void *)buf;
+				for (q = p; q != RT_NULL; q= q->next)
+				{
+					/* read data from device */
+					memcpy((void *)q->payload, buffer, q->len);
+					buffer += q->len;
+				}
+				rt_free(buf);
+				buf = RT_NULL;
+			} else {
+				for (q = p; q != RT_NULL; q= q->next)
+				{
+					/* read data from device */
+					memcpy((void *)q->payload, buffer, q->len);
+					buffer += q->len;
+				}
+			
+			}
+
+			//NetReceive(buffer, length);
+			/* allocate buffer */
+			
+			if (++rx_tail >= MACB_RX_RING_SIZE)
+				rx_tail = 0;
+			reclaim_rx_buffers(macb, rx_tail);
+			break;
+		} else {
+			if (++rx_tail >= MACB_RX_RING_SIZE) {
+				wrapped = 1;
+				rx_tail = 0;
+			}
+		}
+	}
+	
+	/* unlock macb device */
+	rt_sem_release(&sem_lock);
+
+	return p;
+}
+
+void macb_gpio_init()
+{
+	/* Pins used for MII and RMII */
+	at91_sys_write(AT91_PIOA + PIO_PDR, (1 << 19)|(1 << 17)|(1 << 14)|(1 << 15)|(1 << 18)|(1 << 16)|(1 << 12)|(1 << 13)|(1 << 21)|(1 << 20));
+	at91_sys_write(AT91_PIOA + PIO_ASR, (1 << 19)|(1 << 17)|(1 << 14)|(1 << 15)|(1 << 18)|(1 << 16)|(1 << 12)|(1 << 13)|(1 << 21)|(1 << 20));
+}
+
+void macb_initialize()
+{
+	struct rt_macb_eth *macb = &macb_device;
+	unsigned long macb_hz;
+	rt_uint32_t ncfgr;
+	
+	macb->rx_buffer = rt_malloc(MACB_RX_BUFFER_SIZE);
+	macb->rx_ring = rt_malloc(MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
+	macb->tx_ring = rt_malloc(MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc));
+	
+	macb->rx_buffer_dma = (unsigned long)macb->rx_buffer;
+	macb->rx_ring_dma = (unsigned long)macb->rx_ring;
+	macb->tx_ring_dma = (unsigned long)macb->tx_ring;
+
+	macb->regs = (void *)AT91SAM9260_BASE_EMAC;
+	macb->phy_addr = 0x00;
+	
+	/*
+	 * Do some basic initialization so that we at least can talk
+	 * to the PHY
+	 */
+	macb_hz = clk_get_rate(clk_get("mck"));
+	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);
+
+	macb_writel(macb, NCFGR, ncfgr);
+}
+
+void rt_hw_macb_init()
+{
+	at91_sys_write(AT91_PMC + AT91_PMC_PCER, 1 << AT91SAM9260_ID_EMAC); //enable macb clock
+	macb_gpio_init();
+	macb_initialize();
+	rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
+	rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+
+	macb_device.dev_addr[0] = 0x00;
+	macb_device.dev_addr[1] = 0x60;
+	macb_device.dev_addr[2] = 0x6E;
+	macb_device.dev_addr[3] = 0x11;
+	macb_device.dev_addr[4] = 0x22;
+	macb_device.dev_addr[5] = 0x33;
+	
+	macb_device.parent.parent.init       = rt_macb_init;
+	macb_device.parent.parent.open       = rt_macb_open;
+	macb_device.parent.parent.close      = rt_macb_close;
+	macb_device.parent.parent.read       = rt_macb_read;
+	macb_device.parent.parent.write      = rt_macb_write;
+	macb_device.parent.parent.control    = rt_macb_control;
+	macb_device.parent.parent.user_data  = &macb_device;
+
+	macb_device.parent.eth_rx     = rt_macb_rx;
+	macb_device.parent.eth_tx     = rt_macb_tx;
+
+	eth_device_init(&(macb_device.parent), "e0");
+	//eth_system_device_init();
+	//set_if("192.168.1.30", "192.168.1.1", "255.255.255.0");
+	/* instal interrupt */
+	//rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, RT_NULL);
+	//rt_hw_interrupt_umask(AT91SAM9260_ID_EMAC);
+}

+ 335 - 0
bsp/at91sam9260/macb.h

@@ -0,0 +1,335 @@
+/*
+ * File      : macb.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-03-18     weety      first version
+ */
+#ifndef _MACB_H
+#define _MACB_H
+#include <mii.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 (AVR32) */
+#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))
+
+/* Register access macros */
+#define macb_readl(port,reg)				\
+	readl((port)->regs + MACB_##reg)
+#define macb_writel(port,reg,value)			\
+	writel((value), (port)->regs + MACB_##reg)
+
+struct dma_desc {
+	rt_uint32_t	addr;
+	rt_uint32_t	ctrl;
+};
+
+/* DMA descriptor bitfields */
+#define MACB_RX_USED_OFFSET			0
+#define MACB_RX_USED_SIZE			1
+#define MACB_RX_WRAP_OFFSET			1
+#define MACB_RX_WRAP_SIZE			1
+#define MACB_RX_WADDR_OFFSET			2
+#define MACB_RX_WADDR_SIZE			30
+
+#define MACB_RX_FRMLEN_OFFSET			0
+#define MACB_RX_FRMLEN_SIZE			12
+#define MACB_RX_OFFSET_OFFSET			12
+#define MACB_RX_OFFSET_SIZE			2
+#define MACB_RX_SOF_OFFSET			14
+#define MACB_RX_SOF_SIZE			1
+#define MACB_RX_EOF_OFFSET			15
+#define MACB_RX_EOF_SIZE			1
+#define MACB_RX_CFI_OFFSET			16
+#define MACB_RX_CFI_SIZE			1
+#define MACB_RX_VLAN_PRI_OFFSET			17
+#define MACB_RX_VLAN_PRI_SIZE			3
+#define MACB_RX_PRI_TAG_OFFSET			20
+#define MACB_RX_PRI_TAG_SIZE			1
+#define MACB_RX_VLAN_TAG_OFFSET			21
+#define MACB_RX_VLAN_TAG_SIZE			1
+#define MACB_RX_TYPEID_MATCH_OFFSET		22
+#define MACB_RX_TYPEID_MATCH_SIZE		1
+#define MACB_RX_SA4_MATCH_OFFSET		23
+#define MACB_RX_SA4_MATCH_SIZE			1
+#define MACB_RX_SA3_MATCH_OFFSET		24
+#define MACB_RX_SA3_MATCH_SIZE			1
+#define MACB_RX_SA2_MATCH_OFFSET		25
+#define MACB_RX_SA2_MATCH_SIZE			1
+#define MACB_RX_SA1_MATCH_OFFSET		26
+#define MACB_RX_SA1_MATCH_SIZE			1
+#define MACB_RX_EXT_MATCH_OFFSET		28
+#define MACB_RX_EXT_MATCH_SIZE			1
+#define MACB_RX_UHASH_MATCH_OFFSET		29
+#define MACB_RX_UHASH_MATCH_SIZE		1
+#define MACB_RX_MHASH_MATCH_OFFSET		30
+#define MACB_RX_MHASH_MATCH_SIZE		1
+#define MACB_RX_BROADCAST_OFFSET		31
+#define MACB_RX_BROADCAST_SIZE			1
+
+#define MACB_TX_FRMLEN_OFFSET			0
+#define MACB_TX_FRMLEN_SIZE			11
+#define MACB_TX_LAST_OFFSET			15
+#define MACB_TX_LAST_SIZE			1
+#define MACB_TX_NOCRC_OFFSET			16
+#define MACB_TX_NOCRC_SIZE			1
+#define MACB_TX_BUF_EXHAUSTED_OFFSET		27
+#define MACB_TX_BUF_EXHAUSTED_SIZE		1
+#define MACB_TX_UNDERRUN_OFFSET			28
+#define MACB_TX_UNDERRUN_SIZE			1
+#define MACB_TX_ERROR_OFFSET			29
+#define MACB_TX_ERROR_SIZE			1
+#define MACB_TX_WRAP_OFFSET			30
+#define MACB_TX_WRAP_SIZE			1
+#define MACB_TX_USED_OFFSET			31
+#define MACB_TX_USED_SIZE			1
+
+
+#endif /* _MACB_H */
+

+ 181 - 0
bsp/at91sam9260/mii.h

@@ -0,0 +1,181 @@
+/*
+ * File      : mii.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-03-18     weety      first version
+ */
+
+#ifndef __MII_H__
+#define __MII_H__
+
+/* Generic MII registers. */
+
+#define MII_BMCR            0x00        /* Basic mode control register */
+#define MII_BMSR            0x01        /* Basic mode status register  */
+#define MII_PHYSID1         0x02        /* PHYS ID 1                   */
+#define MII_PHYSID2         0x03        /* PHYS ID 2                   */
+#define MII_ADVERTISE       0x04        /* Advertisement control reg   */
+#define MII_LPA             0x05        /* Link partner ability reg    */
+#define MII_EXPANSION       0x06        /* Expansion register          */
+#define MII_CTRL1000        0x09        /* 1000BASE-T control          */
+#define MII_STAT1000        0x0a        /* 1000BASE-T status           */
+#define MII_ESTATUS	    0x0f	/* Extended Status */
+#define MII_DCOUNTER        0x12        /* Disconnect counter          */
+#define MII_FCSCOUNTER      0x13        /* False carrier counter       */
+#define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15        /* Receive error counter       */
+#define MII_SREVISION       0x16        /* Silicon revision            */
+#define MII_RESV1           0x17        /* Reserved...                 */
+#define MII_LBRERROR        0x18        /* Lpback, rx, bypass error    */
+#define MII_PHYADDR         0x19        /* PHY address                 */
+#define MII_RESV2           0x1a        /* Reserved...                 */
+#define MII_TPISTATUS       0x1b        /* TPI status for 10mbps       */
+#define MII_NCONFIG         0x1c        /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV               0x003f  /* Unused...                   */
+#define BMCR_SPEED1000		0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST               0x0080  /* Collision test              */
+#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */
+#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */
+#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */
+#define BMCR_RESET              0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP              0x0001  /* Ext-reg capability          */
+#define BMSR_JCD                0x0002  /* Jabber detected             */
+#define BMSR_LSTATUS            0x0004  /* Link status                 */
+#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT             0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV               0x00c0  /* Unused...                   */
+#define BMSR_ESTATEN		0x0100	/* Extended Status in R15 */
+#define BMSR_100HALF2           0x0200  /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2           0x0400  /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT          0x001f  /* Selector bits               */
+#define ADVERTISE_CSMA          0x0001  /* Only selector supported     */
+#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL     0x0020  /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF     0x0040  /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause    */
+#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
+#define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause               */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
+#define ADVERTISE_RESV          0x1000  /* Unused...                   */
+#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */
+#define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */
+#define ADVERTISE_NPAGE         0x8000  /* Next page bit               */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+			ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+                       ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT                0x001f  /* Same as advertise selector  */
+#define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_1000XFULL           0x0020  /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_1000XHALF           0x0040  /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_1000XPAUSE          0x0080  /* Can do 1000BASE-X pause     */
+#define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_1000XPAUSE_ASYM     0x0100  /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
+#define LPA_PAUSE_CAP           0x0400  /* Can pause                   */
+#define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically     */
+#define LPA_RESV                0x1000  /* Unused...                   */
+#define LPA_RFAULT              0x2000  /* Link partner faulted        */
+#define LPA_LPACK               0x4000  /* Link partner acked us       */
+#define LPA_NPAGE               0x8000  /* Next page bit               */
+
+#define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
+#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY          0x0001  /* Can do N-way auto-nego      */
+#define EXPANSION_LCWP          0x0002  /* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words    */
+#define EXPANSION_NPCAPABLE     0x0008  /* Link partner supports npage */
+#define EXPANSION_MFAULTS       0x0010  /* Multiple faults detected    */
+#define EXPANSION_RESV          0xffe0  /* Unused...                   */
+
+#define ESTATUS_1000_TFULL	0x2000	/* Can do 1000BT Full */
+#define ESTATUS_1000_THALF	0x1000	/* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1          0x00ff  /* Unused...                   */
+#define NWAYTEST_LOOPBACK       0x0100  /* Enable loopback for N-way   */
+#define NWAYTEST_RESV2          0xfe00  /* Unused...                   */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK       0x2000  /* Link partner local receiver status */
+#define LPA_1000REMRXOK         0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
+
+/* Flow control flags */
+#define FLOW_CTRL_TX		0x01
+#define FLOW_CTRL_RX		0x02
+
+/**
+ * mii_nway_result
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * Given a set of MII abilities, check each bit and returns the
+ * currently supported media, in the priority order defined by
+ * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
+ * value of LPA solely, as described above.
+ *
+ * The one exception to IEEE 802.3u is that 100baseT4 is placed
+ * between 100T-full and 100T-half.  If your phy does not support
+ * 100T4 this is fine.  If your phy places 100T4 elsewhere in the
+ * priority order, you will need to roll your own function.
+ */
+static inline unsigned int mii_nway_result (unsigned int negotiated)
+{
+        unsigned int ret;
+
+        if (negotiated & LPA_100FULL)
+                ret = LPA_100FULL;
+        else if (negotiated & LPA_100BASE4)
+                ret = LPA_100BASE4;
+        else if (negotiated & LPA_100HALF)
+                ret = LPA_100HALF;
+        else if (negotiated & LPA_10FULL)
+                ret = LPA_10FULL;
+        else
+                ret = LPA_10HALF;
+
+        return ret;
+}
+
+
+#endif /* __MII_H__ */
+

+ 1 - 1
bsp/at91sam9260/rtconfig.h

@@ -120,7 +120,7 @@
 
 
 /* SECTION: lwip, a lightweight TCP/IP protocol stack */
 /* SECTION: lwip, a lightweight TCP/IP protocol stack */
 /* Using lightweight TCP/IP protocol stack */
 /* Using lightweight TCP/IP protocol stack */
-//#define RT_USING_LWIP
+#define RT_USING_LWIP
 #define RT_LWIP_DNS
 #define RT_LWIP_DNS
 
 
 /* Trace LwIP protocol */
 /* Trace LwIP protocol */

+ 5 - 0
bsp/at91sam9260/startup.c

@@ -116,7 +116,12 @@ void rtthread_startup(void)
 #endif
 #endif
 
 
 #ifdef RT_USING_LWIP
 #ifdef RT_USING_LWIP
+	/* register ethernetif device */
+	eth_system_device_init();
 	rt_hw_macb_init();
 	rt_hw_macb_init();
+	/* init lwip system */
+	lwip_sys_init();
+	rt_kprintf("TCP/IP initialized!\n");
 #endif
 #endif
 
 
 	/*init all registed devices */
 	/*init all registed devices */