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

📄 net_3c59x.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 4 页
字号:
   alignment contraint on tx_ring[] and rx_ring[]. */struct boom_rx_desc {  uint32_t next;  uint32_t status;  uint32_t addr;  uint32_t length;};/* Values for the Rx status entry. */#define RX_COMPLETE 0x00008000struct boom_tx_desc {  uint32_t next;  uint32_t status;  uint32_t addr;  uint32_t length;};/* The action to take with a media selection timer tick.   Note that we deviate from the 3Com order by checking 10base2 before AUI. */static struct media_table {  char *name;  uint32_t media_bits:16;		/* Bits to set in Wn4_Media register. */  uint32_t mask:8;			/* The transceiver-present bit in Wn3_Config.*/  uint32_t next:8;			/* The media type to try next. */  uint64_t wait;			/* Time (ms) before we check media status. */} media_tbl[] = {  { "10baseT",   Media_10TP,0x08, 3 /* 10baseT->10base2 */,     1400  },  { "10Mbs AUI", Media_SQE, 0x20, 8 /* AUI->default */,         1000  },  { "undefined", 0,	    0x80, 0 /* Undefined */,            500000 },  { "10base2",   0,	    0x10, 1 /* 10base2->AUI. */,        200  },  { "100baseTX", Media_Lnk, 0x02, 5 /* 100baseTX->100baseFX */, 1400 },  { "100baseFX", Media_Lnk, 0x04, 6 /* 100baseFX->MII */,       1400 },  { "MII",	 0,	    0x40, 0 /* MII->10baseT */,         1400 },  { "undefined", 0,	    0x01, 0 /* Undefined/100baseT4 */,  500000 },  { "Default",	 0,	    0xFF, 0 /* Use default */, 		500000 },};struct vortex_private {  /* The Rx and Tx rings are here to keep them quad-word-aligned. */  struct boom_rx_desc rx_ring[RX_RING_SIZE];#if 0  struct boom_tx_desc tx_ring[TX_RING_SIZE];#endif  /* The addresses of transmit- and receive-in-place buffers. We can   * fit two packets per page */   uint8_t *rx_pkt_buf[RX_RING_SIZE];    struct sk_buff* rx_skbuff[RX_RING_SIZE];#if 0  struct sk_buff* tx_skbuff[TX_RING_SIZE];#endif#if 0  unsigned int cur_rx, cur_tx;	/* The next free ring entry */  unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */#endif  const char *product_name;#if 0  struct sk_buff *tx_skb;	/* Packet being eaten by bus master ctrl.  */#endif  int capabilities;		/* Adapter capabilities word. */  int options;			/* User-settable misc. driver options. */  int lastRxPackets;		/* For media autoselection. */  uint32_t availMedia : 8;		/* From Wn3Options */  uint32_t mediaOverride : 3;	/* From Wn3Options */  uint32_t defaultMedia : 3;	/* Read from the EEPROM. */  uint32_t fullDuplex : 1;  uint32_t autoSelect : 1;  uint32_t busMaster : 1;		/* Vortex can only do a fragment bus-m. */  uint32_t fullBusMasterTX : 1;  uint32_t fullBusMasterRX : 1;	/* Boomerang  */  uint32_t txFull : 1;  uint16_t txStartThresh;};#define private devInfo[0] #define rxFilter devInfo[1]#define curInts devInfo[2]const int vortex_debug = 4;static void Invoke(NetInterface *, Invocation& inv); /* FORWARD */static void RxPacket(NetInterface *); /* FORWARD */static void ReadPacket(NetInterface *ni, Invocation& inv); /* FORWARD */#ifdef NET_MULTIREADstatic void MultiReadPacket(NetInterface *ni, Invocation& inv); /* FORWARD */#endifstatic void WritePacket(NetInterface *ni, Invocation& inv); /* FORWARD */#if 0static void Disable(NetInterface *); /* FORWARD */#endifstatic void Enable(NetInterface *); /* FORWARD */static void UpdateStatistics(NetInterface *); /* FORWARD */static void HandleInterrupt(NetInterface *); /* FORWARD */static void HandleInterrupt(IntAction *); /* FORWARD */inline voidOutCmd(NetInterface *ni, uint16_t cmd, bool andWait = false){  out16(cmd, ni->ioAddr + El3Cmd);  if (andWait)    while (in16(ni->ioAddr + El3Status) & CmdInProgress)      ;}inline voidSetWindow(NetInterface* ni, int whichWindow){  OutCmd(ni, SelectWindow | whichWindow);}static voidvortex_probe1(NetInterface *ni){  vortex_private *vp = (vortex_private *) ni->private;  uint32_t eeprom[0x40];  uint32_t checksum = 0;  MsgLog::dprintf(false, "NI: 3Com %s io=0x%x ", ni->name, ni->ioAddr);		    SetWindow(ni, 0);  for(int i = 0; i < RX_RING_SIZE; i++) {    if ((i % 2) == 0) {      vp->rx_pkt_buf[i] = new (0) uint8_t[EROS_PAGE_SIZE];      vp->rx_pkt_buf[i+1] = vp->rx_pkt_buf[i] + (EROS_PAGE_SIZE/2);      vp->rx_ring[i].next = (uint32_t) &vp->rx_ring[(i+1)%RX_RING_SIZE];      vp->rx_ring[i].status = 0;	/* Clear complete bit. */      vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;      vp->rx_ring[i].addr = (uint32_t) vp->rx_pkt_buf[i];    }  }  /* Fetch out the enet address: */  for (int i = 0; i < 0x18; i++) {    uint16_t *phys_addr = (uint16_t *)ni->info.niAddr;    out16(EEPROM_Read + i, ni->ioAddr + Wn0EepromCmd);    /* must wait at least 162us, this is conservative */#if 0    Machine::SpinWaitUs(162);    uint16_t hw = in16(ni->ioAddr + Wn0EepromCmd);    if ((hw & 0x8000u) != 0)      MsgLog::dprintf(true, "3c59x.c: Couldn't read EEPROM (0x%04x)\n", hw);#endif    for (int timer = 162*4 + 400; timer >= 0; timer--) {      /* SLOW_DOWN_IO; */      if ((in16(ni->ioAddr + Wn0EepromCmd) & 0x8000) == 0)	break;    }    eeprom[i] = inw(ni->ioAddr + Wn0EepromData);    checksum ^= eeprom[i];    /* First three locations are the ethernet address : */    if (i < 3)      phys_addr[i] = htons(in16(ni->ioAddr + Wn0EepromData));  }  ni->info.niAddrLen = 6;  checksum = (checksum ^ (checksum >> 8)) & 0xff;  if (checksum != 0x00)    MsgLog::dprintf(true, "*** INVALID CHECKSUM 0x%x\n", checksum);  for (int i = 0; i < 6; i++)    MsgLog::printf("%c%02x", i ? ':' : ' ', (uint8_t) ni->info.niAddr[i]);  MsgLog::dprintf(false, ", IRQ %d\n", ni->irq);  {    char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};    union wn3_config config;    SetWindow(ni, 3);    vp->availMedia = in16(ni->ioAddr + Wn3Options);    config.i = in32(ni->ioAddr + Wn3Config);    if (vortex_debug > 1)      MsgLog::dprintf(false, "  Internal config register is 0x%4x, transceivers 0x%x.\n",	     config.i, in16(ni->ioAddr + Wn3Options));    MsgLog::dprintf(false, "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",	   8 << config.u.ram_size,	   config.u.ram_width ? "word" : "byte",	   ram_split[config.u.ram_split],	   config.u.autoselect ? "autoselect/" : "",	   media_tbl[config.u.xcvr].name);    ni->xcvr = config.u.xcvr;    vp->defaultMedia = config.u.xcvr;    vp->autoSelect = config.u.autoselect;#if 0    config.u.ram_split = 0;    out32(ni->ioAddr + Wn3Config, config.i);    MsgLog::dprintf(true, "  Overrode to 5:3 (rx:tx) split\n");#endif  }  if (vp->mediaOverride != 7) {    MsgLog::dprintf(false, "  Media override to transceiver type %d (%s).\n",	   vp->mediaOverride, media_tbl[vp->mediaOverride].name);    ni->xcvr = vp->mediaOverride;  }  vp->capabilities = eeprom[16];  vp->fullBusMasterTX = (vp->capabilities & 0x20) ? 1 : 0;  /* Rx is broken at 10mbps, so we always disable it. */  /* vp->full_bus_master_rx = 0;*/  vp->fullBusMasterRX = (vp->capabilities & 0x20) ? 1 : 0;  vp->txStartThresh = 64;    SetWindow(ni, 7);#if 0  /* We do a request_region() to register /proc/ioports info. */  /* Not in the EROS logic. */  request_region(ioaddr, VORTEX_TOTAL_SIZE, vp->product_name);#endif}static NetInterface *vortex_found_device(uint32_t ioAddr,		    uint8_t irq,		    uint16_t boardNdx,		    uint32_t options){  NetInterface *ni = NetInterface::Alloc();  if (ni == 0) {    MsgLog::dprintf(true, "Failed to allocate NetInterface struct\n");    return 0;  }  ni->irq = irq;  ni->ioAddr = ioAddr;  ni->ioLen = product_info[boardNdx].ioSize;  ni->addr = 0;  ni->len = 0;  ni->xcvr = 6;			/* until proven otherwise */  ni->name = product_info[boardNdx].name;  ni->devClass = DEV_NET_ENET;  ni->Invoke = Invoke;  ni->info.niStatus = 0;  ni->watchDog.client_ptr = ni;  ni->updateStats = UpdateStatistics;    if (options == 0)    options = product_info[boardNdx].defaultOptions;    /* Private storage must be aligned to quadword boundary. */  vortex_private *vp = (vortex_private *)    PhysMem::Alloc(sizeof(vortex_private), McMemHi, 8);   if (vp)    bzero(vp, sizeof (vortex_private));  else    MsgLog::dprintf(true, "Vortex: private memory allocation failed!\n");  ni->private = (uint32_t) vp;  vp->options = options;#if 0  vp->mediaOverride = ((options & 7) == 2) ? 0 : (options & 7);  vp->busMaster = (options & 16) ? 1 : 0;  vp->fullDuplex = (options & 8) ? 1 : 0;  if (options == 0)    vp->mediaOverride = 7;#else  vp->mediaOverride = 6;	/* require 100baseTX for now */  vp->busMaster = 1;  vp->fullDuplex = 1;#endif  vortex_probe1(ni);  return ni;}static boolPCI_Probe(AutoConf * /* ac */){  bool result = false;  #if 0  MsgLog::dprintf(true, "Probing for vortex boards...\n");#endif    uint32_t nCards = 0;  if (PciBios::Present()) {    for (int ndx = 0; ndx < 0xff; ndx++) {      uint8_t bus;      uint8_t devFn;      uint16_t vendor;      uint16_t device;      uint16_t pciCmd;      uint8_t pciLatency;      uint8_t irq;      uint32_t ioAddr;            uint32_t result =PciBios::FindClass(PCI_CLASS_NETWORK_ETHERNET << 8,				      ndx, bus, devFn);#if 0      MsgLog::dprintf(true, "Result of FindClass(%x, %x, ..., ...)"		      " = 0x%08x\n", PCI_CLASS_NETWORK_ETHERNET << 8,		      ndx, result);#endif      if (result != PciBios::OK)	break;      PciBios::ReadConfig16(bus, devFn, PCI_VENDOR_ID, vendor);      PciBios::ReadConfig16(bus, devFn, PCI_DEVICE_ID, device);      PciBios::ReadConfig8(bus, devFn, PCI_INTERRUPT_LINE, irq);      PciBios::ReadConfig32(bus, devFn, PCI_BASE_ADDRESS_0, ioAddr);      ioAddr &= ~0x3;		/* kill off I/O space marker */      if (vendor != PCI_VENDOR_ID_3COM)	continue;#if 0      MsgLog::dprintf(false, "Found PCI card. ven=0x%04x, dev=0x%04x"		      " irq=%d io=0x%03x\n",		      vendor, device, irq, ioAddr);#endif      uint32_t whichBoard = 0;      for (; product_info[whichBoard].prodId; whichBoard++) {	if (device == product_info[whichBoard].prodId)	    break;      }      if (product_info[whichBoard].prodId == 0) {	MsgLog::dprintf(true, "Unknown 3com PCI ethernet adapter type"			" 0x%04x detected: not configured\n",			device);	continue;      }#if 0      /* Do not check the I/O region until attach time. */      if (IoRegion::IsAvailable(ioAddr, product_info[whichBoard].ioSize) == false)	continue;#endif      NetInterface *ni = vortex_found_device(ioAddr, irq, whichBoard, nCards);      if (ni) {	PciBios::ReadConfig16(bus, devFn, PCI_COMMAND, pciCmd);	if (!pciCmd & PCI_COMMAND_MASTER) {	  MsgLog::dprintf(false, "PCI Master bit not set. Setting....\n");	  pciCmd |= pciCmd;	  	  PciBios::WriteConfig16(bus, devFn, PCI_COMMAND, pciCmd);	}	PciBios::ReadConfig8(bus, devFn, PCI_COMMAND, pciLatency);	if (pciLatency != 248) {	  MsgLog::dprintf(false, "%s: Overriding PCI latency"			  " timer (CFLT) setting of %d, new value is 248.\n",			  ni->name, pciLatency);	  PciBios::WriteConfig8(bus, devFn, PCI_LATENCY_TIMER,				248);	}	nCards++;	result = true;      }    }  }  return result;}static boolProbe(struct AutoConf * ac){  return PCI_Probe(ac);    /* No EtherLink III family cards are present until proven otherwise. */}static voidni_Attach(NetInterface* ni){  MsgLog::dprintf(false, "Attaching %s io=0x%x, irq=%d "		  "  [%02x:%02x:%02x:%02x:%02x:%02x]\n",		  ni->name,		  ni->ioAddr,		  ni->irq,		  ni->info.niAddr[0],		  ni->info.niAddr[1],		  ni->info.niAddr[2],		  ni->info.niAddr[3],		  ni->info.niAddr[4],		  ni->info.niAddr[5]);  if (ni->info.niStatus & NI_ATTACHED) {    MsgLog::dprintf(true, "NI 0x%08x already attached\n", ni);    return;  }  /* Reserve I/O port addresses used by adapter. */  if ( IoRegion::Allocate(ni->ioAddr, ni->ioLen, ni->name) == false ) {    MsgLog::dprintf(true, "Unable to allocate I/O region io=0x%x: "		    "port range is taken\n",		    ni->ioAddr);    return;  }  /* Reserve the IRQ: */  IntAction *ia = new IntAction(ni->irq, ni->name, HandleInterrupt, (uint32_t) ni);  if ( IRQ::WireExclusive(ia) == false ) {    IoRegion::Release(ni->ioAddr, ni->ioLen);    MsgLog::dprintf(true, "Unable to enable %s at io=0x%x: "		    "irq %d is taken\n",		    ni->name,		    ni->ioAddr, ni->irq);    return;  }  /* Interrupt is reserved, but not enabled at this point. */  ni->info.niStatus |= NI_ATTACHED;  Enable(ni);}static boolAttach(struct AutoConf * /* ac */){  for (uint32_t i = 0; i < KTUNE_NNETDEV; i++) {    NetInterface *ni;    if ( (ni = NetInterface::Get(i)) == 0 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -