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

📄 dev_net_rtl8019.c

📁 嵌入式的开发的一个开源仿真程序源码,其是开源的,很不错的奉献给大家
💻 C
📖 第 1 页 / 共 2 页
字号:
	  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 + -