/* This function sets up the descriptor list used for receive packets */
static err_t lpc_rx_setup(struct lpc_enetdata *lpc_netifdata)
{
	s32_t idx;

	/* Set to start of list */
	lpc_netifdata->rx_get_idx = 0;
	lpc_netifdata->rx_next_idx = 0;
	lpc_netifdata->rx_free_descs = LPC_NUM_BUFF_RXDESCS;

	/* Clear initial RX descriptor list */
	memset(lpc_netifdata->prdesc, 0, sizeof(lpc_netifdata->prdesc));

	/* Setup buffer chaining before allocating pbufs for descriptors
	   just in case memory runs out. */
	for (idx = 0; idx < LPC_NUM_BUFF_RXDESCS; idx++) {
		lpc_netifdata->prdesc[idx].CTRL = RDES_ENH_RCH;
		lpc_netifdata->prdesc[idx].B2ADD = (u32_t)
										   &lpc_netifdata->prdesc[idx + 1];
	}
	lpc_netifdata->prdesc[LPC_NUM_BUFF_RXDESCS - 1].CTRL =
		RDES_ENH_RCH | RDES_ENH_RER;
	lpc_netifdata->prdesc[LPC_NUM_BUFF_RXDESCS - 1].B2ADD =
		(u32_t) &lpc_netifdata->prdesc[0];
	LPC_ETHERNET->DMA_REC_DES_ADDR = (u32_t) lpc_netifdata->prdesc;

	/* Setup up RX pbuf queue, but post a warning if not enough were
	   queued for all descriptors. */
	if (lpc_rx_queue(lpc_netifdata->netif) != LPC_NUM_BUFF_RXDESCS) {
		LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
					("lpc_rx_setup: Warning, not enough memory for RX pbufs\n"));
	}

	return ERR_OK;
}
/* Sets up the RX descriptor ring buffers. */
STATIC err_t lpc_rx_setup(lpc_enetdata_t *lpc_enetif)
{
    /* Setup pointers to RX structures */
    Chip_ENET_InitRxDescriptors(LPC_ETHERNET, lpc_enetif->prxd, lpc_enetif->prxs, LPC_NUM_BUFF_RXDESCS);

    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->pnetif);

    return ERR_OK;
}
示例#3
0
/** \brief  Sets up the RX descriptor ring buffers.
 *
 *  This function sets up the descriptor list used for receive packets.
 *
 *  \param[in]  lpc_enetif  Pointer to driver data structure
 *  \returns                   Always returns ERR_OK
 */
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;

	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);

	return ERR_OK;
}
示例#4
0
/**
 * @brief	main routine for example_lwip_tcpecho_sa_18xx43xx
 * @return	Function should not exit.
 */
int main(void)
{
	uint32_t physts;
	ip_addr_t ipaddr, netmask, gw;

	prvSetupHardware();

	/* Initialize LWIP */
	lwip_init();

	LWIP_DEBUGF(LWIP_DBG_ON, ("Starting LWIP TCP echo server...\n"));

	/* Static IP assignment */
#if LWIP_DHCP
	IP4_ADDR(&gw, 0, 0, 0, 0);
	IP4_ADDR(&ipaddr, 0, 0, 0, 0);
	IP4_ADDR(&netmask, 0, 0, 0, 0);
#else
	IP4_ADDR(&gw, 10, 1, 10, 1);
	IP4_ADDR(&ipaddr, 10, 1, 10, 234);
	IP4_ADDR(&netmask, 255, 255, 255, 0);
	APP_PRINT_IP(&ipaddr);
#endif

	/* Add netif interface for lpc17xx_8x */
	netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
			  ethernet_input);
	netif_set_default(&lpc_netif);
	netif_set_up(&lpc_netif);

#if LWIP_DHCP
	dhcp_start(&lpc_netif);
