IGbE: Fix a couple of bugs.
--HG-- extra : convert_revision : a1f16bd82b6fbd5b6b5dc0f08b9e69858bea86ca
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user