static void ethernetif_input( void * pvParameters ) { struct ethernetif *ethernetif; struct eth_hdr *ethhdr; struct pbuf *p; struct netif *netif; netif = (struct netif*) pvParameters; for( ;; ) { do { ethernetif = netif->state; /* move received packet into a new pbuf */ p = low_level_input( netif ); if( p == NULL ) { /* No packet could be read. Wait a for an interrupt to tell us there is more data available. */ vEMACWaitForInput(); } } while( p == NULL ); /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; switch( htons( ethhdr->type ) ) { /* IP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: if (netif->input(p, netif)!=ERR_OK){ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); pbuf_free(p); p = NULL; } break; } } } |
static struct pbuf *low_level_input( struct netif *netif ) { struct pbuf *p = NULL; static xSemaphoreHandle xRxSemaphore = NULL; /* Parameter not used. */ ( void ) netif; if( xRxSemaphore == NULL ) vSemaphoreCreateBinary( xRxSemaphore ); /* Access to the emac is guarded using a semaphore. */ if( xSemaphoreTake( xRxSemaphore, netifGUARD_BLOCK_TIME ) ) { if( EMAC_CheckReceiveIndex() == TRUE ) { p = EMAC_ReadPacketBuffer( NULL ); if(p != NULL){ #if LINK_STATS lwip_stats.link.recv++; #endif /* LINK_STATS */ } else { // drop packet(); #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif /* LINK_STATS */ } } xSemaphoreGive( xRxSemaphore ); } return p; } |
/*--------------------------- rx_descr_init ---------------------------------*/ /*********************************************************************//** * @brief Initializes RX Descriptor * @param[in] None * @return None ***********************************************************************/ static void rx_descr_init (void) { uint32_t i; for (i = 0; i < EMAC_NUM_RX_FRAG; i++) { RX_DESC_PACKET(i) = RX_BUF(i); RX_DESC_CTRL(i) = EMAC_RCTRL_INT | (EMAC_ETH_FRAG_SIZE-1); RX_STAT_INFO(i) = 0; RX_STAT_HASHCRC(i) = 0; } /* Set EMAC Receive Descriptor Registers. */ LPC_EMAC->RxDescriptor = RX_DESC_BASE; LPC_EMAC->RxStatus = RX_STAT_BASE; LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG-1; /* Rx Descriptors Point to 0 */ LPC_EMAC->RxConsumeIndex = 0; } struct pbuf* EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct) { struct pbuf* p; uint32_t size; uint32_t Index; /* init p pointer */ p = NULL; Index = LPC_EMAC->RxConsumeIndex; if(Index != LPC_EMAC->RxProduceIndex) { size = (RX_STAT_INFO(Index) & 0x7ff)+1; if (size > EMAC_ETH_FRAG_SIZE) size = EMAC_ETH_FRAG_SIZE; /* allocate buffer */ p = pbuf_alloc(PBUF_LINK, size, PBUF_RAM); if (p != NULL) { struct pbuf* q; uint8_t *ptr; ptr = (uint8_t*)RX_BUF(Index); for (q = p; q != NULL; q= q->next) { memcpy(q->payload, ptr, q->len); ptr += q->len; } } /* move Index to the next */ if(++Index > LPC_EMAC->RxDescriptorNumber) Index = 0; /* set consume index */ LPC_EMAC->RxConsumeIndex = Index; } return p; } void ENET_IRQHandler( void ) { unsigned long ulStatus; long lHigherPriorityTaskWoken = pdFALSE; ulStatus = LPC_EMAC->IntStatus; /* Clear the interrupt. */ LPC_EMAC->IntClear = ulStatus; if( ulStatus & EMAC_INT_RX_DONE ) { /* Ensure the uIP task is not blocked as data has arrived. */ xSemaphoreGiveFromISR( xSemaphore, &lHigherPriorityTaskWoken ); } if( ulStatus & EMAC_INT_TX_DONE ) { EMAC_UpdateTxProduceIndex(); } portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); } |
if ((phy_id != DP83848C_ID) && (phy_id != LAN8720_ID)) |
/* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; |