#endif

	/* Initialize and start application */
	echo_init();

	/* This could be done in the sysTick ISR, but may stay in IRQ context
	   too long, so do this stuff with a background loop. */
	while (1) {
		/* Handle packets as part of this loop, not in the IRQ handler */
		lpc_enetif_input(&lpc_netif);

		/* lpc_rx_queue will re-qeueu receive buffers. This normally occurs
		   automatically, but in systems were memory is constrained, pbufs
		   may not always be able to get allocated, so this function can be
		   optionally enabled to re-queue receive buffers. */
#if 0
		while (lpc_rx_queue(&lpc_netif)) {}
#endif

		/* Free TX buffers that are done sending */
		lpc_tx_reclaim(&lpc_netif);

		/* LWIP timers - ARP, DHCP, TCP, etc. */
		sys_check_timeouts();

		/* Call the PHY status update state machine once in a while
		   to keep the link status up-to-date */
		physts = lpcPHYStsPoll();

		/* Only check for connection state when the PHY status has changed */
		if (physts & PHY_LINK_CHANGED) {
			if (physts & PHY_LINK_CONNECTED) {
				Board_LED_Set(0, true);

				/* Set interface speed and duplex */
				if (physts & PHY_LINK_SPEED100) {
					Chip_ENET_SetSpeed(LPC_ETHERNET, 1);
					NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
				}
				else {
					Chip_ENET_SetSpeed(LPC_ETHERNET, 0);
					NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
				}
				if (physts & PHY_LINK_FULLDUPLX) {
					Chip_ENET_SetDuplex(LPC_ETHERNET, true);
				}
				else {
					Chip_ENET_SetDuplex(LPC_ETHERNET, false);
				}

				netif_set_link_up(&lpc_netif);
			}
			else {
				Board_LED_Set(0, false);
				netif_set_link_down(&lpc_netif);
			}

			DEBUGOUT("Link connect status: %d\r\n", ((physts & PHY_LINK_CONNECTED) != 0));
		}
	}

	/* Never returns, for warning only */
	return 0;
}
示例#5
0
/** \brief  Allocates a pbuf and returns the data from the incoming packet.
 *
 *  \param[in] netif the lwip network interface structure for this lpc_enetif
 *  \return a pbuf filled with the received packet (including MAC header)
 *         NULL on memory error
 */
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;
	u16_t origLength;

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
	/* 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);

		/* 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;

		/* 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);

		/* Re-enable RX */
		LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
		sys_mutex_unlock(&lpc_enetif->TXLockMutex);
#endif
#endif

		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)) {
#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);
#endif

			/* 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);

			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
				("lpc_low_level_input: Packet dropped with errors (0x%x)\r\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];
			origLength = p->len;
			p->len = (u16_t) length;

			/* Free pbuf from descriptor */
			lpc_enetif->rxb[idx] = NULL;
			lpc_enetif->rx_free_descs++;

			/* Attempt to queue new buffer(s) */
			if (lpc_rx_queue(lpc_enetif->netif) == 0) {
    			/* Drop the frame due to OOM. */
    			LINK_STATS_INC(link.drop);

    			/* Re-queue the pbuf for receive */
    			p->len = origLength;
    			lpc_rxqueue_pbuf(lpc_enetif, p);

    			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
    				("lpc_low_level_input: Packet index %d dropped for OOM\r\n",
    				idx));
			
#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
        		sys_mutex_unlock(&lpc_enetif->TXLockMutex);
#endif
#endif

		        return NULL;
			}

			LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
				("lpc_low_level_input: Packet received: %p, size %d (index=%d)\r\n",
				p, length, idx));

			/* Save size */
			p->tot_len = (u16_t) length;
			LINK_STATS_INC(link.recv);
		}
	}

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
	sys_mutex_unlock(&lpc_enetif->TXLockMutex);
#endif
#endif

	return p;
}
/* Gets data from queue and forwards to LWIP */
static struct pbuf *lpc_low_level_input(struct netif *netif) {
	struct lpc_enetdata *lpc_netifdata = netif->state;
	u32_t status, ridx;
	int rxerr = 0;
	struct pbuf *p;

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
	/* Get exclusive access */
	sys_mutex_lock(&lpc_netifdata->TXLockMutex);
#endif
#endif

	/* If there are no used descriptors, then this call was
	   not for a received packet, try to setup some descriptors now */
	if (lpc_netifdata->rx_free_descs == LPC_NUM_BUFF_RXDESCS) {
		lpc_rx_queue(netif);
#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
		sys_mutex_unlock(&lpc_netifdata->TXLockMutex);
#endif
#endif
		return NULL;
	}

	/* Get index for next descriptor with data */
	ridx = lpc_netifdata->rx_get_idx;

	/* Return if descriptor is still owned by DMA */
	if (lpc_netifdata->prdesc[ridx].STATUS & RDES_OWN) {
#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
		sys_mutex_unlock(&lpc_netifdata->TXLockMutex);
#endif
#endif
		return NULL;
	}

	/* Get address of pbuf for this descriptor */
	p = lpc_netifdata->rxpbufs[ridx];

