📄 ctrl_rtl8019.c
字号:
IOWR_CTRL_RTL8019_9346CR(dev->base_addr, 0);
OSTimeDlyHMSM(0,0,1,0);
/*
* Switch to register page 0 and set data configuration register
* to byte-wide DMA transfers, normal operation (no loopback),
* send command not executed and 8 byte fifo threshold.
*/
IOWR_CTRL_RTL8019_CR(dev->base_addr,CTRL_RTL8019_CR_STP_MSK | CTRL_RTL8019_CR_RD2_MSK);
IOWR_CTRL_RTL8019_DCR(dev->base_addr,CTRL_RTL8019_DCR_LS_MSK | CTRL_RTL8019_DCR_FT1_MSK);
/*
* Clear remote dma byte count register.
*/
IOWR_CTRL_RTL8019_RBCR0(dev->base_addr,0);
IOWR_CTRL_RTL8019_RBCR1(dev->base_addr,0);
/*
* Temporarily set receiver to monitor mode and transmitter to
* internal loopback mode. Incoming packets will not be stored
* in the nic ring buffer and no data will be send to the network.
*/
IOWR_CTRL_RTL8019_RCR(dev->base_addr,CTRL_RTL8019_RCR_MON_MSK);
IOWR_CTRL_RTL8019_TCR(dev->base_addr,CTRL_RTL8019_TCR_LB0_MSK);
/*
* Configure the nic's ring buffer page layout.
* NIC_PG0_BNRY: Last page read.
* NIC_PG0_PSTART: First page of receiver buffer.
* NIC_PG0_PSTOP: Last page of receiver buffer.
*/
IOWR_CTRL_RTL8019_TPSR(dev->base_addr,NIC_FIRST_TX_PAGE);
IOWR_CTRL_RTL8019_BNRY(dev->base_addr,NIC_STOP_PAGE - 1);
uc=NIC_FIRST_RX_PAGE;
IOWR_CTRL_RTL8019_PSTART(dev->base_addr,uc);
uc=NIC_STOP_PAGE;
IOWR_CTRL_RTL8019_PSTOP(dev->base_addr, uc);
/*
* Once again clear interrupt status register.
*/
IOWR_CTRL_RTL8019_ISR(dev->base_addr,0xff);
/*
* Read the MAC address out of flash
*/
ret_code = get_mac_addr(lwip_dev);
if (ret_code != ERR_OK)
{
goto exit;
}
/*
* Switch to register page 1 and copy our MAC address into the nic.
* We are still in stop mode.
*/
IOWR_CTRL_RTL8019_CR(dev->base_addr,CTRL_RTL8019_CR_STP_MSK | CTRL_RTL8019_CR_RD2_MSK | CTRL_RTL8019_CR_PS0_MSK);
IOWR_CTRL_RTL8019_PAR0(dev->base_addr,lwip_dev->netif->hwaddr[0]);
IOWR_CTRL_RTL8019_PAR1(dev->base_addr,lwip_dev->netif->hwaddr[1]);
IOWR_CTRL_RTL8019_PAR2(dev->base_addr,lwip_dev->netif->hwaddr[2]);
IOWR_CTRL_RTL8019_PAR3(dev->base_addr,lwip_dev->netif->hwaddr[3]);
IOWR_CTRL_RTL8019_PAR4(dev->base_addr,lwip_dev->netif->hwaddr[4]);
IOWR_CTRL_RTL8019_PAR5(dev->base_addr,lwip_dev->netif->hwaddr[5]);
/*
* Clear multicast filter bits to disable all packets.
*/
IOWR_CTRL_RTL8019_MAR0(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR1(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR2(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR3(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR4(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR5(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR6(dev->base_addr,0);
IOWR_CTRL_RTL8019_MAR7(dev->base_addr,0);
/*
* Set current page pointer to one page after the boundary pointer.
*/
IOWR_CTRL_RTL8019_CURR(dev->base_addr,NIC_FIRST_RX_PAGE);
/*
* Switch back to register page 0, remaining in stop mode.
*/
IOWR_CTRL_RTL8019_CR(dev->base_addr,CTRL_RTL8019_CR_STP_MSK | CTRL_RTL8019_CR_RD2_MSK);
/*
* Take receiver out of monitor mode and enable it for accepting
* broadcasts.
*/
IOWR_CTRL_RTL8019_RCR(dev->base_addr, CTRL_RTL8019_RCR_AB_MSK);
/*
* Clear all interrupt status flags and enable interrupts.
*/
IOWR_CTRL_RTL8019_ISR(dev->base_addr,0xff);
/* 2005/12/12 LJS IMR SETUP */
/*
* Fire up the nic by clearing the stop bit and setting the start bit.
* To activate the local receive dma we must also take the nic out of
* the local loopback mode.
*/
IOWR_CTRL_RTL8019_CR(dev->base_addr,CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK);
IOWR_CTRL_RTL8019_TCR(dev->base_addr,0);
OSTimeDlyHMSM(0,0,1,0);
/* maximum transfer unit */
dev->lwip_dev_list.dev.netif->mtu = 1500;
/* broadcast capability */
dev->lwip_dev_list.dev.netif->flags = NETIF_FLAG_BROADCAST;
dev->semaphore = sys_sem_new(1);
if (dev->semaphore == NULL)
{
ret_code = ERR_MEM;
goto exit;
}
dev->arp_semaphore = sys_sem_new(1);
if (dev->arp_semaphore == NULL)
{
ret_code = ERR_MEM;
goto exit;
}
if (alt_irq_register ( dev->irq, dev,
ctrl_rtl8019_irq))
{
ret_code = ERR_IF;
goto exit;
}
/* Note: transmitter if polled, thus no NIC_IMR_PTXE */
IOWR_CTRL_RTL8019_IMR(dev->base_addr,CTRL_RTL8019_IMR_PRXE_MSK | CTRL_RTL8019_IMR_RXEE_MSK | CTRL_RTL8019_IMR_TXEE_MSK | CTRL_RTL8019_IMR_OVWE_MSK);
exit:
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_init() exit = %d\n", ret_code));
getState(0);
return ret_code;
}
/*!
* Complete remote DMA.
*/
static void NicCompleteDma(unsigned int addr)
{
u_char i;
/*
* Complete remote dma.
*/
IOWR_CTRL_RTL8019_CR(addr,CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK);
/*
* Check that we have a DMA complete flag.
*/
for (i = 0; i <= 20; i++)
if (IORD_CTRL_RTL8019_ISR(addr) & CTRL_RTL8019_ISR_RDC_MSK)
break;
/*
* Reset remote dma complete flag.
*/
IOWR_CTRL_RTL8019_ISR(addr,CTRL_RTL8019_ISR_RDC_MSK);
}
/*
* Write data block to the NIC.
*/
static void NicWrite(unsigned int addr,u_char * buf, u_short len)
{
register u_short l = len - 1;
register u_char ih = (u_short) l >> 8;
register u_char il = (u_char) l;
if (!len)
return;
do {
do {
IOWR_CTRL_RTL8019_DATA(addr,*buf++);
} while (il-- != 0);
} while (ih-- != 0);
}
/*
* Read data block from the NIC.
*/
static void NicRead(unsigned int addr,u_char * buf, u_short len)
{
register u_short l = len - 1;
register u_char ih = (u_short) l >> 8;
register u_char il = (u_char) l;
if (!len)
return;
do {
do {
*buf++ = IORD_CTRL_RTL8019_DATA(addr);
} while (il-- != 0);
} while (ih-- != 0);
}
/*
* ctrl_rtl8019_rx
* Handle all the receives
*/
void ctrl_rtl8019_rx( alt_lwip_dev* dev )
{
alt_u8 isr;
ctrl_rtl8019_if *lan_dev = (ctrl_rtl8019_if *)dev->netif->state;
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("rtl8019_rx()"));
/* 2005\12\11 LJS MODIFY in this function the isr PRX is set,don't check the isr*/
/*
IOWR_CTRL_RTL8019_CR(lan_dev->base_addr,CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK);
isr=IORD_CTRL_RTL8019_ISR(lan_dev->base_addr);
while(isr & CTRL_RTL8019_ISR_PRX_MSK)
{
ctrl_rtl8019_input(lan_dev);
IOWR_CTRL_RTL8019_CR(lan_dev->base_addr,CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK);
isr=IORD_CTRL_RTL8019_ISR(lan_dev->base_addr);
}
*/
ctrl_rtl8019_input(lan_dev);
/* Re-enable RX interrupts */
IOWR_CTRL_RTL8019_IMR(lan_dev->base_addr,CTRL_RTL8019_IMR_PRXE_MSK | CTRL_RTL8019_IMR_RXEE_MSK | CTRL_RTL8019_IMR_TXEE_MSK | CTRL_RTL8019_IMR_OVWE_MSK);
}
/*!
* \brief Fetch the next packet out of the receive ring buffer.
*
* Nic interrupts must be disabled when calling this funtion.
*/
/*-----------------------------------------------------------------------------------*
*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*
*-----------------------------------------------------------------------------------*/
static struct pbuf*
low_level_input(ctrl_rtl8019_if *dev)
{
struct pbuf *p=NULL, *q;
struct nic_pkt_header hdr;
u_short count;
u_char *buf;
u_char nextpg;
u_char bnry;
u_char curr;
u_short i;
u_char drop = 0;
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_input()\n"));
/* we don't want to be interrupted by NIC owerflow */
//irq_context=alt_irq_disable_all();
/*
* Get the current page pointer. It points to the page where the NIC
* will start saving the next incoming packet.
*/
IOWR_CTRL_RTL8019_CR(dev->base_addr, CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK | CTRL_RTL8019_CR_PS0_MSK);
Delay16Cycles();
curr = IORD_CTRL_RTL8019_CURR(dev->base_addr);
IOWR_CTRL_RTL8019_CR(dev->base_addr, CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD2_MSK);
/*
* Get the pointer to the last page we read from. The following page
* is the one where we start reading. If it's equal to the current
* page pointer, then there's nothing to read. In this case we return
* a null pointer.
*/
if ((bnry = IORD_CTRL_RTL8019_BNRY(dev->base_addr) + 1) >= NIC_STOP_PAGE)
bnry = NIC_FIRST_RX_PAGE;
if (bnry == curr) {
//alt_irq_enable_all(irq_context);
return 0;
}
/*
* Read the NIC specific packet header.
*/
IOWR_CTRL_RTL8019_RBCR0(dev->base_addr,4);
IOWR_CTRL_RTL8019_RBCR1(dev->base_addr,0);
IOWR_CTRL_RTL8019_RSAR0(dev->base_addr,0);
IOWR_CTRL_RTL8019_RSAR1(dev->base_addr,bnry);
buf = (u_char *) & hdr;
IOWR_CTRL_RTL8019_CR(dev->base_addr,CTRL_RTL8019_CR_STA_MSK | CTRL_RTL8019_CR_RD0_MSK);
Delay16Cycles();
for (i = 0; i < sizeof(struct nic_pkt_header); i++)
{
*buf=IORD_CTRL_RTL8019_DATA(dev->base_addr);
buf++;
}
NicCompleteDma(dev->base_addr);
/*
* Check packet length. Silently discard packets of illegal size.
*/
if (hdr.ph_size < 60 + sizeof(struct nic_pkt_header) || /* */
hdr.ph_size > 1514 + sizeof(struct nic_pkt_header)) {
drop = 1;
}
/*
* Calculate the page of the next packet. If it differs from the
* pointer in the packet header, we return with errorcode.
*/
nextpg = bnry + (hdr.ph_size >> 8) + ((hdr.ph_size & 0xFF) != 0);
if (nextpg >= NIC_STOP_PAGE) {
nextpg -= NIC_STOP_PAGE;
nextpg += NIC_FIRST_RX_PAGE;
}
if (nextpg != hdr.ph_nextpg) {
u_char nextpg1 = nextpg + 1;
if (nextpg1 >= NIC_STOP_PAGE) {
nextpg1 -= NIC_STOP_PAGE;
nextpg1 += NIC_FIRST_RX_PAGE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -