예제 #1
0
/**
 * This function will read a single packet from the Stellaris ethernet
 * interface, if available, and return a pointer to a pbuf.  The timestamp
 * of the packet will be placed into the pbuf structure.
 *
 * @param netif the lwip network interface structure for this ethernetif
 * @return pointer to pbuf packet if available, NULL otherswise.
 */
static struct pbuf * low_level_input(struct netif *netif)
{
	struct pbuf *p, *q;
	u16_t len;
	u32_t temp;
	int i;
	unsigned long *ptr;
#if LWIP_PTPD
	u32_t time_s, time_ns;

	/* Get the current timestamp if PTPD is enabled */
	lwIPHostGetTime(&time_s, &time_ns);
#endif

	/* Check if a packet is available, if not, return NULL packet. */
	if ((HWREG(ETH_BASE + MAC_O_NP) & MAC_NP_NPR_M) == 0)
	{
		int err = ETHServiceTaskLastError(0);
		if ((ETH_ERROR & err) && (ETH_OVERFLOW & err))
		{
			LWIP_DEBUGF(CORTEX_DEBUG, ("low_level_input: Ethernet overflow\n"));LINK_STATS_INC(link.drop);
		}
		return (NULL);
	}

	/**
	 * Obtain the size of the packet and put it into the "len" variable.
	 * Note:  The length returned in the FIFO length position includes the
	 * two bytes for the length + the 4 bytes for the FCS.
	 *
	 */
	temp = HWREG(ETH_BASE + MAC_O_DATA);
	len = temp & 0xFFFF;

	/* We allocate a pbuf chain of pbufs from the pool. */
	p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

	/* If a pbuf was allocated, read the packet into the pbuf. */
	if (p != NULL)
	{
		/* Place the first word into the first pbuf location. */
		*(unsigned long *) p->payload = temp;
		p->payload = (char *) (p->payload) + 4;
		p->len -= 4;

		/* Process all but the last buffer in the pbuf chain. */
		q = p;
		while (q != NULL)
		{
			/* Setup a byte pointer into the payload section of the pbuf. */
			ptr = q->payload;

			/**
			 * Read data from FIFO into the current pbuf
			 * (assume pbuf length is modulo 4)
			 *
			 */
			for (i = 0; i < q->len; i += 4)
			{
				*ptr++ = HWREG(ETH_BASE + MAC_O_DATA);
			}

			/* Link in the next pbuf in the chain. */
			q = q->next;
		}

		/* Restore the first pbuf parameters to their original values. */
		p->payload = (char *) (p->payload) - 4;
		p->len += 4;

		/* Adjust the link statistics */
		LINK_STATS_INC(link.recv);

#if LWIP_PTPD
		// Place the timestamp in the PBUF
		p->time_s = time_s;
		p->time_ns = time_ns;
#endif
	}

	// If no pbuf available, just drain the RX fifo.
	else
	{
		for (i = 4; i < len; i += 4)
		{
			temp = HWREG(ETH_BASE + MAC_O_DATA);
		}

		// Adjust the link statistics
		LINK_STATS_INC(link.memerr);LINK_STATS_INC(link.drop);
	}

	return (p);
}
예제 #2
0
파일: lwip_drv.cpp 프로젝트: bratkov/tmos
/**
 * This function will read a single packet from the Stellaris ethernet
 * interface, if available, and return a pointer to a pbuf.  The timestamp
 * of the packet will be placed into the pbuf structure.
 *
 * @param netif the lwip network interface structure for this ethernetif
 * @return pointer to pbuf packet if available, NULL otherswise.
 */
static struct pbuf *low_level_receive(struct netif *netif)
{
	MAC_Type* mac = (MAC_Type*)netif->state;
	struct pbuf *p, *q;
	u16_t len;
	u32_t temp;
	int i;
	unsigned long *ptr;
#if LWIP_PTPD
	u32_t time_s, time_ns;

	/* Get the current timestamp if PTPD is enabled */
	lwIPHostGetTime(&time_s, &time_ns);
#endif

	/* Check if a packet is available, if not, return NULL packet. */
	if ((mac->MACNP & MAC_NP_NPR_M) == 0)
	{
		return (NULL);
	}

	/**
	 * Obtain the size of the packet and put it into the "len" variable.
	 * Note:  The length returned in the FIFO length position includes the
	 * two bytes for the length + the 4 bytes for the FCS.
	 *
	 */
	temp = mac->MACDATA;
	len = temp & 0xFFFF;

	/* We allocate a pbuf chain of pbufs from the pool. */
	p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

	/* If a pbuf was allocated, read the packet into the pbuf. */
	if (p != NULL)
	{
		/* Place the first word into the first pbuf location. */
		*(unsigned long *) p->payload = temp;
		p->payload = (char *) (p->payload) + 4;
		p->len -= 4;

		/* Process all but the last buffer in the pbuf chain. */
		q = p;
		while (q != NULL)
		{
			/* Setup a byte pointer into the payload section of the pbuf. */
			ptr = (unsigned long *)q->payload;

			/**
			 * Read data from FIFO into the current pbuf
			 * (assume pbuf length is modulo 4)
			 *
			 */
			for (i = 0; i < q->len; i += 4)
			{
				*ptr++ = mac->MACDATA;
			}

			/* Link in the next pbuf in the chain. */
			q = q->next;
		}

		/* Restore the first pbuf parameters to their original values. */
		p->payload = (char *) (p->payload) - 4;
		p->len += 4;

		/* Adjust the link statistics */
		LINK_STATS_INC(link.recv);

#if LWIP_PTPD
		/* Place the timestamp in the PBUF */
		p->time_s = time_s;
		p->time_ns = time_ns;
#endif
	}

	/* If no pbuf available, just drain the RX fifo. */
	else
	{
		for (i = 4; i < len; i += 4)
		{
			temp = mac->MACDATA;
		}

		/* Adjust the link statistics */
		LINK_STATS_INC(link.memerr);
		LINK_STATS_INC(link.drop);
	}

	return (p);
}