	/* Get receive packet status */
	status = lpc_netifdata->prdesc[ridx].STATUS;

	/* Check packet for errors */
	if (status & RDES_ES) {
		LINK_STATS_INC(link.drop);

		/* Error conditions that cause a packet drop */
		if (status & intMask) {
			LINK_STATS_INC(link.err);
			rxerr = 1;
		}
		else
		/* Length error check needs qualification */
		if ((status & (RDES_LE | RDES_FT)) == RDES_LE) {
			LINK_STATS_INC(link.lenerr);
			rxerr = 1;
		}
		else
		/* CRC error check needs qualification */
		if ((status & (RDES_CE | RDES_LS)) == (RDES_CE | RDES_LS)) {
			LINK_STATS_INC(link.chkerr);
			rxerr = 1;
		}

		/* Descriptor error check needs qualification */
		if ((status & (RDES_DE | RDES_LS)) == (RDES_DE | RDES_LS)) {
			LINK_STATS_INC(link.err);
			rxerr = 1;
		}
		else
		/* Dribble bit error only applies in half duplex mode */
		if ((status & RDES_DE) &&
			(!(LPC_ETHERNET->MAC_CONFIG & MAC_CFG_DM))) {
			LINK_STATS_INC(link.err);
			rxerr = 1;
		}
	}

	/* Increment free descriptor count and next get index */
	lpc_netifdata->rx_free_descs++;
	ridx++;
	if (ridx >= LPC_NUM_BUFF_RXDESCS) {
		ridx = 0;
	}
	lpc_netifdata->rx_get_idx = ridx;

	/* If an error occurred, just re-queue the pbuf */
	if (rxerr) {
		lpc_rxqueue_pbuf(lpc_netifdata, p);
		p = NULL;

		LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
					("lpc_low_level_input: RX error condition status 0x%08x\n",
					 status));
	}
	else {
		/* Attempt to queue a new pbuf for the descriptor */
		lpc_rx_queue(netif);

		/* Get length of received packet */
		p->len = p->tot_len = (u16_t) RDES_FLMSK(status);

		LINK_STATS_INC(link.recv);

		LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
					("lpc_low_level_input: Packet received, %d bytes, "
					 "status 0x%08x\n", p->len, status));
	}

	/* (Re)start receive polling */
	LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
	/* Get exclusive access */
	sys_mutex_unlock(&lpc_netifdata->TXLockMutex);
#endif
#endif

	return p;
}
示例#7
0
/**
 * @brief	main routine for example_lwip_tcpecho_sa_17xx40xx
 * @return	Function should not exit.
 */
int main(void)
{
	uint32_t physts;
	ip_addr_t ipaddr, netmask, gw;
	static int prt_ip = 0;

	prvSetupHardware();






	/* Initialize LWIP */
	lwip_init();



	///LWIP_DEBUGF(LWIP_DBG_ON, ("Starting LWIP TCP echo server...\n"));

	/* Static IP assignment */

	IP4_ADDR(&gw, 0, 0, 0, 0);
	IP4_ADDR(&ipaddr, 0, 0, 0, 0);
	IP4_ADDR(&netmask, 0, 0, 0, 0);

	/* Add netif interface for lpc17xx_8x */


	netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,  ethernet_input);
	netif_set_default(&lpc_netif);
	netif_set_up(&lpc_netif);


	dhcp_start(&lpc_netif);



	uint8_t fl = 0 ;



	while (1)

	{



		/* Handle packets as part of this loop, not in the IRQ handler */



				lpc_enetif_input(&lpc_netif);



				/* lpc_rx_queue will re-qeueu receive buffers. This normally occurs
				   automatically, but in systems were memory is constrained, pbufs
				   may not always be able to get allocated, so this function can be
				   optionally enabled to re-queue receive buffers. */

		#if 0
				while (lpc_rx_queue(&lpc_netif)) {}
		#endif

				/* Free TX buffers that are done sending */
				lpc_tx_reclaim(&lpc_netif);

				/* LWIP timers - ARP, DHCP, TCP, etc. */
				sys_check_timeouts();

				/* Call the PHY status update state machine once in a while
				   to keep the link status up-to-date */
				physts = lpcPHYStsPoll();

				/* Only check for connection state when the PHY status has changed */

				if (physts & PHY_LINK_CHANGED)
				{
					if (physts & PHY_LINK_CONNECTED)
					{



						prt_ip = 0;

						/* Set interface speed and duplex */
						if (physts & PHY_LINK_SPEED100)
						{
							Chip_ENET_Set100Mbps(LPC_ETHERNET);
							NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
						}
						else
						{
							Chip_ENET_Set10Mbps(LPC_ETHERNET);
							NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
						}
						if (physts & PHY_LINK_FULLDUPLX) {
							Chip_ENET_SetFullDuplex(LPC_ETHERNET);
						}
						else {
							Chip_ENET_SetHalfDuplex(LPC_ETHERNET);
						}

						netif_set_link_up(&lpc_netif);
					}
					else
					{



						netif_set_link_down(&lpc_netif);
					}

					DEBUGOUT("Link connect status: %d\r\n", ((physts & PHY_LINK_CONNECTED) != 0));
				}

				/* Print IP address info */

				if (!prt_ip)
				{
					if (lpc_netif.ip_addr.addr)
					{
						static char tmp_buff[16];
						DEBUGOUT("IP_ADDR    : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.ip_addr, tmp_buff, 16));
						DEBUGOUT("NET_MASK   : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.netmask, tmp_buff, 16));
						DEBUGOUT("GATEWAY_IP : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.gw, tmp_buff, 16));
						prt_ip = 1;




						mqttAppInit();

						mqttAppConnect();



						//////   mqttAppDisconnect();


					}
				}

				if(mqttIsConnected()==1)
				{
					mqttAppHandle();


					if (fl == 0)
					{



						mqttAppSubscribe("lpc/#");
						mqttAppSubscribe("lpc/teste");


						fl = 1;

					}

				}








	}



	return 0;
}
/* Allocates a pbuf and returns the data from the incoming packet */
STATIC struct pbuf *lpc_low_level_input(struct netif *netif) {
    lpc_enetdata_t *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->rx_lock_mutex);
#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 (Chip_ENET_GetIntStatus(LPC_ETHERNET) & ENET_INT_RXOVERRUN) {
        LINK_STATS_INC(link.err);
        LINK_STATS_INC(link.drop);

        /* Temporarily disable RX */
        Chip_ENET_RXDisable(LPC_ETHERNET);

        /* Reset the RX side */
        Chip_ENET_ResetRXLogic(LPC_ETHERNET);
        Chip_ENET_ClearIntStatus(LPC_ETHERNET, ENET_INT_RXOVERRUN);

        /* 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);

        /* Re-enable RX */
        Chip_ENET_RXEnable(LPC_ETHERNET);

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
        sys_mutex_unlock(&lpc_enetif->rx_lock_mutex);
#endif
#endif

        return NULL;
    }

    /* Determine if a frame has been received */
    length = 0;
    idx = Chip_ENET_GetRXConsumeIndex(LPC_ETHERNET);
    if (!Chip_ENET_IsRxEmpty(LPC_ETHERNET)) {
        /* Handle errors */
        if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_ERR |
                                                ENET_RINFO_SYM_ERR | ENET_RINFO_ALIGN_ERR | ENET_RINFO_LEN_ERR)) {
#if LINK_STATS
            if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_ERR |
                                                    ENET_RINFO_SYM_ERR | ENET_RINFO_ALIGN_ERR)) {
                LINK_STATS_INC(link.chkerr);
            }
            if (lpc_enetif->prxs[idx].StatusInfo & ENET_RINFO_LEN_ERR) {
                LINK_STATS_INC(link.lenerr);
            }
#endif

            /* 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);

            LWIP_DEBUGF(EMAC_DEBUG | 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 = ENET_RINFO_SIZE(lpc_enetif->prxs[idx].StatusInfo) - 4;	/* Remove FCS */

            /* 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++;

            /* Queue new buffer(s) */
            if (lpc_rx_queue(lpc_enetif->pnetif) == 0) {

                /* Re-queue the pbuf for receive */
                lpc_rxqueue_pbuf(lpc_enetif, p);

                /* Drop the frame */
                LINK_STATS_INC(link.drop);

                LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
                            ("lpc_low_level_input: Packet dropped since it could not allocate Rx Buffer\n"));

                p = NULL;
            }
            else {

                LWIP_DEBUGF(EMAC_DEBUG | 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);
            }
        }

        /* Update Consume index */
        Chip_ENET_IncRXConsumeIndex(LPC_ETHERNET);
    }

#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
    sys_mutex_unlock(&lpc_enetif->rx_lock_mutex);
#endif
#endif

    return p;
}