NXP LPC1768 Ethernet driver for lwip and CMSIS-RTOS

Dependents:   EthernetInterface EthernetInterface EthernetInterface_RSF EthernetInterface ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed 5, the networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of the NXP LPC port of the Lightweight TCP/IP Stack

Copyright(C) 2011, NXP Semiconductor
All rights reserved.

Software that is described herein is for illustrative purposes only
which provides customers with programming information regarding the
products. This software is supplied "AS IS" without any warranties.
NXP Semiconductors assumes no responsibility or liability for the
use of the software, conveys no license or title under any patent,
copyright, or mask work right to the product. NXP Semiconductors
reserves the right to make changes in the software without
notification. NXP Semiconductors also make no representation or
warranty that such application will be suitable for the specified
use without further testing or modification.

Files at this revision

API Documentation at this revision

Comitter:
emilmont
Date:
Thu May 30 17:15:45 2013 +0100
Parent:
4:d827a085afd9
Child:
6:59b01b9349d5
Commit message:
Add LPC4088 target

Changed in this revision

arch/lpc17_emac.c Show annotated file Show diff for this revision Revisions of this file
arch/lpc17_emac.h Show annotated file Show diff for this revision Revisions of this file
arch/lpc17xx_emac.h Show annotated file Show diff for this revision Revisions of this file
arch/lpc_emac_config.h Show annotated file Show diff for this revision Revisions of this file
arch/lpc_phy.h Show annotated file Show diff for this revision Revisions of this file
arch/lpc_phy_dp83848.c Show annotated file Show diff for this revision Revisions of this file
--- a/arch/lpc17_emac.c	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc17_emac.c	Thu May 30 17:15:45 2013 +0100
@@ -1,11 +1,11 @@
 /**********************************************************************
-* $Id$        lpc17_emac.c            2011-11-20
+* $Id$		lpc17_emac.c			2011-11-20
 *//**
-* @file        lpc17_emac.c
-* @brief    LPC17 ethernet driver for LWIP
-* @version    1.0
-* @date        20. Nov. 2011
-* @author    NXP MCU SW Application Team
+* @file		lpc17_emac.c
+* @brief	LPC17 ethernet driver for LWIP
+* @version	1.0
+* @date		20. Nov. 2011
+* @author	NXP MCU SW Application Team
 * 
 * Copyright(C) 2011, NXP Semiconductor
 * All rights reserved.
@@ -54,7 +54,7 @@
 #error LPC_NUM_BUFF_RXDESCS must be at least 3
 #endif
 
-/** @defgroup lwip17xx_emac_DRIVER    lpc17 EMAC driver for LWIP
+/** @defgroup lwip17xx_emac_DRIVER	lpc17 EMAC driver for LWIP
  * @ingroup lwip_emac
  *
  * @{
@@ -97,127 +97,139 @@
  */
 typedef struct
 {
-    volatile u32_t packet;        /**< Pointer to buffer */
-    volatile u32_t control;       /**< Control word */
+	volatile u32_t packet;        /**< Pointer to buffer */
+	volatile u32_t control;       /**< Control word */
 } LPC_TXRX_DESC_T;
 
 /** \brief  Structure of a RX status entry
  */
 typedef struct
 {
-    volatile u32_t statusinfo;   /**< RX status word */
-    volatile u32_t statushashcrc; /**< RX hash CRC */
+	volatile u32_t statusinfo;   /**< RX status word */
+	volatile u32_t statushashcrc; /**< RX hash CRC */
 } LPC_TXRX_STATUS_T;
 
 /* LPC EMAC driver data structure */
 struct lpc_enetdata {
     /* prxs must be 8 byte aligned! */
-    LPC_TXRX_STATUS_T prxs[LPC_NUM_BUFF_RXDESCS]; /**< Pointer to RX statuses */
-    struct netif *netif;        /**< Reference back to LWIP parent netif */
-    LPC_TXRX_DESC_T ptxd[LPC_NUM_BUFF_TXDESCS];   /**< Pointer to TX descriptor list */
-    LPC_TXRX_STATUS_T ptxs[LPC_NUM_BUFF_TXDESCS]; /**< Pointer to TX statuses */
-    LPC_TXRX_DESC_T prxd[LPC_NUM_BUFF_RXDESCS];   /**< Pointer to RX descriptor list */
-    struct pbuf *rxb[LPC_NUM_BUFF_RXDESCS]; /**< RX pbuf pointer list, zero-copy mode */
-    u32_t rx_fill_desc_index; /**< RX descriptor next available index */
-    volatile u32_t rx_free_descs; /**< Count of free RX descriptors */
-    struct pbuf *txb[LPC_NUM_BUFF_TXDESCS]; /**< TX pbuf pointer list, zero-copy mode */
-    u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
+	LPC_TXRX_STATUS_T prxs[LPC_NUM_BUFF_RXDESCS]; /**< Pointer to RX statuses */
+	struct netif *netif;        /**< Reference back to LWIP parent netif */
+	LPC_TXRX_DESC_T ptxd[LPC_NUM_BUFF_TXDESCS];   /**< Pointer to TX descriptor list */
+	LPC_TXRX_STATUS_T ptxs[LPC_NUM_BUFF_TXDESCS]; /**< Pointer to TX statuses */
+	LPC_TXRX_DESC_T prxd[LPC_NUM_BUFF_RXDESCS];   /**< Pointer to RX descriptor list */
+	struct pbuf *rxb[LPC_NUM_BUFF_RXDESCS]; /**< RX pbuf pointer list, zero-copy mode */
+	u32_t rx_fill_desc_index; /**< RX descriptor next available index */
+	volatile u32_t rx_free_descs; /**< Count of free RX descriptors */
+	struct pbuf *txb[LPC_NUM_BUFF_TXDESCS]; /**< TX pbuf pointer list, zero-copy mode */
+	u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
 #if NO_SYS == 0
-    sys_sem_t RxSem; /**< RX receive thread wakeup semaphore */
-    sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
-    sys_mutex_t TXLockMutex; /**< TX critical section mutex */
-    sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
+	sys_sem_t RxSem; /**< RX receive thread wakeup semaphore */
+	sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
+	sys_mutex_t TXLockMutex; /**< TX critical section mutex */
+	sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
 #endif
 };
 
+#if defined(TARGET_LPC4088)
+#  if defined (__ICCARM__)
+#     define ETHMEM_SECTION
+#  elif defined(TOOLCHAIN_GCC_CR)
+#     define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
+#  else
+#     define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
+#  endif
+#else
+#   define ETHMEM_SECTION ALIGNED(8)
+#endif
+
 /** \brief  LPC EMAC driver work data
  */
