summaryrefslogtreecommitdiff
path: root/dev
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2004-07-30 11:29:45 -0400
committerNathan Binkert <binkertn@umich.edu>2004-07-30 11:29:45 -0400
commite60a4c58ee3aca6027c2d03f3360012e8dc4f742 (patch)
treeda1d7ac7f31edb9b8c8af461471fa818f4c94386 /dev
parent8f87a57e70f8a676cdd016458a13431e0019475c (diff)
downloadgem5-e60a4c58ee3aca6027c2d03f3360012e8dc4f742.tar.xz
Fix a few bugs in the receive state machine. In doing back to tracking
whether or not the state machine is enabled rather than tracking the specific instance of trying to halt the state machine. dev/ns_gige.cc: change back to tracking the state machine's enableness instead of whether or not it is trying to halt. Also fix a major bug that would cause the NIC to drop packets when the rx state machine was idle, but enabled. Fix a couple other bugs in the state machine where the idle interrupt would happen at the wrong time. Add a warning to deal with improper values of intrTick dev/ns_gige.hh: We need to keep track of whether the state machine is enabled or not separately from the control register since the bits don't always reflect the truth. --HG-- extra : convert_revision : 20056b225fa62a0744473babfd693506aa5f29b2
Diffstat (limited to 'dev')
-rw-r--r--dev/ns_gige.cc90
-rw-r--r--dev/ns_gige.hh4
2 files changed, 50 insertions, 44 deletions
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index 27cda69da..331966f9c 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -108,10 +108,10 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
: PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), ioEnable(false),
maxTxFifoSize(tx_fifo_size), maxRxFifoSize(rx_fifo_size),
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
- txXferLen(0), rxXferLen(0), txState(txIdle), CTDD(false),
- txFifoAvail(tx_fifo_size), txHalt(false),
+ txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false),
+ CTDD(false), txFifoAvail(tx_fifo_size),
txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
- CRDD(false), rxPktBytes(0), rxFifoCnt(0), rxHalt(false),
+ rxEnable(false), CRDD(false), rxPktBytes(0), rxFifoCnt(0),
rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
rxDmaReadEvent(this), rxDmaWriteEvent(this),
txDmaReadEvent(this), txDmaWriteEvent(this),
@@ -586,24 +586,23 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
switch (daddr) {
case CR:
regs.command = reg;
- if ((reg & (CR_TXE | CR_TXD)) == (CR_TXE | CR_TXD)) {
- txHalt = true;
+ if (reg & CR_TXD) {
+ txEnable = false;
} else if (reg & CR_TXE) {
- //the kernel is enabling the transmit machine
+ txEnable = true;
+
+ // the kernel is enabling the transmit machine
if (txState == txIdle)
txKick();
- } else if (reg & CR_TXD) {
- txHalt = true;
}
- if ((reg & (CR_RXE | CR_RXD)) == (CR_RXE | CR_RXD)) {
- rxHalt = true;
+ if (reg & CR_RXD) {
+ rxEnable = false;
} else if (reg & CR_RXE) {
- if (rxState == rxIdle) {
+ rxEnable = true;
+
+ if (rxState == rxIdle)
rxKick();
- }
- } else if (reg & CR_RXD) {
- rxHalt = true;
}
if (reg & CR_TXR)
@@ -777,6 +776,7 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
case RXDP:
regs.rxdp = reg;
+ CRDD = false;
break;
case RXDP_HI:
@@ -1076,6 +1076,15 @@ NSGigE::cpuIntrPost(Tick when)
// schedule another.
// HOWEVER, must be sure that the scheduled intrTick is in the
// future (this was formerly the source of a bug)
+ /**
+ * @todo this warning should be removed and the intrTick code should
+ * be fixed.
+ */
+ if (intrTick < curTick && intrTick != 0) {
+ warn("intrTick < curTick !!! intrTick=%d curTick=%d\n",
+ intrTick, curTick);
+ intrTick = 0;
+ }
assert((intrTick >= curTick) || (intrTick == 0));
if (when > intrTick && intrTick != 0)
return;
@@ -1154,11 +1163,10 @@ NSGigE::txReset()
CTDD = false;
txFifoAvail = maxTxFifoSize;
- txHalt = false;
+ txEnable = false;;
txFragPtr = 0;
assert(txDescCnt == 0);
txFifo.clear();
- regs.command &= ~CR_TXE;
txState = txIdle;
assert(txDmaState == dmaIdle);
}
@@ -1171,12 +1179,11 @@ NSGigE::rxReset()
CRDD = false;
assert(rxPktBytes == 0);
rxFifoCnt = 0;
- rxHalt = false;
+ rxEnable = false;
rxFragPtr = 0;
assert(rxDescCnt == 0);
assert(rxDmaState == dmaIdle);
rxFifo.clear();
- regs.command &= ~CR_RXE;
rxState = rxIdle;
}
@@ -1340,7 +1347,7 @@ NSGigE::rxKick()
// an event and come back to this loop.
switch (rxState) {
case rxIdle:
- if (!regs.command & CR_RXE) {
+ if (!rxEnable) {
DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n");
goto exit;
}
@@ -1395,7 +1402,9 @@ NSGigE::rxKick()
rxDescCache.extsts);
if (rxDescCache.cmdsts & CMDSTS_OWN) {
+ devIntrPost(ISR_RXIDLE);
rxState = rxIdle;
+ goto exit;
} else {
rxState = rxFifoBlock;
rxFragPtr = rxDescCache.bufptr;
@@ -1566,18 +1575,20 @@ NSGigE::rxKick()
if (rxDescCache.cmdsts & CMDSTS_INTR)
devIntrPost(ISR_RXDESC);
- if (rxHalt) {
+ if (!rxEnable) {
DPRINTF(EthernetSM, "Halting the RX state machine\n");
rxState = rxIdle;
- rxHalt = false;
+ goto exit;
} else
rxState = rxAdvance;
break;
case rxAdvance:
if (rxDescCache.link == 0) {
+ devIntrPost(ISR_RXIDLE);
rxState = rxIdle;
- return;
+ CRDD = true;
+ goto exit;
} else {
rxState = rxDescRead;
regs.rxdp = rxDescCache.link;
@@ -1601,12 +1612,6 @@ NSGigE::rxKick()
DPRINTF(EthernetSM, "entering next rx state = %s\n",
NsRxStateStrings[rxState]);
- if (rxState == rxIdle) {
- regs.command &= ~CR_RXE;
- devIntrPost(ISR_RXIDLE);
- return;
- }
-
goto next;
exit:
@@ -1805,7 +1810,7 @@ NSGigE::txKick()
switch (txState) {
case txIdle:
- if (!regs.command & CR_TXE) {
+ if (!txEnable) {
DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n");
goto exit;
}
@@ -1865,7 +1870,9 @@ NSGigE::txKick()
txFragPtr = txDescCache.bufptr;
txDescCnt = txDescCache.cmdsts & CMDSTS_LEN_MASK;
} else {
+ devIntrPost(ISR_TXIDLE);
txState = txIdle;
+ goto exit;
}
break;
@@ -1948,10 +1955,10 @@ NSGigE::txKick()
transmit();
txPacket = 0;
- if (txHalt) {
+ if (!txEnable) {
DPRINTF(EthernetSM, "halting TX state machine\n");
txState = txIdle;
- txHalt = false;
+ goto exit;
} else
txState = txAdvance;
@@ -2004,16 +2011,17 @@ NSGigE::txKick()
if (txDmaState != dmaIdle)
goto exit;
- if (txDescCache.cmdsts & CMDSTS_INTR) {
+ if (txDescCache.cmdsts & CMDSTS_INTR)
devIntrPost(ISR_TXDESC);
- }
txState = txAdvance;
break;
case txAdvance:
if (txDescCache.link == 0) {
+ devIntrPost(ISR_TXIDLE);
txState = txIdle;
+ goto exit;
} else {
txState = txDescRead;
regs.txdp = txDescCache.link;
@@ -2036,12 +2044,6 @@ NSGigE::txKick()
DPRINTF(EthernetSM, "entering next tx state=%s\n",
NsTxStateStrings[txState]);
- if (txState == txIdle) {
- regs.command &= ~CR_TXE;
- devIntrPost(ISR_TXIDLE);
- return;
- }
-
goto next;
exit:
@@ -2123,7 +2125,7 @@ NSGigE::recvPacket(PacketPtr packet)
DPRINTF(Ethernet, "\n\nReceiving packet from wire, rxFifoAvail=%d\n",
maxRxFifoSize - rxFifoCnt);
- if (rxState == rxIdle) {
+ if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n");
interface->recvDone();
return true;
@@ -2388,9 +2390,9 @@ NSGigE::serialize(ostream &os)
*/
int txState = this->txState;
SERIALIZE_SCALAR(txState);
+ SERIALIZE_SCALAR(txEnable);
SERIALIZE_SCALAR(CTDD);
SERIALIZE_SCALAR(txFifoAvail);
- SERIALIZE_SCALAR(txHalt);
SERIALIZE_SCALAR(txFragPtr);
SERIALIZE_SCALAR(txDescCnt);
int txDmaState = this->txDmaState;
@@ -2401,10 +2403,10 @@ NSGigE::serialize(ostream &os)
*/
int rxState = this->rxState;
SERIALIZE_SCALAR(rxState);
+ SERIALIZE_SCALAR(rxEnable);
SERIALIZE_SCALAR(CRDD);
SERIALIZE_SCALAR(rxPktBytes);
SERIALIZE_SCALAR(rxFifoCnt);
- SERIALIZE_SCALAR(rxHalt);
SERIALIZE_SCALAR(rxDescCnt);
int rxDmaState = this->rxDmaState;
SERIALIZE_SCALAR(rxDmaState);
@@ -2550,9 +2552,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
int txState;
UNSERIALIZE_SCALAR(txState);
this->txState = (TxState) txState;
+ UNSERIALIZE_SCALAR(txEnable);
UNSERIALIZE_SCALAR(CTDD);
UNSERIALIZE_SCALAR(txFifoAvail);
- UNSERIALIZE_SCALAR(txHalt);
UNSERIALIZE_SCALAR(txFragPtr);
UNSERIALIZE_SCALAR(txDescCnt);
int txDmaState;
@@ -2565,10 +2567,10 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
int rxState;
UNSERIALIZE_SCALAR(rxState);
this->rxState = (RxState) rxState;
+ UNSERIALIZE_SCALAR(rxEnable);
UNSERIALIZE_SCALAR(CRDD);
UNSERIALIZE_SCALAR(rxPktBytes);
UNSERIALIZE_SCALAR(rxFifoCnt);
- UNSERIALIZE_SCALAR(rxHalt);
UNSERIALIZE_SCALAR(rxDescCnt);
int rxDmaState;
UNSERIALIZE_SCALAR(rxDmaState);
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index c326d0921..82f640db1 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -186,6 +186,8 @@ class NSGigE : public PciDev
/* tx State Machine */
TxState txState;
+ bool txEnable;
+
/** Current Transmit Descriptor Done */
bool CTDD;
/** current amt of free space in txDataFifo in bytes */
@@ -200,6 +202,8 @@ class NSGigE : public PciDev
/** rx State Machine */
RxState rxState;
+ bool rxEnable;
+
/** Current Receive Descriptor Done */
bool CRDD;
/** num of bytes in the current packet being drained from rxDataFifo */