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

📄 redlogic_rtl8019.c

📁 RT8019网络控制器在FPGA中的驱动设计
💻 C
📖 第 1 页 / 共 2 页
字号:
        return;
    do {
        do {
            IOWR_REDLOGIC_RTL8019_DATA(addr,*buf++);
        } while (il-- != 0);
    } while (ih-- != 0);
}
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_REDLOGIC_RTL8019_DATA(addr);
        } while (il-- != 0);
    } while (ih-- != 0);
}
void redlogic_rtl8019_rx(  alt_lwip_dev* dev )
{
    alt_u8  isr;
    redlogic_rtl8019_if *lan_dev = (redlogic_rtl8019_if *)dev->netif->state;  
    LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("rtl8019_rx()"));
    IOWR_REDLOGIC_RTL8019_CR(lan_dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    isr=IORD_REDLOGIC_RTL8019_ISR(lan_dev->base_addr);
    while(isr & REDLOGIC_RTL8019_ISR_PRX_MSK)
    {
        redlogic_rtl8019_input(lan_dev);
        IOWR_REDLOGIC_RTL8019_CR(lan_dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    	isr=IORD_REDLOGIC_RTL8019_ISR(lan_dev->base_addr);
    }
    IOWR_REDLOGIC_RTL8019_IMR(lan_dev->base_addr,REDLOGIC_RTL8019_IMR_PRXE_MSK | REDLOGIC_RTL8019_IMR_RXEE_MSK | REDLOGIC_RTL8019_IMR_TXEE_MSK | REDLOGIC_RTL8019_IMR_OVWE_MSK);
}
static struct pbuf*
low_level_input(redlogic_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"));
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr, REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK);
    Delay16Cycles();
    curr = IORD_REDLOGIC_RTL8019_CURR(dev->base_addr);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr, REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    if ((bnry = IORD_REDLOGIC_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;
    }
    IOWR_REDLOGIC_RTL8019_RBCR0(dev->base_addr,4);
    IOWR_REDLOGIC_RTL8019_RBCR1(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RSAR0(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RSAR1(dev->base_addr,bnry);
    buf = (u_char *) & hdr;
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD0_MSK);
    Delay16Cycles();
    for (i = 0; i < sizeof(struct nic_pkt_header); i++)
    {
        *buf=IORD_REDLOGIC_RTL8019_DATA(dev->base_addr);
        buf++;
    }
    NicCompleteDma(dev->base_addr);
    if (hdr.ph_size < 60 + sizeof(struct nic_pkt_header) ||     
        hdr.ph_size > 1514 + sizeof(struct nic_pkt_header)) {
        drop = 1;
    }
    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;
        }
        if (nextpg1 != hdr.ph_nextpg) {
            return NULL;
        }
        nextpg = nextpg1;
    }
    if (!drop && ((hdr.ph_status & 0x0E) == 0)) {
        count = hdr.ph_size - 4;
    	p = pbuf_alloc(PBUF_RAW, count, PBUF_POOL);
        if (p != NULL ) {
            IOWR_REDLOGIC_RTL8019_RBCR0(dev->base_addr,count);
            IOWR_REDLOGIC_RTL8019_RBCR1(dev->base_addr,count >> 8);
            IOWR_REDLOGIC_RTL8019_RSAR0(dev->base_addr,sizeof(struct nic_pkt_header));
            IOWR_REDLOGIC_RTL8019_RSAR1(dev->base_addr,bnry);
            IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD0_MSK);
            Delay16Cycles();
            for(q = p; q != NULL; q = q->next) 
      	    {
            	NicRead(dev->base_addr,q->payload, q->len);
            }
            NicCompleteDma(dev->base_addr);
        }
    }
    if (--nextpg < NIC_FIRST_RX_PAGE)
        nextpg = NIC_STOP_PAGE - 1;
    IOWR_REDLOGIC_RTL8019_BNRY(dev->base_addr,nextpg);
      
    return p;
}
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
    struct pbuf *q;
    redlogic_rtl8019_if *dev = netif->state;
    u_short i;
    u_char padding = 0;
    unsigned short int size;
    LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_output ( %#x)\n",p));
    
    size=0;
    for(q = p; q != NULL; q = q->next) 
    {
        size+=q->len;
    }
    if (size > 1514)
        return -1;
    if (size < 60) {
        padding = (u_char) (60 - p->tot_len);
        size = 60;
    }
    IOWR_REDLOGIC_RTL8019_RBCR0(dev->base_addr, size);
    IOWR_REDLOGIC_RTL8019_RBCR1(dev->base_addr, size >> 8);
    IOWR_REDLOGIC_RTL8019_RSAR0(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RSAR1(dev->base_addr,NIC_FIRST_TX_PAGE);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr, REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD1_MSK);
    for(q = p; q != NULL; q = q->next) 
    {
        NicWrite(dev->base_addr,q->payload, q->len);
    }
    for (i = 0; i < padding; i++)
        IOWR_REDLOGIC_RTL8019_DATA(dev->base_addr,0);
    NicCompleteDma(dev->base_addr);
    IOWR_REDLOGIC_RTL8019_TBCR0(dev->base_addr,(size & 0xff));
    IOWR_REDLOGIC_RTL8019_TBCR1(dev->base_addr,((size >> 8) & 0xff));
    IOWR_REDLOGIC_RTL8019_TPSR(dev->base_addr,NIC_FIRST_TX_PAGE);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_TXP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_ouptput () return OK\n"));
    return 0;
}
u_char NicOverflow(redlogic_rtl8019_if *dev)
{
    u_char cr;
    u_char resend = 0;
    u_char curr;
    while (IORD_REDLOGIC_RTL8019_CR(dev->base_addr) & REDLOGIC_RTL8019_CR_TXP_MSK);
    cr = IORD_REDLOGIC_RTL8019_CR(dev->base_addr);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK);
    curr = IORD_REDLOGIC_RTL8019_CURR(dev->base_addr);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    IOWR_REDLOGIC_RTL8019_RBCR0(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RBCR1(dev->base_addr,0);
    if ((cr & REDLOGIC_RTL8019_CR_TXP_MSK) && ((IORD_REDLOGIC_RTL8019_ISR(dev->base_addr) & (REDLOGIC_RTL8019_ISR_PTX_MSK | REDLOGIC_RTL8019_ISR_TXE_MSK)) == 0))
    {
        resend = 1;
    }
    IOWR_REDLOGIC_RTL8019_TCR(dev->base_addr,REDLOGIC_RTL8019_TCR_LB0_MSK);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    if (--curr < NIC_FIRST_RX_PAGE) {
        curr = NIC_STOP_PAGE - 1;
    }
    IOWR_REDLOGIC_RTL8019_BNRY(dev->base_addr,curr);
    IOWR_REDLOGIC_RTL8019_TCR(dev->base_addr,0);
    if (resend) {
        IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_TXP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    }
    IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,REDLOGIC_RTL8019_ISR_OVW_MSK);
    return resend;
}
void redlogic_rtl8019_irq(void* context, alt_u32 interrupt)
{
    u_char isr;
    
    int rx_frame_errors;
    int rx_crc_errors;
    int rx_missed_errors;
    redlogic_rtl8019_if *dev =  (redlogic_rtl8019_if *)context;
    
    isr = IORD_REDLOGIC_RTL8019_ISR(dev->base_addr);
    IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,isr);
    if (isr & REDLOGIC_RTL8019_ISR_OVW_MSK) {
        NicOverflow(dev);
    } else {
        if (isr & REDLOGIC_RTL8019_ISR_TXE_MSK);
        if (isr & REDLOGIC_RTL8019_ISR_PRX_MSK){
        	sys_mbox_post(rx_mbox, &dev->lwip_dev_list.dev);
        }
        if (isr & REDLOGIC_RTL8019_ISR_RXE_MSK) {
            rx_frame_errors += IORD_REDLOGIC_RTL8019_CNTR0(dev->base_addr);
            rx_crc_errors += IORD_REDLOGIC_RTL8019_CNTR1(dev->base_addr);
            rx_missed_errors += IORD_REDLOGIC_RTL8019_CNTR2(dev->base_addr);
        }
    }
}
static err_t
redlogic_rtl8019_output(struct netif *netif, struct pbuf *p,
      struct ip_addr *ipaddr)
{
  err_t err;
  redlogic_rtl8019_if* dev = (redlogic_rtl8019_if*)netif->state;

  sys_sem_wait(dev->arp_semaphore);
  err = etharp_output(netif, ipaddr, p);
  sys_sem_signal(dev->arp_semaphore);
  return err;
}
#endif

⌨️ 快捷键说明

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