-ALIGNED(8) struct lpc_enetdata lpc_enetdata;
+ETHMEM_SECTION struct lpc_enetdata lpc_enetdata; 
 
 /* Write a value via the MII link (non-blocking) */
 void lpc_mii_write_noblock(u32_t PhyReg, u32_t Value)
 {
-    /* Write value at PHY address and register */
-    LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
-    LPC_EMAC->MWTD = Value;
+	/* Write value at PHY address and register */
+	LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
+	LPC_EMAC->MWTD = Value;
 }
 
 /* Write a value via the MII link (blocking) */
 err_t lpc_mii_write(u32_t PhyReg, u32_t Value)
 {
-    u32_t mst = 250;
-    err_t sts = ERR_OK;
+	u32_t mst = 250;
+	err_t sts = ERR_OK;
 
-    /* Write value at PHY address and register */
-    lpc_mii_write_noblock(PhyReg, Value);
+	/* Write value at PHY address and register */
+	lpc_mii_write_noblock(PhyReg, Value);
 
-    /* Wait for unbusy status */
-    while (mst > 0) {
-        sts = LPC_EMAC->MIND;
-        if ((sts & EMAC_MIND_BUSY) == 0)
-            mst = 0;
-        else {
-            mst--;
-            osDelay(1);
-        }
-    }
+	/* Wait for unbusy status */
+	while (mst > 0) {
+		sts = LPC_EMAC->MIND;
+		if ((sts & EMAC_MIND_BUSY) == 0)
+			mst = 0;
+		else {
+			mst--;
+			osDelay(1);
+		}
+	}
 
-    if (sts != 0)
-        sts = ERR_TIMEOUT;
+	if (sts != 0)
+		sts = ERR_TIMEOUT;
 
-    return sts;
+	return sts;
 }
 
 /* Reads current MII link busy status */
 u32_t lpc_mii_is_busy(void)
 {
-    return (u32_t) (LPC_EMAC->MIND & EMAC_MIND_BUSY);
+	return (u32_t) (LPC_EMAC->MIND & EMAC_MIND_BUSY);
 }
 
 /* Starts a read operation via the MII link (non-blocking) */
 u32_t lpc_mii_read_data(void)
 {
-    u32_t data = LPC_EMAC->MRDD;
-    LPC_EMAC->MCMD = 0;
+	u32_t data = LPC_EMAC->MRDD;
+	LPC_EMAC->MCMD = 0;
 
-    return data;
+	return data;
 }
 
 /* Starts a read operation via the MII link (non-blocking) */
 void lpc_mii_read_noblock(u32_t PhyReg) 
 {
-    /* Read value at PHY address and register */
-    LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
-    LPC_EMAC->MCMD = EMAC_MCMD_READ;
+	/* Read value at PHY address and register */
+	LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
+	LPC_EMAC->MCMD = EMAC_MCMD_READ;
 }
 
 /* Read a value via the MII link (blocking) */
 err_t lpc_mii_read(u32_t PhyReg, u32_t *data) 
 {
-    u32_t mst = 250;
-    err_t sts = ERR_OK;
+	u32_t mst = 250;
+	err_t sts = ERR_OK;
 
-    /* Read value at PHY address and register */
-    lpc_mii_read_noblock(PhyReg);
+	/* Read value at PHY address and register */
+	lpc_mii_read_noblock(PhyReg);
 
-    /* Wait for unbusy status */
-    while (mst > 0) {
-        sts = LPC_EMAC->MIND & ~EMAC_MIND_MII_LINK_FAIL;
-        if ((sts & EMAC_MIND_BUSY) == 0) {
-            mst = 0;
-            *data = LPC_EMAC->MRDD;
-        } else {
-            mst--;
-            osDelay(1);
-        }
-    }
+	/* Wait for unbusy status */
+	while (mst > 0) {
+		sts = LPC_EMAC->MIND & ~EMAC_MIND_MII_LINK_FAIL;
+		if ((sts & EMAC_MIND_BUSY) == 0) {
+			mst = 0;
+			*data = LPC_EMAC->MRDD;
+		} else {
+			mst--;
+			osDelay(1);
+		}
+	}
 
-    LPC_EMAC->MCMD = 0;
+	LPC_EMAC->MCMD = 0;
 
-    if (sts != 0)
-        sts = ERR_TIMEOUT;
+	if (sts != 0)
+		sts = ERR_TIMEOUT;
 
-    return sts;
+	return sts;
 }
 
 /** \brief  Queues a pbuf into the RX descriptor list
@@ -227,33 +239,33 @@
  */
 static void lpc_rxqueue_pbuf(struct lpc_enetdata *lpc_enetif, struct pbuf *p)
 {
-    u32_t idx;
+	u32_t idx;
 
-    /* Get next free descriptor index */
-    idx = lpc_enetif->rx_fill_desc_index;
+	/* Get next free descriptor index */
+	idx = lpc_enetif->rx_fill_desc_index;
 
-    /* Setup descriptor and clear statuses */
-    lpc_enetif->prxd[idx].control = EMAC_RCTRL_INT | ((u32_t) (p->len - 1));
-    lpc_enetif->prxd[idx].packet = (u32_t) p->payload;
-    lpc_enetif->prxs[idx].statusinfo = 0xFFFFFFFF;
-    lpc_enetif->prxs[idx].statushashcrc = 0xFFFFFFFF;
+	/* Setup descriptor and clear statuses */
+	lpc_enetif->prxd[idx].control = EMAC_RCTRL_INT | ((u32_t) (p->len - 1));
+	lpc_enetif->prxd[idx].packet = (u32_t) p->payload;
+	lpc_enetif->prxs[idx].statusinfo = 0xFFFFFFFF;
+	lpc_enetif->prxs[idx].statushashcrc = 0xFFFFFFFF;
 
-    /* Save pbuf pointer for push to network layer later */
-    lpc_enetif->rxb[idx] = p;
+	/* Save pbuf pointer for push to network layer later */
+	lpc_enetif->rxb[idx] = p;
 
-    /* Wrap at end of descriptor list */
-    idx++;
-    if (idx >= LPC_NUM_BUFF_RXDESCS)
-        idx = 0;
+	/* Wrap at end of descriptor list */
+	idx++;
+	if (idx >= LPC_NUM_BUFF_RXDESCS)
+		idx = 0;
 
-    /* Queue descriptor(s) */
-    lpc_enetif->rx_free_descs -= 1;
-    lpc_enetif->rx_fill_desc_index = idx;
-    LPC_EMAC->RxConsumeIndex = idx;
+	/* Queue descriptor(s) */
+	lpc_enetif->rx_free_descs -= 1;
+	lpc_enetif->rx_fill_desc_index = idx;
+	LPC_EMAC->RxConsumeIndex = idx;
 
-    LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-        ("lpc_rxqueue_pbuf: pbuf packet queued: %p (free desc=%d)\n", p,
-            lpc_enetif->rx_free_descs));
+	LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+		("lpc_rxqueue_pbuf: pbuf packet queued: %p (free desc=%d)\n", p,
+			lpc_enetif->rx_free_descs));
 }
 
 /** \brief  Attempt to allocate and requeue a new pbuf for RX
@@ -263,35 +275,35 @@
  */
 s32_t lpc_rx_queue(struct netif *netif)
 {
-    struct lpc_enetdata *lpc_enetif = netif->state;
-    struct pbuf *p;
-    s32_t queued = 0;
+	struct lpc_enetdata *lpc_enetif = netif->state;
+	struct pbuf *p;
+	s32_t queued = 0;
 
-    /* Attempt to requeue as many packets as possible */
-    while (lpc_enetif->rx_free_descs > 0) {
-        /* Allocate a pbuf from the pool. We need to allocate at the
-           maximum size as we don't know the size of the yet to be
-           received packet. */
-        p = pbuf_alloc(PBUF_RAW, (u16_t) EMAC_ETH_MAX_FLEN, PBUF_RAM);
-        if (p == NULL) {
-            LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-                ("lpc_rx_queue: could not allocate RX pbuf (free desc=%d)\n",
-                lpc_enetif->rx_free_descs));
-            return queued;
-        }
+	/* Attempt to requeue as many packets as possible */
+	while (lpc_enetif->rx_free_descs > 0) {
+		/* Allocate a pbuf from the pool. We need to allocate at the
+		   maximum size as we don't know the size of the yet to be
+		   received packet. */
+		p = pbuf_alloc(PBUF_RAW, (u16_t) EMAC_ETH_MAX_FLEN, PBUF_RAM);
+		if (p == NULL) {
+			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+				("lpc_rx_queue: could not allocate RX pbuf (free desc=%d)\n",
+				lpc_enetif->rx_free_descs));
+			return queued;
+		}
 
-        /* pbufs allocated from the RAM pool should be non-chained. */
-        LWIP_ASSERT("lpc_rx_queue: pbuf is not contiguous (chained)",
-            pbuf_clen(p) <= 1);
+		/* pbufs allocated from the RAM pool should be non-chained. */
+		LWIP_ASSERT("lpc_rx_queue: pbuf is not contiguous (chained)",
+			pbuf_clen(p) <= 1);
 
-        /* Queue packet */
-        lpc_rxqueue_pbuf(lpc_enetif, p);
+		/* Queue packet */
+		lpc_rxqueue_pbuf(lpc_enetif, p);
 
-        /* Update queued count */
-        queued++;
-    }
+		/* Update queued count */
+		queued++;
+	}
 
