Fix a bug where we would improperly calculate if the FIFO was

full by adding a reserve feature to the packet fifo which allows
us to reserve space in the fifo if only part of a packet was
copied into the fifo.

dev/ns_gige.cc:
    use the new reserve feature in the fifo to properly determine
    when we're full.  assert that adding a packet to the fifo suceeds.
dev/pktfifo.hh:
    add the ability to reserve space in the fifo.  This is useful for
    partial writing of packets into the fifo.

--HG--
extra : convert_revision : 83f871f34fac237bb464c9513cf6490b5c62420e
This commit is contained in:
Nathan Binkert 2004-11-16 23:59:51 -05:00
parent 8de12dc09a
commit a109296bde
2 changed files with 21 additions and 12 deletions

View file

@ -1341,9 +1341,6 @@ NSGigE::rxKick()
// sanity check - i think the driver behaves like this
assert(rxDescCnt >= rxPktBytes);
// Must clear the value before popping to decrement the
// reference count
rxFifo.pop();
}
@ -1564,9 +1561,6 @@ NSGigE::transmit()
* besides, it's functionally the same.
*/
devIntrPost(ISR_TXOK);
} else {
DPRINTF(Ethernet,
"May need to rethink always sending the descriptors back?\n");
}
if (!txFifo.empty() && !txEvent.scheduled()) {
@ -1822,7 +1816,11 @@ NSGigE::txKick()
// this is just because the receive can't handle a
// packet bigger want to make sure
assert(txPacket->length <= 1514);
txFifo.push(txPacket);
#ifndef NDEBUG
bool success =
#endif
txFifo.push(txPacket);
assert(success);
/*
* this following section is not tqo spec, but
@ -1903,6 +1901,7 @@ NSGigE::txKick()
txPacketBufPtr += txXferLen;
txFragPtr += txXferLen;
txDescCnt -= txXferLen;
txFifo.reserve(txXferLen);
txState = txFifoBlock;
break;

View file

@ -43,6 +43,7 @@ class PacketFifo
std::list<PacketPtr> fifo;
int _maxsize;
int _size;
int _reserved;
public:
explicit PacketFifo(int max) : _maxsize(max), _size(0) {}
@ -50,18 +51,27 @@ class PacketFifo
int maxsize() const { return _maxsize; }
int packets() const { return fifo.size(); }
int size() const { return _size; }
int avail() const { return _maxsize - _size; }
bool empty() const { return _size == 0; }
bool full() const { return _size >= _maxsize; }
int size() const { return _size + _reserved; }
int avail() const { return maxsize() - size(); }
bool empty() const { return size() == 0; }
bool full() const { return size() >= maxsize(); }
int reserve(int len = 0)
{
_reserved += len;
assert(avail() >= 0);
return _reserved;
}
bool push(PacketPtr ptr)
{
if (avail() < ptr->length)
assert(_reserved <= ptr->length);
if (avail() < ptr->length - _reserved)
return false;
_size += ptr->length;
fifo.push_back(ptr);
_reserved = 0;
return true;
}