📄 zlg_avalon_rtl8019.c
字号:
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 + -