⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zlg_avalon_rtl8019.c

📁 周立功 SOPC嵌入式系统实验教程 网卡芯片驱动及其应用
💻 C
📖 第 1 页 / 共 2 页
字号:
    sys_sem_signal(dev->arp_semaphore);
    /* skip Ethernet header */
    pbuf_header(p, -(s16_t)sizeof(struct eth_hdr));
    /* pass to network layer */
    netif->input(p, netif);
    break;
      
    case ETHTYPE_ARP:
      /* 
      * pass p to ARP module  
      * 
      */
      sys_sem_wait(dev->arp_semaphore);
      etharp_arp_input(netif, (struct eth_addr *)&netif->hwaddr, p);
      sys_sem_signal(dev->arp_semaphore);
      break;
    default:
      pbuf_free(p);
      p = NULL;
      break;
  }
}
/*********************************************************************************************************
** Function name:		zlg_avalon_rtl8019_output
**
** Descriptions:    This function is called by the TCP/IP stack when an IP packet
**                  should be sent. It calls the function called low_level_output() to
**                  do the actual transmission of the packet.    
**
** input parameters:  netif -- a pointer to netif structure defined in netif.h
**                    pbuf  -- a pointer to a packet buffer
**                    ipaddr-- a pointer to IP address.
**							  
** Returned value:	  Error information 
**         
** Used global variables:	 None
** Calling modules:		     
**
** Created by:				Jing.Zhang
** Created Date:			2005/12/08
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static err_t
zlg_avalon_rtl8019_output(struct netif *netif, struct pbuf *p,
      struct ip_addr *ipaddr)
{
  err_t err;
  zlg_avalon_rtl8019_if* dev = (zlg_avalon_rtl8019_if*)netif->state;

  sys_sem_wait(dev->arp_semaphore);

  /* resolve hardware address, then send (or queue) packet */
   
  err = etharp_output(netif, ipaddr, p);
  sys_sem_signal(dev->arp_semaphore);

  return err;
}

/*********************************************************************************************************
** Function name:	    zlg_avalon_rtl8019_rx
**
** Descriptions:		Handle all the receives
**
** input parameters:	dev-- a pointer to lwip device
**                      	
**		               				
** Returned value:		none 
**         
** Used global variables:	None
** Calling modules:		
**
** Created by:				Jing.Zhang
** Created Date:			2005/12/08
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:  
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

void zlg_avalon_rtl8019_rx(alt_lwip_dev* dev )
{
  zlg_avalon_rtl8019_if *lan_dev = (zlg_avalon_rtl8019_if *)dev->netif->state;
  
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("lan91c111_rx()"));

  zlg_avalon_rtl8019_input(lan_dev);
  
  /* Re-enable RX interrupts */
  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(lan_dev->irq_pio_base, 0);
  IOWR_ALTERA_AVALON_PIO_IRQ_MASK(lan_dev->irq_pio_base, 1);
  SelectPage(lan_dev->base_addr,0);
  SET_IMR_REG(lan_dev->base_addr,0x11);
}

