📄 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 unsigned char mac[]={0x01,0x02,0x03,0x04,0x05,0x06};
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;
}
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;
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);
IOWR_REDLOGIC_RTL8019_PSTART(dev->base_addr,NIC_FIRST_RX_PAGE);
IOWR_REDLOGIC_RTL8019_PSTOP(dev->base_addr, NIC_STOP_PAGE);
IOWR_REDLOGIC_RTL8019_ISR(dev->base_addr,0xff);
IOWR_REDLOGIC_RTL8019_CR(dev->base_addr,REDLOGIC_RTL8019_CR_STP_MSK | REDLOGIC_RTL8019_CR_RD2_MSK | REDLOGIC_RTL8019_CR_PS0_MSK);
for (i = 0; i < 6; i++)
reg_write(dev->base_addr,1 + i, mac[i]);
for (i = 0; i < 8; i++)
reg_write(dev->base_addr,8 + i, 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_IMR(dev->base_addr,REDLOGIC_RTL8019_IMR_PRXE_MSK | REDLOGIC_RTL8019_IMR_RXEE_MSK | REDLOGIC_RTL8019_IMR_TXEE_MSK | REDLOGIC_RTL8019_IMR_OVWE_MSK);
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;
}
exit:
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE, ("low_level_init() exit = %d\n", ret_code));
return ret_code;
}
static void NicCompleteDma(unsigned int addr)
{
u_char i;
IOWR_REDLOGIC_RTL8019_CR(addr,REDLOGIC_RTL8019_CR_STA_MSK | REDLOGIC_RTL8019_CR_RD2_MSK);
for (i = 0; i <= 20; i++)
if (IORD_REDLOGIC_RTL8019_ISR(addr) & REDLOGIC_RTL8019_ISR_RDC_MSK)
break;
IOWR_REDLOGIC_RTL8019_ISR(addr,REDLOGIC_RTL8019_ISR_RDC_MSK);
}
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -