/** * This function should be called when a packet is ready to be read * from the interface. It uses the function prvLowLevelInput() that * should handle the actual reception of bytes from the network * interface. Then the type of the received packet is determined and * the appropriate input function is called. * * @param pxNetIf the lwip network interface structure for this ethernetif */ static void prvEthernetInput( const unsigned char * const pucInputData, long lInputLength ) { /* This is taken from lwIP example code and therefore does not conform to the FreeRTOS coding standard. */ struct eth_hdr *pxHeader; struct pbuf *p; /* move received packet into a new pbuf */ p = prvLowLevelInput( pucInputData, lInputLength ); /* no packet could be read, silently ignore this */ if( p != NULL ) { /* points to packet payload, which starts with an Ethernet header */ pxHeader = p->payload; switch( htons( pxHeader->type ) ) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: /* full packet send to tcpip_thread to process */ if( pxlwIPNetIf->input( p, pxlwIPNetIf ) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) ); pbuf_free(p); p = NULL; } break; default: pbuf_free( p ); p = NULL; break; } } }
static void prvRxHandler( void *pvNetIf ) { /* This is taken from lwIP example code and therefore does not conform to the FreeRTOS coding standard. */ struct eth_hdr *pxHeader; struct pbuf *p; unsigned short usInputLength; static unsigned char ucBuffer[ 1520 ] __attribute__((aligned(32))); extern portBASE_TYPE xInsideISR; struct netif *pxNetIf = ( struct netif * ) pvNetIf; XIntc_AckIntr( XPAR_ETHERNET_LITE_BASEADDR, XPAR_ETHERNET_LITE_IP2INTC_IRPT_MASK ); /* Ensure the pbuf handling functions don't attempt to use critical sections. */ xInsideISR++; usInputLength = ( long ) XEmacLite_Recv( &xEMACInstance, ucBuffer ); /* move received packet into a new pbuf */ p = prvLowLevelInput( ucBuffer, usInputLength ); /* no packet could be read, silently ignore this */ if( p != NULL ) { /* points to packet payload, which starts with an Ethernet header */ pxHeader = p->payload; switch( htons( pxHeader->type ) ) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: /* full packet send to tcpip_thread to process */ if( pxNetIf->input( p, pxNetIf ) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) ); pbuf_free(p); p = NULL; } break; default: pbuf_free( p ); p = NULL; break; } } xInsideISR--; }
void ENET_IRQHandler( void ) { uint32_t ulInterruptCause; extern volatile portBASE_TYPE xInsideISR; struct pbuf *p; struct eth_hdr *pxHeader; xInsideISR++; while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 ) { /* Clear the interrupt. */ LPC_EMAC->IntClear = ulInterruptCause; /* Clear fatal error conditions. */ if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U ) { LPC_EMAC->Command |= EMAC_CR_TX_RES; } if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL ) { /* A packet has been received. */ if( EMAC_CheckReceiveIndex() != FALSE ) { if( EMAC_CheckReceiveDataStatus( EMAC_RINFO_LAST_FLAG ) == SET ) { /* move received packet into a new pbuf */ p = prvLowLevelInput(); /* no packet could be read, silently ignore this */ if( p != NULL ) { /* points to packet payload, which starts with an Ethernet header */ pxHeader = p->payload; switch( htons( pxHeader->type ) ) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: /* Full packet send to tcpip_thread to process */ configASSERT( pxNetIfInUse ); if( pxNetIfInUse->input( p, pxNetIfInUse ) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) ); pbuf_free(p); p = NULL; } break; default: pbuf_free( p ); p = NULL; break; } } else { configASSERT( ( volatile void * ) NULL ); } } /* Release the frame. */ EMAC_UpdateRxConsumeIndex(); } } if( ( ulInterruptCause & EMAC_INT_TX_DONE ) != 0UL ) { /* Nothing to do here. */ } } xInsideISR--; }
/*-----------------------------------------------------------*/ static void ftMac100_rx_task ( void *arg ) { struct xFtmac100If *macIf = arg; struct eth_hdr *pxHeader; struct pbuf *p; struct ftmac100_rxdes *rxdes; struct netif *pxNetIf = macIf->netIf; int error = 0; do { sys_sem_wait( &macIf->rx_sem ); check_next: rxdes = &gRxDes[macIf->rx_pointer]; if( rxdes->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN ) { continue; } if( !(rxdes->rxdes0 & FTMAC100_RXDES0_FRS) ) { error = 1; LWIP_DEBUGF( NETIF_DEBUG, ( "ftmac100 rx desc not first segment\n" ) ); } if( rxdes->rxdes0 & (FTMAC100_RXDES0_FTL | FTMAC100_RXDES0_RUNT | FTMAC100_RXDES0_RX_ODD_NB) ) { error = 1; LWIP_DEBUGF( NETIF_DEBUG, ( "ftmac100: rx length error\n" ) ); #if LINK_STATS LINK_STATS_INC( link.lenerr ); #endif } if( rxdes->rxdes0 & FTMAC100_RXDES0_CRC_ERR ) { error = 1; LWIP_DEBUGF( NETIF_DEBUG, ( "ftmac100: rx checksum error\n" ) ); #if LINK_STATS LINK_STATS_INC( link.lenerr ); #endif } if ( error ) { #if LINK_STATS LINK_STATS_INC( link.drop ); #endif rxdes->rxdes0 = FTMAC100_RXDES0_RXDMA_OWN; ftMac100_rx_pointer_incr( &macIf->rx_pointer ); goto check_next; } /* * It is impossible to get multi-segment packets * because we always provide big enough receive buffers. */ if( !(rxdes->rxdes0 & FTMAC100_RXDES0_LRS) ) LWIP_DEBUGF( NETIF_DEBUG, ( "ftmac100 rx multi-segment packets\n" ) ); /* move received packet into a new pbuf */ p = prvLowLevelInput( (const unsigned char * const) rxdes->rxdes2, (unsigned short)(rxdes->rxdes0 & FTMAC100_RXDES0_RFL) ); /* no packet could be read, silently ignore this */ if( p != NULL ) { #if LINK_STATS LINK_STATS_INC( link.recv ); #endif /* points to packet payload, which starts with an Ethernet header */ pxHeader = p->payload; switch( htons( pxHeader->type ) ) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: /* full packet send to tcpip_thread to process */ if( pxNetIf->input( p, pxNetIf ) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) ); pbuf_free(p); p = NULL; } break; default: pbuf_free( p ); p = NULL; break; } } else { #if LINK_STATS LINK_STATS_INC( link.memerr ); #endif } /* Done. Give desc back to hw and increment index */ rxdes->rxdes0 = FTMAC100_RXDES0_RXDMA_OWN; ftMac100_rx_pointer_incr( &macIf->rx_pointer ); goto check_next; } while (1); }