static int receive_packets(struct netmap_ring *ring, u_int limit, int dump) { struct netmap_slot *slot; u_int cur, rx, n; u_char *p; #ifdef TIME_NANO clock_gettime(CLOCK_REALTIME, &g_time); #else gettimeofday(&g_time, 0); #endif cur = ring->cur; n = nm_ring_space(ring); if (n < limit) limit = n; for (rx = 0; rx < limit; rx++) { slot = &ring->slot[cur]; p = (u_char*)NETMAP_BUF(ring, slot->buf_idx); eth_input(p, slot->len); cur = nm_ring_next(ring, cur); } ring->head = ring->cur = cur; return (rx); }
/* ethernet buffer */ void eth_rx_thread_entry(void* parameter) { struct eth_device* device; INT8U err = 0; while (1) { device = OSQPend( pRxMsgQueue , 0,&err); if ( err == OS_NO_ERR) { struct pbuf *p; /* receive all of buffer */ while (1) { p = device->eth_rx(device); if (p != RT_NULL) { /* notify to upper layer */ eth_input(p, device->netif); } else break; } } } }
/*---------------------------------------------------------------------------*/ void eth_drv_input(uint8_t *packet, uint16_t len) { LOG6LBR_PRINTF(PACKET, ETH_IN, "read: %d\n", uip_len + UIP_LLH_LEN); LOG6LBR_DUMP_PACKET(ETH_IN, uip_buf, uip_len + UIP_LLH_LEN); #if CETIC_6LBR_WITH_IP64 if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0 && (((struct uip_eth_hdr *)packet)->type != UIP_HTONS(UIP_ETHTYPE_IPV6))) { IP64_INPUT(packet, len); } else { uip_len = len - UIP_LLH_LEN; memcpy(uip_buf, packet, len); eth_input(); } #else uip_len = len - UIP_LLH_LEN; eth_input(); #endif }
static void handle_fd(fd_set * rset, fd_set * wset) { /* Optional delay between outgoing packets */ /* Base delay times number of 6lowpan fragments to be sent */ /* delaymsec = 10; */ if(delaymsec) { struct timeval tv; int dmsec; gettimeofday(&tv, NULL); dmsec = (tv.tv_sec - delaystartsec) * 1000 + tv.tv_usec / 1000 - delaystartmsec; if(dmsec < 0) delaymsec = 0; if(dmsec > delaymsec) delaymsec = 0; } if(delaymsec == 0) { int size; if(FD_ISSET(tunfd, rset)) { size = tun_input(tmp_tap_buf, sizeof(tmp_tap_buf)); printf("TUN data incoming read:%d\n", size); if(ethernet_has_fcs) { //Remove extra data from packet capture uip_len = size - ETHERNET_LLH_LEN - 4; } else { uip_len = size - ETHERNET_LLH_LEN; } memcpy(ll_header, tmp_tap_buf, ETHERNET_LLH_LEN); memcpy(uip_buf, tmp_tap_buf + ETHERNET_LLH_LEN, uip_len); eth_input(); if(slip_config_basedelay) { struct timeval tv; gettimeofday(&tv, NULL); delaymsec = slip_config_basedelay; delaystartsec = tv.tv_sec; delaystartmsec = tv.tv_usec / 1000; } } } }
static int eth_process_recv_queue(struct eth_rx_queue *rxq) { struct mbuf *pos = rxq->head; #ifdef ENABLE_KSTATS kstats_accumulate tmp; #endif if (!pos) return -EAGAIN; /* NOTE: pos could get freed after eth_input(), so check next here */ rxq->head = pos->next; rxq->len--; KSTATS_PUSH(eth_input, &tmp); eth_input(rxq, pos); KSTATS_POP(&tmp); return 0; }
/* ethernet buffer */ void eth_rx_thread_entry(void* parameter) { struct eth_device* device; while (1) { if (rt_mb_recv(ð_rx_thread_mb, (UInt32*)&device, RT_WAITING_FOREVER) == RT_EOK) { struct pbuf *p; /* receive all of buffer */ while (1) { p = device->eth_rx(&(device->parent)); if (p != NULL) { /* notify to upper layer */ eth_input(p, device->netif); } else break; } } } }
/*-----------------------------------------------------------------------------------*/ static void mcf5272fec_rx(void) { /* This is the receive ISR. It is written to be a high-level ISR. */ u32_t old_level; mcf5272if_t *mcf5272 = mcf5272if; MCF5272_IMM *imm = mcf5272->imm; u32_t value; u16_t flags; unsigned int rx_remove_sof; unsigned int rx_remove_eof; struct pbuf *p; rx_remove_sof = rx_remove_eof = mcf5272->rx_remove; /* Loop, looking for filled buffers at eof */ while ((((flags = mcf5272->rxbd_a[rx_remove_eof].flags) & MCF5272_FEC_RX_BD_E) == 0) && (mcf5272->rx_pbuf_a[rx_remove_eof] != 0)) { /* See if this is last buffer in frame */ if ((flags & MCF5272_FEC_RX_BD_L) != 0) { /* This frame is ready to go. Start at first descriptor in frame. */ p = 0; do { /* Adjust pbuf length if this is last buffer in frame */ if (rx_remove_sof == rx_remove_eof) { mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len = mcf5272->rx_pbuf_a[rx_remove_sof]->len = (u16_t) (mcf5272->rxbd_a[rx_remove_sof].data_len - (p ? p->tot_len : 0)); } else mcf5272->rx_pbuf_a[rx_remove_sof]->len = mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len = mcf5272->rxbd_a[rx_remove_sof].data_len; /* Chain pbuf */ if (p == 0) { p = mcf5272->rx_pbuf_a[rx_remove_sof]; // First in chain p->tot_len = p->len; // Important since len might have changed } else { pbuf_chain(p, mcf5272->rx_pbuf_a[rx_remove_sof]); pbuf_free(mcf5272->rx_pbuf_a[rx_remove_sof]); } /* Clear pointer to mark descriptor as free */ mcf5272->rx_pbuf_a[rx_remove_sof] = 0; mcf5272->rxbd_a[rx_remove_sof].p_buf = 0; if (rx_remove_sof != rx_remove_eof) INC_RX_BD_INDEX(rx_remove_sof); else break; } while (1); INC_RX_BD_INDEX(rx_remove_sof); /* Check error status of frame */ if (flags & (MCF5272_FEC_RX_BD_LG | MCF5272_FEC_RX_BD_NO | MCF5272_FEC_RX_BD_CR | MCF5272_FEC_RX_BD_OV)) { #ifdef LINK_STATS lwip_stats.link.drop++; if (flags & MCF5272_FEC_RX_BD_LG) lwip_stats.link.lenerr++; //Jumbo gram else if (flags & (MCF5272_FEC_RX_BD_NO | MCF5272_FEC_RX_BD_OV)) lwip_stats.link.err++; else if (flags & MCF5272_FEC_RX_BD_CR) lwip_stats.link.chkerr++; // CRC errors #endif /* Drop errored frame */ pbuf_free(p); } else { /* Good frame. increment stat */ #ifdef LINK_STATS lwip_stats.link.recv++; #endif eth_input(p, mcf5272->netif); } } INC_RX_BD_INDEX(rx_remove_eof); } mcf5272->rx_remove = rx_remove_sof; /* clear interrupt status for rx interrupt */ old_level = sys_arch_protect(); MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_EIR_RXF); value = MCF5272_RD_FEC_IMR(imm); /* Set rx interrupt bit again */ MCF5272_WR_FEC_IMR(imm, (value | MCF5272_FEC_IMR_RXFEN)); /* Now we can re-enable higher priority interrupts again */ sys_arch_unprotect(old_level); /* Fill up empty descriptor rings */ fill_rx_ring(mcf5272); /* Tell fec that we have filled up her ring */ MCF5272_WR_FEC_RDAR(imm, 1); return; }
static void process_rcvd_packets(void *arg_nif) { struct netif* netif = (struct netif*)arg_nif; struct nifce_info* nip = (struct nifce_info*)netif->state; unsigned int *mangle_ptr; void *handle = nip->handle; int int_sts; ADI_ETHER_BUFFER* buffers_to_reuse; ADI_ETHER_BUFFER* buffers_to_process; ADI_ETHER_BUFFER* recycle_list = 0; ADI_ETHER_BUFFER* bp; ADI_ETHER_BUFFER* nbp; ADI_ETHER_BUFFER* lbp; // now check for received buffers int_sts = ker_disable_interrupts(ker_kPriorityLevelAll); buffers_to_process = nip->rcv_list; nip->rcv_list = NULL; nip->rxmsg_processed =0; ker_enable_interrupts(int_sts); // create a pbuf for each received buffer and call eth_input to process it bp = buffers_to_process; while (bp != 0) { struct hw_eth_hdr* ethhdr = (struct hw_eth_hdr*)((char*)bp->Data+2); u16_t length = bp->ProcessedElementCount - 6; // 2 + 4crc byte to store length struct pbuf* p; int unpack_arp = 0; nbp = bp->pNext; bp->pNext = 0; // (char*)bp->Data + 2 contrain the actual data. if (Trace_Function) Trace_Function('R',length,((unsigned char *)bp->Data+2)); // see whether we need two extra u16_t fields for alignment if (length >= (sizeof(struct etharp_hdr) - 6) && htons(ethhdr->type) == ETHTYPE_ARP) { length += 4; // need fields unused2 and unused3 in struct etharp_hdr unpack_arp = 1; } length += 2;// for field unused1 in struct eth_hdr p = pbuf_alloc(PBUF_RAW, length, PBUF_RAM); if (p != NULL) { //u8_t* psrc = (u8_t*)bp->Data; u8_t* psrc = (u8_t*)bp->Data+2; u8_t* pdst = (u8_t*)p->payload; // set field unused1 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy in eth_hdr data memcpy(pdst, psrc, 14); pdst += 14; psrc += 14; if (unpack_arp) { // copy etharp frame into pbuf up to field unused2 memcpy(pdst, psrc, 14); pdst += 14; psrc += 14; // set field unused2 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy more of frame up to field unused3 memcpy(pdst, psrc, 10); pdst += 10; psrc += 10; // set field unused3 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy remainder of frame memcpy(pdst, psrc, 4); } else { // just copy the rest of the frame into the pbuf in one go memcpy(pdst, psrc, length - 16); } #ifdef LINK_STATS lwip_stats.link.recv++; #endif mangle_ptr = ((unsigned int*)&bp->Reserved)+4; // TODO: get-rid of Reserved. eth_input(p, ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->netif); } // p!=NULL else { #ifdef LINK_STATS lwip_stats.link.memerr++; // had to drop frame - no memory for pbuf #endif } mangle_ptr = ((unsigned int*)&bp->Reserved)+4; bp->ElementCount = ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->max_buf_len; bp->CallbackParameter = bp; bp->PayLoad =0; bp->StatusWord =0; bp->ProcessedElementCount=0; bp->ProcessedFlag =0; bp->pNext = recycle_list; recycle_list = bp; bp = nbp; } // while // return the buffers to the driver if (recycle_list != 0) adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)recycle_list); }
void mcf523xfec_rx_task( void *arg ) { mcf523xfec_if_t *fecif = arg; struct pbuf *p, *q; nbuf_t *pNBuf; uint8 *pPayLoad; do { sys_sem_wait( fecif->rx_sem ); while( nbuf_rx_next_ready( ) ) { pNBuf = nbuf_rx_allocate( ); if( pNBuf != NULL ) { LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->status & RX_BD_L ", pNBuf->status & RX_BD_L ); /* This flags indicate that the frame has been damaged. In * this case we must update the link stats if enabled and * remove the frame from the FEC. */ if( pNBuf->status & ( RX_BD_LG | RX_BD_NO | RX_BD_CR | RX_BD_OV ) ) { #ifdef LINK_STATS lwip_stats.link.drop++; if( pNBuf->status & RX_BD_LG ) { lwip_stats.link.lenerr++; } else if( pNBuf->status & ( RX_BD_NO | RX_BD_OV ) ) { lwip_stats.link.err++; } else { lwip_stats.link.chkerr++; } #endif } else { /* The frame must no be valid. Perform some checks to see if the FEC * driver is working correctly. */ LWIP_ASSERT( "mcf523xfec_rx_task: pNBuf->length != 0", pNBuf->length != 0 ); p = pbuf_alloc( PBUF_RAW, pNBuf->length, PBUF_POOL ); if( p != NULL ) { #if ETH_PAD_SIZE pbuf_header( p, -ETH_PAD_SIZE ); #endif pPayLoad = pNBuf->data; for( q = p; q != NULL; q = q->next ) { memcpy( q->payload, pPayLoad, q->len ); pPayLoad += q->len; } #if ETH_PAD_SIZE pbuf_header( p, ETH_PAD_SIZE ); #endif /* Ethernet frame received. Handling it is not device * dependent and therefore done in another function. */ eth_input( fecif->netif, p ); } } nbuf_rx_release( pNBuf ); /* Tell the HW that there are new free RX buffers. */ MCF_FEC_RDAR = 1; } else { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif } } /* Set RX Debug PIN to low since handling of next frame is possible. */ FEC_DEBUG_RX_TIMING( 0 ); } while( 1 ); }
/** * Ethernet rx task being called periodically by FreeRTOS * * @param MAC interface descriptor * @return none */ void MAC_Rx_Task(void *arg ) { mcf5xxxfec_if_t *fecif; struct pbuf *p, *q; nbuf_t *pNBuf; uint8 *pPayLoad; fecif = (mcf5xxxfec_if_t *)arg; do { sys_sem_wait( fecif->rx_sem ); while( NBUF_ReadyRX( ) ) { pNBuf = NBUF_AllocRX( ); if( pNBuf != NULL ) { /*FSL: removed to avoid get stuck if a BABR happens*/ //LWIP_ASSERT( "MAC_Rx_Task: pNBuf->status & RX_BD_L ", // pNBuf->status & RX_BD_L ); /* This flags indicate that the frame has been damaged. In * this case we must update the link stats if enabled and * remove the frame from the FEC. */ //if ( pNBuf->status & RX_ERROR_ALL_FLAGS ) // FIXME: turn off CRC checking for now... it is throwing error even when I manually check the received packet // as byte-for-byte correct if ( pNBuf->status & (RX_ERROR_ALL_FLAGS & ~RX_ERROR_CHKSM_FLAG) ) { #if LINK_STATS lwip_stats.link.drop++; if ( pNBuf->status & RX_ERROR_LENGTH_FLAG ) { lwip_stats.link.lenerr++; } else if ( pNBuf->status & RX_ERROR_CHKSM_FLAG ) { lwip_stats.link.chkerr++; } else { lwip_stats.link.err++; } #endif } else { /* The frame must now be valid. Perform some checks to see if the FEC * driver is working correctly. */ LWIP_ASSERT( "MAC_Rx_Task: pNBuf->length != 0", pNBuf->length != 0 ); p = pbuf_alloc( PBUF_RAW, pNBuf->length, PBUF_POOL ); if( p != NULL ) { #if ETH_PAD_SIZE pbuf_header( p, -ETH_PAD_SIZE ); #endif pPayLoad = pNBuf->data; for( q = p; q != NULL; q = q->next ) { memcpy( q->payload, pPayLoad, q->len ); pPayLoad += q->len; } #if ETH_PAD_SIZE pbuf_header( p, ETH_PAD_SIZE ); #endif /* Ethernet frame received. Handling it is not device * dependent and therefore done in another function. */ eth_input( fecif->netif, p ); } } /*release the buffer under any circumstance*/ /*now we can release buffer*/ NBUF_ReleaseRX( pNBuf ); /* Tell the HW that there are new free RX buffers. */ FEC_ReadyRX(); } else { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif } } /* Set RX Debug PIN to low since handling of next frame is possible. */ FEC_DEBUG_RX_TIMING( 0 ); } while( 1 ); }