-    return queued;
+	return queued;
 }
 
 /** \brief  Sets up the RX descriptor ring buffers.
@@ -303,18 +315,18 @@
  */
 static err_t lpc_rx_setup(struct lpc_enetdata *lpc_enetif)
 {
-    /* Setup pointers to RX structures */
-    LPC_EMAC->RxDescriptor = (u32_t) &lpc_enetif->prxd[0];
-    LPC_EMAC->RxStatus = (u32_t) &lpc_enetif->prxs[0];
-    LPC_EMAC->RxDescriptorNumber = LPC_NUM_BUFF_RXDESCS - 1;
+	/* Setup pointers to RX structures */
+	LPC_EMAC->RxDescriptor = (u32_t) &lpc_enetif->prxd[0];
+	LPC_EMAC->RxStatus = (u32_t) &lpc_enetif->prxs[0];
+	LPC_EMAC->RxDescriptorNumber = LPC_NUM_BUFF_RXDESCS - 1;
 
-    lpc_enetif->rx_free_descs = LPC_NUM_BUFF_RXDESCS;
-    lpc_enetif->rx_fill_desc_index = 0;
+	lpc_enetif->rx_free_descs = LPC_NUM_BUFF_RXDESCS;
+	lpc_enetif->rx_fill_desc_index = 0;
 
-    /* Build RX buffer and descriptors */
-    lpc_rx_queue(lpc_enetif->netif);
+	/* Build RX buffer and descriptors */
+	lpc_rx_queue(lpc_enetif->netif);
 
-    return ERR_OK;
+	return ERR_OK;
 }
 
 /** \brief  Allocates a pbuf and returns the data from the incoming packet.
@@ -325,117 +337,117 @@
  */
 static struct pbuf *lpc_low_level_input(struct netif *netif)
 {
-    struct lpc_enetdata *lpc_enetif = netif->state;
-    struct pbuf *p = NULL;
-    u32_t idx, length;
+	struct lpc_enetdata *lpc_enetif = netif->state;
+	struct pbuf *p = NULL;
+	u32_t idx, length;
 
 #ifdef LOCK_RX_THREAD
 #if NO_SYS == 0
-    /* Get exclusive access */
-    sys_mutex_lock(&lpc_enetif->TXLockMutex);
+	/* Get exclusive access */
+	sys_mutex_lock(&lpc_enetif->TXLockMutex);
 #endif
 #endif
 
-    /* Monitor RX overrun status. This should never happen unless
-       (possibly) the internal bus is behing held up by something.
-       Unless your system is running at a very low clock speed or
-       there are possibilities that the internal buses may be held
-       up for a long time, this can probably safely be removed. */
-    if (LPC_EMAC->IntStatus & EMAC_INT_RX_OVERRUN) {
-        LINK_STATS_INC(link.err);
-        LINK_STATS_INC(link.drop);
+	/* Monitor RX overrun status. This should never happen unless
+	   (possibly) the internal bus is behing held up by something.
+	   Unless your system is running at a very low clock speed or
+	   there are possibilities that the internal buses may be held
+	   up for a long time, this can probably safely be removed. */
+	if (LPC_EMAC->IntStatus & EMAC_INT_RX_OVERRUN) {
+		LINK_STATS_INC(link.err);
+		LINK_STATS_INC(link.drop);
 
-        /* Temporarily disable RX */
-        LPC_EMAC->MAC1 &= ~EMAC_MAC1_REC_EN;
+		/* Temporarily disable RX */
+		LPC_EMAC->MAC1 &= ~EMAC_MAC1_REC_EN;
 
-        /* Reset the RX side */
-        LPC_EMAC->MAC1 |= EMAC_MAC1_RES_RX;
-        LPC_EMAC->IntClear = EMAC_INT_RX_OVERRUN;
+		/* Reset the RX side */
+		LPC_EMAC->MAC1 |= EMAC_MAC1_RES_RX;
+		LPC_EMAC->IntClear = EMAC_INT_RX_OVERRUN;
 
-        /* De-allocate all queued RX pbufs */
-        for (idx = 0; idx < LPC_NUM_BUFF_RXDESCS; idx++) {
-            if (lpc_enetif->rxb[idx] != NULL) {
-                pbuf_free(lpc_enetif->rxb[idx]);
-                lpc_enetif->rxb[idx] = NULL;
-            }
-        }
+		/* De-allocate all queued RX pbufs */
+		for (idx = 0; idx < LPC_NUM_BUFF_RXDESCS; idx++) {
+			if (lpc_enetif->rxb[idx] != NULL) {
+				pbuf_free(lpc_enetif->rxb[idx]);
+				lpc_enetif->rxb[idx] = NULL;
+			}
+		}
 
-        /* Start RX side again */
-        lpc_rx_setup(lpc_enetif);
+		/* Start RX side again */
+		lpc_rx_setup(lpc_enetif);
 
-        /* Re-enable RX */
-        LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
+		/* Re-enable RX */
+		LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
 
 #ifdef LOCK_RX_THREAD
 #if NO_SYS == 0
-        sys_mutex_unlock(&lpc_enetif->TXLockMutex);
+		sys_mutex_unlock(&lpc_enetif->TXLockMutex);
 #endif
 #endif
 
-        return NULL;
-    }
+		return NULL;
+	}
 
-    /* Determine if a frame has been received */
-    length = 0;
-    idx = LPC_EMAC->RxConsumeIndex;
-    if (LPC_EMAC->RxProduceIndex != idx) {
-        /* Handle errors */
-        if (lpc_enetif->prxs[idx].statusinfo & (EMAC_RINFO_CRC_ERR |
-            EMAC_RINFO_SYM_ERR | EMAC_RINFO_ALIGN_ERR | EMAC_RINFO_LEN_ERR)) {
+	/* Determine if a frame has been received */
+	length = 0;
+	idx = LPC_EMAC->RxConsumeIndex;
+	if (LPC_EMAC->RxProduceIndex != idx) {
+		/* Handle errors */
+		if (lpc_enetif->prxs[idx].statusinfo & (EMAC_RINFO_CRC_ERR |
+			EMAC_RINFO_SYM_ERR | EMAC_RINFO_ALIGN_ERR | EMAC_RINFO_LEN_ERR)) {
 #if LINK_STATS
-            if (lpc_enetif->prxs[idx].statusinfo & (EMAC_RINFO_CRC_ERR |
-                EMAC_RINFO_SYM_ERR | EMAC_RINFO_ALIGN_ERR))
-                LINK_STATS_INC(link.chkerr);
-            if (lpc_enetif->prxs[idx].statusinfo & EMAC_RINFO_LEN_ERR)
-                LINK_STATS_INC(link.lenerr);
+			if (lpc_enetif->prxs[idx].statusinfo & (EMAC_RINFO_CRC_ERR |
+				EMAC_RINFO_SYM_ERR | EMAC_RINFO_ALIGN_ERR))
+				LINK_STATS_INC(link.chkerr);
+			if (lpc_enetif->prxs[idx].statusinfo & EMAC_RINFO_LEN_ERR)
+				LINK_STATS_INC(link.lenerr);
 #endif
 
-            /* Drop the frame */
-            LINK_STATS_INC(link.drop);
+			/* Drop the frame */
+			LINK_STATS_INC(link.drop);
 
-            /* Re-queue the pbuf for receive */
-            lpc_enetif->rx_free_descs++;
-            p = lpc_enetif->rxb[idx];
-            lpc_enetif->rxb[idx] = NULL;
-            lpc_rxqueue_pbuf(lpc_enetif, p);
+			/* Re-queue the pbuf for receive */
+			lpc_enetif->rx_free_descs++;
+			p = lpc_enetif->rxb[idx];
+			lpc_enetif->rxb[idx] = NULL;
+			lpc_rxqueue_pbuf(lpc_enetif, p);
 
-            LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-                ("lpc_low_level_input: Packet dropped with errors (0x%x)\n",
-                lpc_enetif->prxs[idx].statusinfo));
-            
-            p = NULL;
-        } else {
-            /* A packet is waiting, get length */
-            length = (lpc_enetif->prxs[idx].statusinfo & 0x7FF) + 1;
+			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+				("lpc_low_level_input: Packet dropped with errors (0x%x)\n",
+				lpc_enetif->prxs[idx].statusinfo));
+			
+			p = NULL;
+		} else {
+			/* A packet is waiting, get length */
+			length = (lpc_enetif->prxs[idx].statusinfo & 0x7FF) + 1;
 
-            /* Zero-copy */
-            p = lpc_enetif->rxb[idx];
-            p->len = (u16_t) length;
+			/* Zero-copy */
+			p = lpc_enetif->rxb[idx];
+			p->len = (u16_t) length;
 
-            /* Free pbuf from desriptor */
-            lpc_enetif->rxb[idx] = NULL;
-            lpc_enetif->rx_free_descs++;
+			/* Free pbuf from desriptor */
+			lpc_enetif->rxb[idx] = NULL;
+			lpc_enetif->rx_free_descs++;
 
-            LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-                ("lpc_low_level_input: Packet received: %p, size %d (index=%d)\n",
-                p, length, idx));
+			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+				("lpc_low_level_input: Packet received: %p, size %d (index=%d)\n",
+				p, length, idx));
 
-            /* Save size */
-            p->tot_len = (u16_t) length;
-            LINK_STATS_INC(link.recv);
+			/* Save size */
+			p->tot_len = (u16_t) length;
+			LINK_STATS_INC(link.recv);
 
-            /* Queue new buffer(s) */
-            lpc_rx_queue(lpc_enetif->netif);
-        }
-    }
+			/* Queue new buffer(s) */
+			lpc_rx_queue(lpc_enetif->netif);
+		}
+	}
 
 #ifdef LOCK_RX_THREAD
 #if NO_SYS == 0
-    sys_mutex_unlock(&lpc_enetif->TXLockMutex);
+	sys_mutex_unlock(&lpc_enetif->TXLockMutex);
 #endif
 #endif
 
-    return p;  
+	return p;  
 }
 
 /** \brief  Attempt to read a packet from the EMAC interface.
@@ -444,37 +456,37 @@
  */
 void lpc_enetif_input(struct netif *netif)
 {
-    struct eth_hdr *ethhdr;
-    struct pbuf *p;
+	struct eth_hdr *ethhdr;
+	struct pbuf *p;
 
-    /* move received packet into a new pbuf */
-    p = lpc_low_level_input(netif);
-    if (p == NULL)
-        return;
+	/* move received packet into a new pbuf */
+	p = lpc_low_level_input(netif);
+	if (p == NULL)
+		return;
 
-    /* points to packet payload, which starts with an Ethernet header */
-    ethhdr = p->payload;
+	/* points to packet payload, which starts with an Ethernet header */
+	ethhdr = p->payload;
 
-    switch (htons(ethhdr->type)) {
-        case ETHTYPE_IP:
-        case ETHTYPE_ARP:
+	switch (htons(ethhdr->type)) {
+		case ETHTYPE_IP:
+		case ETHTYPE_ARP:
 #if PPPOE_SUPPORT
-        case ETHTYPE_PPPOEDISC:
-        case ETHTYPE_PPPOE:
+		case ETHTYPE_PPPOEDISC:
+		case ETHTYPE_PPPOE:
 #endif /* PPPOE_SUPPORT */
-            /* full packet send to tcpip_thread to process */
-            if (netif->input(p, netif) != ERR_OK) {
-                LWIP_DEBUGF(NETIF_DEBUG, ("lpc_enetif_input: IP input error\n"));
-                /* Free buffer */
-                pbuf_free(p);
-            }
-            break;
+			/* full packet send to tcpip_thread to process */
+			if (netif->input(p, netif) != ERR_OK) {
+				LWIP_DEBUGF(NETIF_DEBUG, ("lpc_enetif_input: IP input error\n"));
+				/* Free buffer */
+				pbuf_free(p);
+			}
+			break;
 
-        default:
-            /* Return buffer */
-            pbuf_free(p);
-            break;
-    }
+		default:
+			/* Return buffer */
+			pbuf_free(p);
+			break;
+	}
 }
 
 /** \brief  Determine if the passed address is usable for the ethernet
@@ -484,11 +496,15 @@
  *  \return          1 if the packet address is not safe, otherwise 0
  */
 static s32_t lpc_packet_addr_notsafe(void *addr) {
-    /* Check for legal address ranges */
-    if ((((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20083FFF))) {
-        return 0;
-    }
-    return 1;
+	/* Check for legal address ranges */
+#if defined(TARGET_LPC1768)  
+	if ((((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20083FFF))) {
+#elif defined(TARGET_LPC4088)
+	if ((((u32_t) addr >= 0x20000000) && ((u32_t) addr < 0x20007FFF))) {
+#endif  
+	    return 0;
+	}
+	return 1;
 }
 
 /** \brief  Sets up the TX descriptor ring buffers.
@@ -499,22 +515,22 @@
  */
 static err_t lpc_tx_setup(struct lpc_enetdata *lpc_enetif)
 {
-    s32_t idx;
+	s32_t idx;
 
-    /* Build TX descriptors for local buffers */
-    for (idx = 0; idx < LPC_NUM_BUFF_TXDESCS; idx++) {
-        lpc_enetif->ptxd[idx].control = 0;
-        lpc_enetif->ptxs[idx].statusinfo = 0xFFFFFFFF;
-    }
+	/* Build TX descriptors for local buffers */
+	for (idx = 0; idx < LPC_NUM_BUFF_TXDESCS; idx++) {
+		lpc_enetif->ptxd[idx].control = 0;
+		lpc_enetif->ptxs[idx].statusinfo = 0xFFFFFFFF;
+	}
 
-    /* Setup pointers to TX structures */
-    LPC_EMAC->TxDescriptor = (u32_t) &lpc_enetif->ptxd[0];
-    LPC_EMAC->TxStatus = (u32_t) &lpc_enetif->ptxs[0];
-    LPC_EMAC->TxDescriptorNumber = LPC_NUM_BUFF_TXDESCS - 1;
+	/* Setup pointers to TX structures */
+	LPC_EMAC->TxDescriptor = (u32_t) &lpc_enetif->ptxd[0];
+	LPC_EMAC->TxStatus = (u32_t) &lpc_enetif->ptxs[0];
+	LPC_EMAC->TxDescriptorNumber = LPC_NUM_BUFF_TXDESCS - 1;
 
-    lpc_enetif->lpc_last_tx_idx = 0;
+	lpc_enetif->lpc_last_tx_idx = 0;
 
-    return ERR_OK;
+	return ERR_OK;
 }
 
 /** \brief  Free TX buffers that are complete
@@ -525,31 +541,31 @@
 static void lpc_tx_reclaim_st(struct lpc_enetdata *lpc_enetif, u32_t cidx)
 {
 #if NO_SYS == 0
-    /* Get exclusive access */
-    sys_mutex_lock(&lpc_enetif->TXLockMutex);
+	/* Get exclusive access */
+	sys_mutex_lock(&lpc_enetif->TXLockMutex);
 #endif
 
-    while (cidx != lpc_enetif->lpc_last_tx_idx) {
-        if (lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] != NULL) {
-            LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-                ("lpc_tx_reclaim_st: Freeing packet %p (index %d)\n",
-                lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx],
-                lpc_enetif->lpc_last_tx_idx));
-            pbuf_free(lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx]);
-             lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] = NULL;
-        }
+	while (cidx != lpc_enetif->lpc_last_tx_idx) {
+		if (lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] != NULL) {
+			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+				("lpc_tx_reclaim_st: Freeing packet %p (index %d)\n",
+				lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx],
+				lpc_enetif->lpc_last_tx_idx));
+			pbuf_free(lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx]);
+		 	lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] = NULL;
+		}
 
 #if NO_SYS == 0
-        osSemaphoreRelease(lpc_enetif->xTXDCountSem.id);
+		osSemaphoreRelease(lpc_enetif->xTXDCountSem.id);
 #endif
-        lpc_enetif->lpc_last_tx_idx++;
-        if (lpc_enetif->lpc_last_tx_idx >= LPC_NUM_BUFF_TXDESCS)
-            lpc_enetif->lpc_last_tx_idx = 0;
-    }
+		lpc_enetif->lpc_last_tx_idx++;
+		if (lpc_enetif->lpc_last_tx_idx >= LPC_NUM_BUFF_TXDESCS)
+			lpc_enetif->lpc_last_tx_idx = 0;
+	}
 
 #if NO_SYS == 0
-    /* Restore access */
-    sys_mutex_unlock(&lpc_enetif->TXLockMutex);
+	/* Restore access */
+	sys_mutex_unlock(&lpc_enetif->TXLockMutex);
 #endif
 }
 
@@ -559,8 +575,8 @@
  */
 void lpc_tx_reclaim(struct netif *netif)
 {
-    lpc_tx_reclaim_st((struct lpc_enetdata *) netif->state,
-        LPC_EMAC->TxConsumeIndex);
+	lpc_tx_reclaim_st((struct lpc_enetdata *) netif->state,
+		LPC_EMAC->TxConsumeIndex);
 }
 
  /** \brief  Polls if an available TX descriptor is ready. Can be used to
@@ -571,22 +587,22 @@
  */
 s32_t lpc_tx_ready(struct netif *netif)
 {
-    s32_t fb;
-    u32_t idx, cidx;
+	s32_t fb;
+	u32_t idx, cidx;
 
-    cidx = LPC_EMAC->TxConsumeIndex;
-    idx = LPC_EMAC->TxProduceIndex;
+	cidx = LPC_EMAC->TxConsumeIndex;
+	idx = LPC_EMAC->TxProduceIndex;
 
-    /* Determine number of free buffers */
-    if (idx == cidx)
-        fb = LPC_NUM_BUFF_TXDESCS;
-    else if (cidx > idx)
-        fb = (LPC_NUM_BUFF_TXDESCS - 1) -
-            ((idx + LPC_NUM_BUFF_TXDESCS) - cidx);
-    else
-        fb = (LPC_NUM_BUFF_TXDESCS - 1) - (cidx - idx);
+	/* Determine number of free buffers */
+	if (idx == cidx)
+		fb = LPC_NUM_BUFF_TXDESCS;
+	else if (cidx > idx)
+		fb = (LPC_NUM_BUFF_TXDESCS - 1) -
+			((idx + LPC_NUM_BUFF_TXDESCS) - cidx);
+	else
+		fb = (LPC_NUM_BUFF_TXDESCS - 1) - (cidx - idx);
 
-    return fb;
+	return fb;
 }
 
 /** \brief  Low level output of a packet. Never call this from an
@@ -599,125 +615,125 @@
  */
 static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p)
 {
-    struct lpc_enetdata *lpc_enetif = netif->state;
-    struct pbuf *q;
-    u8_t *dst;
+	struct lpc_enetdata *lpc_enetif = netif->state;
+	struct pbuf *q;
+	u8_t *dst;
     u32_t idx;
-    struct pbuf *np;
-    u32_t dn, notdmasafe = 0;
+	struct pbuf *np;
+	u32_t dn, notdmasafe = 0;
 
-    /* Zero-copy TX buffers may be fragmented across mutliple payload
-       chains. Determine the number of descriptors needed for the
-       transfer. The pbuf chaining can be a mess! */
-    dn = (u32_t) pbuf_clen(p);
+	/* Zero-copy TX buffers may be fragmented across mutliple payload
+	   chains. Determine the number of descriptors needed for the
+	   transfer. The pbuf chaining can be a mess! */
+	dn = (u32_t) pbuf_clen(p);
 
-    /* Test to make sure packet addresses are DMA safe. A DMA safe
-       address is once that uses external memory or periphheral RAM.
-       IRAM and FLASH are not safe! */
-    for (q = p; q != NULL; q = q->next)
-        notdmasafe += lpc_packet_addr_notsafe(q->payload);
+	/* Test to make sure packet addresses are DMA safe. A DMA safe
+	   address is once that uses external memory or periphheral RAM.
+	   IRAM and FLASH are not safe! */
+	for (q = p; q != NULL; q = q->next)
+		notdmasafe += lpc_packet_addr_notsafe(q->payload);
 
 #if LPC_TX_PBUF_BOUNCE_EN==1
-    /* If the pbuf is not DMA safe, a new bounce buffer (pbuf) will be
-       created that will be used instead. This requires an copy from the
-       non-safe DMA region to the new pbuf */
-    if (notdmasafe) {
-        /* Allocate a pbuf in DMA memory */
-        np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-        if (np == NULL)
-            return ERR_MEM;    
+	/* If the pbuf is not DMA safe, a new bounce buffer (pbuf) will be
+	   created that will be used instead. This requires an copy from the
+	   non-safe DMA region to the new pbuf */
+	if (notdmasafe) {
+		/* Allocate a pbuf in DMA memory */
+		np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+		if (np == NULL)
+			return ERR_MEM;	
 
-        /* This buffer better be contiguous! */
-        LWIP_ASSERT("lpc_low_level_output: New transmit pbuf is chained",
-            (pbuf_clen(np) == 1));
+		/* This buffer better be contiguous! */
+		LWIP_ASSERT("lpc_low_level_output: New transmit pbuf is chained",
+			(pbuf_clen(np) == 1));
 
-        /* Copy to DMA safe pbuf */
-        dst = (u8_t *) np->payload;
-         for(q = p; q != NULL; q = q->next) {
-            /* Copy the buffer to the descriptor's buffer */
-              MEMCPY(dst, (u8_t *) q->payload, q->len);
-          dst += q->len;
-        }
-        np->len = p->tot_len; 
+		/* Copy to DMA safe pbuf */
+		dst = (u8_t *) np->payload;
+	 	for(q = p; q != NULL; q = q->next) {
+			/* Copy the buffer to the descriptor's buffer */
+	  		MEMCPY(dst, (u8_t *) q->payload, q->len);
+		  dst += q->len;
+		}
+		np->len = p->tot_len; 
 
-        LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-            ("lpc_low_level_output: Switched to DMA safe buffer, old=%p, new=%p\n",
-            q, np));
+		LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+			("lpc_low_level_output: Switched to DMA safe buffer, old=%p, new=%p\n",
+			q, np));
 
-        /* use the new buffer for descrptor queueing. The original pbuf will
-           be de-allocated outsuide this driver. */
-        p = np;
-        dn = 1;
-    }
+		/* use the new buffer for descrptor queueing. The original pbuf will
+		   be de-allocated outsuide this driver. */
+		p = np;
+		dn = 1;
+	}
 #else