/*********************************************************************************************************
** Function name:	    low_level_input
**
** Descriptions:	Should allocate a pbuf and transfer the bytes of the incoming
**                  packet from the interface into the pbuf.
**
** input parameters:	dev -- a pointer to a rtl8019 device structure
**		               				
** Returned value:		error information 
**         
** Used global variables:	None
** Calling modules:		
**
** Created by:				Jing.Zhang
** Created Date:			2005/12/08
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

static struct pbuf*
low_level_input(zlg_avalon_rtl8019_if *dev)
{
  struct pbuf *p=NULL;
  alt_u32 i,num;
  alt_u16 header[2];
  alt_u16 *pdata16;
  alt_u8 bnry,curr;

  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_input()\n"));
  /*
  * protect hardware output with a semaphore
  */
  sys_sem_wait(dev->semaphore);

  /* Get Boundary    */
  SelectPage(dev->base_addr,0);
  bnry = GET_BNRY_REG(dev->base_addr);
  /* Get current page  */
  SelectPage(dev->base_addr,1);
  curr = GET_CURR_REG(dev->base_addr);
  if(0 == curr) /* errors occur in the process of reading CURR */
  {
	  goto exit;
  }
  if(++bnry>0x7f) /* Guarantee the bnry in the receive buffer ring */
  {
	  bnry = 0x4c;
  }
  
  
  /* Check if there is any new coming packet  */
  if(bnry!=curr)
  {
	  SelectPage(dev->base_addr,0);
	  SET_RSAR0_REG(dev->base_addr,0x00);
	  SET_RSAR1_REG(dev->base_addr,bnry);
	  SET_RBCR0_REG(dev->base_addr,4);
	  SET_RBCR1_REG(dev->base_addr,0x00);
    SET_CR_REG(dev->base_addr,0x0a); //Start Remote Read
      
	  /* Get the header information of a packet    */
	  /* Status and the pointer to the next packet in the header[0] */
	  /* the length of the packet in the header[1] */
	  header[0] = READ_DATA(dev->base_addr,0x10);
    header[1] = READ_DATA(dev->base_addr,0x10);

    SET_RBCR0_REG(dev->base_addr,0x00);
	  SET_RBCR1_REG(dev->base_addr,0x00);
    SET_CR_REG(dev->base_addr,0x22); //Stop Remote Read
    SET_ISR_REG(dev->base_addr,0x40);
	  /* Discard the CRC  */
	  header[1] = header[1] - 4;

	  /* Check the information of the packet */
	  if(((header[0]&0x0001) == 0)||((header[0]&0xff00)>0x7f00) 
		  ||((header[0]&0xff00)<0x4c00)||(header[1]>0x600))
	  {
		  /*  Errors occur in the received packet  */
		  SelectPage(dev->base_addr,1);
		  curr = GET_CURR_REG(dev->base_addr);
		  SelectPage(dev->base_addr,0);
		  bnry = curr -1;  //restore the value of bnry
		  if(bnry < 0x4c)  
		  {
			  bnry = 0x7f; 
		  }
		  SET_BNRY_REG(dev->base_addr,bnry); //restore the bnry register
		  goto exit; 
	  }//end of if(((header[0]&0x0001) == 0)||....
	  else
	  {
		  //the packet is ok, read the rest of data packet
		  SelectPage(dev->base_addr,0);
		  SET_RSAR0_REG(dev->base_addr,4); //Discard the header of the packet
		  SET_RSAR1_REG(dev->base_addr,bnry);
		  SET_RBCR0_REG(dev->base_addr,header[1]&0x00ff);
		  SET_RBCR1_REG(dev->base_addr,header[1]>>8);
		  SET_CR_REG(dev->base_addr,0x0a);  //Set and Start DMA read operation
#ifdef ALT_DEBUG     
      printf("bnry is %d\ncurr is %d\n",bnry,curr);
#endif
		  /* allocate packet buffer to hold the received data packet  */
		  p = pbuf_alloc(PBUF_RAW, header[1], PBUF_POOL);

		  if(NULL == p)
			  goto exit;  /* Fail to allocate memory, goto the error handler */
		  else
		  {
			  /* succeed to get the packet buffer, then read the received data packet*/
        num = (header[1]+1)>>1; /* recalculate the count of data for 16-bit buf */
        pdata16 = (alt_u16 *)p->payload; /* get the data buffer                */
			  for(i=0; i<num; i++)
				  *(pdata16++) = READ_DATA(dev->base_addr,0x10);				  
		  }

		  /* Stop the DMA operation */
		  SET_RBCR0_REG(dev->base_addr,0x00);
	    SET_RBCR1_REG(dev->base_addr,0x00);
      SET_CR_REG(dev->base_addr,0x22); //Stop Remote Read		
      SET_ISR_REG(dev->base_addr,0x40);  
	  }// end of else
      
	  /* adjust bnry register */
	  bnry=(header[0]>>8)-1;	
	  if(bnry<0x4c)
		  bnry=0x7f;
	  SET_BNRY_REG(dev->base_addr,bnry); //restore the bnry register
	  
	  
#if LINK_STATS
      lwip_stats.link.recv++;
#endif /* LINK_STATS */      
    } 
    else 
    {
#if LINK_STATS
      lwip_stats.link.memerr++;
      lwip_stats.link.drop++;
#endif /* LINK_STATS */      
    }
 
  /* Just get rid of the packet */
exit:

  sys_sem_signal(dev->semaphore);
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_input (exits p =%#x)\n", p));
  return p;  
}


/*********************************************************************************************************
** Function name:	    low_level_output
**
** Descriptions:		do the actual transmission of the packet. The packet is
**                      contained in the pbuf that is passed to the function. This pbuf
**                      might be chained..
**
** input parameters:	dev -- a pointer to a rtl8019 device structure
**		               				
** Returned value:		error information 
**         
** Used global variables:	None
** Calling modules:		
**
** Created by:				Jing.Zhang
** Created Date:			2005/11/08
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
  static alt_u32 Tx_Buf_Sel = 0; 
  err_t err = ERR_OK;
  struct pbuf *q;
  int i,num;
  alt_u16* pdata16;
  zlg_avalon_rtl8019_if *dev = netif->state;

  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_output ( %#x)\n",p));

  /*****  Protect hardware output with a semaphore  *****/
  
  sys_sem_wait(dev->semaphore);
  
  /*****  Select transmit buffer  ***********************/
  Tx_Buf_Sel = Tx_Buf_Sel^1;
  if(Tx_Buf_Sel)
  {
	  SET_RSAR1_REG(dev->base_addr,0x40);   //Set higher address
  }
  else
  {
	  SET_RSAR1_REG(dev->base_addr,0x46);
  }
  SET_RSAR0_REG(dev->base_addr,0x00);      //Set lower address
  
  /*****  Set transmit count    ***********************/
  SET_RBCR0_REG(dev->base_addr,p->tot_len&0x00ff);
  SET_RBCR1_REG(dev->base_addr,p->tot_len>>8);
  SET_CR_REG(dev->base_addr,0x12); //Start Remote Write

  /*****  Write Data buffer    ***********************/
  for(q = p; q != NULL; q = q->next) 
  {
	  num = (q->len +1)>>1;  /*  recalculate the number of data  */
      pdata16 = (alt_u16 *)q->payload;
	  for (i=0; i<num; i++)
		  WRITE_DATA(dev->base_addr,0x10,*(pdata16++));    
  }
  
  /*****  Stop DMA Command    ***********************/
  SET_RBCR0_REG(dev->base_addr,0x00);
  SET_RBCR1_REG(dev->base_addr,0x00);
  SET_CR_REG(dev->base_addr,0x22); 
  SET_ISR_REG(dev->base_addr,0x40);

  /*****  Set Transmit Page Start Register    ******/
  if(Tx_Buf_Sel)
  {
	  SET_TPSR_REG(dev->base_addr,0x40);
  }
  else
  {
	  SET_TPSR_REG(dev->base_addr,0x46);
  }

  /*** Compensate data payload lower than 60 bytes **/
  if(p->tot_len<60)
  {
	  SET_TBCR0_REG(dev->base_addr,60);
    SET_TBCR1_REG(dev->base_addr,0x00);
  }
  else
  {  
	  SET_TBCR0_REG(dev->base_addr,p->tot_len&0x00ff);
    SET_TBCR1_REG(dev->base_addr,p->tot_len>>8);
  }

  SET_CR_REG(dev->base_addr,0x3e);  //Issue Send packet command
  
  /* Wait for send packet command to complete */
  for(i=0; i<6; i++)
  {
	  while(GET_CR_REG(dev->base_addr)&ZLG_8019AS_CR_TXP_MSK);
	  if(GET_TSR_REG(dev->base_addr)&ZLG_8019AS_TSR_PTX_MSK)
		  break;
	  else
		  SET_CR_REG(dev->base_addr,0x3e);  //Send packet again
  }

  /*** Fail to Send packet *****/
  if(6 == i)
	  err = ERR_IF;

  sys_sem_signal(dev->semaphore);
#ifdef ALT_DEBUG   
  printf("Tx_Buf_Sel is %d \n",Tx_Buf_Sel);
#endif

#if LINK_STATS
  lwip_stats.link.xmit++;
#endif /* LINK_STATS */      
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_ouptput () return OK\n"));


  return err;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -