From d167e2bb971327f030f1a7a71a45b7588a1dd3dc Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 10 Feb 2008 19:32:12 -0500 Subject: [PATCH] IGbE: Fix a couple of bugs. --HG-- extra : convert_revision : a1f16bd82b6fbd5b6b5dc0f08b9e69858bea86ca --- src/dev/i8254xGBe.cc | 38 ++++++++++++++++++-------------------- src/dev/i8254xGBe.hh | 30 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index 460f6a9fb..3f56ec53a 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -691,7 +691,7 @@ IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s) { } -bool +void IGbE::RxDescCache::writePacket(EthPacketPtr packet) { // We shouldn't have to deal with any of these yet @@ -707,7 +707,6 @@ IGbE::RxDescCache::writePacket(EthPacketPtr packet) pktDone = false; igbe->dmaWrite(igbe->platform->pciToDma(unusedCache.front()->buf), packet->length, &pktEvent, packet->data); - return true; } void @@ -717,7 +716,6 @@ IGbE::RxDescCache::pktComplete() RxDesc *desc; desc = unusedCache.front(); - uint16_t crcfixup = igbe->regs.rctl.secrc() ? 0 : 4 ; desc->len = htole((uint16_t)(pktPtr->length + crcfixup)); DPRINTF(EthernetDesc, "pktPtr->length: %d stripcrc offset: %d value written: %d %d\n", @@ -938,6 +936,7 @@ IGbE::TxDescCache::pktComplete() DPRINTF(EthernetDesc, "DMA of packet complete\n"); + desc = unusedCache.front(); assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc)); @@ -1215,6 +1214,7 @@ IGbE::txStateMachine() return; } + int size; size = txDescCache.getPacketSize(); if (size > 0 && txFifo.avail() > size) { @@ -1261,6 +1261,7 @@ IGbE::ethRxPkt(EthPacketPtr pkt) postInterrupt(IT_RXO, true); return false; } + return true; } @@ -1290,6 +1291,8 @@ IGbE::rxStateMachine() if (descLeft == 0) { rxDescCache.writeback(0); + DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing" + " writeback and stopping ticking\n"); rxTick = false; } @@ -1342,16 +1345,14 @@ IGbE::rxStateMachine() EthPacketPtr pkt; pkt = rxFifo.front(); - DPRINTF(EthernetSM, "RXS: Writing packet into memory\n"); - if (rxDescCache.writePacket(pkt)) { - DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n"); - rxFifo.pop(); - DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n"); - rxTick = false; - rxDmaPacket = true; - return; - } + rxDescCache.writePacket(pkt); + DPRINTF(EthernetSM, "RXS: Writing packet into memory\n"); + DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n"); + rxFifo.pop(); + DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n"); + rxTick = false; + rxDmaPacket = true; } void @@ -1362,10 +1363,8 @@ IGbE::txWire() return; } - if (etherInt->askBusy()) { - // We'll get woken up when the packet ethTxDone() gets called - txFifoTick = false; - } else { + + if (etherInt->sendPacket(txFifo.front())) { if (DTRACE(EthernetSM)) { IpPtr ip(txFifo.front()); if (ip) @@ -1374,13 +1373,12 @@ IGbE::txWire() else DPRINTF(EthernetSM, "Transmitting Non-Ip packet\n"); } - - bool r = etherInt->sendPacket(txFifo.front()); - assert(r); - r += 1; DPRINTF(EthernetSM, "TxFIFO: Successful transmit, bytes available in fifo: %d\n", txFifo.avail()); txFifo.pop(); + } else { + // We'll get woken up when the packet ethTxDone() gets called + txFifoTick = false; } } diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh index 30aa6430e..9403c87b6 100644 --- a/src/dev/i8254xGBe.hh +++ b/src/dev/i8254xGBe.hh @@ -282,8 +282,12 @@ class IGbE : public EtherDevice wbOut = max_to_wb; - for (int x = 0; x < wbOut; x++) - memcpy(&wbBuf[x], usedCache[x], sizeof(T)); + for (int x = 0; x < wbOut; x++) { + assert(usedCache.size()); + memcpy(&wbBuf[x], usedCache[0], sizeof(T)); + delete usedCache[0]; + usedCache.pop_front(); + } assert(wbOut); @@ -298,13 +302,17 @@ class IGbE : public EtherDevice { size_t max_to_fetch; + if (curFetching) + return; + if (descTail() >= cachePnt) max_to_fetch = descTail() - cachePnt; else max_to_fetch = descLen() - cachePnt; - max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() - - unusedCache.size())); + size_t free_cache = size - usedCache.size() - unusedCache.size(); + + max_to_fetch = std::min(max_to_fetch, free_cache); DPRINTF(EthernetDesc, "Fetching descriptors head: %d tail: " "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n", @@ -312,7 +320,7 @@ class IGbE : public EtherDevice max_to_fetch, descLeft()); // Nothing to do - if (max_to_fetch == 0 || curFetching) + if (max_to_fetch == 0) return; // So we don't have two descriptor fetches going on at once @@ -322,7 +330,6 @@ class IGbE : public EtherDevice descBase() + cachePnt * sizeof(T), igbe->platform->pciToDma(descBase() + cachePnt * sizeof(T)), curFetching * sizeof(T)); - assert(curFetching); igbe->dmaRead(igbe->platform->pciToDma(descBase() + cachePnt * sizeof(T)), curFetching * sizeof(T), &fetchEvent, (uint8_t*)fetchBuf); @@ -369,11 +376,6 @@ class IGbE : public EtherDevice #ifndef NDEBUG long oldHead = curHead; #endif - for (int x = 0; x < wbOut; x++) { - assert(usedCache.size()); - delete usedCache[0]; - usedCache.pop_front(); - }; curHead += wbOut; wbOut = 0; @@ -523,7 +525,7 @@ class IGbE : public EtherDevice * @param packet ethernet packet to write * @return if the packet could be written (there was a free descriptor) */ - bool writePacket(EthPacketPtr packet); + void writePacket(EthPacketPtr packet); /** Called by event when dma to write packet is completed */ void pktComplete(); @@ -553,9 +555,7 @@ class IGbE : public EtherDevice virtual long descLen() const { return igbe->regs.tdlen() >> 4; } virtual void updateHead(long h) { igbe->regs.tdh(h); } virtual void enableSm(); - virtual void intAfterWb() const { - igbe->postInterrupt(iGbReg::IT_TXDW); - } + virtual void intAfterWb() const { igbe->postInterrupt(iGbReg::IT_TXDW); } virtual void fetchAfterWb() { if (!igbe->txTick && igbe->getState() == SimObject::Running) fetchDescriptors(); -- 2.30.2