-    if (notdmasafe)
-        LWIP_ASSERT("lpc_low_level_output: Not a DMA safe pbuf",
-            (notdmasafe == 0));
+	if (notdmasafe)
+		LWIP_ASSERT("lpc_low_level_output: Not a DMA safe pbuf",
+			(notdmasafe == 0));
 #endif
 
-    /* Wait until enough descriptors are available for the transfer. */
-    /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
-    while (dn > lpc_tx_ready(netif))
+	/* Wait until enough descriptors are available for the transfer. */
+	/* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
+	while (dn > lpc_tx_ready(netif))
 #if NO_SYS == 0
-        osSemaphoreWait(lpc_enetif->xTXDCountSem.id, osWaitForever);
+	    osSemaphoreWait(lpc_enetif->xTXDCountSem.id, osWaitForever);
 #else
-        osDelay(1);
+		osDelay(1);
 #endif
 
-    /* Get free TX buffer index */
-    idx = LPC_EMAC->TxProduceIndex;
+	/* Get free TX buffer index */
+	idx = LPC_EMAC->TxProduceIndex;
 
 #if NO_SYS == 0
-    /* Get exclusive access */
-    sys_mutex_lock(&lpc_enetif->TXLockMutex);
+	/* Get exclusive access */
+	sys_mutex_lock(&lpc_enetif->TXLockMutex);
 #endif
 
-    /* Prevent LWIP from de-allocating this pbuf. The driver will
-       free it once it's been transmitted. */
-    if (!notdmasafe)
-        pbuf_ref(p);
+	/* Prevent LWIP from de-allocating this pbuf. The driver will
+	   free it once it's been transmitted. */
+	if (!notdmasafe)
+		pbuf_ref(p);
 
-    /* Setup transfers */
-    q = p;
-    while (dn > 0) {
-        dn--;
+	/* Setup transfers */
+	q = p;
+	while (dn > 0) {
+		dn--;
 
-        /* Only save pointer to free on last descriptor */
-        if (dn == 0) {
-            /* Save size of packet and signal it's ready */
-            lpc_enetif->ptxd[idx].control = (q->len - 1) | EMAC_TCTRL_INT |
-                EMAC_TCTRL_LAST;
+		/* Only save pointer to free on last descriptor */
+		if (dn == 0) {
+			/* Save size of packet and signal it's ready */
+			lpc_enetif->ptxd[idx].control = (q->len - 1) | EMAC_TCTRL_INT |
+				EMAC_TCTRL_LAST;
             lpc_enetif->txb[idx] = p;
-        }
-        else {
-            /* Save size of packet, descriptor is not last */
-            lpc_enetif->ptxd[idx].control = (q->len - 1) | EMAC_TCTRL_INT;
-            lpc_enetif->txb[idx] = NULL;
-        }
+		}
+		else {
+			/* Save size of packet, descriptor is not last */
+			lpc_enetif->ptxd[idx].control = (q->len - 1) | EMAC_TCTRL_INT;
+			lpc_enetif->txb[idx] = NULL;
+		}
 
-        LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
-            ("lpc_low_level_output: pbuf packet(%p) sent, chain#=%d,"
-            " size = %d (index=%d)\n", q->payload, dn, q->len, idx));
+		LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
+			("lpc_low_level_output: pbuf packet(%p) sent, chain#=%d,"
+			" size = %d (index=%d)\n", q->payload, dn, q->len, idx));
 
-        lpc_enetif->ptxd[idx].packet = (u32_t) q->payload;
+		lpc_enetif->ptxd[idx].packet = (u32_t) q->payload;
 
-        q = q->next;
+		q = q->next;
 
-        idx++;
-        if (idx >= LPC_NUM_BUFF_TXDESCS)
-            idx = 0;
-    }
+		idx++;
+		if (idx >= LPC_NUM_BUFF_TXDESCS)
+			idx = 0;
+	}
 
-    LPC_EMAC->TxProduceIndex = idx;
+	LPC_EMAC->TxProduceIndex = idx;
 
-    LINK_STATS_INC(link.xmit);
+	LINK_STATS_INC(link.xmit);
 
 #if NO_SYS == 0
-    /* Restore access */
-    sys_mutex_unlock(&lpc_enetif->TXLockMutex);
+	/* Restore access */
+	sys_mutex_unlock(&lpc_enetif->TXLockMutex);
 #endif
 
-    return ERR_OK;
+	return ERR_OK;
 }
 
 /** \brief  LPC EMAC interrupt handler.
@@ -728,18 +744,18 @@
 void ENET_IRQHandler(void)
 {
 #if NO_SYS == 1
-    /* Interrupts are not used without an RTOS */
+	/* Interrupts are not used without an RTOS */
     NVIC_DisableIRQ(ENET_IRQn);
 #else
-    uint32_t ints;
+	uint32_t ints;
 
-    /* Interrupts are of 2 groups - transmit or receive. Based on the
-       interrupt, kick off the receive or transmit (cleanup) task */
+	/* Interrupts are of 2 groups - transmit or receive. Based on the
+	   interrupt, kick off the receive or transmit (cleanup) task */
 
-    /* Get pending interrupts */
-    ints = LPC_EMAC->IntStatus;
+	/* Get pending interrupts */
+	ints = LPC_EMAC->IntStatus;
 
-    if (ints & RXINTGROUP) {
+	if (ints & RXINTGROUP) {
         /* RX group interrupt(s): Give semaphore to wakeup RX receive task.*/
         sys_sem_signal(&lpc_enetdata.RxSem);
     }
@@ -749,8 +765,8 @@
         sys_sem_signal(&lpc_enetdata.TxCleanSem);
     }
     
-    /* Clear pending interrupts */
-    LPC_EMAC->IntClear = ints;
+	/* Clear pending interrupts */
+	LPC_EMAC->IntClear = ints;
 #endif
 }
 
@@ -834,105 +850,128 @@
  */
 static err_t low_level_init(struct netif *netif)
 {
-    struct lpc_enetdata *lpc_enetif = netif->state;
-    err_t err = ERR_OK;
+	struct lpc_enetdata *lpc_enetif = netif->state;
+	err_t err = ERR_OK;
 
-    /* Enable MII clocking */
-    LPC_SC->PCONP |= CLKPWR_PCONP_PCENET;
-    
-    LPC_PINCON->PINSEL2 = 0x50150105;                  /* Enable P1 Ethernet Pins. */
-    LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
-    
-    /* Reset all MAC logic */
-    LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX |
-        EMAC_MAC1_RES_RX | EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES |
-        EMAC_MAC1_SOFT_RES;
-    LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES |
-        EMAC_CR_PASS_RUNT_FRM;
-    osDelay(10);
-    
-    /* Initial MAC initialization */
-    LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
-    LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN |
-        EMAC_MAC2_VLAN_PAD_EN;
-    LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
+	/* Enable MII clocking */
+	LPC_SC->PCONP |= CLKPWR_PCONP_PCENET;
+	
+#if defined(TARGET_LPC1768)  
+	LPC_PINCON->PINSEL2 = 0x50150105;                  /* Enable P1 Ethernet Pins. */
+	LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
+#elif defined(TARGET_LPC4088)
+  LPC_IOCON->P1_0  &= ~0x07;    /*  ENET I/O config */
+  LPC_IOCON->P1_0  |= 0x01;     /* ENET_TXD0 */
+  LPC_IOCON->P1_1  &= ~0x07;
+  LPC_IOCON->P1_1  |= 0x01;     /* ENET_TXD1 */
+  LPC_IOCON->P1_4  &= ~0x07;
+  LPC_IOCON->P1_4  |= 0x01;     /* ENET_TXEN */
+  LPC_IOCON->P1_8  &= ~0x07;
+  LPC_IOCON->P1_8  |= 0x01;     /* ENET_CRS */
+  LPC_IOCON->P1_9  &= ~0x07;
+  LPC_IOCON->P1_9  |= 0x01;     /* ENET_RXD0 */
+  LPC_IOCON->P1_10 &= ~0x07;
+  LPC_IOCON->P1_10 |= 0x01;     /* ENET_RXD1 */
+  LPC_IOCON->P1_14 &= ~0x07;
+  LPC_IOCON->P1_14 |= 0x01;     /* ENET_RX_ER */
+  LPC_IOCON->P1_15 &= ~0x07;
+  LPC_IOCON->P1_15 |= 0x01;     /* ENET_REF_CLK */
+  LPC_IOCON->P1_16 &= ~0x07;    /* ENET/PHY I/O config */
+  LPC_IOCON->P1_16 |= 0x01;     /* ENET_MDC */
+  LPC_IOCON->P1_17 &= ~0x07;
+  LPC_IOCON->P1_17 |= 0x01;     /* ENET_MDIO */
+#endif  
+	
+	/* Reset all MAC logic */
+	LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX |
+		EMAC_MAC1_RES_RX | EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES |
+		EMAC_MAC1_SOFT_RES;
+	LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES |
+		EMAC_CR_PASS_RUNT_FRM;
+	osDelay(10);
+	
+	/* Initial MAC initialization */
+	LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
+	LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN |
+		EMAC_MAC2_VLAN_PAD_EN;
+	LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
 
-    /* Set RMII management clock rate to lowest speed */
-    LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(11) | EMAC_MCFG_RES_MII;
-    LPC_EMAC->MCFG &= ~EMAC_MCFG_RES_MII;
+	/* Set RMII management clock rate to lowest speed */
+	LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(11) | EMAC_MCFG_RES_MII;
+	LPC_EMAC->MCFG &= ~EMAC_MCFG_RES_MII;
 
-    /* Maximum number of retries, 0x37 collision window, gap */
-    LPC_EMAC->CLRT = EMAC_CLRT_DEF;
-    LPC_EMAC->IPGR = EMAC_IPGR_P1_DEF | EMAC_IPGR_P2_DEF;
+	/* Maximum number of retries, 0x37 collision window, gap */
+	LPC_EMAC->CLRT = EMAC_CLRT_DEF;
+	LPC_EMAC->IPGR = EMAC_IPGR_P1_DEF | EMAC_IPGR_P2_DEF;
 
 #if LPC_EMAC_RMII
-    /* RMII setup */
-    LPC_EMAC->Command = EMAC_CR_PASS_RUNT_FRM | EMAC_CR_RMII;
+	/* RMII setup */
+	LPC_EMAC->Command = EMAC_CR_PASS_RUNT_FRM | EMAC_CR_RMII;
 #else
-    /* MII setup */
-    LPC_EMAC->CR = EMAC_CR_PASS_RUNT_FRM;
+	/* MII setup */
+	LPC_EMAC->CR = EMAC_CR_PASS_RUNT_FRM;
 #endif
 
-    /* Initialize the PHY and reset */
+	/* Initialize the PHY and reset */
     err = lpc_phy_init(netif, LPC_EMAC_RMII);
-    if (err != ERR_OK)
-         return err;
+	if (err != ERR_OK)
+ 		return err;
 
-    /* Save station address */
-    LPC_EMAC->SA2 = (u32_t) netif->hwaddr[0] |
-        (((u32_t) netif->hwaddr[1]) << 8);
-    LPC_EMAC->SA1 = (u32_t) netif->hwaddr[2] |
-        (((u32_t) netif->hwaddr[3]) << 8);
-    LPC_EMAC->SA0 = (u32_t) netif->hwaddr[4] |
-        (((u32_t) netif->hwaddr[5]) << 8);
+	/* Save station address */
+	LPC_EMAC->SA2 = (u32_t) netif->hwaddr[0] |
+		(((u32_t) netif->hwaddr[1]) << 8);
+	LPC_EMAC->SA1 = (u32_t) netif->hwaddr[2] |
+		(((u32_t) netif->hwaddr[3]) << 8);
+	LPC_EMAC->SA0 = (u32_t) netif->hwaddr[4] |
+		(((u32_t) netif->hwaddr[5]) << 8);
 
-    /* Setup transmit and receive descriptors */
-    if (lpc_tx_setup(lpc_enetif) != ERR_OK)
-        return ERR_BUF;
-    if (lpc_rx_setup(lpc_enetif) != ERR_OK)
-        return ERR_BUF;
+	/* Setup transmit and receive descriptors */
+	if (lpc_tx_setup(lpc_enetif) != ERR_OK)
+		return ERR_BUF;
+	if (lpc_rx_setup(lpc_enetif) != ERR_OK)
+		return ERR_BUF;
 
-    /* Enable packet reception */
+	/* Enable packet reception */
 #if IP_SOF_BROADCAST_RECV
-    LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN | EMAC_RFC_BCAST_EN;
+	LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_MCAST_EN;
 #else
-    LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN;
+	LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN;
 #endif
 
-    /* Clear and enable rx/tx interrupts */
-    LPC_EMAC->IntClear = 0xFFFF;
-    LPC_EMAC->IntEnable = RXINTGROUP | TXINTGROUP;
+	/* Clear and enable rx/tx interrupts */
+	LPC_EMAC->IntClear = 0xFFFF;
+	LPC_EMAC->IntEnable = RXINTGROUP | TXINTGROUP;
 
-    /* Enable RX and TX */
-    LPC_EMAC->Command |= EMAC_CR_RX_EN | EMAC_CR_TX_EN;
-    LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
+	/* Enable RX and TX */
+	LPC_EMAC->Command |= EMAC_CR_RX_EN | EMAC_CR_TX_EN;
+	LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
 
-    return err;
+	return err;
 }
 
 /* This function provides a method for the PHY to setup the EMAC
    for the PHY negotiated duplex mode */
 void lpc_emac_set_duplex(int full_duplex)
 {
-    if (full_duplex) {
-        LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
-        LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
-        LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
-    } else {
-        LPC_EMAC->MAC2    &= ~EMAC_MAC2_FULL_DUP;
-        LPC_EMAC->Command &= ~EMAC_CR_FULL_DUP;
-        LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
-    }
+	if (full_duplex) {
+		LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
+		LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
+		LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
+	} else {
+		LPC_EMAC->MAC2    &= ~EMAC_MAC2_FULL_DUP;
+		LPC_EMAC->Command &= ~EMAC_CR_FULL_DUP;
+		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
+	}
 }
 
 /* This function provides a method for the PHY to setup the EMAC
    for the PHY negotiated bit rate */
 void lpc_emac_set_speed(int mbs_100)
 {
-    if (mbs_100)
-        LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
-    else
-        LPC_EMAC->SUPP = 0;
+	if (mbs_100)
+		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
+	else
+		LPC_EMAC->SUPP = 0;
 }
 
 /**
@@ -945,13 +984,13 @@
  * \return ERR_OK or error code
  */
 err_t lpc_etharp_output(struct netif *netif, struct pbuf *q,
-    ip_addr_t *ipaddr)
+	ip_addr_t *ipaddr)
 {
-    /* Only send packet is link is up */
-    if (netif->flags & NETIF_FLAG_LINK_UP)
-        return etharp_output(netif, q, ipaddr);
+	/* Only send packet is link is up */
+	if (netif->flags & NETIF_FLAG_LINK_UP)
+		return etharp_output(netif, q, ipaddr);
 
-    return ERR_CONN;
+	return ERR_CONN;
 }
 
 #if NO_SYS == 0
@@ -975,38 +1014,38 @@
  */
 err_t lpc_enetif_init(struct netif *netif)
 {
-    err_t err;
+	err_t err;
 
-    LWIP_ASSERT("netif != NULL", (netif != NULL));
+	LWIP_ASSERT("netif != NULL", (netif != NULL));
     
-    lpc_enetdata.netif = netif;
+	lpc_enetdata.netif = netif;
 
-    /* set MAC hardware address */
-    mbed_mac_address((char *)netif->hwaddr);
-    netif->hwaddr_len = ETHARP_HWADDR_LEN;
+	/* set MAC hardware address */
+	mbed_mac_address((char *)netif->hwaddr);
+	netif->hwaddr_len = ETHARP_HWADDR_LEN;
 
-     /* maximum transfer unit */
-    netif->mtu = 1500;
+ 	/* maximum transfer unit */
+	netif->mtu = 1500;
 
-    /* device capabilities */
-    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;
+	/* device capabilities */
+	netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
 
-    /* Initialize the hardware */
-    netif->state = &lpc_enetdata;
-    err = low_level_init(netif);
-    if (err != ERR_OK)
-        return err;
+	/* Initialize the hardware */
+	netif->state = &lpc_enetdata;
+	err = low_level_init(netif);
+	if (err != ERR_OK)
+		return err;
 
 #if LWIP_NETIF_HOSTNAME
-    /* Initialize interface hostname */
-    netif->hostname = "lwiplpc";
+	/* Initialize interface hostname */
+	netif->hostname = "lwiplpc";
 #endif /* LWIP_NETIF_HOSTNAME */
 
-    netif->name[0] = 'e';
-    netif->name[1] = 'n';
+	netif->name[0] = 'e';
+	netif->name[1] = 'n';
 
-    netif->output = lpc_etharp_output;
-    netif->linkoutput = lpc_low_level_output;
+	netif->output = lpc_etharp_output;
+	netif->linkoutput = lpc_low_level_output;
 
     /* CMSIS-RTOS, start tasks */
 #if NO_SYS == 0
@@ -1015,24 +1054,24 @@
     lpc_enetdata.xTXDCountSem.def.semaphore = lpc_enetdata.xTXDCountSem.data;
 #endif
     lpc_enetdata.xTXDCountSem.id = osSemaphoreCreate(&lpc_enetdata.xTXDCountSem.def, LPC_NUM_BUFF_TXDESCS);
-    LWIP_ASSERT("xTXDCountSem creation error", (lpc_enetdata.xTXDCountSem.id != NULL));
+	LWIP_ASSERT("xTXDCountSem creation error", (lpc_enetdata.xTXDCountSem.id != NULL));
 
-    err = sys_mutex_new(&lpc_enetdata.TXLockMutex);
-    LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
+	err = sys_mutex_new(&lpc_enetdata.TXLockMutex);
+	LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
 
-    /* Packet receive task */
-    err = sys_sem_new(&lpc_enetdata.RxSem, 0);
-    LWIP_ASSERT("RxSem creation error", (err == ERR_OK));
-    sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
+	/* Packet receive task */
+	err = sys_sem_new(&lpc_enetdata.RxSem, 0);
+	LWIP_ASSERT("RxSem creation error", (err == ERR_OK));
+	sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
 
-    /* Transmit cleanup task */
-    err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);
-    LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK));
-    sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
-    
-    /* periodic PHY status update */
-    osTimerId phy_timer = osTimerCreate(osTimer(phy_update), osTimerPeriodic, (void *)netif);
-    osTimerStart(phy_timer, 250);
+	/* Transmit cleanup task */
+	err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);
+	LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK));
+	sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
+	
+	/* periodic PHY status update */
+	osTimerId phy_timer = osTimerCreate(osTimer(phy_update), osTimerPeriodic, (void *)netif);
+	osTimerStart(phy_timer, 250);
 #endif
     
     return ERR_OK;
