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

📄 ctrl_rtl8019.c

📁 基于康草科技中一款SOPC开发板上的8019的以太网驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -