{
}
-bool
+void
IGbE::RxDescCache::writePacket(EthPacketPtr packet)
{
// We shouldn't have to deal with any of these yet
pktDone = false;
igbe->dmaWrite(igbe->platform->pciToDma(unusedCache.front()->buf),
packet->length, &pktEvent, packet->data);
- return true;
}
void
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",
DPRINTF(EthernetDesc, "DMA of packet complete\n");
+
desc = unusedCache.front();
assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc));
return;
}
+
int size;
size = txDescCache.getPacketSize();
if (size > 0 && txFifo.avail() > size) {
postInterrupt(IT_RXO, true);
return false;
}
+
return true;
}
if (descLeft == 0) {
rxDescCache.writeback(0);
+ DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing"
+ " writeback and stopping ticking\n");
rxTick = false;
}
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
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)
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;
}
}
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);
{
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",
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
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);
#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;
* @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();
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();