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