Major update to sinic to support VSINIC better
authorNathan Binkert <binkertn@umich.edu>
Wed, 26 Apr 2006 21:52:33 +0000 (17:52 -0400)
committerNathan Binkert <binkertn@umich.edu>
Wed, 26 Apr 2006 21:52:33 +0000 (17:52 -0400)
dev/sinic.cc:
    - Size the virtualRegs array based on the configured value
    - Add debugging stuff for uniquely identifying vnic usage
    - Only count totally unprocessed packets when notifying via RxDone
    - Add initial virtual address support
    - Fix some bugs in accessing packets out of order to make sure that
    busy packets are processed first
    - Add fifo watermark stuff
    - Make number of vnics, zero/delay copy and watermarks parameters
dev/sinic.hh:
    add rxUnique and txUnique to uniquely identify tx and rx VNICs
    Create a separate list of Busy VNICs since more than one might
    be busy and we want to service those first
    Add more watermark stuff and new parameters
dev/sinicreg.hh:
    Make the number of virtual nics a read-only parameter
    add bits for ZeroCopy/DelayCopy
    rename Virtual to Vaddr so it's not ambiguous
    Add a flag for TxData/RxData to indicate a virtual address
    Report rxfifo status in RxDone
python/m5/objects/Ethernet.py:
    add more options for the fifo thresholds
    add number of vnics as a parameter
    add copy type as a parameter
    add virtual addressing as a parameter

--HG--
extra : convert_revision : 850e2433b585d65469d4c5d85ad7ca820db10f4a

dev/sinic.cc
dev/sinic.hh
dev/sinicreg.hh
python/m5/objects/Ethernet.py

index 88e365e661294b2aba09c96db6ed234765eaf3d6..d19ef268fbb22c75314eff1a7b29c1794bb138a5 100644 (file)
@@ -85,7 +85,8 @@ Base::Base(Params *p)
 }
 
 Device::Device(Params *p)
-    : Base(p), plat(p->plat), physmem(p->physmem),
+    : Base(p), plat(p->plat), physmem(p->physmem), rxUnique(0), txUnique(0),
+      virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
       rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
       rxKickTick(0), txKickTick(0),
       txEvent(this), rxDmaEvent(this), txDmaEvent(this),
@@ -315,12 +316,9 @@ void
 Device::prepareIO(int cpu, int index)
 {
     int size = virtualRegs.size();
-    if (index < size)
-        return;
-
-    virtualRegs.resize(index + 1);
-    for (int i = size; i <= index; ++i)
-        virtualRegs[i].rxPacket = rxFifo.end();
+    if (index > size)
+        panic("Trying to access a vnic that doesn't exist %d > %d\n",
+              index, size);
 }
 
 void
@@ -333,7 +331,10 @@ Device::prepareRead(int cpu, int index)
 
     // update rx registers
     uint64_t rxdone = vnic.RxDone;
-    rxdone = set_RxDone_Packets(rxdone, rxFifo.packets());
+    rxdone = set_RxDone_Packets(rxdone, rxFifo.countPacketsAfter(rxFifoPtr));
+    rxdone = set_RxDone_Empty(rxdone, rxFifo.empty());
+    rxdone = set_RxDone_High(rxdone, rxFifo.size() > regs.RxFifoMark);
+    rxdone = set_RxDone_NotHigh(rxdone, rxLow);
     regs.RxData = vnic.RxData;
     regs.RxDone = rxdone;
     regs.RxWait = rxdone;
@@ -527,10 +528,32 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
             panic("receive machine busy with another request! rxState=%s",
                   RxStateStrings[rxState]);
 
+        vnic.rxUnique = rxUnique++;
         vnic.RxDone = Regs::RxDone_Busy;
         vnic.RxData = reg64;
-        rxList.push_back(index);
-        if (rxEnable && rxState == rxIdle) {
+
+        if (Regs::get_RxData_Vaddr(reg64)) {
+            Addr vaddr = Regs::get_RxData_Addr(reg64);
+            Addr paddr = vtophys(req->xc, vaddr);
+            DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d): "
+                    "vaddr=%#x, paddr=%#x\n",
+                    index, vnic.rxUnique, vaddr, paddr);
+
+            vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr);
+        } else {
+            DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d)\n",
+                    index, vnic.rxUnique);
+        }
+
+        if (vnic.rxPacket == rxFifo.end()) {
+            DPRINTF(EthernetPIO, "request new packet...appending to rxList\n");
+            rxList.push_back(index);
+        } else {
+            DPRINTF(EthernetPIO, "packet exists...appending to rxBusy\n");
+            rxBusy.push_back(index);
+        }
+
+        if (rxEnable && (rxState == rxIdle || rxState == rxFifoBlock)) {
             rxState = rxFifoBlock;
             rxKick();
         }
@@ -541,8 +564,23 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
             panic("transmit machine busy with another request! txState=%s",
                   TxStateStrings[txState]);
 
+        vnic.txUnique = txUnique++;
         vnic.TxDone = Regs::TxDone_Busy;
         vnic.TxData = reg64;
+
+        if (Regs::get_TxData_Vaddr(reg64)) {
+            Addr vaddr = Regs::get_TxData_Addr(reg64);
+            Addr paddr = vtophys(req->xc, vaddr);
+            DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): "
+                    "vaddr=%#x, paddr=%#x\n",
+                    index, vnic.txUnique, vaddr, paddr);
+
+            vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);
+        } else {
+            DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n",
+                    index, vnic.txUnique);
+        }
+
         if (txList.empty() || txList.front() != index)
             txList.push_back(index);
         if (txEnable && txState == txIdle && txList.front() == index) {
@@ -768,10 +806,21 @@ Device::reset()
         regs.Config |= Config_TxThread;
     if (params()->rss)
         regs.Config |= Config_RSS;
+    if (params()->zero_copy)
+        regs.Config |= Config_ZeroCopy;
+    if (params()->delay_copy)
+        regs.Config |= Config_DelayCopy;
+    if (params()->virtual_addr)
+        regs.Config |= Config_Vaddr;
+
+    if (params()->delay_copy && params()->zero_copy)
+        panic("Can't delay copy and zero copy");
+
     regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow;
     regs.RxMaxCopy = params()->rx_max_copy;
     regs.TxMaxCopy = params()->tx_max_copy;
     regs.RxMaxIntr = params()->rx_max_intr;
+    regs.VirtualCount = params()->virtual_count;
     regs.RxFifoSize = params()->rx_fifo_size;
     regs.TxFifoSize = params()->tx_fifo_size;
     regs.RxFifoMark = params()->rx_fifo_threshold;
@@ -779,6 +828,8 @@ Device::reset()
     regs.HwAddr = params()->eaddr;
 
     rxList.clear();
+    rxBusy.clear();
+    rxActive = -1;
     txList.clear();
 
     rxState = rxIdle;
@@ -788,6 +839,7 @@ Device::reset()
     rxFifoPtr = rxFifo.end();
     txFifo.clear();
     rxEmpty = false;
+    rxLow = true;
     txFull = false;
 
     int size = virtualRegs.size();
@@ -825,7 +877,7 @@ Device::rxDmaDone()
 void
 Device::rxKick()
 {
-    VirtualReg *vnic;
+    VirtualReg *vnic = NULL;
 
     DPRINTF(EthernetSM, "rxKick: rxState=%s (rxFifo.size=%d)\n",
             RxStateStrings[rxState], rxFifo.size());
@@ -840,16 +892,50 @@ Device::rxKick()
     if (rxState == rxIdle)
         goto exit;
 
-    assert(!rxList.empty());
-    vnic = &virtualRegs[rxList.front()];
+    if (rxActive == -1) {
+        if (rxState != rxFifoBlock)
+            panic("no active vnic while in state %s", RxStateStrings[rxState]);
 
-    DPRINTF(EthernetSM, "processing rxState=%s for virtual nic %d\n",
-            RxStateStrings[rxState], rxList.front());
+        DPRINTF(EthernetSM, "processing rxState=%s\n",
+                RxStateStrings[rxState]);
+    } else {
+        vnic = &virtualRegs[rxActive];
+        DPRINTF(EthernetSM,
+                "processing rxState=%s for vnic %d (rxunique %d)\n",
+                RxStateStrings[rxState], rxActive, vnic->rxUnique);
+    }
 
     switch (rxState) {
       case rxFifoBlock:
-        if (vnic->rxPacket != rxFifo.end()) {
+        if (DTRACE(EthernetSM)) {
+            PacketFifo::iterator end = rxFifo.end();
+            int size = virtualRegs.size();
+            for (int i = 0; i < size; ++i) {
+                VirtualReg *vn = &virtualRegs[i];
+                if (vn->rxPacket != end &&
+                    !Regs::get_RxDone_Busy(vn->RxDone)) {
+                    DPRINTF(EthernetSM,
+                            "vnic %d (rxunique %d), has outstanding packet %d\n",
+                            i, vn->rxUnique,
+                            rxFifo.countPacketsBefore(vn->rxPacket));
+                }
+            }
+        }
+
+        if (!rxBusy.empty()) {
+            rxActive = rxBusy.front();
+            rxBusy.pop_front();
+            vnic = &virtualRegs[rxActive];
+
+            if (vnic->rxPacket == rxFifo.end())
+                panic("continuing vnic without packet\n");
+
+            DPRINTF(EthernetSM,
+                    "continue processing for vnic %d (rxunique %d)\n",
+                    rxActive, vnic->rxUnique);
+
             rxState = rxBeginCopy;
+
             break;
         }
 
@@ -858,8 +944,19 @@ Device::rxKick()
             goto exit;
         }
 
+        if (rxList.empty())
+            panic("Not idle, but nothing to do!");
+
         assert(!rxFifo.empty());
 
+        rxActive = rxList.front();
+        rxList.pop_front();
+        vnic = &virtualRegs[rxActive];
+
+        DPRINTF(EthernetSM,
+                "processing new packet for vnic %d (rxunique %d)\n",
+                rxActive, vnic->rxUnique);
+
         // Grab a new packet from the fifo.
         vnic->rxPacket = rxFifoPtr++;
         vnic->rxPacketOffset = 0;
@@ -913,6 +1010,11 @@ Device::rxKick()
         rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
         rxState = rxCopy;
 
+        if (rxDmaAddr == 1LL) {
+            rxState = rxCopyDone;
+            break;
+        }
+
         if (dmaInterface) {
             dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen,
                                 curTick, &rxDmaEvent, true);
@@ -934,31 +1036,44 @@ Device::rxKick()
         goto exit;
 
       case rxCopyDone:
-        vnic->RxDone = vnic->rxDoneData | rxDmaLen;
+        vnic->RxDone = vnic->rxDoneData;
         vnic->RxDone |= Regs::RxDone_Complete;
 
         if (vnic->rxPacketBytes == rxDmaLen) {
-            DPRINTF(EthernetSM, "rxKick: packet complete on vnic %d\n",
-                    rxList.front());
+            // Packet is complete.  Indicate how many bytes were copied
+            vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone, rxDmaLen);
+
+            DPRINTF(EthernetSM,
+                    "rxKick: packet complete on vnic %d (rxunique %d)\n",
+                    rxActive, vnic->rxUnique);
             rxFifo.remove(vnic->rxPacket);
             vnic->rxPacket = rxFifo.end();
         } else {
-            vnic->RxDone |= Regs::RxDone_More;
             vnic->rxPacketBytes -= rxDmaLen;
             vnic->rxPacketOffset += rxDmaLen;
+            vnic->RxDone |= Regs::RxDone_More;
+            vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone,
+                                                    vnic->rxPacketBytes);
             DPRINTF(EthernetSM,
-                    "rxKick: packet not complete on vnic %d: %d bytes left\n",
-                    rxList.front(), vnic->rxPacketBytes);
+                    "rxKick: packet not complete on vnic %d (rxunique %d): "
+                    "%d bytes left\n",
+                    rxActive, vnic->rxUnique, vnic->rxPacketBytes);
         }
 
