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