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

📄 net_3c59x.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 4 页
字号:
#define exitVec foobar	  uint64_t ew = rdtsc();	  ew -= dw;	  ni->stats.rxCpuCycles += ew;	  return;	}	/* Else wait for at least one packet. */	ni->stats.rdStall++;	Thread::Current()->SleepOn(ni->rdQ);	ni->curInts |= RxComplete;	OutCmd(ni, SetIntrMask | ni->curInts);	Thread::Current()->Yield();      }          if (rx_status & RxsError)	SkipBadRxPackets(ni);    } while (rx_status & RxsError);    uint16_t len = rx_status & Rxsuint8_ts;    curExitVec->len = len;        /* We know that the input buffer is aligned and also that it is     * of sufficient size:     */    ins32(ni->ioAddr + Wn1RxFifo,	  inv.exit.data + curExitVec->offset,	  (len+3) >> 2);    ni->stats.rxPackets++;    haveData = true;    OutCmd(ni, RxDiscard, true);  }  rx_status = in16(ni->ioAddr + Wn1RxStatus);  if ((rx_status & RxsIncomplete) == 0 && ((rx_status & RxsError) == 0))    ni->stats.rxMore++;#undef exitVec#ifdef VERBOSE  MsgLog::dprintf(true, "%s (3c59x): Drop out w/ %d pkts\n",		  ni->name, curExitVec - &tmpExitVec[1]);#endif  /* Copy out to the REAL exit vec: */  bcopy(&tmpExitVec, exitVec, tmpExitVec->len);  uint64_t ew = rdtsc();  ew -= dw;  ni->stats.rxCpuCycles += ew;}#endifstatic inline voidHandleInterrupt(NetInterface * ni){  uint16_t status;		/* Status is accessable from every window */    for (;;) {    status = in16(ni->ioAddr + El3Status);#if 0    MsgLog::printf("HI: status = 0x%04x\n", status);#endif    if ( (status & (IntLatch | (RxComplete&ni->curInts) | UpdateStats)) == 0)      break;    /* Only run RxPacket if we are supposed to be accepting RX interrupts: */    if (status & RxComplete & ni->curInts)      RxPacket(ni);    if (status & TxAvail) {      ni->watchDog.Disarm();      ni->wrQ.WakeAll();#ifdef ENET_DEBUG      MsgLog::printf("Got txAvail intr\n");#endif      OutCmd(ni, AckIntr | TxAvail);    }#if 0    if ( status & DownComplete ) {    }    if ( status & DmaDone ) {    }    if (status & UpComplete) {    }#endif    if ( status & (AdapterFail | RxEarly | UpdateStats) ) {      if (status & UpdateStats)	UpdateStatistics(ni);      if (status & RxEarly)	MsgLog::fatal("RxEarly interrupt\n");      if (status & AdapterFail) {	/* Reset receiver and re-init the adapter: */	OutCmd(ni, RxReset, true);	/* Reset the RX filter to current settings: */	OutCmd(ni, SetRxFilter | ni->rxFilter);	/* Re-enable the RX FIFO: */	OutCmd(ni, RxEnable);	/* Ack this part of the interrupt: */	OutCmd(ni, AckIntr | AdapterFail);      }    }    /* Acknowledge the interrupt: */    OutCmd(ni, AckIntr | IntRequested | IntLatch);  }}static voidHandleInterrupt(IntAction *ia){  /* Previous interrupt architecture line. Left in for reference.   * EL3Type        *elink = EL3Type::FindCard(interfaces[0]->irq);   */  NetInterface* ni = (NetInterface*) ia->drvr_ptr;  HandleInterrupt(ni);}static voidEnable(NetInterface * ni){  if (ni->info.niStatus & NI_ENABLED)    return;  if ( (ni->info.niStatus & NI_ATTACHED) == 0 )    return;  vortex_private *vp = (vortex_private *) ni->private;  wn3_config config;  SetWindow(ni, 3);  if (vp->fullDuplex)    out8(MacFullDuplex, ni->ioAddr + Wn3MacCtrl); /* FIX enum value */  config.i = in32(ni->ioAddr + Wn3Config);  if (vp->mediaOverride != 7) {    MsgLog::dprintf(false, "%s: Media override to xcvr %d (%s).\n",		   ni->name, vp->mediaOverride,		   media_tbl[vp->mediaOverride].name);    ni->xcvr = vp->mediaOverride;  }  else if (vp->autoSelect) {#if 0    /* Start with 100baseTx */    ni->xcvr = 4;    while (! (vp->availableMedia & media_tble[ni->xcvr].mask) )      ni->xcvr = media_tvle[ni->xcvr].next;    MsgLog::dprintf("%s: Initial media type %s.\n",		    ni->name, media_tbl[ni->xcvr].name);    mediaTimer.client_ptr = ni;    mediaTimer.WakupIn(media_tbl[ni->xcvr].wait, VortexTimer);#else    MsgLog::dprintf(true, "Autoconfig not yet supported\n");#endif  }  else    ni->xcvr = vp->defaultMedia;  config.u.xcvr = ni->xcvr;  out32(config.i, ni->ioAddr + Wn3Config);  MsgLog::dprintf(false,"Enable(): config was 0x%x\n", config.i);      OutCmd(ni, TxReset, true);  OutCmd(ni, RxReset, true);	/* need to wait? */  OutCmd(ni, SetStatusMask | 0x0); /* DISABLES INTERRUPTS */  IRQ::Enable(ni->irq);  if (vortex_debug > 1){    SetWindow(ni, 4);    MsgLog::printf("%s: Enable() irq %d media status 0x%4x.\n",		   ni->name, ni->irq, in16(ni->ioAddr + Wn4MediaType));  }  /* Set the station address and mask in window 2 each time opened. */  SetWindow(ni, 2);  {    int i;    for (i = 0; i < 6; i++)      out8(ni->info.niAddr[i], ni->ioAddr + i);    for (; i < 12; i+=2)		/* why rewrite eeprom? */      out16(0, ni->ioAddr + i);  }  if (ni->xcvr == 3) {    OutCmd(ni, StartCoax);    /* In theory, we ought to delay here, but the lost packets are     * okay on an ethernet...     */  }  SetWindow(ni, 4);  out16((in16(ni->ioAddr + Wn4MediaType) & ~(Media_10TP|Media_SQE)) |	media_tbl[ni->xcvr].media_bits, ni->ioAddr + Wn4MediaType);  /* Clear out the statistics buffers: */  OutCmd(ni, StatsDisable);  SetWindow(ni, 6);  for (int i = 0; i < 10; i++)    in8(ni->ioAddr + i);  in16(ni->ioAddr + 10);  in16(ni->ioAddr + 12);  /* On Vortex, also clear BadSSD counter: */  SetWindow(ni, 4);  inb(ni->ioAddr + 12);  /* And enable yet more stats on the boomerang: */  out16(0x0040, ni->ioAddr + Wn4NetDiag);  /* Back to Window 7 for normal activity */  SetWindow(ni, 7);  if (vp->fullBusMasterRX) {#ifdef USE_RX_RING    /* FIX -- initialize the ring structures */    out32(&vp->rx_ring[0], ni->ioAddr + UpListPtr);#endif        MsgLog::dprintf(false, "Ring buffer RX init not yet implemented\n");  }  if (vp->fullBusMasterTX) {    /* vp->curTx = vp->dirtyTx = 0;     * Suitably set TxFreeThresh     * Clear out TX ring     * out32(0, ni->ioAddr + DownListPtr);     */    MsgLog::dprintf(false, "Ring buffer TX init not yet implemented\n");  }  ni->rxFilter = RxIndividual | RxBroadcast;  ni->info.niStatus |= NI_BROADCAST | NI_STATION;      OutCmd(ni, SetRxFilter | ni->rxFilter);  OutCmd(ni, StatsEnable);  /* Let transmissions start early, since we know we can keep up once     we get some headroom to make up for intervening timer interrupts. */  OutCmd(ni, SetTxStartThresh | vp->txStartThresh);  OutCmd(ni, RxEnable);  OutCmd(ni, TxEnable);  /* Allow status bits to be seen. */#if 0  OutCmd(ni, SetStatusMask | AdapterFail|IntRequested|UpdateStats | 	 (vp->fullBusMasterTX ? DownComplete : TxAvail) |	 (vp->fullBusMasterRX ? UpComplete : RxComplete) | 	 (vp->busMaster ? DmaDone : 0));#else  OutCmd(ni, SetStatusMask | 0x1ff);#endif  uint16_t status = in16(ni->ioAddr + El3Status);  MsgLog::dprintf(false, "status prior to ackintr = 0x%04x\n", status);  /* Ack all pending events, and set active indicator mask. */  OutCmd(ni, AckIntr | IntLatch | TxAvail | RxEarly | IntRequested);#if 1  /* FIX: Don't really want RxComplete here! */  ni->curInts = IntLatch | TxAvail | UpdateStats;  ni->curInts = 0x01ff;#else  /* FIX: Don't really want RxComplete here! */  ni->curInts = IntLatch | TxAvail | RxComplete | UpdateStats	 | (vp->busMaster ? DmaDone : 0) | UpComplete | DownComplete;#endif  OutCmd(ni, SetIntrMask | ni->curInts);}#if 0static voidDisable(NetInterface *ni){  OutCmd(ni, StatsDisable);  OutCmd(ni, RxDisable);  OutCmd(ni, TxDisable);  if (ni->xcvr == 3)    OutCmd(ni, StopCoax);	/* turn off thin-net power */  IRQ::Disable(ni->irq);  OutCmd(ni, SetIntrMask | 0x0000);  UpdateStatistics(ni);#if 0  vortex_private *vp = (vortex_private *) ni->private;    if (vp->fullBusMasterRX) { /* Free Boomerang bus master Rx buffers. */    out32(0, ni->ioAddr + UpListPtr);    for (i = 0; i < RX_RING_SIZE; i++)      if (vp->rx_skbuff[i]) {	vp->rx_skbuff[i]->free = 1;	dev_kfree_skb (vp->rx_skbuff[i], FREE_WRITE);	vp->rx_skbuff[i] = 0;      }  }  if (vp->fullBusMasterTX) { /* Free Boomerang bus master Tx buffers. */    out32(0, ni->ioAddr + DownListPtr);    for (i = 0; i < TX_RING_SIZE; i++)      if (vp->tx_skbuff[i]) {	dev_kfree_skb(vp->tx_skbuff[i], FREE_WRITE);	vp->tx_skbuff[i] = 0;      }  }#endif}#endifstatic voidUpdateStatistics(NetInterface *ni){#if 0  vortex_private *vp = (vortex_private *) ni->private;#endif#if 0  OutCmd(ni, StatsDisable);#endif  /* Switch to the stats window, and read everything. */  SetWindow(ni,6);  /* Note that the sequential read of registers 6 and 9 can cause   * rollover if stats get updated at the wrong instant!   */    ni->stats.txCarrierErrors            += in8(ni->ioAddr + 0);  ni->stats.txHeartbeatErrors          += in8(ni->ioAddr + 1);  /* multiple collisions */        (void) in8(ni->ioAddr + 2);  ni->stats.collisions                 += in8(ni->ioAddr + 3);  ni->stats.txWindowErrors             += in8(ni->ioAddr + 4);  ni->stats.rxFifoErrors               += in8(ni->ioAddr + 5);  ni->stats.txPackets                  += in8(ni->ioAddr + 6);  ni->stats.txPackets                  += (in8(ni->ioAddr + 9)&0x30)<<4;  /* rxPackets */                  (void) in8(ni->ioAddr + 7);  /* txDeferrals */                (void) in8(ni->ioAddr + 8);  /* total RX octets */            (void) in16(ni->ioAddr + 10);  /* total TX octets */            (void) in16(ni->ioAddr + 12);  /* New: On the Vortex we must also clear the BadSSD counter. */  SetWindow(ni, 4);  (void) in8(ni->ioAddr + 12);  /* We change back to window 7 (not 1) with the Vortex. */  SetWindow(ni, 7);#if 0  OutCmd(ni, StatsEnable);#endif}static voidInvoke(NetInterface *ni, Invocation& inv){#ifndef OPTION_PURE_ENTRY_STRINGS  Thread::CurContext()->SetupEntryString(inv);#endif#ifndef OPTION_PURE_EXIT_STRINGS  inv.invokee->SetupExitString(inv, inv.validLen);#endif  COMMIT_POINT();    switch (inv.entry.code) {  case OC_NI_Read:    {      ReadPacket(ni, inv);      break;    }  case OC_NI_Write:    {      if (inv.entry.len >= MIN_ENET_PACKET_SZ &&	  inv.entry.len <= MAX_ENET_PACKET_SZ)	WritePacket(ni, inv);      else	inv.exit.code = RC_RequestError;      break;    }#ifdef NET_MULTIREAD  case OC_NI_MultiRead:    {      MultiReadPacket(ni, inv);      break;    }#endif  case OC_NI_MultiWrite:    {      inv.exit.code = RC_UnknownRequest;      return;    }  case OC_NI_GetInfo:    {      inv.CopyOut(sizeof(ni->info), &ni->info);      return;    }  case OC_NI_GetStats:    {      inv.CopyOut(sizeof(ni->stats), &ni->stats);      return;    }  case OC_NI_Reset:    {      inv.exit.code = RC_UnknownRequest;      return;    }  default:    inv.exit.code = RC_UnknownRequest;  }}

⌨️ 快捷键说明

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