📄 dev_net_rtl8019.c
字号:
io->CNTR0 = 0;
*data = io->CNTR0;
break;
}
} //end if page0
if ((io->CR >> 6) == 1)
{ //read page1
switch (offset)
{
case 0x00: //CR
*data = io->CR;;
break;
case 0x01: //PAR0 - PAR5 ,MAC addr
*data = io->PAR0;
break;
case 0x02:
*data = io->PAR1;
break;
case 0x03:
*data = io->PAR2;
break;
case 0x04:
*data = io->PAR3;
break;
case 0x05:
*data = io->PAR4;
break;
case 0x06:
*data = io->PAR5;
break;
case 0x07: //CURR
*data = io->CURR;
break;
}
} //end if PAGE1
if ((io->CR >> 6) == 2)
{ //read page2
switch (offset)
{
case 0x00: //CR
*data = io->CR;
break;
case 0x01: //PSTART
*data = io->PSTART;
break;
case 0x02: //PSTOP
*data = io->PSTOP;
break;
case 0x04: //TPSR
*data = io->TPSR;
break;
case 0x0C: //RCR
*data = io->RCR;
break;
case 0x0D: //TCR
*data = io->TCR;
break;
case 0x0E: //DCR
*data = io->DCR;
break;
case 0x0F: //IMR
*data = io->IMR;
break;
}
} //end if page2
return ret;
}
static int
net_rtl8019_write_halfword (struct device_desc *dev, u32 addr, u16 data)
{
struct net_device *net_dev = (struct net_device *) dev->dev;
struct net_rtl8019_io *io = (struct net_rtl8019_io *) dev->data;
int offset = (u8) (addr - dev->base);
int ret = ADDR_HIT;
if (offset == 0x10)
{ //remote write
if (io->DCR & 0x1)
{
remote_write_word (dev, (u16) data);
}
}
return ret;
//DBG_PRINT("nic write begin: offset %x, data %x\n",offset,data);
}
//offset should be 00-0f, 10 or 1f
static int
net_rtl8019_write_byte (struct device_desc *dev, u32 addr, u8 data)
{
struct net_device *net_dev = (struct net_device *) dev->dev;
struct net_rtl8019_io *io = (struct net_rtl8019_io *) dev->data;
int offset = (u8) (addr - dev->base);
int ret = ADDR_HIT;
if (offset == 0x10)
{ //remote write
/* FIXME: don't use DCR here. */
//if (io->DCR & 0x2) {
remote_write_byte (dev, (u8) data);
//}
return ret;
}
if (offset == 0x1f)
{ //reset
net_rtl8019_reset (dev);
return ret;
}
if ((io->CR >> 6) == 0)
{ //write page0
switch (offset)
{
case 0x00: //CR
write_cr (dev, data);
break;
case 0x01: //PSTART
io->PSTART = data;
break;
case 0x02: //PSTOP
io->PSTOP = data;
break;
case 0x03: //BNRY
io->BNRY = data;
break;
case 0x04: //TPSR
io->TPSR = data;
break;
case 0x05: //TBCR0
io->TBCR0 = data;
break;
case 0x06: //TBCR1
io->TBCR1 = data;
break;
case 0x07: //ISR (write means clear)
io->ISR = (io->ISR & (~data));
/*
if (io->IMR & io->ISR) {
}
*/
//UNSET_NET_INT ();
break;
case 0x08: //RSAR0
io->RSAR0 = data;
break;
case 0x09: //RSAR1
io->RSAR1 = data;
break;
case 0x0a: //RBCR0
io->RBCR0 = data;
break;
case 0x0b: //RBCR1
io->RBCR1 = data;
break;
case 0x0c: //RCR
io->RCR = data;
break;
case 0x0d: //TCR
io->TCR = data;
break;
case 0x0e: //DCR
io->DCR = data;
break;
case 0x0f: //IMR
//printf("IMR:%x -> %x. ISR:%x\n", io->IMR, data, io->ISR);
io->IMR = data;
/*
if (io->IMR & io->ISR) {
net_rtl8019_set_update_intr(dev);
}
*/
break;
}
return;
} //end if page0
if ((io->CR >> 6) == 1)
{ //write page1
switch (offset)
{
case 0x00: //CR
write_cr (dev, data);
break;
case 0x01: //PAR0 - PAR5 ,MAC addr
io->PAR0 = data;
break;
case 0x02:
io->PAR1 = data;
break;
case 0x03:
io->PAR2 = data;
break;
case 0x04:
io->PAR3 = data;
break;
case 0x05:
io->PAR4 = data;
break;
case 0x06:
io->PAR5 = data;
break;
case 0x07: //CURR
io->CURR = data;
break;
}
return;
} //end if page1
//yangye 2003-1-21
//add write page2 ,only CR
if ((io->CR >> 6) == 2)
{ //write page2
if (offset == 0x00)
{
write_cr (dev, data);
return ret;
}
} //end if page2
DBG_PRINT ("error write page or error write register\n");
return ret;
}
static void
rtl8019_input (struct device_desc *dev)
{
struct net_device *net_dev = (struct net_device *) dev->dev;
struct net_rtl8019_io *io = (struct net_rtl8019_io *) dev->data;
int packet_len, rtl8019_len;
u8 buf[1600];
u8 frame_header[4];
u8 *bufptr;
u8 *sramptr;
u16 i, j, len;
u32 free_pages, occupy_pages, next_page;
if ((io->CR & CMD_STOP) || (io->TCR & TCR_LOOP_EXT))
{
return;
}
if (io->CURR < io->BNRY)
{
free_pages = io->BNRY - io->CURR;
}
else
{
free_pages = (io->PSTOP - io->PSTART) - (io->CURR - io->BNRY);
}
packet_len = net_dev->net_read (net_dev, buf, sizeof (buf));
if (packet_len < 0)
return;
/* if packet_len < 60, pad zero to 60 bytes length. */
if (packet_len < 60)
{
memset (buf + packet_len, 0, 60 - packet_len);
packet_len = 60;
}
rtl8019_len = packet_len + 4;
occupy_pages = (rtl8019_len + 255) / PAGE_SIZE;
/* check if we have available space to receive packet */
if (occupy_pages > free_pages)
{
io->ISR |= ISR_OVW;
if ((ISR_OVW & io->IMR))
{
net_rtl8019_set_update_intr (dev);
}
DBG_PRINT ("%s: read data overflow!\n", __FUNCTION__);
return;
}
next_page = io->CURR + occupy_pages;
if (next_page >= io->PSTOP)
{
next_page -= io->PSTOP - io->PSTART;
}
//add 8019 frame header
frame_header[0] = RSR_RXOK;
frame_header[1] = next_page;
frame_header[2] = (rtl8019_len & 0xFF); //low 8 bit
frame_header[3] = (rtl8019_len >> 8); //high 8 bit
/* check if we are in in promiscuous mode */
if (!(io->RCR & RCR_PRO))
{
/* not in promiscuous mode */
if (!is_broadcast (buf))
{
DBG_PRINT (" destination address is a broadcast address!!!\n");
if (!(io->RCR & RCR_AB))
{
/* reject broadcast destination address */
return;
}
}
else if (is_multicast (buf))
{
DBG_PRINT ("destination address is a multicast address!!!\n");
if (!(io->RCR & RCR_AM))
{
/* reject multicast destination address */
return;
}
}
else if ((io->PAR0 != buf[0]) || (io->PAR1 != buf[1])
|| (io->PAR2 != buf[2]) || (io->PAR3 != buf[3])
|| (io->PAR4 != buf[4]) || (io->PAR5 != buf[5]))
{
return;
}
}
sramptr = &io->sram[(io->CURR - START_PAGE) * PAGE_SIZE];
if (next_page > io->CURR || ((io->CURR + occupy_pages) == io->PSTOP))
{
memcpy (sramptr, frame_header, 4);
memcpy (sramptr + 4, buf, packet_len);
}
else
{
int copy_bytes = (io->PSTOP - io->CURR) * PAGE_SIZE;
memcpy (sramptr, frame_header, 4);
memcpy (sramptr + 4, buf, copy_bytes - 4);
sramptr = &io->sram[(io->PSTART - START_PAGE) * PAGE_SIZE];
memcpy (sramptr, (void *) (buf + copy_bytes - 4),
(packet_len - copy_bytes + 4));
}
io->CURR = next_page;
io->RSR |= RSR_RXOK;
#if 0
print_packet (sramptr, rtl8019_len);
#endif
/*** send CPU a rx interrupt here! *****/
io->ISR |= ISR_PRX; //got packet int
if ((ISR_PRX & io->IMR))
{
//printf ("+++%s: raise RX interrupt, ISR:%x, IMR:%x\n", __FUNCTION__, io->ISR, io->IMR);
set_time (rtl8019_len);
io->need_update = 1;
net_rtl8019_set_update_intr (dev);
}
}
static u8
rtl8019_output (struct device_desc *dev, u8 * buf, u16 packet_len)
{
struct net_device *net_dev = (struct net_device *) dev->dev;
struct net_rtl8019_io *io = (struct net_rtl8019_io *) dev->data;
int len;
if (io->CR & CMD_STOP)
{ //nic in stop mode
return;
}
#if 0
print_packet (buf, packet_len);
#endif
if ((len = net_dev->net_write (net_dev, buf, packet_len)) == -1)
{
fprintf (stderr, "write to tapif error in skyeye-ne2k.c\n");
return -1;
}
//printf ("+++%s: trans\n", __FUNCTION__);
return 0;
}
static int
net_rtl8019_setup (struct device_desc *dev)
{
int i;
int enough = 0;
struct net_rtl8019_io *io;
struct device_interrupt *intr = &dev->intr;
dev->fini = net_rtl8019_fini;
dev->reset = net_rtl8019_reset;
dev->update = net_rtl8019_update;
dev->read_byte = net_rtl8019_read_byte;
dev->write_byte = net_rtl8019_write_byte;
dev->read_halfword = net_rtl8019_read_halfword;
dev->write_halfword = net_rtl8019_write_halfword;
io = (struct net_rtl8019_io *) malloc (sizeof (struct net_rtl8019_io));
memset (io, 0, sizeof (struct net_rtl8019_io));
if (io == NULL)
return 1;
dev->data = (void *) io;
net_rtl8019_reset (dev);
init_sigaction ();
/* see if we need to set default values.
* */
set_device_default (dev, rtl8019_net_def);
intr->interrupts[INT_RTL8019] = 16;
for (i = 0; i < MAX_DEVICE_NUM; i++)
{
if (rtl8019_devs[i] == NULL)
{
rtl8019_devs[i] = dev;
enough = 1;
break;
}
}
if (enough == 0)
return 1;
return 0;
}
void
net_rtl8019_init (struct device_module_set *mod_set)
{
int i;
register_device_module ("rtl8019", mod_set, &net_rtl8019_setup);
for (i = 0; i < MAX_DEVICE_NUM; i++)
rtl8019_devs[i] = NULL;
}
//zzc:#endif __CYGWIN__
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -