Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of lwip-eth by
Revision 7:99e5141a51dc, committed 2013-06-13
- Comitter:
- lemniskata
- Date:
- Thu Jun 13 20:00:22 2013 +0000
- Parent:
- 6:59b01b9349d5
- Commit message:
- V1
Changed in this revision
diff -r 59b01b9349d5 -r 99e5141a51dc arch/lpc17_emac.c --- a/arch/lpc17_emac.c Mon Jun 03 12:06:46 2013 +0100 +++ b/arch/lpc17_emac.c Thu Jun 13 20:00:22 2013 +0000 @@ -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,36 +97,36 @@ */ 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 }; @@ -149,87 +149,87 @@ /* 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 @@ -239,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 @@ -275,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. @@ -315,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. @@ -337,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. @@ -456,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 @@ -496,15 +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 */ + /* Check for legal address ranges */ #if defined(TARGET_LPC1768) - if ((((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20083FFF))) { + if ((((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20083FFF))) { #elif defined(TARGET_LPC4088) - if ((((u32_t) addr >= 0x20000000) && ((u32_t) addr < 0x20007FFF))) { + if ((((u32_t) addr >= 0x20000000) && ((u32_t) addr < 0x20007FFF))) { #endif - return 0; - } - return 1; + return 0; + } + return 1; } /** \brief Sets up the TX descriptor ring buffers. @@ -515,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 @@ -541,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 } @@ -575,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 @@ -587,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 @@ -615,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. @@ -744,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); } @@ -765,8 +765,8 @@ sys_sem_signal(&lpc_enetdata.TxCleanSem); } - /* Clear pending interrupts */ - LPC_EMAC->IntClear = ints; + /* Clear pending interrupts */ + LPC_EMAC->IntClear = ints; #endif } @@ -850,15 +850,15 @@ */ 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; - + /* 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; + 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 */ @@ -881,97 +881,97 @@ 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; + + /* 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 | EMAC_RFC_MCAST_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; } /** @@ -984,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 @@ -1014,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 | NETIF_FLAG_IGMP; + /* 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 @@ -1054,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;
diff -r 59b01b9349d5 -r 99e5141a51dc arch/lpc17_emac.h --- a/arch/lpc17_emac.h Mon Jun 03 12:06:46 2013 +0100 +++ b/arch/lpc17_emac.h Thu Jun 13 20:00:22 2013 +0000 @@ -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.
diff -r 59b01b9349d5 -r 99e5141a51dc arch/lpc_emac_config.h --- a/arch/lpc_emac_config.h Mon Jun 03 12:06:46 2013 +0100 +++ b/arch/lpc_emac_config.h Thu Jun 13 20:00:22 2013 +0000 @@ -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 -/** +/** * @} */
diff -r 59b01b9349d5 -r 99e5141a51dc arch/lpc_phy.h --- a/arch/lpc_phy.h Mon Jun 03 12:06:46 2013 +0100 +++ b/arch/lpc_phy.h Thu Jun 13 20:00:22 2013 +0000 @@ -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.
diff -r 59b01b9349d5 -r 99e5141a51dc arch/lpc_phy_dp83848.c --- a/arch/lpc_phy_dp83848.c Mon Jun 03 12:06:46 2013 +0100 +++ b/arch/lpc_phy_dp83848.c Thu Jun 13 20:00:22 2013 +0000 @@ -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 @@ -110,9 +110,9 @@ /** \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 */ @@ -142,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 & LNK_STAT_VALID) - 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 & LNK_STAT_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 & LNK_STAT_SPEED10MPS) - 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, @@ -206,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. @@ -225,121 +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); + // 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; - u32_t data = 0; - u32_t tmp; + s32_t changed = 0; + u32_t data = 0; + u32_t tmp; - 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; + 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: + 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; - //read the status register to get link status - lpc_mii_read_noblock(DP8_BMSR_REG); - phyustate = 2; - } - 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(); + case 2: + /* Wait for read status state */ + if (!lpc_mii_is_busy()) { + /* Update PHY status */ + tmp = lpc_mii_read_data(); - 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; - } + 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; - } + changed = lpc_update_phy_sts(netif, data); + phyustate = 0; + } + break; + } - return changed; + return changed; } /**