-        rxList.pop_front();
-        rxState = rxList.empty() ? rxIdle : rxFifoBlock;
+        rxActive = -1;
+        rxState = rxBusy.empty() && rxList.empty() ? rxIdle : rxFifoBlock;
 
         if (rxFifo.empty()) {
             devIntrPost(Regs::Intr_RxEmpty);
             rxEmpty = true;
         }
 
+        if (rxFifo.size() < params()->rx_fifo_low_mark)
+            rxLow = true;
+
+        if (rxFifo.size() > params()->rx_fifo_threshold)
+            rxLow = false;
+
         devIntrPost(Regs::Intr_RxDMA);
         break;
 
@@ -1353,6 +1468,7 @@ Device::serialize(ostream &os)
     SERIALIZE_SCALAR(regs.RxMaxCopy);
     SERIALIZE_SCALAR(regs.TxMaxCopy);
     SERIALIZE_SCALAR(regs.RxMaxIntr);
+    SERIALIZE_SCALAR(regs.VirtualCount);
     SERIALIZE_SCALAR(regs.RxData);
     SERIALIZE_SCALAR(regs.RxDone);
     SERIALIZE_SCALAR(regs.TxData);
@@ -1372,8 +1488,6 @@ Device::serialize(ostream &os)
         paramOut(os, reg + ".TxData", vnic->TxData);
         paramOut(os, reg + ".TxDone", vnic->TxDone);
 
-        PacketFifo::iterator rxFifoPtr;
-
         bool rxPacketExists = vnic->rxPacket != rxFifo.end();
         paramOut(os, reg + ".rxPacketExists", rxPacketExists);
         if (rxPacketExists) {
@@ -1392,18 +1506,26 @@ Device::serialize(ostream &os)
         paramOut(os, reg + ".rxDoneData", vnic->rxDoneData);
     }
 
-    VirtualList::iterator i, end;
-    int count;
+    int rxFifoPtr = rxFifo.countPacketsBefore(this->rxFifoPtr);
+    SERIALIZE_SCALAR(rxFifoPtr);
 
-    int rxListSize = rxList.size();
-    SERIALIZE_SCALAR(rxListSize);
+    SERIALIZE_SCALAR(rxActive);
+
+    VirtualList::iterator i, end;
     for (count = 0, i = rxList.begin(), end = rxList.end(); i != end; ++i)
         paramOut(os, csprintf("rxList%d", count++), *i);
+    int rxListSize = count;
+    SERIALIZE_SCALAR(rxListSize);
+
+    for (count = 0, i = rxBusy.begin(), end = rxBusy.end(); i != end; ++i)
+        paramOut(os, csprintf("rxBusy%d", count++), *i);
+    int rxBusySize = count;
+    SERIALIZE_SCALAR(rxBusySize);
 
-    int txListSize = txList.size();
-    SERIALIZE_SCALAR(txListSize);
     for (count = 0, i = txList.begin(), end = txList.end(); i != end; ++i)
         paramOut(os, csprintf("txList%d", count++), *i);
+    int txListSize = count;
+    SERIALIZE_SCALAR(txListSize);
 
     /*
      * Serialize rx state machine
@@ -1411,6 +1533,7 @@ Device::serialize(ostream &os)
     int rxState = this->rxState;
     SERIALIZE_SCALAR(rxState);
     SERIALIZE_SCALAR(rxEmpty);
+    SERIALIZE_SCALAR(rxLow);
     rxFifo.serialize("rxFifo", os);
 
     /*
@@ -1451,11 +1574,14 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(regs.RxMaxCopy);
     UNSERIALIZE_SCALAR(regs.TxMaxCopy);
     UNSERIALIZE_SCALAR(regs.RxMaxIntr);
+    UNSERIALIZE_SCALAR(regs.VirtualCount);
     UNSERIALIZE_SCALAR(regs.RxData);
     UNSERIALIZE_SCALAR(regs.RxDone);
     UNSERIALIZE_SCALAR(regs.TxData);
     UNSERIALIZE_SCALAR(regs.TxDone);
 
+    UNSERIALIZE_SCALAR(rxActive);
+
     int rxListSize;
     UNSERIALIZE_SCALAR(rxListSize);
     rxList.clear();
@@ -1465,6 +1591,15 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
         rxList.push_back(value);
     }
 
+    int rxBusySize;
+    UNSERIALIZE_SCALAR(rxBusySize);
+    rxBusy.clear();
+    for (int i = 0; i < rxBusySize; ++i) {
+        int value;
+        paramIn(cp, section, csprintf("rxBusy%d", i), value);
+        rxBusy.push_back(value);
+    }
+
     int txListSize;
     UNSERIALIZE_SCALAR(txListSize);
     txList.clear();
@@ -1480,9 +1615,16 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
     int rxState;
     UNSERIALIZE_SCALAR(rxState);
     UNSERIALIZE_SCALAR(rxEmpty);
+    UNSERIALIZE_SCALAR(rxLow);
     this->rxState = (RxState) rxState;
     rxFifo.unserialize("rxFifo", cp, section);
 
+    int rxFifoPtr;
+    UNSERIALIZE_SCALAR(rxFifoPtr);
+    this->rxFifoPtr = rxFifo.begin();
+    for (int i = 0; i < rxFifoPtr; ++i)
+        ++this->rxFifoPtr;
+
     /*
      * Unserialize tx state machine
      */
@@ -1520,6 +1662,9 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
         paramIn(cp, section, reg + ".TxData", vnic->TxData);
         paramIn(cp, section, reg + ".TxDone", vnic->TxDone);
 
+        vnic->rxUnique = rxUnique++;
+        vnic->txUnique = txUnique++;
+
         bool rxPacketExists;
         paramIn(cp, section, reg + ".rxPacketExists", rxPacketExists);
         if (rxPacketExists) {
@@ -1549,10 +1694,8 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
     /*
      * re-add addrRanges to bus bridges
      */
-    if (pioInterface) {
+    if (pioInterface)
         pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0]));
-        pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1]));
-    }
 }
 
 Tick
@@ -1634,6 +1777,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
     Param<uint32_t> rx_fifo_size;
     Param<uint32_t> tx_fifo_size;
     Param<uint32_t> rx_fifo_threshold;
+    Param<uint32_t> rx_fifo_low_mark;
+    Param<uint32_t> tx_fifo_high_mark;
     Param<uint32_t> tx_fifo_threshold;
 
     Param<bool> rx_filter;
@@ -1641,6 +1786,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
     Param<bool> rx_thread;
     Param<bool> tx_thread;
     Param<bool> rss;
+    Param<uint32_t> virtual_count;
+    Param<bool> zero_copy;
+    Param<bool> delay_copy;
+    Param<bool> virtual_addr;
 
 END_DECLARE_SIM_OBJECT_PARAMS(Device)
 
@@ -1678,13 +1827,19 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
     INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"),
     INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"),
     INIT_PARAM(rx_fifo_threshold, "max size in bytes of rxFifo"),
+    INIT_PARAM(rx_fifo_low_mark, "max size in bytes of rxFifo"),
+    INIT_PARAM(tx_fifo_high_mark, "max size in bytes of txFifo"),
     INIT_PARAM(tx_fifo_threshold, "max size in bytes of txFifo"),
 
     INIT_PARAM(rx_filter, "Enable Receive Filter"),
     INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
     INIT_PARAM(rx_thread, ""),
     INIT_PARAM(tx_thread, ""),
-    INIT_PARAM(rss, "")
+    INIT_PARAM(rss, ""),
+    INIT_PARAM(virtual_count, ""),
+    INIT_PARAM(zero_copy, ""),
+    INIT_PARAM(delay_copy, ""),
+    INIT_PARAM(virtual_addr, "")
 
 END_INIT_SIM_OBJECT_PARAMS(Device)
 
@@ -1726,6 +1881,8 @@ CREATE_SIM_OBJECT(Device)
     params->rx_fifo_size = rx_fifo_size;
     params->tx_fifo_size = tx_fifo_size;
     params->rx_fifo_threshold = rx_fifo_threshold;
+    params->rx_fifo_low_mark = rx_fifo_low_mark;
+    params->tx_fifo_high_mark = tx_fifo_high_mark;
     params->tx_fifo_threshold = tx_fifo_threshold;
 
     params->rx_filter = rx_filter;
@@ -1733,6 +1890,10 @@ CREATE_SIM_OBJECT(Device)
     params->rx_thread = rx_thread;
     params->tx_thread = tx_thread;
     params->rss = rss;
+    params->virtual_count = virtual_count;
+    params->zero_copy = zero_copy;
+    params->delay_copy = delay_copy;
+    params->virtual_addr = virtual_addr;
 
     return new Device(params);
 }
index 25172fa459c875328a5a5e702b968d43123a03a5..892b3ab6944dc9e0cbe7dbbacc00ae3486d7ac2d 100644 (file)
@@ -122,7 +122,7 @@ class Device : public Base
         uint32_t RxMaxCopy;    // 0x10
         uint32_t TxMaxCopy;    // 0x14
         uint32_t RxMaxIntr;    // 0x18
