summaryrefslogtreecommitdiff
path: root/src/dev/i8254xGBe.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/i8254xGBe.hh')
-rw-r--r--src/dev/i8254xGBe.hh36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh
index 95eac4f82..50101325a 100644
--- a/src/dev/i8254xGBe.hh
+++ b/src/dev/i8254xGBe.hh
@@ -147,9 +147,10 @@ class IGbE : public EtherDevice
/** Send an interrupt to the cpu
*/
+ void delayIntEvent();
void cpuPostInt();
// Event to moderate interrupts
- EventWrapper<IGbE, &IGbE::cpuPostInt> interEvent;
+ EventWrapper<IGbE, &IGbE::delayIntEvent> interEvent;
/** Clear the interupt line to the cpu
*/
@@ -177,6 +178,7 @@ class IGbE : public EtherDevice
virtual void updateHead(long h) = 0;
virtual void enableSm() = 0;
virtual void intAfterWb() const {}
+ virtual void fetchAfterWb() = 0;
std::deque<T*> usedCache;
std::deque<T*> unusedCache;
@@ -283,12 +285,6 @@ class IGbE : public EtherDevice
for (int x = 0; x < wbOut; x++)
memcpy(&wbBuf[x], usedCache[x], sizeof(T));
- for (int x = 0; x < wbOut; x++) {
- assert(usedCache.size());
- delete usedCache[0];
- usedCache.pop_front();
- };
-
assert(wbOut);
igbe->dmaWrite(igbe->platform->pciToDma(descBase() + curHead * sizeof(T)),
@@ -307,7 +303,6 @@ class IGbE : public EtherDevice
else
max_to_fetch = descLen() - cachePnt;
-
max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() -
unusedCache.size()));
@@ -369,10 +364,16 @@ class IGbE : public EtherDevice
*/
void wbComplete()
{
+
long curHead = descHead();
#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;
@@ -387,12 +388,17 @@ class IGbE : public EtherDevice
oldHead, curHead);
// If we still have more to wb, call wb now
+ bool oldMoreToWb = moreToWb;
if (moreToWb) {
DPRINTF(EthernetDesc, "Writeback has more todo\n");
writeback(wbAlignment);
}
+
intAfterWb();
- igbe->checkDrain();
+ if (!oldMoreToWb) {
+ igbe->checkDrain();
+ }
+ fetchAfterWb();
}
@@ -502,6 +508,10 @@ class IGbE : public EtherDevice
virtual long descTail() const { return igbe->regs.rdt(); }
virtual void updateHead(long h) { igbe->regs.rdh(h); }
virtual void enableSm();
+ virtual void fetchAfterWb() {
+ if (!igbe->rxTick && igbe->getState() == SimObject::Running)
+ fetchDescriptors();
+ }
bool pktDone;
@@ -544,7 +554,13 @@ 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();
+ }
bool pktDone;
bool isTcp;