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

📄 redlogic_rtl8019.c

📁 RT8019网络控制器在FPGA中的驱动设计
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef LWIP
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <altera_avalon_pio_regs.h>
#include "alt_types.h"
#include "redlogic_rtl8019_regs.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "netif/etharp.h"
#include "system.h"
#include "arch/perf.h"
#include "sys/alt_irq.h"
#include "redlogic_rtl8019.h"
#define IFNAME0 'n'
#define IFNAME1 '9'
extern sys_mbox_t  rx_mbox;
static err_t
redlogic_rtl8019_output(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr);
static struct pbuf* low_level_input(redlogic_rtl8019_if *dev);
static err_t low_level_output(struct netif *netif, struct pbuf *p);
static err_t low_level_init(redlogic_rtl8019_if* dev);
void redlogic_rtl8019_irq(void* context, alt_u32 interrupt);
static inline void Delay16Cycles(void)
{
    unsigned int i;
    for(i=0;i<100;i++);
}
u_char reg_read(unsigned int base,u_char reg)
{
  unsigned char uc;  
  uc=IORD_8DIRECT(base, reg); 
  return uc;  
} 
u_char reg_write(base,reg, data)
{ 
  IOWR_8DIRECT(base, reg, data);
  return data;
}
void getState(unsigned char *RTL_BASE_ADDR)
{
  unsigned char old_cr,uc;
  unsigned char tsr,isr,rsr;
  unsigned char rcr,tcr,dcr,imr;
  unsigned char  pstart,pstop;
  int iRet;
  old_cr=IORD_REDLOGIC_RTL8019_CR(0x00800000);
  IOWR_REDLOGIC_RTL8019_CR(0x00800000,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK );
  tsr=IORD_REDLOGIC_RTL8019_TSR(0x00800000);
  isr=IORD_REDLOGIC_RTL8019_ISR(0x00800000);
  rsr=IORD_REDLOGIC_RTL8019_RSR(0x00800000);
  IOWR_REDLOGIC_RTL8019_CR(0x00800000, REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK |  REDLOGIC_RTL8019_CR_PS1_MSK); 
  pstop=IORD_REDLOGIC_RTL8019_PSTOP(0x00800000);
  pstart=IORD_REDLOGIC_RTL8019_PSTART(0x00800000);
  rcr=IORD_REDLOGIC_RTL8019_RCR(0x00800000);
  tcr=IORD_REDLOGIC_RTL8019_TCR(0x00800000);
  dcr=IORD_REDLOGIC_RTL8019_DCR(0x00800000);
  imr=IORD_REDLOGIC_RTL8019_IMR(0x00800000);
  IOWR_REDLOGIC_RTL8019_CR(0x00800000,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK);   
  uc=IORD_REDLOGIC_RTL8019_PAR0(0x00800000);
  uc=IORD_REDLOGIC_RTL8019_PAR1(0x00800000);
  uc=IORD_REDLOGIC_RTL8019_PAR2(0x00800000);
  uc=IORD_REDLOGIC_RTL8019_PAR3(0x00800000);
  uc=IORD_REDLOGIC_RTL8019_PAR4(0x00800000);
  uc=IORD_REDLOGIC_RTL8019_PAR5(0x00800000);  
  IOWR_REDLOGIC_RTL8019_CR(0x00800000,old_cr); 
}
int rtl8019_Reset(redlogic_rtl8019_if* dev)
{
    unsigned char  i;
    unsigned char  j;
    for (j = 0; j < 20; j++) {
        IOWR_ALTERA_AVALON_PIO_DATA(E_RST_BASE,0x01); 
        OSTimeDlyHMSM(0,0,1,0);
        IOWR_ALTERA_AVALON_PIO_DATA(E_RST_BASE,0x00); 
        for (i = 0; i < 20; i++) {
            OSTimeDlyHMSM(0,0,1,0);
            i=IORD_REDLOGIC_RTL8019_ISR(dev->base_addr);
            if ((i & REDLOGIC_RTL8019_ISR_RST_MSK ) != 0 )
                return 0;    
            i=IORD_REDLOGIC_RTL8019_8019ID0(dev->base_addr); 
            if ( i == 0x50 )
                return 0;
            i= IORD_REDLOGIC_RTL8019_8019ID1(dev->base_addr);
            if( i == 0x70)
                return 0; 
        }
    }
    return -1;
}
static void redlogic_rtl8019_input(redlogic_rtl8019_if *dev)
{
  struct eth_hdr  *ethhdr;
  struct pbuf     *p;
  struct netif*   netif = dev->lwip_dev_list.dev.netif;
  p = low_level_input(dev);
  if (p == NULL) return;
  ethhdr = p->payload;
  switch (htons(ethhdr->type)) {
  case ETHTYPE_IP:
    sys_sem_wait(dev->arp_semaphore);
    etharp_ip_input(netif, p);
    sys_sem_signal(dev->arp_semaphore);
    pbuf_header(p, -(s16_t)sizeof(struct eth_hdr));
    netif->input(p, netif);
    break;      
    case ETHTYPE_ARP:
      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;
  }
}
err_t redlogic_rtl8019_init(struct netif *netif)
{
  err_t ret_code;
  redlogic_rtl8019_if* dev = (redlogic_rtl8019_if*)netif->state;
  dev->lwip_dev_list.dev.netif = netif;

  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("redlogic_rtl8019_init()\n"));
  netif->name[0] = IFNAME0;
  netif->name[1] = IFNAME1;
  netif->output = redlogic_rtl8019_output;
  netif->linkoutput = low_level_output;
  if (netif->state == NULL ) 
  {
    ret_code = ERR_IF;
    goto exit;
  }
  if (dev->bus_width != 8)
  {
    printf("This driver doesn't support the Ethernet add on card at present\n");
    ret_code = ERR_IF;
    goto exit;
  }
  ret_code = low_level_init(dev);
  if (ret_code == ERR_OK)
  {
    etharp_init();
  }
  else
  {
    free(netif->state);
  }
exit:
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("redlogic_rtl8019_init() exit = %d\n",ret_code));

  return ret_code;
}
static err_t low_level_init(redlogic_rtl8019_if* dev)
{
    unsigned char i,uc;
    alt_lwip_dev* lwip_dev = &dev->lwip_dev_list.dev;
    err_t ret_code = ERR_OK;
    
    LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_init()\n"));
  lwip_dev->netif->hwaddr_len = 6;
    if (rtl8019_Reset(dev)) {
        return -1;
    }
    IOWR_REDLOGIC_RTL8019_IMR(dev->base_addr,0x00);
    IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,0xff);
    OSTimeDlyHMSM(0,0,1,0);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK | REDLOGIC_RTL8019_CR_PS1_MSK);
    IOWR_REDLOGIC_RTL8019_9346CR(dev->base_addr, REDLOGIC_RTL8019_9346CR_EEM0_MSK | REDLOGIC_RTL8019_9346CR_EEM1_MSK);
    IOWR_REDLOGIC_RTL8019_CONFIG2(dev->base_addr, REDLOGIC_RTL8019_CONFIG2_BSELB_MSK);
    IOWR_REDLOGIC_RTL8019_CONFIG3(dev->base_addr,REDLOGIC_RTL8019_CONFIG3_LEDS0_MSK|REDLOGIC_RTL8019_CONFIG3_LEDS1_MSK );
    IOWR_REDLOGIC_RTL8019_9346CR(dev->base_addr, 0);
    OSTimeDlyHMSM(0,0,1,0);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    IOWR_REDLOGIC_RTL8019_DCR(dev->base_addr,REDLOGIC_RTL8019_DCR_LS_MSK | REDLOGIC_RTL8019_DCR_FT1_MSK);
    IOWR_REDLOGIC_RTL8019_RBCR0(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RBCR1(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_RCR(dev->base_addr,REDLOGIC_RTL8019_RCR_MON_MSK);
    IOWR_REDLOGIC_RTL8019_TCR(dev->base_addr,REDLOGIC_RTL8019_TCR_LB0_MSK);
    IOWR_REDLOGIC_RTL8019_TPSR(dev->base_addr,NIC_FIRST_TX_PAGE);
    IOWR_REDLOGIC_RTL8019_BNRY(dev->base_addr,NIC_STOP_PAGE - 1);
    uc=NIC_FIRST_RX_PAGE;
    IOWR_REDLOGIC_RTL8019_PSTART(dev->base_addr,uc);
    uc=NIC_STOP_PAGE;
    IOWR_REDLOGIC_RTL8019_PSTOP(dev->base_addr, uc);
    IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,0xff);
    ret_code = get_mac_addr(lwip_dev);
    if (ret_code != ERR_OK) 
    {
      goto exit;
    }
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK);
    IOWR_REDLOGIC_RTL8019_PAR0(dev->base_addr,lwip_dev->netif->hwaddr[0]);
    IOWR_REDLOGIC_RTL8019_PAR1(dev->base_addr,lwip_dev->netif->hwaddr[1]);
    IOWR_REDLOGIC_RTL8019_PAR2(dev->base_addr,lwip_dev->netif->hwaddr[2]);
    IOWR_REDLOGIC_RTL8019_PAR3(dev->base_addr,lwip_dev->netif->hwaddr[3]);
    IOWR_REDLOGIC_RTL8019_PAR4(dev->base_addr,lwip_dev->netif->hwaddr[4]);
    IOWR_REDLOGIC_RTL8019_PAR5(dev->base_addr,lwip_dev->netif->hwaddr[5]);
    IOWR_REDLOGIC_RTL8019_MAR0(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR1(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR2(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR3(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR4(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR5(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR6(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_MAR7(dev->base_addr,0);
    IOWR_REDLOGIC_RTL8019_CURR(dev->base_addr,NIC_FIRST_RX_PAGE);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    IOWR_REDLOGIC_RTL8019_RCR(dev->base_addr, REDLOGIC_RTL8019_RCR_AB_MSK);
    IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,0xff);
    IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
    IOWR_REDLOGIC_RTL8019_TCR(dev->base_addr,0);
    OSTimeDlyHMSM(0,0,1,0);
    dev->lwip_dev_list.dev.netif->mtu = 1500;
    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, 
                          redlogic_rtl8019_irq))
    {
        ret_code = ERR_IF;
        goto exit;
    }
    IOWR_REDLOGIC_RTL8019_IMR(dev->base_addr,REDLOGIC_RTL8019_IMR_PRXE_MSK | REDLOGIC_RTL8019_IMR_RXEE_MSK | REDLOGIC_RTL8019_IMR_TXEE_MSK | REDLOGIC_RTL8019_IMR_OVWE_MSK); 
    exit:

⌨️ 快捷键说明

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