Beispiel #1
0
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);
}
Beispiel #2
0
/* 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;
			}
		}
	}
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
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
}
Beispiel #4
0
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;
      }
    }
  }
}
Beispiel #5
0
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(&eth_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;
			}
		}
	}
}
Beispiel #7
0
/*-----------------------------------------------------------------------------------*/
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;
}
Beispiel #8
0
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);

}
Beispiel #9
0
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 );
}
Beispiel #10
0
/**
 * 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 );
}