-        uint32_t Reserved0;    // 0x1c
+        uint32_t VirtualCount; // 0x1c
         uint32_t RxFifoSize;   // 0x20
         uint32_t TxFifoSize;   // 0x24
         uint32_t RxFifoMark;   // 0x28
@@ -147,6 +147,9 @@ class Device : public Base
         int rxPacketBytes;
         uint64_t rxDoneData;
 
+        Counter rxUnique;
+        Counter txUnique;
+
         VirtualReg()
             : RxData(0), RxDone(0), TxData(0), TxDone(0),
               rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
@@ -154,8 +157,12 @@ class Device : public Base
     };
     typedef std::vector<VirtualReg> VirtualRegs;
     typedef std::list<int> VirtualList;
+    Counter rxUnique;
+    Counter txUnique;
     VirtualRegs virtualRegs;
     VirtualList rxList;
+    VirtualList rxBusy;
+    int rxActive;
     VirtualList txList;
 
     uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
@@ -171,6 +178,7 @@ class Device : public Base
     PacketFifo rxFifo;
     PacketFifo::iterator rxFifoPtr;
     bool rxEmpty;
+    bool rxLow;
     Addr rxDmaAddr;
     uint8_t *rxDmaData;
     int rxDmaLen;
@@ -347,6 +355,8 @@ class Device : public Base
         uint32_t rx_fifo_size;
         uint32_t tx_fifo_size;
         uint32_t rx_fifo_threshold;
+        uint32_t rx_fifo_low_mark;
+        uint32_t tx_fifo_high_mark;
         uint32_t tx_fifo_threshold;
         Tick dma_read_delay;
         Tick dma_read_factor;
@@ -356,6 +366,10 @@ class Device : public Base
         bool rx_thread;
         bool tx_thread;
         bool rss;
+        uint32_t virtual_count;
+        bool zero_copy;
+        bool delay_copy;
+        bool virtual_addr;
     };
 
   protected:
index 1f9bebc7d31c2dd94c552aecfcdbb920a76e1276..d41eb5b16d02051ef36c83d33358ce12a759dac7 100644 (file)
@@ -55,8 +55,8 @@
 namespace Sinic {
 namespace Regs {
 
-static const int VirtualMask = 0xff;
 static const int VirtualShift = 8;
+static const int VirtualMask = 0xff;
 
 // Registers
 __SINIC_REG32(Config,        0x00); // 32: configuration register
@@ -66,7 +66,7 @@ __SINIC_REG32(IntrMask,      0x0c); // 32: interrupt mask
 __SINIC_REG32(RxMaxCopy,     0x10); // 32: max bytes per rx copy
 __SINIC_REG32(TxMaxCopy,     0x14); // 32: max bytes per tx copy
 __SINIC_REG32(RxMaxIntr,     0x18); // 32: max receives per interrupt
-__SINIC_REG32(Reserved0,     0x1c); // 32: reserved
+__SINIC_REG32(VirtualCount,  0x1c); // 32: number of virutal NICs
 __SINIC_REG32(RxFifoSize,    0x20); // 32: rx fifo capacity in bytes
 __SINIC_REG32(TxFifoSize,    0x24); // 32: tx fifo capacity in bytes
 __SINIC_REG32(RxFifoMark,    0x28); // 32: rx fifo high watermark
@@ -81,12 +81,14 @@ __SINIC_REG32(HwAddr,        0x60); // 64: mac address
 __SINIC_REG32(Size,          0x68); // register addres space size
 
 // Config register bits
+__SINIC_VAL32(Config_ZeroCopy, 12, 1); // enable zero copy
+__SINIC_VAL32(Config_DelayCopy,11, 1); // enable delayed copy
 __SINIC_VAL32(Config_RSS,      10, 1); // enable receive side scaling
 __SINIC_VAL32(Config_RxThread,  9, 1); // enable receive threads
 __SINIC_VAL32(Config_TxThread,  8, 1); // enable transmit thread
 __SINIC_VAL32(Config_Filter,    7, 1); // enable receive filter
 __SINIC_VAL32(Config_Vlan,      6, 1); // enable vlan tagging
-__SINIC_VAL32(Config_Virtual,   5, 1); // enable virtual addressing
+__SINIC_VAL32(Config_Vaddr,     5, 1); // enable virtual addressing
 __SINIC_VAL32(Config_Desc,      4, 1); // enable tx/rx descriptors
 __SINIC_VAL32(Config_Poll,      3, 1); // enable polling
 __SINIC_VAL32(Config_IntEn,     2, 1); // enable interrupts
@@ -112,13 +114,15 @@ __SINIC_REG32(Intr_NoDelay,   0x01cc); // interrupts that aren't coalesced
 __SINIC_REG32(Intr_Res,      ~0x01ff); // reserved interrupt bits
 
 // RX Data Description
-__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M
-__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB
+__SINIC_VAL64(RxData_Vaddr, 60,  1); // Addr is virtual
+__SINIC_VAL64(RxData_Len,   40, 20); // 0 - 256k
+__SINIC_VAL64(RxData_Addr,   0, 40); // Address 1TB
 
 // TX Data Description
 __SINIC_VAL64(TxData_More,     63,  1); // Packet not complete (will dma more)
 __SINIC_VAL64(TxData_Checksum, 62,  1); // do checksum
-__SINIC_VAL64(TxData_Len,      40, 20); // 0 - 1M
+__SINIC_VAL64(TxData_Vaddr,    60,  1); // Addr is virtual
+__SINIC_VAL64(TxData_Len,      40, 20); // 0 - 256k
 __SINIC_VAL64(TxData_Addr,      0, 40); // Address 1TB
 
 // RX Done/Busy Information
@@ -126,9 +130,9 @@ __SINIC_VAL64(RxDone_Packets,   32, 16); // number of packets in rx fifo
 __SINIC_VAL64(RxDone_Busy,      31,  1); // receive dma busy copying
 __SINIC_VAL64(RxDone_Complete,  30,  1); // valid data (packet complete)
 __SINIC_VAL64(RxDone_More,      29,  1); // Packet has more data (dma again)
-__SINIC_VAL64(RxDone_Res0,      28,  1); // reserved
-__SINIC_VAL64(RxDone_Res1,      27,  1); // reserved
-__SINIC_VAL64(RxDone_Res2,      26,  1); // reserved
+__SINIC_VAL64(RxDone_Empty,     28,  1); // rx fifo is empty
+__SINIC_VAL64(RxDone_High,      27,  1); // rx fifo is above the watermark
+__SINIC_VAL64(RxDone_NotHigh,   26,  1); // rxfifo never hit the high watermark
 __SINIC_VAL64(RxDone_TcpError,  25,  1); // TCP packet error (bad checksum)
 __SINIC_VAL64(RxDone_UdpError,  24,  1); // UDP packet error (bad checksum)
 __SINIC_VAL64(RxDone_IpError,   23,  1); // IP packet error (bad checksum)
@@ -175,7 +179,7 @@ regInfo(Addr daddr)
         { 4, true,  false, "RxMaxCopy"  },
         { 4, true,  false, "TxMaxCopy"  },
         { 4, true,  false, "RxMaxIntr"  },
-        invalid,
+        { 4, true,  false, "VirtualCount"  },
         { 4, true,  false, "RxFifoSize" },
         { 4, true,  false, "TxFifoSize" },
         { 4, true,  false, "RxFifoMark" },
index 6113e656f9f1208964a0bd837729a94a39d27d0f..68b21b4041186953106363ffccb53b8da1626fb4 100644 (file)
@@ -105,8 +105,14 @@ class Sinic(EtherDevBase):
     rx_max_copy = Param.MemorySize('1514B', "rx max copy")
     tx_max_copy = Param.MemorySize('16kB', "tx max copy")
     rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
-    rx_fifo_threshold = Param.MemorySize('48kB', "rx fifo high threshold")
-    tx_fifo_threshold = Param.MemorySize('16kB', "tx fifo low threshold")
+    rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold")
+    rx_fifo_low_mark = Param.MemorySize('128kB', "rx fifo low threshold")
+    tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold")
+    tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold")
+    virtual_count = Param.UInt32(1, "Virtualized SINIC")
+    zero_copy = Param.Bool(False, "Zero copy receive")
+    delay_copy = Param.Bool(False, "Delayed copy transmit")
+    virtual_addr = Param.Bool(False, "Virtual addressing")
 
 class SinicInt(EtherInt):
     type = 'SinicInt'