--- a/arch/lpc17_emac.h	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc17_emac.h	Thu May 30 17:15:45 2013 +0100
@@ -1,11 +1,11 @@
 /**********************************************************************
-* $Id$        lpc17_emac.h            2011-11-20
+* $Id$		lpc17_emac.h			2011-11-20
 *//**
-* @file        lpc17_emac.h
-* @brief    LPC17 ethernet driver header file for LWIP
-* @version    1.0
-* @date        20. Nov. 2011
-* @author    NXP MCU SW Application Team
+* @file		lpc17_emac.h
+* @brief	LPC17 ethernet driver header file for LWIP
+* @version	1.0
+* @date		20. Nov. 2011
+* @author	NXP MCU SW Application Team
 * 
 * Copyright(C) 2011, NXP Semiconductor
 * All rights reserved.
--- a/arch/lpc17xx_emac.h	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc17xx_emac.h	Thu May 30 17:15:45 2013 +0100
@@ -34,7 +34,7 @@
 #define LPC17XX_EMAC_H_
 
 /* Includes ------------------------------------------------------------------- */
-#include "LPC17xx.h"
+#include "cmsis.h"
 
 #ifdef __cplusplus
 extern "C"
--- a/arch/lpc_emac_config.h	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc_emac_config.h	Thu May 30 17:15:45 2013 +0100
@@ -1,11 +1,11 @@
 /**********************************************************************
-* $Id$        lpc_emac_config.h            2011-11-20
+* $Id$		lpc_emac_config.h			2011-11-20
 *//**
-* @file        lpc_emac_config.h
-* @brief    PHY and EMAC configuration file
-* @version    1.0
-* @date        20 Nov. 2011
-* @author    NXP MCU SW Application Team
+* @file		lpc_emac_config.h
+* @brief	PHY and EMAC configuration file
+* @version	1.0
+* @date		20 Nov. 2011
+* @author	NXP MCU SW Application Team
 * 
 * Copyright(C) 2011, NXP Semiconductor
 * All rights reserved.
@@ -33,7 +33,7 @@
 {
 #endif
 
-/** @defgroup lwip_phy_config    LWIP PHY configuration
+/** @defgroup lwip_phy_config	LWIP PHY configuration
  * @ingroup lwip_phy
  *
  * Configuration options for the PHY connected to the LPC EMAC.
@@ -63,11 +63,11 @@
  */
 #define PHY_USE_100MBS 1 /**< Sets data rate to 100Mbps. */
 
-/**          
+/**		  
  * @}
  */
 
-/** @defgroup lwip_emac_config    LWIP EMAC configuration
+/** @defgroup lwip_emac_config	LWIP EMAC configuration
  * @ingroup lwip_emac
  *
  * Configuration options for the LPC EMAC.
@@ -98,7 +98,7 @@
  */
 #define LPC_TX_PBUF_BOUNCE_EN 1
 
-/**          
+/**		  
  * @}
  */
 
--- a/arch/lpc_phy.h	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc_phy.h	Thu May 30 17:15:45 2013 +0100
@@ -1,11 +1,11 @@
 /**********************************************************************
-* $Id$        lpc_phy.h            2011-11-20
+* $Id$		lpc_phy.h			2011-11-20
 *//**
-* @file        lpc_phy.h
-* @brief    Common PHY definitions used with all PHYs
-* @version    1.0
-* @date        20 Nov. 2011
-* @author    NXP MCU SW Application Team
+* @file		lpc_phy.h
+* @brief	Common PHY definitions used with all PHYs
+* @version	1.0
+* @date		20 Nov. 2011
+* @author	NXP MCU SW Application Team
 * 
 * Copyright(C) 2011, NXP Semiconductor
 * All rights reserved.
--- a/arch/lpc_phy_dp83848.c	Fri Mar 01 15:30:33 2013 +0000
+++ b/arch/lpc_phy_dp83848.c	Thu May 30 17:15:45 2013 +0100
@@ -1,11 +1,11 @@
 /**********************************************************************
-* $Id$        lpc_phy_dp83848.c            2011-11-20
+* $Id$		lpc_phy_dp83848.c			2011-11-20
 *//**
-* @file        lpc_phy_dp83848.c
-* @brief    DP83848C PHY status and control.
-* @version    1.0
-* @date        20 Nov. 2011
-* @author    NXP MCU SW Application Team
+* @file		lpc_phy_dp83848.c
+* @brief	DP83848C PHY status and control.
+* @version	1.0
+* @date		20 Nov. 2011
+* @author	NXP MCU SW Application Team
 *
 * Copyright(C) 2011, NXP Semiconductor
 * All rights reserved.
@@ -30,7 +30,7 @@
 #include "lpc_emac_config.h"
 #include "lpc_phy.h"
 
-/** @defgroup dp83848_phy    PHY status and control for the DP83848.
+/** @defgroup dp83848_phy	PHY status and control for the DP83848.
  * @ingroup lwip_phy
  *
  * Various functions for controlling and monitoring the status of the
@@ -44,6 +44,8 @@
 /** \brief  DP83848 PHY register offsets */
 #define DP8_BMCR_REG        0x0  /**< Basic Mode Control Register */
 #define DP8_BMSR_REG        0x1  /**< Basic Mode Status Reg */
+#define DP8_IDR1_REG        0x2  /**< Basic Mode Status Reg */
+#define DP8_IDR2_REG        0x3  /**< Basic Mode Status Reg */
 #define DP8_ANADV_REG       0x4  /**< Auto_Neg Advt Reg  */
 #define DP8_ANLPA_REG       0x5  /**< Auto_neg Link Partner Ability Reg */
 #define DP8_ANEEXP_REG      0x6  /**< Auto-neg Expansion Reg  */
@@ -52,6 +54,8 @@
 #define DP8_PHY_RBR_REG     0x17 /**< PHY RMII and Bypass Register  */
 #define DP8_PHY_STS_REG     0x19 /**< PHY Status Register  */
 
+#define DP8_PHY_SCSR_REG    0x1f /**< PHY Special Control/Status Register (LAN8720)  */
+
 /** \brief DP83848 Control register definitions */
 #define DP8_RESET          (1 << 15)  /**< 1= S/W Reset */
 #define DP8_LOOPBACK       (1 << 14)  /**< 1=loopback Enabled */
@@ -90,12 +94,25 @@
 #define DP8_PHYID1_OUI     0x2000     /**< Expected PHY ID1 */
 #define DP8_PHYID2_OUI     0x5c90     /**< Expected PHY ID2 */
 
+/** \brief LAN8720 PHY Special Control/Status Register */
+#define PHY_SCSR_100MBIT    0x0008    /**< Speed: 1=100 MBit, 0=10Mbit */
+#define PHY_SCSR_DUPLEX     0x0010    /**< PHY Duplex Mask             */
+
+/** \brief Link status bits */
+#define LNK_STAT_VALID       0x01 
+#define LNK_STAT_FULLDUPLEX  0x02
+#define LNK_STAT_SPEED10MPS  0x04
+
+/** \brief PHY ID definitions */
+#define DP83848C_ID         0x20005C90  /**< PHY Identifier - DP83848C */
+#define LAN8720_ID          0x0007C0F0  /**< PHY Identifier - LAN8720  */
+
 /** \brief PHY status structure used to indicate current status of PHY.
  */
 typedef struct {
-    u32_t     phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */
-    u32_t     phy_full_duplex:1;  /**< Half/full duplex connection speed flag. */
-    u32_t     phy_link_active:1;  /**< Phy link active flag. */
+	u32_t     phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */
+	u32_t     phy_full_duplex:1;  /**< Half/full duplex connection speed flag. */
+	u32_t     phy_link_active:1;  /**< Phy link active flag. */
 } PHY_STATUS_TYPE;
 
 /** \brief  PHY update flags */
@@ -107,6 +124,12 @@
 /** \brief  PHY update counter for state machine */
 static s32_t phyustate;
 
