Use the new PacketFifo class to avoid manual calculations
authorNathan Binkert <binkertn@umich.edu>
Sat, 13 Nov 2004 21:52:08 +0000 (16:52 -0500)
committerNathan Binkert <binkertn@umich.edu>
Sat, 13 Nov 2004 21:52:08 +0000 (16:52 -0500)
--HG--
extra : convert_revision : afa193904b7ed4d5e5c50e9dcb78e8e855b00ecc

SConscript
dev/ns_gige.cc
dev/ns_gige.hh
dev/pktfifo.cc [new file with mode: 0644]
dev/pktfifo.hh [new file with mode: 0644]

index a2b1c44fa162bcb8c8f59970b498a36757273f48..4fedf25ba75917c7643cdb36287f2ab6d834ae09 100644 (file)
@@ -271,6 +271,7 @@ full_system_sources = Split('''
        dev/etherdev.cc
        dev/pciconfigall.cc
        dev/pcidev.cc
+       dev/pktfifo.cc
        dev/scsi.cc
        dev/scsi_ctrl.cc
        dev/scsi_disk.cc
index 39bae07ab25fb5a613f61fc386e814de7847cccb..e34420a8e0656d83cc23fb57467668d59ea13108 100644 (file)
@@ -1060,7 +1060,6 @@ NSGigE::txReset()
     DPRINTF(Ethernet, "transmit reset\n");
 
     CTDD = false;
-    txFifoAvail = maxTxFifoSize;
     txEnable = false;;
     txFragPtr = 0;
     assert(txDescCnt == 0);
@@ -1076,7 +1075,6 @@ NSGigE::rxReset()
 
     CRDD = false;
     assert(rxPktBytes == 0);
-    rxFifoCnt = 0;
     rxEnable = false;
     rxFragPtr = 0;
     assert(rxDescCnt == 0);
@@ -1346,9 +1344,7 @@ NSGigE::rxKick()
 
             // Must clear the value before popping to decrement the
             // reference count
-            rxFifo.front() = NULL;
-            rxFifo.pop_front();
-            rxFifoCnt -= rxPacket->length;
+            rxFifo.pop();
         }
 
 
@@ -1536,7 +1532,7 @@ NSGigE::transmit()
     }
 
     DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n",
-            maxTxFifoSize - txFifoAvail);
+            txFifo.size());
     if (interface->sendPacket(txFifo.front())) {
 #if TRACING_ON
         if (DTRACE(Ethernet)) {
@@ -1556,12 +1552,9 @@ NSGigE::transmit()
         txBytes += txFifo.front()->length;
         txPackets++;
 
-        txFifoAvail += txFifo.front()->length;
-
         DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n",
-                txFifoAvail);
-        txFifo.front() = NULL;
-        txFifo.pop_front();
+                txFifo.avail());
+        txFifo.pop();
 
         /*
          * normally do a writeback of the descriptor here, and ONLY
@@ -1829,7 +1822,7 @@ NSGigE::txKick()
                 // this is just because the receive can't handle a
                 // packet bigger want to make sure
                 assert(txPacket->length <= 1514);
-                txFifo.push_back(txPacket);
+                txFifo.push(txPacket);
 
                 /*
                  * this following section is not tqo spec, but
@@ -1875,7 +1868,7 @@ NSGigE::txKick()
             }
         } else {
             DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
-            if (txFifoAvail) {
+            if (!txFifo.full()) {
                 txState = txFragRead;
 
                 /*
@@ -1884,7 +1877,7 @@ NSGigE::txKick()
                  * is not enough room in the fifo, just whatever room
                  * is left in the fifo
                  */
-                txXferLen = min<uint32_t>(txDescCnt, txFifoAvail);
+                txXferLen = min<uint32_t>(txDescCnt, txFifo.avail());
 
                 txDmaAddr = txFragPtr & 0x3fffffff;
                 txDmaData = txPacketBufPtr;
@@ -1910,7 +1903,6 @@ NSGigE::txKick()
         txPacketBufPtr += txXferLen;
         txFragPtr += txXferLen;
         txDescCnt -= txXferLen;
-        txFifoAvail -= txXferLen;
 
         txState = txFifoBlock;
         break;
@@ -2025,7 +2017,7 @@ NSGigE::recvPacket(PacketPtr packet)
     rxPackets++;
 
     DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
-            maxRxFifoSize - rxFifoCnt);
+            rxFifo.avail());
 
     if (!rxEnable) {
         DPRINTF(Ethernet, "receive disabled...packet dropped\n");
@@ -2040,15 +2032,14 @@ NSGigE::recvPacket(PacketPtr packet)
         return true;
     }
 
-    if ((rxFifoCnt + packet->length) >= maxRxFifoSize) {
+    if (rxFifo.avail() < packet->length) {
         DPRINTF(Ethernet,
                 "packet will not fit in receive buffer...packet dropped\n");
         devIntrPost(ISR_RXORN);
         return false;
     }
 
-    rxFifo.push_back(packet);
-    rxFifoCnt += packet->length;
+    rxFifo.push(packet);
     interface->recvDone();
 
     rxKick();
@@ -2119,19 +2110,8 @@ NSGigE::serialize(ostream &os)
     /*
      * Serialize the data Fifos
      */
-    int txNumPkts = txFifo.size();
-    SERIALIZE_SCALAR(txNumPkts);
-    int i = 0;
-    pktiter_t end = txFifo.end();
-    for (pktiter_t p = txFifo.begin(); p != end; ++p)
-        (*p)->serialize(csprintf("txFifo%d", i++), os);
-
-    int rxNumPkts = rxFifo.size();
-    SERIALIZE_SCALAR(rxNumPkts);
-    i = 0;
-    end = rxFifo.end();
-    for (pktiter_t p = rxFifo.begin(); p != end; ++p)
-        (*p)->serialize(csprintf("rxFifo%d", i++), os);
+    rxFifo.serialize("rxFifo", os);
+    txFifo.serialize("txFifo", os);
 
     /*
      * Serialize the various helper variables
@@ -2174,7 +2154,6 @@ NSGigE::serialize(ostream &os)
     SERIALIZE_SCALAR(txState);
     SERIALIZE_SCALAR(txEnable);
     SERIALIZE_SCALAR(CTDD);
-    SERIALIZE_SCALAR(txFifoAvail);
     SERIALIZE_SCALAR(txFragPtr);
     SERIALIZE_SCALAR(txDescCnt);
     int txDmaState = this->txDmaState;
@@ -2188,7 +2167,6 @@ NSGigE::serialize(ostream &os)
     SERIALIZE_SCALAR(rxEnable);
     SERIALIZE_SCALAR(CRDD);
     SERIALIZE_SCALAR(rxPktBytes);
-    SERIALIZE_SCALAR(rxFifoCnt);
     SERIALIZE_SCALAR(rxDescCnt);
     int rxDmaState = this->rxDmaState;
     SERIALIZE_SCALAR(rxDmaState);
@@ -2270,22 +2248,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     /*
      * unserialize the data fifos
      */
-    int txNumPkts;
-    UNSERIALIZE_SCALAR(txNumPkts);
-    int i;
-    for (i = 0; i < txNumPkts; ++i) {
-        PacketPtr p = new PacketData;
-        p->unserialize(csprintf("rxFifo%d", i), cp, section);
-        txFifo.push_back(p);
-    }
-
-    int rxNumPkts;
-    UNSERIALIZE_SCALAR(rxNumPkts);
-    for (i = 0; i < rxNumPkts; ++i) {
-        PacketPtr p = new PacketData;
-        p->unserialize(csprintf("rxFifo%d", i), cp, section);
-        rxFifo.push_back(p);
-    }
+    rxFifo.unserialize("rxFifo", cp, section);
+    txFifo.unserialize("txFifo", cp, section);
 
     /*
      * unserialize the various helper variables
@@ -2336,7 +2300,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     this->txState = (TxState) txState;
     UNSERIALIZE_SCALAR(txEnable);
     UNSERIALIZE_SCALAR(CTDD);
-    UNSERIALIZE_SCALAR(txFifoAvail);
     UNSERIALIZE_SCALAR(txFragPtr);
     UNSERIALIZE_SCALAR(txDescCnt);
     int txDmaState;
@@ -2352,7 +2315,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(rxEnable);
     UNSERIALIZE_SCALAR(CRDD);
     UNSERIALIZE_SCALAR(rxPktBytes);
-    UNSERIALIZE_SCALAR(rxFifoCnt);
     UNSERIALIZE_SCALAR(rxDescCnt);
     int rxDmaState;
     UNSERIALIZE_SCALAR(rxDmaState);
index fc2c88a6ca9e4a1ee1b8aea09301a590dc4175ca..90711d63fc3e72e4b908d5d553187e1548a0ce0e 100644 (file)
@@ -41,6 +41,7 @@
 #include "dev/io_device.hh"
 #include "dev/ns_gige_reg.h"
 #include "dev/pcidev.hh"
+#include "dev/pktfifo.hh"
 #include "mem/bus/bus.hh"
 #include "sim/eventq.hh"
 
@@ -158,10 +159,8 @@ class NSGigE : public PciDev
 
     /*** BASIC STRUCTURES FOR TX/RX ***/
     /* Data FIFOs */
-    pktbuf_t txFifo;
-    uint32_t maxTxFifoSize;
-    pktbuf_t rxFifo;
-    uint32_t maxRxFifoSize;
+    PacketFifo txFifo;
+    PacketFifo rxFifo;
 
     /** various helper vars */
     PacketPtr txPacket;
@@ -183,8 +182,6 @@ class NSGigE : public PciDev
 
     /** Current Transmit Descriptor Done */
     bool CTDD;
-    /** current amt of free space in txDataFifo in bytes */
-    uint32_t txFifoAvail;
     /** halt the tx state machine after next packet */
     bool txHalt;
     /** ptr to the next byte in the current fragment */
@@ -201,8 +198,6 @@ class NSGigE : public PciDev
     bool CRDD;
     /** num of bytes in the current packet being drained from rxDataFifo */
     uint32_t rxPktBytes;
-    /** number of bytes in the rxFifo */
-    uint32_t rxFifoCnt;
     /** halt the rx state machine after current packet */
     bool rxHalt;
     /** ptr to the next byte in current fragment */
diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc
new file mode 100644 (file)
index 0000000..cf09ae9
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "base/misc.hh"
+#include "dev/pktfifo.hh"
+
+using namespace std;
+
+void
+PacketFifo::serialize(const string &base, ostream &os)
+{
+    paramOut(os, base + ".size", _size);
+    paramOut(os, base + ".maxsize", _maxsize);
+    paramOut(os, base + ".packets", fifo.size());
+
+    int i = 0;
+    std::list<PacketPtr>::iterator p = fifo.begin();
+    std::list<PacketPtr>::iterator end = fifo.end();
+    while (p != end) {
+        (*p)->serialize(csprintf("%s.packet%d", base, i), os);
+        ++p;
+        ++i;
+    }
+}
+
+void
+PacketFifo::unserialize(const string &base, Checkpoint *cp,
+                        const string &section)
+{
+    paramIn(cp, section, base + ".size", _size);
+    paramIn(cp, section, base + ".maxsize", _maxsize);
+    int fifosize;
+    paramIn(cp, section, base + ".packets", fifosize);
+
+    fifo.clear();
+    fifo.resize(fifosize);
+
+    for (int i = 0; i < fifosize; ++i) {
+        PacketPtr p = new PacketData;
+        p->unserialize(csprintf("%s.packet%d", base, i), cp, section);
+        fifo.push_back(p);
+    }
+}
diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh
new file mode 100644 (file)
index 0000000..a54a499
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DEV_PKTFIFO_HH__
+#define __DEV_PKTFIFO_HH__
+
+#include <iosfwd>
+#include <list>
+#include <string>
+
+#include "dev/etherpkt.hh"
+#include "sim/serialize.hh"
+
+class Checkpoint;
+class PacketFifo
+{
+  protected:
+    std::list<PacketPtr> fifo;
+    int _maxsize;
+    int _size;
+
+  public:
+    explicit PacketFifo(int max) : _maxsize(max), _size(0) {}
+    virtual ~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; }
+
+    bool push(PacketPtr ptr)
+    {
+        if (avail() < ptr->length)
+            return false;
+
+        _size += ptr->length;
+        fifo.push_back(ptr);
+        return true;
+    }
+
+    PacketPtr front() { return fifo.front(); }
+
+    void pop()
+    {
+        if (empty())
+            return;
+
+        _size -= fifo.front()->length;
+        fifo.front() = NULL;
+        fifo.pop_front();
+    }
+
+    void clear()
+    {
+        fifo.clear();
+        _size = 0;
+    }
+
+/**
+ * Serialization stuff
+ */
+  public:
+    void serialize(const std::string &base, std::ostream &os);
+    void unserialize(const std::string &base,
+                     Checkpoint *cp, const std::string &section);
+};
+
+#endif // __DEV_PKTFIFO_HH__