+/** \brief  Holds the PHY ID */
+static u32_t phy_id;
+
+/** \brief  Temporary holder of link status for LAN7420 */
+static u32_t phy_lan7420_sts_tmp;
+
 /** \brief  Update PHY status from passed value
  *
  *  This function updates the current PHY status based on the
@@ -119,61 +142,61 @@
  */
 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts)
 {
-    s32_t changed = 0;
+	s32_t changed = 0;
 
-    /* Update link active status */
-    if (linksts & DP8_VALID_LINK)
-        physts.phy_link_active = 1;
-    else
-        physts.phy_link_active = 0;
+	/* Update link active status */
+	if (linksts & LNK_STAT_VALID)
+		physts.phy_link_active = 1;
+	else
+		physts.phy_link_active = 0;
 
-    /* Full or half duplex */
-    if (linksts & DP8_FULLDUPLEX)
-        physts.phy_full_duplex = 1;
-    else
-        physts.phy_full_duplex = 0;
+	/* Full or half duplex */
+	if (linksts & LNK_STAT_FULLDUPLEX)
+		physts.phy_full_duplex = 1;
+	else
+		physts.phy_full_duplex = 0;
 
-    /* Configure 100MBit/10MBit mode. */
-    if (linksts & DP8_SPEED10MBPS)
-        physts.phy_speed_100mbs = 0;
-    else
-        physts.phy_speed_100mbs = 1;
+	/* Configure 100MBit/10MBit mode. */
+	if (linksts & LNK_STAT_SPEED10MPS)
+		physts.phy_speed_100mbs = 0;
+	else
+		physts.phy_speed_100mbs = 1;
 
-    if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) {
-        changed = 1;
-        if (physts.phy_speed_100mbs) {
-            /* 100MBit mode. */
-            lpc_emac_set_speed(1);
+	if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) {
+		changed = 1;
+		if (physts.phy_speed_100mbs) {
+			/* 100MBit mode. */
+			lpc_emac_set_speed(1);
 
-            NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
-        }
-        else {
-            /* 10MBit mode. */
-            lpc_emac_set_speed(0);
+			NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
+		}
+		else {
+			/* 10MBit mode. */
+			lpc_emac_set_speed(0);
 
-            NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
-        }
+			NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
+		}
 
-        olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs;
-    }
+		olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs;
+	}
 
-    if (physts.phy_full_duplex != olddphysts.phy_full_duplex) {
-        changed = 1;
-        if (physts.phy_full_duplex)
-            lpc_emac_set_duplex(1);
-        else
-            lpc_emac_set_duplex(0);
+	if (physts.phy_full_duplex != olddphysts.phy_full_duplex) {
+		changed = 1;
+		if (physts.phy_full_duplex)
+			lpc_emac_set_duplex(1);
+		else
+			lpc_emac_set_duplex(0);
 
-        olddphysts.phy_full_duplex = physts.phy_full_duplex;
-    }
+		olddphysts.phy_full_duplex = physts.phy_full_duplex;
+	}
 
-    if (physts.phy_link_active != olddphysts.phy_link_active) {
-        changed = 1;
+	if (physts.phy_link_active != olddphysts.phy_link_active) {
+		changed = 1;
 #if NO_SYS == 1
-        if (physts.phy_link_active)
-            netif_set_link_up(netif);
-        else
-            netif_set_link_down(netif);
+		if (physts.phy_link_active)
+			netif_set_link_up(netif);
+		else
+			netif_set_link_down(netif);
 #else
         if (physts.phy_link_active)
             tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
@@ -183,10 +206,10 @@
                 (void*) netif, 1);
 #endif
 
-        olddphysts.phy_link_active = physts.phy_link_active;
-    }
+		olddphysts.phy_link_active = physts.phy_link_active;
+	}
 
-    return changed;
+	return changed;
 }
 
 /** \brief  Initialize the DP83848 PHY.
@@ -202,81 +225,121 @@
  */
 err_t lpc_phy_init(struct netif *netif, int rmii)
 {
-    u32_t tmp;
-    s32_t i;
+	u32_t tmp;
+	s32_t i;
+
+	physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2;
+	physts.phy_full_duplex = olddphysts.phy_full_duplex = 2;
+	physts.phy_link_active = olddphysts.phy_link_active = 2;
+	phyustate = 0;
 
-    physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2;
-    physts.phy_full_duplex = olddphysts.phy_full_duplex = 2;
-    physts.phy_link_active = olddphysts.phy_link_active = 2;
-    phyustate = 0;
+	/* Only first read and write are checked for failure */
+	/* Put the DP83848C in reset mode and wait for completion */
+	if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0)
+		return ERR_TIMEOUT;
+	i = 400;
+	while (i > 0) {
+	    osDelay(1);   /* 1 ms */
+		if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0)
+			return ERR_TIMEOUT;
 
-    /* Only first read and write are checked for failure */
-    /* Put the DP83848C in reset mode and wait for completion */
-    if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0)
-        return ERR_TIMEOUT;
-    i = 400;
-    while (i > 0) {
-        osDelay(1);   /* 1 ms */
-        if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0)
-            return ERR_TIMEOUT;
+		if (!(tmp & (DP8_RESET | DP8_POWER_DOWN)))
+			i = -1;
+		else
+			i--;
+	}
+	/* Timeout? */
+	if (i == 0)
+		return ERR_TIMEOUT;
 
-        if (!(tmp & (DP8_RESET | DP8_POWER_DOWN)))
-            i = -1;
-        else
-            i--;
-    }
-    /* Timeout? */
-    if (i == 0)
-        return ERR_TIMEOUT;
+	// read PHY ID
+	lpc_mii_read(DP8_IDR1_REG, &tmp);
+	phy_id = (tmp << 16);
+	lpc_mii_read(DP8_IDR2_REG, &tmp);    
+	phy_id |= (tmp & 0XFFF0);    
 
-    /* Setup link based on configuration options */
+	/* Setup link based on configuration options */
 #if PHY_USE_AUTONEG==1
-    tmp = DP8_AUTONEG;
+	tmp = DP8_AUTONEG;
 #else
-    tmp = 0;
+	tmp = 0;
 #endif
 #if PHY_USE_100MBS==1
-    tmp |= DP8_SPEED_SELECT;
+	tmp |= DP8_SPEED_SELECT;
 #endif
 #if PHY_USE_FULL_DUPLEX==1
-    tmp |= DP8_DUPLEX_MODE;
+	tmp |= DP8_DUPLEX_MODE;
 #endif
-    lpc_mii_write(DP8_BMCR_REG, tmp);
+	lpc_mii_write(DP8_BMCR_REG, tmp);
 
     /* Enable RMII mode for PHY */
     if (rmii)
         lpc_mii_write(DP8_PHY_RBR_REG, DP8_RBR_RMII_MODE);
 
-    /* The link is not set active at this point, but will be detected
+	/* The link is not set active at this point, but will be detected
        later */
 
-    return ERR_OK;
+	return ERR_OK;
 }
 
 /* Phy status update state machine */
 s32_t lpc_phy_sts_sm(struct netif *netif)
 {
-    s32_t changed = 0;
+	s32_t changed = 0;
+	u32_t data = 0;
+	u32_t tmp;
 
-    switch (phyustate) {
-        default:
-        case 0:
-            /* Read BMSR to clear faults */
-            lpc_mii_read_noblock(DP8_PHY_STAT_REG);
-            phyustate = 1;
-            break;
+	switch (phyustate) {
+		default:
+		case 0:
+			if (phy_id == DP83848C_ID) {    
+				lpc_mii_read_noblock(DP8_PHY_STAT_REG);
+				phyustate = 2;
+			}
+			else if (phy_id == LAN8720_ID) {
+				lpc_mii_read_noblock(DP8_PHY_SCSR_REG);
+				phyustate = 1;        
+			}
+			break;
+
+		case 1:
+			if (phy_id == LAN8720_ID) {
+				tmp = lpc_mii_read_data();
+				// we get speed and duplex here. 
+				phy_lan7420_sts_tmp =  (tmp & PHY_SCSR_DUPLEX)  ? LNK_STAT_FULLDUPLEX : 0;
+				phy_lan7420_sts_tmp |= (tmp & PHY_SCSR_100MBIT) ? 0 : LNK_STAT_SPEED10MPS;
 
-        case 1:
-            /* Wait for read status state */
-            if (!lpc_mii_is_busy()) {
-                /* Update PHY status */
-                changed = lpc_update_phy_sts(netif, lpc_mii_read_data());
-                phyustate = 0;
-            }
-            break;
-    }
+				//read the status register to get link status 
+				lpc_mii_read_noblock(DP8_BMSR_REG);
+				phyustate = 2;        
+			}
+			break;
+
+		case 2:
+			/* Wait for read status state */
+			if (!lpc_mii_is_busy()) {
+				/* Update PHY status */
+				tmp = lpc_mii_read_data();
 
-    return changed;
+				if (phy_id == DP83848C_ID) {
+					// STS register contains all needed status bits
+					data  = (tmp & DP8_VALID_LINK) ? LNK_STAT_VALID : 0;
+					data |= (tmp & DP8_FULLDUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
+					data |= (tmp & DP8_SPEED10MBPS) ? LNK_STAT_SPEED10MPS : 0;
+				}
+				else if (phy_id == LAN8720_ID) {    
+					// we only get the link status here.
+					phy_lan7420_sts_tmp |= (tmp & DP8_LINK_STATUS) ? LNK_STAT_VALID : 0;
+					data = phy_lan7420_sts_tmp;          
+				}
+
+				changed = lpc_update_phy_sts(netif, data);        
+				phyustate = 0;                
+			}
+			break;
+	}
+
+	return changed;
 }
 
 /**