/*
 * Copyright (c) 2006 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.
 *
 * Authors: Ali Saidi
 */

/* @file
 * Device model for Intel's 8254x line of gigabit ethernet controllers.
 * In particular an 82547 revision 2 (82547GI) MAC because it seems to have the
 * fewest workarounds in the driver. It will probably work with most of the
 * other MACs with slight modifications.
 */

#include "dev/net/i8254xGBe.hh"

/*
 * @todo really there are multiple dma engines.. we should implement them.
 */

#include <algorithm>
#include <memory>

#include "base/inet.hh"
#include "base/trace.hh"
#include "debug/Drain.hh"
#include "debug/EthernetAll.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/IGbE.hh"
#include "sim/stats.hh"
#include "sim/system.hh"

using namespace iGbReg;
using namespace Net;

IGbE::IGbE(const Params *p)
    : EtherDevice(p), etherInt(NULL), cpa(NULL),
      rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), inTick(false),
      rxTick(false), txTick(false), txFifoTick(false), rxDmaPacket(false),
      pktOffset(0), fetchDelay(p->fetch_delay), wbDelay(p->wb_delay),
      fetchCompDelay(p->fetch_comp_delay), wbCompDelay(p->wb_comp_delay),
      rxWriteDelay(p->rx_write_delay), txReadDelay(p->tx_read_delay),
      rdtrEvent([this]{ rdtrProcess(); }, name()),
      radvEvent([this]{ radvProcess(); }, name()),
      tadvEvent([this]{ tadvProcess(); }, name()),
      tidvEvent([this]{ tidvProcess(); }, name()),
      tickEvent([this]{ tick(); }, name()),
      interEvent([this]{ delayIntEvent(); }, name()),
      rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
      txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size),
      lastInterrupt(0)
{
    etherInt = new IGbEInt(name() + ".int", this);

    // Initialized internal registers per Intel documentation
    // All registers intialized to 0 by per register constructor
    regs.ctrl.fd(1);
    regs.ctrl.lrst(1);
    regs.ctrl.speed(2);
    regs.ctrl.frcspd(1);
    regs.sts.speed(3); // Say we're 1000Mbps
    regs.sts.fd(1); // full duplex
    regs.sts.lu(1); // link up
    regs.eecd.fwe(1);
    regs.eecd.ee_type(1);
    regs.imr = 0;
    regs.iam = 0;
    regs.rxdctl.gran(1);
    regs.rxdctl.wthresh(1);
    regs.fcrth(1);
    regs.tdwba = 0;
    regs.rlpml = 0;
    regs.sw_fw_sync = 0;

    regs.pba.rxa(0x30);
    regs.pba.txa(0x10);

    eeOpBits            = 0;
    eeAddrBits          = 0;
    eeDataBits          = 0;
    eeOpcode            = 0;

    // clear all 64 16 bit words of the eeprom
    memset(&flash, 0, EEPROM_SIZE*2);

    // Set the MAC address
    memcpy(flash, p->hardware_address.bytes(), ETH_ADDR_LEN);
    for (int x = 0; x < ETH_ADDR_LEN/2; x++)
        flash[x] = htobe(flash[x]);

    uint16_t csum = 0;
    for (int x = 0; x < EEPROM_SIZE; x++)
        csum += htobe(flash[x]);


    // Magic happy checksum value
    flash[EEPROM_SIZE-1] = htobe((uint16_t)(EEPROM_CSUM - csum));

    // Store the MAC address as queue ID
    macAddr = p->hardware_address;

    rxFifo.clear();
    txFifo.clear();
}

IGbE::~IGbE()
{
    delete etherInt;
}

void
IGbE::init()
{
    cpa = CPA::cpa();
    PciDevice::init();
}

EtherInt*
IGbE::getEthPort(const std::string &if_name, int idx)
{

    if (if_name == "interface") {
        if (etherInt->getPeer())
            panic("Port already connected to\n");
        return etherInt;
    }
    return NULL;
}

Tick
IGbE::writeConfig(PacketPtr pkt)
{
    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
    if (offset < PCI_DEVICE_SPECIFIC)
        PciDevice::writeConfig(pkt);
    else
        panic("Device specific PCI config space not implemented.\n");

    //
    // Some work may need to be done here based for the pci COMMAND bits.
    //

    return configDelay;
}

// Handy macro for range-testing register access addresses
#define IN_RANGE(val, base, len) (val >= base && val < (base + len))

Tick
IGbE::read(PacketPtr pkt)
{
    int bar;
    Addr daddr;

    if (!getBAR(pkt->getAddr(), bar, daddr))
        panic("Invalid PCI memory access to unmapped memory.\n");

    // Only Memory register BAR is allowed
    assert(bar == 0);

    // Only 32bit accesses allowed
    assert(pkt->getSize() == 4);

    DPRINTF(Ethernet, "Read device register %#X\n", daddr);

    //
    // Handle read of register here
    //


    switch (daddr) {
      case REG_CTRL:
        pkt->setLE<uint32_t>(regs.ctrl());
        break;
      case REG_STATUS:
        pkt->setLE<uint32_t>(regs.sts());
        break;
      case REG_EECD:
        pkt->setLE<uint32_t>(regs.eecd());
        break;
      case REG_EERD:
        pkt->setLE<uint32_t>(regs.eerd());
        break;
      case REG_CTRL_EXT:
        pkt->setLE<uint32_t>(regs.ctrl_ext());
        break;
      case REG_MDIC:
        pkt->setLE<uint32_t>(regs.mdic());
        break;
      case REG_ICR:
        DPRINTF(Ethernet, "Reading ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
                regs.icr(), regs.imr, regs.iam, regs.ctrl_ext.iame());
        pkt->setLE<uint32_t>(regs.icr());
        if (regs.icr.int_assert() || regs.imr == 0) {
            regs.icr = regs.icr() & ~mask(30);
            DPRINTF(Ethernet, "Cleared ICR. ICR=%#x\n", regs.icr());
        }
        if (regs.ctrl_ext.iame() && regs.icr.int_assert())
            regs.imr &= ~regs.iam;
        chkInterrupt();
        break;
      case REG_EICR:
        // This is only useful for MSI, but the driver reads it every time
        // Just don't do anything
        pkt->setLE<uint32_t>(0);
        break;
      case REG_ITR:
        pkt->setLE<uint32_t>(regs.itr());
        break;
      case REG_RCTL:
        pkt->setLE<uint32_t>(regs.rctl());
        break;
      case REG_FCTTV:
        pkt->setLE<uint32_t>(regs.fcttv());
        break;
      case REG_TCTL:
        pkt->setLE<uint32_t>(regs.tctl());
        break;
      case REG_PBA:
        pkt->setLE<uint32_t>(regs.pba());
        break;
      case REG_WUC:
      case REG_WUFC:
      case REG_WUS:
      case REG_LEDCTL:
        pkt->setLE<uint32_t>(0); // We don't care, so just return 0
        break;
      case REG_FCRTL:
        pkt->setLE<uint32_t>(regs.fcrtl());
        break;
      case REG_FCRTH:
        pkt->setLE<uint32_t>(regs.fcrth());
        break;
      case REG_RDBAL:
        pkt->setLE<uint32_t>(regs.rdba.rdbal());
        break;
      case REG_RDBAH:
        pkt->setLE<uint32_t>(regs.rdba.rdbah());
        break;
      case REG_RDLEN:
        pkt->setLE<uint32_t>(regs.rdlen());
        break;
      case REG_SRRCTL:
        pkt->setLE<uint32_t>(regs.srrctl());
        break;
      case REG_RDH:
        pkt->setLE<uint32_t>(regs.rdh());
        break;
      case REG_RDT:
        pkt->setLE<uint32_t>(regs.rdt());
        break;
      case REG_RDTR:
        pkt->setLE<uint32_t>(regs.rdtr());
        if (regs.rdtr.fpd()) {
            rxDescCache.writeback(0);
            DPRINTF(EthernetIntr,
                    "Posting interrupt because of RDTR.FPD write\n");
            postInterrupt(IT_RXT);
            regs.rdtr.fpd(0);
        }
        break;
      case REG_RXDCTL:
        pkt->setLE<uint32_t>(regs.rxdctl());
        break;
      case REG_RADV:
        pkt->setLE<uint32_t>(regs.radv());
        break;
      case REG_TDBAL:
        pkt->setLE<uint32_t>(regs.tdba.tdbal());
        break;
      case REG_TDBAH:
        pkt->setLE<uint32_t>(regs.tdba.tdbah());
        break;
      case REG_TDLEN:
        pkt->setLE<uint32_t>(regs.tdlen());
        break;
      case REG_TDH:
        pkt->setLE<uint32_t>(regs.tdh());
        break;
      case REG_TXDCA_CTL:
        pkt->setLE<uint32_t>(regs.txdca_ctl());
        break;
      case REG_TDT:
        pkt->setLE<uint32_t>(regs.tdt());
        break;
      case REG_TIDV:
        pkt->setLE<uint32_t>(regs.tidv());
        break;
      case REG_TXDCTL:
        pkt->setLE<uint32_t>(regs.txdctl());
        break;
      case REG_TADV:
        pkt->setLE<uint32_t>(regs.tadv());
        break;
      case REG_TDWBAL:
        pkt->setLE<uint32_t>(regs.tdwba & mask(32));
        break;
      case REG_TDWBAH:
        pkt->setLE<uint32_t>(regs.tdwba >> 32);
        break;
      case REG_RXCSUM:
        pkt->setLE<uint32_t>(regs.rxcsum());
        break;
      case REG_RLPML:
        pkt->setLE<uint32_t>(regs.rlpml);
        break;
      case REG_RFCTL:
        pkt->setLE<uint32_t>(regs.rfctl());
        break;
      case REG_MANC:
        pkt->setLE<uint32_t>(regs.manc());
        break;
      case REG_SWSM:
        pkt->setLE<uint32_t>(regs.swsm());
        regs.swsm.smbi(1);
        break;
      case REG_FWSM:
        pkt->setLE<uint32_t>(regs.fwsm());
        break;
      case REG_SWFWSYNC:
        pkt->setLE<uint32_t>(regs.sw_fw_sync);
        break;
      default:
        if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE*4) &&
            !IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE*8) &&
            !IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE*4) &&
            !IN_RANGE(daddr, REG_CRCERRS, STATS_REGS_SIZE))
            panic("Read request to unknown register number: %#x\n", daddr);
        else
            pkt->setLE<uint32_t>(0);
    };

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
IGbE::write(PacketPtr pkt)
{
    int bar;
    Addr daddr;


    if (!getBAR(pkt->getAddr(), bar, daddr))
        panic("Invalid PCI memory access to unmapped memory.\n");

    // Only Memory register BAR is allowed
    assert(bar == 0);

    // Only 32bit accesses allowed
    assert(pkt->getSize() == sizeof(uint32_t));

    DPRINTF(Ethernet, "Wrote device register %#X value %#X\n",
            daddr, pkt->getLE<uint32_t>());

    //
    // Handle write of register here
    //
    uint32_t val = pkt->getLE<uint32_t>();

    Regs::RCTL oldrctl;
    Regs::TCTL oldtctl;

    switch (daddr) {
      case REG_CTRL:
        regs.ctrl = val;
        if (regs.ctrl.tfce())
            warn("TX Flow control enabled, should implement\n");
        if (regs.ctrl.rfce())
            warn("RX Flow control enabled, should implement\n");
        break;
      case REG_CTRL_EXT:
        regs.ctrl_ext = val;
        break;
      case REG_STATUS:
        regs.sts = val;
        break;
      case REG_EECD:
        int oldClk;
        oldClk = regs.eecd.sk();
        regs.eecd = val;
        // See if this is a eeprom access and emulate accordingly
        if (!oldClk && regs.eecd.sk()) {
            if (eeOpBits < 8) {
                eeOpcode = eeOpcode << 1 | regs.eecd.din();
                eeOpBits++;
            } else if (eeAddrBits < 8 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
                eeAddr = eeAddr << 1 | regs.eecd.din();
                eeAddrBits++;
            } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
                assert(eeAddr>>1 < EEPROM_SIZE);
                DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n",
                        flash[eeAddr>>1] >> eeDataBits & 0x1,
                        flash[eeAddr>>1]);
                regs.eecd.dout((flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1);
                eeDataBits++;
            } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) {
                regs.eecd.dout(0);
                eeDataBits++;
            } else
                panic("What's going on with eeprom interface? opcode:"
                      " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)eeOpcode,
                      (uint32_t)eeOpBits, (uint32_t)eeAddr,
                      (uint32_t)eeAddrBits, (uint32_t)eeDataBits);

            // Reset everything for the next command
            if ((eeDataBits == 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) ||
                (eeDataBits == 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI)) {
                eeOpBits = 0;
                eeAddrBits = 0;
                eeDataBits = 0;
                eeOpcode = 0;
                eeAddr = 0;
            }

            DPRINTF(EthernetEEPROM, "EEPROM: opcode: %#X:%d addr: %#X:%d\n",
                    (uint32_t)eeOpcode, (uint32_t) eeOpBits,
                    (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
            if (eeOpBits == 8 && !(eeOpcode == EEPROM_READ_OPCODE_SPI ||
                                   eeOpcode == EEPROM_RDSR_OPCODE_SPI ))
                panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
                      (uint32_t)eeOpBits);


        }
        // If driver requests eeprom access, immediately give it to it
        regs.eecd.ee_gnt(regs.eecd.ee_req());
        break;
      case REG_EERD:
        regs.eerd = val;
        if (regs.eerd.start()) {
            regs.eerd.done(1);
            assert(regs.eerd.addr() < EEPROM_SIZE);
            regs.eerd.data(flash[regs.eerd.addr()]);
            regs.eerd.start(0);
            DPRINTF(EthernetEEPROM, "EEPROM: read addr: %#X data %#x\n",
                    regs.eerd.addr(), regs.eerd.data());
        }
        break;
      case REG_MDIC:
        regs.mdic = val;
        if (regs.mdic.i())
            panic("No support for interrupt on mdic complete\n");
        if (regs.mdic.phyadd() != 1)
            panic("No support for reading anything but phy\n");
        DPRINTF(Ethernet, "%s phy address %x\n",
                regs.mdic.op() == 1 ? "Writing" : "Reading",
                regs.mdic.regadd());
        switch (regs.mdic.regadd()) {
          case PHY_PSTATUS:
            regs.mdic.data(0x796D); // link up
            break;
          case PHY_PID:
            regs.mdic.data(params()->phy_pid);
            break;
          case PHY_EPID:
            regs.mdic.data(params()->phy_epid);
            break;
          case PHY_GSTATUS:
            regs.mdic.data(0x7C00);
            break;
          case PHY_EPSTATUS:
            regs.mdic.data(0x3000);
            break;
          case PHY_AGC:
            regs.mdic.data(0x180); // some random length
            break;
          default:
            regs.mdic.data(0);
        }
        regs.mdic.r(1);
        break;
      case REG_ICR:
        DPRINTF(Ethernet, "Writing ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
                regs.icr(), regs.imr, regs.iam, regs.ctrl_ext.iame());
        if (regs.ctrl_ext.iame())
            regs.imr &= ~regs.iam;
        regs.icr = ~bits(val,30,0) & regs.icr();
        chkInterrupt();
        break;
      case REG_ITR:
        regs.itr = val;
        break;
      case REG_ICS:
        DPRINTF(EthernetIntr, "Posting interrupt because of ICS write\n");
        postInterrupt((IntTypes)val);
        break;
      case REG_IMS:
        regs.imr |= val;
        chkInterrupt();
        break;
      case REG_IMC:
        regs.imr &= ~val;
        chkInterrupt();
        break;
      case REG_IAM:
        regs.iam = val;
        break;
      case REG_RCTL:
        oldrctl = regs.rctl;
        regs.rctl = val;
        if (regs.rctl.rst()) {
            rxDescCache.reset();
            DPRINTF(EthernetSM, "RXS: Got RESET!\n");
            rxFifo.clear();
            regs.rctl.rst(0);
        }
        if (regs.rctl.en())
            rxTick = true;
        restartClock();
        break;
      case REG_FCTTV:
        regs.fcttv = val;
        break;
      case REG_TCTL:
        regs.tctl = val;
        oldtctl = regs.tctl;
        regs.tctl = val;
        if (regs.tctl.en())
            txTick = true;
        restartClock();
        if (regs.tctl.en() && !oldtctl.en()) {
            txDescCache.reset();
        }
        break;
      case REG_PBA:
        regs.pba.rxa(val);
        regs.pba.txa(64 - regs.pba.rxa());
        break;
      case REG_WUC:
      case REG_WUFC:
      case REG_WUS:
      case REG_LEDCTL:
      case REG_FCAL:
      case REG_FCAH:
      case REG_FCT:
      case REG_VET:
      case REG_AIFS:
      case REG_TIPG:
        ; // We don't care, so don't store anything
        break;
      case REG_IVAR0:
        warn("Writing to IVAR0, ignoring...\n");
        break;
      case REG_FCRTL:
        regs.fcrtl = val;
        break;
      case REG_FCRTH:
        regs.fcrth = val;
        break;
      case REG_RDBAL:
        regs.rdba.rdbal( val & ~mask(4));
        rxDescCache.areaChanged();
        break;
      case REG_RDBAH:
        regs.rdba.rdbah(val);
        rxDescCache.areaChanged();
        break;
      case REG_RDLEN:
        regs.rdlen = val & ~mask(7);
        rxDescCache.areaChanged();
        break;
      case REG_SRRCTL:
        regs.srrctl = val;
        break;
      case REG_RDH:
        regs.rdh = val;
        rxDescCache.areaChanged();
        break;
      case REG_RDT:
        regs.rdt = val;
        DPRINTF(EthernetSM, "RXS: RDT Updated.\n");
        if (drainState() == DrainState::Running) {
            DPRINTF(EthernetSM, "RXS: RDT Fetching Descriptors!\n");
            rxDescCache.fetchDescriptors();
        } else {
            DPRINTF(EthernetSM, "RXS: RDT NOT Fetching Desc b/c draining!\n");
        }
        break;
      case REG_RDTR:
        regs.rdtr = val;
        break;
      case REG_RADV:
        regs.radv = val;
        break;
      case REG_RXDCTL:
        regs.rxdctl = val;
        break;
      case REG_TDBAL:
        regs.tdba.tdbal( val & ~mask(4));
        txDescCache.areaChanged();
        break;
      case REG_TDBAH:
        regs.tdba.tdbah(val);
        txDescCache.areaChanged();
        break;
      case REG_TDLEN:
        regs.tdlen = val & ~mask(7);
        txDescCache.areaChanged();
        break;
      case REG_TDH:
        regs.tdh = val;
        txDescCache.areaChanged();
        break;
      case REG_TXDCA_CTL:
        regs.txdca_ctl = val;
        if (regs.txdca_ctl.enabled())
            panic("No support for DCA\n");
        break;
      case REG_TDT:
        regs.tdt = val;
        DPRINTF(EthernetSM, "TXS: TX Tail pointer updated\n");
        if (drainState() == DrainState::Running) {
            DPRINTF(EthernetSM, "TXS: TDT Fetching Descriptors!\n");
            txDescCache.fetchDescriptors();
        } else {
            DPRINTF(EthernetSM, "TXS: TDT NOT Fetching Desc b/c draining!\n");
        }
        break;
      case REG_TIDV:
        regs.tidv = val;
        break;
      case REG_TXDCTL:
        regs.txdctl = val;
        break;
      case REG_TADV:
        regs.tadv = val;
        break;
      case REG_TDWBAL:
        regs.tdwba &= ~mask(32);
        regs.tdwba |= val;
        txDescCache.completionWriteback(regs.tdwba & ~mask(1),
                                        regs.tdwba & mask(1));
        break;
      case REG_TDWBAH:
        regs.tdwba &= mask(32);
        regs.tdwba |= (uint64_t)val << 32;
        txDescCache.completionWriteback(regs.tdwba & ~mask(1),
                                        regs.tdwba & mask(1));
        break;
      case REG_RXCSUM:
        regs.rxcsum = val;
        break;
      case REG_RLPML:
        regs.rlpml = val;
        break;
      case REG_RFCTL:
        regs.rfctl = val;
        if (regs.rfctl.exsten())
            panic("Extended RX descriptors not implemented\n");
        break;
      case REG_MANC:
        regs.manc = val;
        break;
      case REG_SWSM:
        regs.swsm = val;
        if (regs.fwsm.eep_fw_semaphore())
            regs.swsm.swesmbi(0);
        break;
      case REG_SWFWSYNC:
        regs.sw_fw_sync = val;
        break;
      default:
        if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE*4) &&
            !IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE*8) &&
            !IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE*4))
            panic("Write request to unknown register number: %#x\n", daddr);
    };

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
IGbE::postInterrupt(IntTypes t, bool now)
{
    assert(t);

    // Interrupt is already pending
    if (t & regs.icr() && !now)
        return;

    regs.icr = regs.icr() | t;

    Tick itr_interval = SimClock::Int::ns * 256 * regs.itr.interval();
    DPRINTF(EthernetIntr,
            "EINT: postInterrupt() curTick(): %d itr: %d interval: %d\n",
            curTick(), regs.itr.interval(), itr_interval);

    if (regs.itr.interval() == 0 || now ||
        lastInterrupt + itr_interval <= curTick()) {
        if (interEvent.scheduled()) {
            deschedule(interEvent);
        }
        cpuPostInt();
    } else {
        Tick int_time = lastInterrupt + itr_interval;
        assert(int_time > 0);
        DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for tick %d\n",
                int_time);
        if (!interEvent.scheduled()) {
            schedule(interEvent, int_time);
        }
    }
}

void
IGbE::delayIntEvent()
{
    cpuPostInt();
}


void
IGbE::cpuPostInt()
{

    postedInterrupts++;

    if (!(regs.icr() & regs.imr)) {
        DPRINTF(Ethernet, "Interrupt Masked. Not Posting\n");
        return;
    }

    DPRINTF(Ethernet, "Posting Interrupt\n");


    if (interEvent.scheduled()) {
        deschedule(interEvent);
    }

    if (rdtrEvent.scheduled()) {
        regs.icr.rxt0(1);
        deschedule(rdtrEvent);
    }
    if (radvEvent.scheduled()) {
        regs.icr.rxt0(1);
        deschedule(radvEvent);
    }
    if (tadvEvent.scheduled()) {
        regs.icr.txdw(1);
        deschedule(tadvEvent);
    }
    if (tidvEvent.scheduled()) {
        regs.icr.txdw(1);
        deschedule(tidvEvent);
    }

    regs.icr.int_assert(1);
    DPRINTF(EthernetIntr, "EINT: Posting interrupt to CPU now. Vector %#x\n",
            regs.icr());

    intrPost();

    lastInterrupt = curTick();
}

void
IGbE::cpuClearInt()
{
    if (regs.icr.int_assert()) {
        regs.icr.int_assert(0);
        DPRINTF(EthernetIntr,
                "EINT: Clearing interrupt to CPU now. Vector %#x\n",
                regs.icr());
        intrClear();
    }
}

void
IGbE::chkInterrupt()
{
    DPRINTF(Ethernet, "Checking interrupts icr: %#x imr: %#x\n", regs.icr(),
            regs.imr);
    // Check if we need to clear the cpu interrupt
    if (!(regs.icr() & regs.imr)) {
        DPRINTF(Ethernet, "Mask cleaned all interrupts\n");
        if (interEvent.scheduled())
            deschedule(interEvent);
        if (regs.icr.int_assert())
            cpuClearInt();
    }
    DPRINTF(Ethernet, "ITR = %#X itr.interval = %#X\n",
            regs.itr(), regs.itr.interval());

    if (regs.icr() & regs.imr) {
        if (regs.itr.interval() == 0)  {
            cpuPostInt();
        } else {
            DPRINTF(Ethernet,
                    "Possibly scheduling interrupt because of imr write\n");
            if (!interEvent.scheduled()) {
                Tick t = curTick() + SimClock::Int::ns * 256 * regs.itr.interval();
                DPRINTF(Ethernet, "Scheduling for %d\n", t);
                schedule(interEvent, t);
            }
        }
    }
}


///////////////////////////// IGbE::DescCache //////////////////////////////

template<class T>
IGbE::DescCache<T>::DescCache(IGbE *i, const std::string n, int s)
    : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0),
      wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
      wbDelayEvent([this]{ writeback1(); }, n),
      fetchDelayEvent([this]{ fetchDescriptors1(); }, n),
      fetchEvent([this]{ fetchComplete(); }, n),
      wbEvent([this]{ wbComplete(); }, n)
{
    fetchBuf = new T[size];
    wbBuf = new T[size];
}

template<class T>
IGbE::DescCache<T>::~DescCache()
{
    reset();
    delete[] fetchBuf;
    delete[] wbBuf;
}

template<class T>
void
IGbE::DescCache<T>::areaChanged()
{
    if (usedCache.size() > 0 || curFetching || wbOut)
        panic("Descriptor Address, Length or Head changed. Bad\n");
    reset();

}

template<class T>
void
IGbE::DescCache<T>::writeback(Addr aMask)
{
    int curHead = descHead();
    int max_to_wb = usedCache.size();

    // Check if this writeback is less restrictive that the previous
    // and if so setup another one immediately following it
    if (wbOut) {
        if (aMask < wbAlignment) {
            moreToWb = true;
            wbAlignment = aMask;
        }
        DPRINTF(EthernetDesc,
                "Writing back already in process, returning\n");
        return;
    }

    moreToWb = false;
    wbAlignment = aMask;


    DPRINTF(EthernetDesc, "Writing back descriptors head: %d tail: "
            "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
            curHead, descTail(), descLen(), cachePnt, max_to_wb,
            descLeft());

    if (max_to_wb + curHead >= descLen()) {
        max_to_wb = descLen() - curHead;
        moreToWb = true;
        // this is by definition aligned correctly
    } else if (wbAlignment != 0) {
        // align the wb point to the mask
        max_to_wb = max_to_wb & ~wbAlignment;
    }

    DPRINTF(EthernetDesc, "Writing back %d descriptors\n", max_to_wb);

    if (max_to_wb <= 0) {
        if (usedCache.size())
            igbe->anBegin(annSmWb, "Wait Alignment", CPA::FL_WAIT);
        else
            igbe->anWe(annSmWb, annUsedCacheQ);
        return;
    }

    wbOut = max_to_wb;

    assert(!wbDelayEvent.scheduled());
    igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
    igbe->anBegin(annSmWb, "Prepare Writeback Desc");
}

template<class T>
void
IGbE::DescCache<T>::writeback1()
{
    // If we're draining delay issuing this DMA
    if (igbe->drainState() != DrainState::Running) {
        igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
        return;
    }

    DPRINTF(EthernetDesc, "Begining DMA of %d descriptors\n", wbOut);

    for (int x = 0; x < wbOut; x++) {
        assert(usedCache.size());
        memcpy(&wbBuf[x], usedCache[x], sizeof(T));
        igbe->anPq(annSmWb, annUsedCacheQ);
        igbe->anPq(annSmWb, annDescQ);
        igbe->anQ(annSmWb, annUsedDescQ);
    }


    igbe->anBegin(annSmWb, "Writeback Desc DMA");

    assert(wbOut);
    igbe->dmaWrite(pciToDma(descBase() + descHead() * sizeof(T)),
                   wbOut * sizeof(T), &wbEvent, (uint8_t*)wbBuf,
                   igbe->wbCompDelay);
}

template<class T>
void
IGbE::DescCache<T>::fetchDescriptors()
{
    size_t max_to_fetch;

    if (curFetching) {
        DPRINTF(EthernetDesc,
                "Currently fetching %d descriptors, returning\n",
                curFetching);
        return;
    }

    if (descTail() >= cachePnt)
        max_to_fetch = descTail() - cachePnt;
    else
        max_to_fetch = descLen() - cachePnt;

    size_t free_cache = size - usedCache.size() - unusedCache.size();

    if (!max_to_fetch)
        igbe->anWe(annSmFetch, annUnusedDescQ);
    else
        igbe->anPq(annSmFetch, annUnusedDescQ, max_to_fetch);

    if (max_to_fetch) {
        if (!free_cache)
            igbe->anWf(annSmFetch, annDescQ);
        else
            igbe->anRq(annSmFetch, annDescQ, free_cache);
    }

    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",
            descHead(), descTail(), descLen(), cachePnt,
            max_to_fetch, descLeft());

    // Nothing to do
    if (max_to_fetch == 0)
        return;

    // So we don't have two descriptor fetches going on at once
    curFetching = max_to_fetch;

    assert(!fetchDelayEvent.scheduled());
    igbe->schedule(fetchDelayEvent, curTick() + igbe->fetchDelay);
    igbe->anBegin(annSmFetch, "Prepare Fetch Desc");
}

template<class T>
void
IGbE::DescCache<T>::fetchDescriptors1()
{
    // If we're draining delay issuing this DMA
    if (igbe->drainState() != DrainState::Running) {
        igbe->schedule(fetchDelayEvent, curTick() + igbe->fetchDelay);
        return;
    }

    igbe->anBegin(annSmFetch, "Fetch Desc");

    DPRINTF(EthernetDesc, "Fetching descriptors at %#x (%#x), size: %#x\n",
            descBase() + cachePnt * sizeof(T),
            pciToDma(descBase() + cachePnt * sizeof(T)),
            curFetching * sizeof(T));
    assert(curFetching);
    igbe->dmaRead(pciToDma(descBase() + cachePnt * sizeof(T)),
                  curFetching * sizeof(T), &fetchEvent, (uint8_t*)fetchBuf,
                  igbe->fetchCompDelay);
}

template<class T>
void
IGbE::DescCache<T>::fetchComplete()
{
    T *newDesc;
    igbe->anBegin(annSmFetch, "Fetch Complete");
    for (int x = 0; x < curFetching; x++) {
        newDesc = new T;
        memcpy(newDesc, &fetchBuf[x], sizeof(T));
        unusedCache.push_back(newDesc);
        igbe->anDq(annSmFetch, annUnusedDescQ);
        igbe->anQ(annSmFetch, annUnusedCacheQ);
        igbe->anQ(annSmFetch, annDescQ);
    }


#ifndef NDEBUG
    int oldCp = cachePnt;
#endif

    cachePnt += curFetching;
    assert(cachePnt <= descLen());
    if (cachePnt == descLen())
        cachePnt = 0;

    curFetching = 0;

    DPRINTF(EthernetDesc, "Fetching complete cachePnt %d -> %d\n",
            oldCp, cachePnt);

    if ((descTail() >= cachePnt ? (descTail() - cachePnt) : (descLen() -
                                                             cachePnt)) == 0)
    {
        igbe->anWe(annSmFetch, annUnusedDescQ);
    } else if (!(size - usedCache.size() - unusedCache.size())) {
        igbe->anWf(annSmFetch, annDescQ);
    } else {
        igbe->anBegin(annSmFetch, "Wait", CPA::FL_WAIT);
    }

    enableSm();
    igbe->checkDrain();
}

template<class T>
void
IGbE::DescCache<T>::wbComplete()
{

    igbe->anBegin(annSmWb, "Finish Writeback");

    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();

        igbe->anDq(annSmWb, annUsedCacheQ);
        igbe->anDq(annSmWb, annDescQ);
    }

    curHead += wbOut;
    wbOut = 0;

    if (curHead >= descLen())
        curHead -= descLen();

    // Update the head
    updateHead(curHead);

    DPRINTF(EthernetDesc, "Writeback complete curHead %d -> %d\n",
            oldHead, curHead);

    // If we still have more to wb, call wb now
    actionAfterWb();
    if (moreToWb) {
        moreToWb = false;
        DPRINTF(EthernetDesc, "Writeback has more todo\n");
        writeback(wbAlignment);
    }

    if (!wbOut) {
        igbe->checkDrain();
        if (usedCache.size())
            igbe->anBegin(annSmWb, "Wait", CPA::FL_WAIT);
        else
            igbe->anWe(annSmWb, annUsedCacheQ);
    }
    fetchAfterWb();
}

template<class T>
void
IGbE::DescCache<T>::reset()
{
    DPRINTF(EthernetDesc, "Reseting descriptor cache\n");
    for (typename CacheType::size_type x = 0; x < usedCache.size(); x++)
        delete usedCache[x];
    for (typename CacheType::size_type x = 0; x < unusedCache.size(); x++)
        delete unusedCache[x];

    usedCache.clear();
    unusedCache.clear();

    cachePnt = 0;

}

template<class T>
void
IGbE::DescCache<T>::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(cachePnt);
    SERIALIZE_SCALAR(curFetching);
    SERIALIZE_SCALAR(wbOut);
    SERIALIZE_SCALAR(moreToWb);
    SERIALIZE_SCALAR(wbAlignment);

    typename CacheType::size_type usedCacheSize = usedCache.size();
    SERIALIZE_SCALAR(usedCacheSize);
    for (typename CacheType::size_type x = 0; x < usedCacheSize; x++) {
        arrayParamOut(cp, csprintf("usedCache_%d", x),
                      (uint8_t*)usedCache[x],sizeof(T));
    }

    typename CacheType::size_type unusedCacheSize = unusedCache.size();
    SERIALIZE_SCALAR(unusedCacheSize);
    for (typename CacheType::size_type x = 0; x < unusedCacheSize; x++) {
        arrayParamOut(cp, csprintf("unusedCache_%d", x),
                      (uint8_t*)unusedCache[x],sizeof(T));
    }

    Tick fetch_delay = 0, wb_delay = 0;
    if (fetchDelayEvent.scheduled())
        fetch_delay = fetchDelayEvent.when();
    SERIALIZE_SCALAR(fetch_delay);
    if (wbDelayEvent.scheduled())
        wb_delay = wbDelayEvent.when();
    SERIALIZE_SCALAR(wb_delay);


}

template<class T>
void
IGbE::DescCache<T>::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(cachePnt);
    UNSERIALIZE_SCALAR(curFetching);
    UNSERIALIZE_SCALAR(wbOut);
    UNSERIALIZE_SCALAR(moreToWb);
    UNSERIALIZE_SCALAR(wbAlignment);

    typename CacheType::size_type usedCacheSize;
    UNSERIALIZE_SCALAR(usedCacheSize);
    T *temp;
    for (typename CacheType::size_type x = 0; x < usedCacheSize; x++) {
        temp = new T;
        arrayParamIn(cp, csprintf("usedCache_%d", x),
                     (uint8_t*)temp,sizeof(T));
        usedCache.push_back(temp);
    }

    typename CacheType::size_type unusedCacheSize;
    UNSERIALIZE_SCALAR(unusedCacheSize);
    for (typename CacheType::size_type x = 0; x < unusedCacheSize; x++) {
        temp = new T;
        arrayParamIn(cp, csprintf("unusedCache_%d", x),
                     (uint8_t*)temp,sizeof(T));
        unusedCache.push_back(temp);
    }
    Tick fetch_delay = 0, wb_delay = 0;
    UNSERIALIZE_SCALAR(fetch_delay);
    UNSERIALIZE_SCALAR(wb_delay);
    if (fetch_delay)
        igbe->schedule(fetchDelayEvent, fetch_delay);
    if (wb_delay)
        igbe->schedule(wbDelayEvent, wb_delay);


}

///////////////////////////// IGbE::RxDescCache //////////////////////////////

IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s)
    : DescCache<RxDesc>(i, n, s), pktDone(false), splitCount(0),
    pktEvent([this]{ pktComplete(); }, n),
    pktHdrEvent([this]{ pktSplitDone(); }, n),
    pktDataEvent([this]{ pktSplitDone(); }, n)

{
    annSmFetch = "RX Desc Fetch";
    annSmWb = "RX Desc Writeback";
    annUnusedDescQ = "RX Unused Descriptors";
    annUnusedCacheQ = "RX Unused Descriptor Cache";
    annUsedCacheQ = "RX Used Descriptor Cache";
    annUsedDescQ = "RX Used Descriptors";
    annDescQ = "RX Descriptors";
}

void
IGbE::RxDescCache::pktSplitDone()
{
    splitCount++;
    DPRINTF(EthernetDesc,
            "Part of split packet done: splitcount now %d\n", splitCount);
    assert(splitCount <= 2);
    if (splitCount != 2)
        return;
    splitCount = 0;
    DPRINTF(EthernetDesc,
            "Part of split packet done: calling pktComplete()\n");
    pktComplete();
}

int
IGbE::RxDescCache::writePacket(EthPacketPtr packet, int pkt_offset)
{
    assert(unusedCache.size());
    //if (!unusedCache.size())
    //    return false;

    pktPtr = packet;
    pktDone = false;
    unsigned buf_len, hdr_len;

    RxDesc *desc = unusedCache.front();
    switch (igbe->regs.srrctl.desctype()) {
      case RXDT_LEGACY:
        assert(pkt_offset == 0);
        bytesCopied = packet->length;
        DPRINTF(EthernetDesc, "Packet Length: %d Desc Size: %d\n",
                packet->length, igbe->regs.rctl.descSize());
        assert(packet->length < igbe->regs.rctl.descSize());
        igbe->dmaWrite(pciToDma(desc->legacy.buf),
                       packet->length, &pktEvent, packet->data,
                       igbe->rxWriteDelay);
        break;
      case RXDT_ADV_ONEBUF:
        assert(pkt_offset == 0);
        bytesCopied = packet->length;
        buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
            igbe->regs.rctl.descSize();
        DPRINTF(EthernetDesc, "Packet Length: %d srrctl: %#x Desc Size: %d\n",
                packet->length, igbe->regs.srrctl(), buf_len);
        assert(packet->length < buf_len);
        igbe->dmaWrite(pciToDma(desc->adv_read.pkt),
                       packet->length, &pktEvent, packet->data,
                       igbe->rxWriteDelay);
        desc->adv_wb.header_len = htole(0);
        desc->adv_wb.sph = htole(0);
        desc->adv_wb.pkt_len = htole((uint16_t)(pktPtr->length));
        break;
      case RXDT_ADV_SPLIT_A:
        int split_point;

        buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
            igbe->regs.rctl.descSize();
        hdr_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.hdrLen() : 0;
        DPRINTF(EthernetDesc,
                "lpe: %d Packet Length: %d offset: %d srrctl: %#x "
                "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
                igbe->regs.rctl.lpe(), packet->length, pkt_offset,
                igbe->regs.srrctl(), desc->adv_read.hdr, hdr_len,
                desc->adv_read.pkt, buf_len);

        split_point = hsplit(pktPtr);

        if (packet->length <= hdr_len) {
            bytesCopied = packet->length;
            assert(pkt_offset == 0);
            DPRINTF(EthernetDesc, "Hdr split: Entire packet in header\n");
            igbe->dmaWrite(pciToDma(desc->adv_read.hdr),
                           packet->length, &pktEvent, packet->data,
                           igbe->rxWriteDelay);
            desc->adv_wb.header_len = htole((uint16_t)packet->length);
            desc->adv_wb.sph = htole(0);
            desc->adv_wb.pkt_len = htole(0);
        } else if (split_point) {
            if (pkt_offset) {
                // we are only copying some data, header/data has already been
                // copied
                int max_to_copy =
                    std::min(packet->length - pkt_offset, buf_len);
                bytesCopied += max_to_copy;
                DPRINTF(EthernetDesc,
                        "Hdr split: Continuing data buffer copy\n");
                igbe->dmaWrite(pciToDma(desc->adv_read.pkt),
                               max_to_copy, &pktEvent,
                               packet->data + pkt_offset, igbe->rxWriteDelay);
                desc->adv_wb.header_len = htole(0);
                desc->adv_wb.pkt_len = htole((uint16_t)max_to_copy);
                desc->adv_wb.sph = htole(0);
            } else {
                int max_to_copy =
                    std::min(packet->length - split_point, buf_len);
                bytesCopied += max_to_copy + split_point;

                DPRINTF(EthernetDesc, "Hdr split: splitting at %d\n",
                        split_point);
                igbe->dmaWrite(pciToDma(desc->adv_read.hdr),
                               split_point, &pktHdrEvent,
                               packet->data, igbe->rxWriteDelay);
                igbe->dmaWrite(pciToDma(desc->adv_read.pkt),
                               max_to_copy, &pktDataEvent,
                               packet->data + split_point, igbe->rxWriteDelay);
                desc->adv_wb.header_len = htole(split_point);
                desc->adv_wb.sph = 1;
                desc->adv_wb.pkt_len = htole((uint16_t)(max_to_copy));
            }
        } else {
            panic("Header split not fitting within header buffer or "
                  "undecodable packet not fitting in header unsupported\n");
        }
        break;
      default:
        panic("Unimplemnted RX receive buffer type: %d\n",
              igbe->regs.srrctl.desctype());
    }
    return bytesCopied;

}

void
IGbE::RxDescCache::pktComplete()
{
    assert(unusedCache.size());
    RxDesc *desc;
    desc = unusedCache.front();

    igbe->anBegin("RXS", "Update Desc");

    uint16_t crcfixup = igbe->regs.rctl.secrc() ? 0 : 4 ;
    DPRINTF(EthernetDesc, "pktPtr->length: %d bytesCopied: %d "
            "stripcrc offset: %d value written: %d %d\n",
            pktPtr->length, bytesCopied, crcfixup,
            htole((uint16_t)(pktPtr->length + crcfixup)),
            (uint16_t)(pktPtr->length + crcfixup));

    // no support for anything but starting at 0
    assert(igbe->regs.rxcsum.pcss() == 0);

    DPRINTF(EthernetDesc, "Packet written to memory updating Descriptor\n");

    uint16_t status = RXDS_DD;
    uint8_t err = 0;
    uint16_t ext_err = 0;
    uint16_t csum = 0;
    uint16_t ptype = 0;
    uint16_t ip_id = 0;

    assert(bytesCopied <= pktPtr->length);
    if (bytesCopied == pktPtr->length)
        status |= RXDS_EOP;

    IpPtr ip(pktPtr);
    Ip6Ptr ip6(pktPtr);

    if (ip || ip6) {
        if (ip) {
            DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n",
                    ip->id());
            ptype |= RXDP_IPV4;
            ip_id = ip->id();
        }
        if (ip6)
            ptype |= RXDP_IPV6;

        if (ip && igbe->regs.rxcsum.ipofld()) {
            DPRINTF(EthernetDesc, "Checking IP checksum\n");
            status |= RXDS_IPCS;
            csum = htole(cksum(ip));
            igbe->rxIpChecksums++;
            if (cksum(ip) != 0) {
                err |= RXDE_IPE;
                ext_err |= RXDEE_IPE;
                DPRINTF(EthernetDesc, "Checksum is bad!!\n");
            }
        }
        TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
        if (tcp && igbe->regs.rxcsum.tuofld()) {
            DPRINTF(EthernetDesc, "Checking TCP checksum\n");
            status |= RXDS_TCPCS;
            ptype |= RXDP_TCP;
            csum = htole(cksum(tcp));
            igbe->rxTcpChecksums++;
            if (cksum(tcp) != 0) {
                DPRINTF(EthernetDesc, "Checksum is bad!!\n");
                err |= RXDE_TCPE;
                ext_err |= RXDEE_TCPE;
            }
        }

        UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
        if (udp && igbe->regs.rxcsum.tuofld()) {
            DPRINTF(EthernetDesc, "Checking UDP checksum\n");
            status |= RXDS_UDPCS;
            ptype |= RXDP_UDP;
            csum = htole(cksum(udp));
            igbe->rxUdpChecksums++;
            if (cksum(udp) != 0) {
                DPRINTF(EthernetDesc, "Checksum is bad!!\n");
                ext_err |= RXDEE_TCPE;
                err |= RXDE_TCPE;
            }
        }
    } else { // if ip
        DPRINTF(EthernetSM, "Proccesing Non-Ip packet\n");
    }

    switch (igbe->regs.srrctl.desctype()) {
      case RXDT_LEGACY:
        desc->legacy.len = htole((uint16_t)(pktPtr->length + crcfixup));
        desc->legacy.status = htole(status);
        desc->legacy.errors = htole(err);
        // No vlan support at this point... just set it to 0
        desc->legacy.vlan = 0;
        break;
      case RXDT_ADV_SPLIT_A:
      case RXDT_ADV_ONEBUF:
        desc->adv_wb.rss_type = htole(0);
        desc->adv_wb.pkt_type = htole(ptype);
        if (igbe->regs.rxcsum.pcsd()) {
            // no rss support right now
            desc->adv_wb.rss_hash = htole(0);
        } else {
            desc->adv_wb.id = htole(ip_id);
            desc->adv_wb.csum = htole(csum);
        }
        desc->adv_wb.status = htole(status);
        desc->adv_wb.errors = htole(ext_err);
        // no vlan support
        desc->adv_wb.vlan_tag = htole(0);
        break;
      default:
        panic("Unimplemnted RX receive buffer type %d\n",
              igbe->regs.srrctl.desctype());
    }

    DPRINTF(EthernetDesc, "Descriptor complete w0: %#x w1: %#x\n",
            desc->adv_read.pkt, desc->adv_read.hdr);

    if (bytesCopied == pktPtr->length) {
        DPRINTF(EthernetDesc,
                "Packet completely written to descriptor buffers\n");
        // Deal with the rx timer interrupts
        if (igbe->regs.rdtr.delay()) {
            Tick delay = igbe->regs.rdtr.delay() * igbe->intClock();
            DPRINTF(EthernetSM, "RXS: Scheduling DTR for %d\n", delay);
            igbe->reschedule(igbe->rdtrEvent, curTick() + delay);
        }

        if (igbe->regs.radv.idv()) {
            Tick delay = igbe->regs.radv.idv() * igbe->intClock();
            DPRINTF(EthernetSM, "RXS: Scheduling ADV for %d\n", delay);
            if (!igbe->radvEvent.scheduled()) {
                igbe->schedule(igbe->radvEvent, curTick() + delay);
            }
        }

        // if neither radv or rdtr, maybe itr is set...
        if (!igbe->regs.rdtr.delay() && !igbe->regs.radv.idv()) {
            DPRINTF(EthernetSM,
                    "RXS: Receive interrupt delay disabled, posting IT_RXT\n");
            igbe->postInterrupt(IT_RXT);
        }

        // If the packet is small enough, interrupt appropriately
        // I wonder if this is delayed or not?!
        if (pktPtr->length <= igbe->regs.rsrpd.idv()) {
            DPRINTF(EthernetSM,
                    "RXS: Posting IT_SRPD beacuse small packet received\n");
            igbe->postInterrupt(IT_SRPD);
        }
        bytesCopied = 0;
    }

    pktPtr = NULL;
    igbe->checkDrain();
    enableSm();
    pktDone = true;

    igbe->anBegin("RXS", "Done Updating Desc");
    DPRINTF(EthernetDesc, "Processing of this descriptor complete\n");
    igbe->anDq("RXS", annUnusedCacheQ);
    unusedCache.pop_front();
    igbe->anQ("RXS", annUsedCacheQ);
    usedCache.push_back(desc);
}

void
IGbE::RxDescCache::enableSm()
{
    if (igbe->drainState() != DrainState::Draining) {
        igbe->rxTick = true;
        igbe->restartClock();
    }
}

bool
IGbE::RxDescCache::packetDone()
{
    if (pktDone) {
        pktDone = false;
        return true;
    }
    return false;
}

bool
IGbE::RxDescCache::hasOutstandingEvents()
{
    return pktEvent.scheduled() || wbEvent.scheduled() ||
        fetchEvent.scheduled() || pktHdrEvent.scheduled() ||
        pktDataEvent.scheduled();

}

void
IGbE::RxDescCache::serialize(CheckpointOut &cp) const
{
    DescCache<RxDesc>::serialize(cp);
    SERIALIZE_SCALAR(pktDone);
    SERIALIZE_SCALAR(splitCount);
    SERIALIZE_SCALAR(bytesCopied);
}

void
IGbE::RxDescCache::unserialize(CheckpointIn &cp)
{
    DescCache<RxDesc>::unserialize(cp);
    UNSERIALIZE_SCALAR(pktDone);
    UNSERIALIZE_SCALAR(splitCount);
    UNSERIALIZE_SCALAR(bytesCopied);
}


///////////////////////////// IGbE::TxDescCache //////////////////////////////

IGbE::TxDescCache::TxDescCache(IGbE *i, const std::string n, int s)
    : DescCache<TxDesc>(i,n, s), pktDone(false), isTcp(false),
      pktWaiting(false), pktMultiDesc(false),
      completionAddress(0), completionEnabled(false),
      useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
      tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
      tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
    pktEvent([this]{ pktComplete(); }, n),
    headerEvent([this]{ headerComplete(); }, n),
    nullEvent([this]{ nullCallback(); }, n)
{
    annSmFetch = "TX Desc Fetch";
    annSmWb = "TX Desc Writeback";
    annUnusedDescQ = "TX Unused Descriptors";
    annUnusedCacheQ = "TX Unused Descriptor Cache";
    annUsedCacheQ = "TX Used Descriptor Cache";
    annUsedDescQ = "TX Used Descriptors";
    annDescQ = "TX Descriptors";
}

void
IGbE::TxDescCache::processContextDesc()
{
    assert(unusedCache.size());
    TxDesc *desc;

    DPRINTF(EthernetDesc, "Checking and  processing context descriptors\n");

    while (!useTso && unusedCache.size() &&
           TxdOp::isContext(unusedCache.front())) {
        DPRINTF(EthernetDesc, "Got context descriptor type...\n");

        desc = unusedCache.front();
        DPRINTF(EthernetDesc, "Descriptor upper: %#x lower: %#X\n",
                desc->d1, desc->d2);


        // is this going to be a tcp or udp packet?
        isTcp = TxdOp::tcp(desc) ? true : false;

        // setup all the TSO variables, they'll be ignored if we don't use
        // tso for this connection
        tsoHeaderLen = TxdOp::hdrlen(desc);
        tsoMss  = TxdOp::mss(desc);

        if (TxdOp::isType(desc, TxdOp::TXD_CNXT) && TxdOp::tse(desc)) {
            DPRINTF(EthernetDesc, "TCP offload enabled for packet hdrlen: "
                    "%d mss: %d paylen %d\n", TxdOp::hdrlen(desc),
                    TxdOp::mss(desc), TxdOp::getLen(desc));
            useTso = true;
            tsoTotalLen = TxdOp::getLen(desc);
            tsoLoadedHeader = false;
            tsoDescBytesUsed = 0;
            tsoUsedLen = 0;
            tsoPrevSeq = 0;
            tsoPktHasHeader = false;
            tsoPkts = 0;
            tsoCopyBytes = 0;
        }

        TxdOp::setDd(desc);
        unusedCache.pop_front();
        igbe->anDq("TXS", annUnusedCacheQ);
        usedCache.push_back(desc);
        igbe->anQ("TXS", annUsedCacheQ);
    }

    if (!unusedCache.size())
        return;

    desc = unusedCache.front();
    if (!useTso && TxdOp::isType(desc, TxdOp::TXD_ADVDATA) &&
        TxdOp::tse(desc)) {
        DPRINTF(EthernetDesc, "TCP offload(adv) enabled for packet "
                "hdrlen: %d mss: %d paylen %d\n",
                tsoHeaderLen, tsoMss, TxdOp::getTsoLen(desc));
        useTso = true;
        tsoTotalLen = TxdOp::getTsoLen(desc);
        tsoLoadedHeader = false;
        tsoDescBytesUsed = 0;
        tsoUsedLen = 0;
        tsoPrevSeq = 0;
        tsoPktHasHeader = false;
        tsoPkts = 0;
    }

    if (useTso && !tsoLoadedHeader) {
        // we need to fetch a header
        DPRINTF(EthernetDesc, "Starting DMA of TSO header\n");
        assert(TxdOp::isData(desc) && TxdOp::getLen(desc) >= tsoHeaderLen);
        pktWaiting = true;
        assert(tsoHeaderLen <= 256);
        igbe->dmaRead(pciToDma(TxdOp::getBuf(desc)),
                      tsoHeaderLen, &headerEvent, tsoHeader, 0);
    }
}

void
IGbE::TxDescCache::headerComplete()
{
    DPRINTF(EthernetDesc, "TSO: Fetching TSO header complete\n");
    pktWaiting = false;

    assert(unusedCache.size());
    TxDesc *desc = unusedCache.front();
    DPRINTF(EthernetDesc, "TSO: len: %d tsoHeaderLen: %d\n",
            TxdOp::getLen(desc), tsoHeaderLen);

    if (TxdOp::getLen(desc) == tsoHeaderLen) {
        tsoDescBytesUsed = 0;
        tsoLoadedHeader = true;
        unusedCache.pop_front();
        usedCache.push_back(desc);
    } else {
        DPRINTF(EthernetDesc, "TSO: header part of larger payload\n");
        tsoDescBytesUsed = tsoHeaderLen;
        tsoLoadedHeader = true;
    }
    enableSm();
    igbe->checkDrain();
}

unsigned
IGbE::TxDescCache::getPacketSize(EthPacketPtr p)
{
    if (!unusedCache.size())
        return 0;

    DPRINTF(EthernetDesc, "Starting processing of descriptor\n");

    assert(!useTso || tsoLoadedHeader);
    TxDesc *desc = unusedCache.front();

    if (useTso) {
        DPRINTF(EthernetDesc, "getPacket(): TxDescriptor data "
                "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
        DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
                "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
                tsoTotalLen, tsoUsedLen, tsoLoadedHeader);

        if (tsoPktHasHeader)
            tsoCopyBytes =  std::min((tsoMss + tsoHeaderLen) - p->length,
                                     TxdOp::getLen(desc) - tsoDescBytesUsed);
        else
            tsoCopyBytes =  std::min(tsoMss,
                                     TxdOp::getLen(desc) - tsoDescBytesUsed);
        unsigned pkt_size =
            tsoCopyBytes + (tsoPktHasHeader ? 0 : tsoHeaderLen);

        DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d "
                "this descLen: %d\n",
                tsoDescBytesUsed, tsoCopyBytes, TxdOp::getLen(desc));
        DPRINTF(EthernetDesc, "TSO: pktHasHeader: %d\n", tsoPktHasHeader);
        DPRINTF(EthernetDesc, "TSO: Next packet is %d bytes\n", pkt_size);
        return pkt_size;
    }

    DPRINTF(EthernetDesc, "Next TX packet is %d bytes\n",
            TxdOp::getLen(unusedCache.front()));
    return TxdOp::getLen(desc);
}

void
IGbE::TxDescCache::getPacketData(EthPacketPtr p)
{
    assert(unusedCache.size());

    TxDesc *desc;
    desc = unusedCache.front();

    DPRINTF(EthernetDesc, "getPacketData(): TxDescriptor data "
            "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
    assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) &&
           TxdOp::getLen(desc));

    pktPtr = p;

    pktWaiting = true;

    DPRINTF(EthernetDesc, "Starting DMA of packet at offset %d\n", p->length);

    if (useTso) {
        assert(tsoLoadedHeader);
        if (!tsoPktHasHeader) {
            DPRINTF(EthernetDesc,
                    "Loading TSO header (%d bytes) into start of packet\n",
                    tsoHeaderLen);
            memcpy(p->data, &tsoHeader,tsoHeaderLen);
            p->length +=tsoHeaderLen;
            tsoPktHasHeader = true;
        }
    }

    if (useTso) {
        DPRINTF(EthernetDesc,
                "Starting DMA of packet at offset %d length: %d\n",
                p->length, tsoCopyBytes);
        igbe->dmaRead(pciToDma(TxdOp::getBuf(desc))
                      + tsoDescBytesUsed,
                      tsoCopyBytes, &pktEvent, p->data + p->length,
                      igbe->txReadDelay);
        tsoDescBytesUsed += tsoCopyBytes;
        assert(tsoDescBytesUsed <= TxdOp::getLen(desc));
    } else {
        igbe->dmaRead(pciToDma(TxdOp::getBuf(desc)),
                      TxdOp::getLen(desc), &pktEvent, p->data + p->length,
                      igbe->txReadDelay);
    }
}

void
IGbE::TxDescCache::pktComplete()
{

    TxDesc *desc;
    assert(unusedCache.size());
    assert(pktPtr);

    igbe->anBegin("TXS", "Update Desc");

    DPRINTF(EthernetDesc, "DMA of packet complete\n");


    desc = unusedCache.front();
    assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) &&
           TxdOp::getLen(desc));

    DPRINTF(EthernetDesc, "TxDescriptor data d1: %#llx d2: %#llx\n",
            desc->d1, desc->d2);

    // Set the length of the data in the EtherPacket
    if (useTso) {
        DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
            "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
            tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
        pktPtr->simLength += tsoCopyBytes;
        pktPtr->length += tsoCopyBytes;
        tsoUsedLen += tsoCopyBytes;
        DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
            tsoDescBytesUsed, tsoCopyBytes);
    } else {
        pktPtr->simLength += TxdOp::getLen(desc);
        pktPtr->length += TxdOp::getLen(desc);
    }



    if ((!TxdOp::eop(desc) && !useTso) ||
        (pktPtr->length < ( tsoMss + tsoHeaderLen) &&
         tsoTotalLen != tsoUsedLen && useTso)) {
        assert(!useTso || (tsoDescBytesUsed == TxdOp::getLen(desc)));
        igbe->anDq("TXS", annUnusedCacheQ);
        unusedCache.pop_front();
        igbe->anQ("TXS", annUsedCacheQ);
        usedCache.push_back(desc);

        tsoDescBytesUsed = 0;
        pktDone = true;
        pktWaiting = false;
        pktMultiDesc = true;

        DPRINTF(EthernetDesc, "Partial Packet Descriptor of %d bytes Done\n",
                pktPtr->length);
        pktPtr = NULL;

        enableSm();
        igbe->checkDrain();
        return;
    }


    pktMultiDesc = false;
    // no support for vlans
    assert(!TxdOp::vle(desc));

    // we only support single packet descriptors at this point
    if (!useTso)
        assert(TxdOp::eop(desc));

    // set that this packet is done
    if (TxdOp::rs(desc))
        TxdOp::setDd(desc);

    DPRINTF(EthernetDesc, "TxDescriptor data d1: %#llx d2: %#llx\n",
            desc->d1, desc->d2);

    if (useTso) {
        IpPtr ip(pktPtr);
        Ip6Ptr ip6(pktPtr);
        if (ip) {
            DPRINTF(EthernetDesc, "TSO: Modifying IP header. Id + %d\n",
                    tsoPkts);
            ip->id(ip->id() + tsoPkts++);
            ip->len(pktPtr->length - EthPtr(pktPtr)->size());
        }
        if (ip6)
            ip6->plen(pktPtr->length - EthPtr(pktPtr)->size());
        TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
        if (tcp) {
            DPRINTF(EthernetDesc,
                    "TSO: Modifying TCP header. old seq %d + %d\n",
                    tcp->seq(), tsoPrevSeq);
            tcp->seq(tcp->seq() + tsoPrevSeq);
            if (tsoUsedLen != tsoTotalLen)
                tcp->flags(tcp->flags() & ~9); // clear fin & psh
        }
        UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
        if (udp) {
            DPRINTF(EthernetDesc, "TSO: Modifying UDP header.\n");
            udp->len(pktPtr->length - EthPtr(pktPtr)->size());
        }
        tsoPrevSeq = tsoUsedLen;
    }

    if (DTRACE(EthernetDesc)) {
        IpPtr ip(pktPtr);
        if (ip)
            DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n",
                    ip->id());
        else
            DPRINTF(EthernetSM, "Proccesing Non-Ip packet\n");
    }

    // Checksums are only ofloaded for new descriptor types
    if (TxdOp::isData(desc) && (TxdOp::ixsm(desc) || TxdOp::txsm(desc))) {
        DPRINTF(EthernetDesc, "Calculating checksums for packet\n");
        IpPtr ip(pktPtr);
        Ip6Ptr ip6(pktPtr);
        assert(ip || ip6);
        if (ip && TxdOp::ixsm(desc)) {
            ip->sum(0);
            ip->sum(cksum(ip));
            igbe->txIpChecksums++;
            DPRINTF(EthernetDesc, "Calculated IP checksum\n");
        }
        if (TxdOp::txsm(desc)) {
            TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
            UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
            if (tcp) {
                tcp->sum(0);
                tcp->sum(cksum(tcp));
                igbe->txTcpChecksums++;
                DPRINTF(EthernetDesc, "Calculated TCP checksum\n");
            } else if (udp) {
                assert(udp);
                udp->sum(0);
                udp->sum(cksum(udp));
                igbe->txUdpChecksums++;
                DPRINTF(EthernetDesc, "Calculated UDP checksum\n");
            } else {
                panic("Told to checksum, but don't know how\n");
            }
        }
    }

    if (TxdOp::ide(desc)) {
        // Deal with the rx timer interrupts
        DPRINTF(EthernetDesc, "Descriptor had IDE set\n");
        if (igbe->regs.tidv.idv()) {
            Tick delay = igbe->regs.tidv.idv() * igbe->intClock();
            DPRINTF(EthernetDesc, "setting tidv\n");
            igbe->reschedule(igbe->tidvEvent, curTick() + delay, true);
        }

        if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
            Tick delay = igbe->regs.tadv.idv() * igbe->intClock();
            DPRINTF(EthernetDesc, "setting tadv\n");
            if (!igbe->tadvEvent.scheduled()) {
                igbe->schedule(igbe->tadvEvent, curTick() + delay);
            }
        }
    }


    if (!useTso ||  TxdOp::getLen(desc) == tsoDescBytesUsed) {
        DPRINTF(EthernetDesc, "Descriptor Done\n");
        igbe->anDq("TXS", annUnusedCacheQ);
        unusedCache.pop_front();
        igbe->anQ("TXS", annUsedCacheQ);
        usedCache.push_back(desc);
        tsoDescBytesUsed = 0;
    }

    if (useTso && tsoUsedLen == tsoTotalLen)
        useTso = false;


    DPRINTF(EthernetDesc,
            "------Packet of %d bytes ready for transmission-------\n",
            pktPtr->length);
    pktDone = true;
    pktWaiting = false;
    pktPtr = NULL;
    tsoPktHasHeader = false;

    if (igbe->regs.txdctl.wthresh() == 0) {
        igbe->anBegin("TXS", "Desc Writeback");
        DPRINTF(EthernetDesc, "WTHRESH == 0, writing back descriptor\n");
        writeback(0);
    } else if (!igbe->regs.txdctl.gran() && igbe->regs.txdctl.wthresh() <=
               descInBlock(usedCache.size())) {
        DPRINTF(EthernetDesc, "used > WTHRESH, writing back descriptor\n");
        igbe->anBegin("TXS", "Desc Writeback");
        writeback((igbe->cacheBlockSize()-1)>>4);
    } else if (igbe->regs.txdctl.wthresh() <= usedCache.size()) {
        DPRINTF(EthernetDesc, "used > WTHRESH, writing back descriptor\n");
        igbe->anBegin("TXS", "Desc Writeback");
        writeback((igbe->cacheBlockSize()-1)>>4);
    }

    enableSm();
    igbe->checkDrain();
}

void
IGbE::TxDescCache::actionAfterWb()
{
    DPRINTF(EthernetDesc, "actionAfterWb() completionEnabled: %d\n",
            completionEnabled);
    igbe->postInterrupt(iGbReg::IT_TXDW);
    if (completionEnabled) {
        descEnd = igbe->regs.tdh();
        DPRINTF(EthernetDesc,
                "Completion writing back value: %d to addr: %#x\n", descEnd,
                completionAddress);
        igbe->dmaWrite(pciToDma(mbits(completionAddress, 63, 2)),
                       sizeof(descEnd), &nullEvent, (uint8_t*)&descEnd, 0);
    }
}

void
IGbE::TxDescCache::serialize(CheckpointOut &cp) const
{
    DescCache<TxDesc>::serialize(cp);

    SERIALIZE_SCALAR(pktDone);
    SERIALIZE_SCALAR(isTcp);
    SERIALIZE_SCALAR(pktWaiting);
    SERIALIZE_SCALAR(pktMultiDesc);

    SERIALIZE_SCALAR(useTso);
    SERIALIZE_SCALAR(tsoHeaderLen);
    SERIALIZE_SCALAR(tsoMss);
    SERIALIZE_SCALAR(tsoTotalLen);
    SERIALIZE_SCALAR(tsoUsedLen);
    SERIALIZE_SCALAR(tsoPrevSeq);;
    SERIALIZE_SCALAR(tsoPktPayloadBytes);
    SERIALIZE_SCALAR(tsoLoadedHeader);
    SERIALIZE_SCALAR(tsoPktHasHeader);
    SERIALIZE_ARRAY(tsoHeader, 256);
    SERIALIZE_SCALAR(tsoDescBytesUsed);
    SERIALIZE_SCALAR(tsoCopyBytes);
    SERIALIZE_SCALAR(tsoPkts);

    SERIALIZE_SCALAR(completionAddress);
    SERIALIZE_SCALAR(completionEnabled);
    SERIALIZE_SCALAR(descEnd);
}

void
IGbE::TxDescCache::unserialize(CheckpointIn &cp)
{
    DescCache<TxDesc>::unserialize(cp);

    UNSERIALIZE_SCALAR(pktDone);
    UNSERIALIZE_SCALAR(isTcp);
    UNSERIALIZE_SCALAR(pktWaiting);
    UNSERIALIZE_SCALAR(pktMultiDesc);

    UNSERIALIZE_SCALAR(useTso);
    UNSERIALIZE_SCALAR(tsoHeaderLen);
    UNSERIALIZE_SCALAR(tsoMss);
    UNSERIALIZE_SCALAR(tsoTotalLen);
    UNSERIALIZE_SCALAR(tsoUsedLen);
    UNSERIALIZE_SCALAR(tsoPrevSeq);;
    UNSERIALIZE_SCALAR(tsoPktPayloadBytes);
    UNSERIALIZE_SCALAR(tsoLoadedHeader);
    UNSERIALIZE_SCALAR(tsoPktHasHeader);
    UNSERIALIZE_ARRAY(tsoHeader, 256);
    UNSERIALIZE_SCALAR(tsoDescBytesUsed);
    UNSERIALIZE_SCALAR(tsoCopyBytes);
    UNSERIALIZE_SCALAR(tsoPkts);

    UNSERIALIZE_SCALAR(completionAddress);
    UNSERIALIZE_SCALAR(completionEnabled);
    UNSERIALIZE_SCALAR(descEnd);
}

bool
IGbE::TxDescCache::packetAvailable()
{
    if (pktDone) {
        pktDone = false;
        return true;
    }
    return false;
}

void
IGbE::TxDescCache::enableSm()
{
    if (igbe->drainState() != DrainState::Draining) {
        igbe->txTick = true;
        igbe->restartClock();
    }
}

bool
IGbE::TxDescCache::hasOutstandingEvents()
{
    return pktEvent.scheduled() || wbEvent.scheduled() ||
        fetchEvent.scheduled();
}


///////////////////////////////////// IGbE /////////////////////////////////

void
IGbE::restartClock()
{
    if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) &&
        drainState() == DrainState::Running)
        schedule(tickEvent, clockEdge(Cycles(1)));
}

DrainState
IGbE::drain()
{
    unsigned int count(0);
    if (rxDescCache.hasOutstandingEvents() ||
        txDescCache.hasOutstandingEvents()) {
        count++;
    }

    txFifoTick = false;
    txTick = false;
    rxTick = false;

    if (tickEvent.scheduled())
        deschedule(tickEvent);

    if (count) {
        DPRINTF(Drain, "IGbE not drained\n");
        return DrainState::Draining;
    } else
        return DrainState::Drained;
}

void
IGbE::drainResume()
{
    Drainable::drainResume();

    txFifoTick = true;
    txTick = true;
    rxTick = true;

    restartClock();
    DPRINTF(EthernetSM, "resuming from drain");
}

void
IGbE::checkDrain()
{
    if (drainState() != DrainState::Draining)
        return;

    txFifoTick = false;
    txTick = false;
    rxTick = false;
    if (!rxDescCache.hasOutstandingEvents() &&
        !txDescCache.hasOutstandingEvents()) {
        DPRINTF(Drain, "IGbE done draining, processing drain event\n");
        signalDrainDone();
    }
}

void
IGbE::txStateMachine()
{
    if (!regs.tctl.en()) {
        txTick = false;
        DPRINTF(EthernetSM, "TXS: TX disabled, stopping ticking\n");
        return;
    }

    // If we have a packet available and it's length is not 0 (meaning it's not
    // a multidescriptor packet) put it in the fifo, otherwise an the next
    // iteration we'll get the rest of the data
    if (txPacket && txDescCache.packetAvailable()
        && !txDescCache.packetMultiDesc() && txPacket->length) {
        anQ("TXS", "TX FIFO Q");
        DPRINTF(EthernetSM, "TXS: packet placed in TX FIFO\n");
#ifndef NDEBUG
        bool success =
#endif
            txFifo.push(txPacket);
        txFifoTick = true && drainState() != DrainState::Draining;
        assert(success);
        txPacket = NULL;
        anBegin("TXS", "Desc Writeback");
        txDescCache.writeback((cacheBlockSize()-1)>>4);
        return;
    }

    // Only support descriptor granularity
    if (regs.txdctl.lwthresh() &&
        txDescCache.descLeft() < (regs.txdctl.lwthresh() * 8)) {
        DPRINTF(EthernetSM, "TXS: LWTHRESH caused posting of TXDLOW\n");
        postInterrupt(IT_TXDLOW);
    }

    if (!txPacket) {
        txPacket = std::make_shared<EthPacketData>(16384);
    }

    if (!txDescCache.packetWaiting()) {
        if (txDescCache.descLeft() == 0) {
            postInterrupt(IT_TXQE);
            anBegin("TXS", "Desc Writeback");
            txDescCache.writeback(0);
            anBegin("TXS", "Desc Fetch");
            anWe("TXS", txDescCache.annUnusedCacheQ);
            txDescCache.fetchDescriptors();
            DPRINTF(EthernetSM, "TXS: No descriptors left in ring, forcing "
                    "writeback stopping ticking and posting TXQE\n");
            txTick = false;
            return;
        }


        if (!(txDescCache.descUnused())) {
            anBegin("TXS", "Desc Fetch");
            txDescCache.fetchDescriptors();
            anWe("TXS", txDescCache.annUnusedCacheQ);
            DPRINTF(EthernetSM, "TXS: No descriptors available in cache, "
                    "fetching and stopping ticking\n");
            txTick = false;
            return;
        }
        anPq("TXS", txDescCache.annUnusedCacheQ);


        txDescCache.processContextDesc();
        if (txDescCache.packetWaiting()) {
            DPRINTF(EthernetSM,
                    "TXS: Fetching TSO header, stopping ticking\n");
            txTick = false;
            return;
        }

        unsigned size = txDescCache.getPacketSize(txPacket);
        if (size > 0 && txFifo.avail() > size) {
            anRq("TXS", "TX FIFO Q");
            anBegin("TXS", "DMA Packet");
            DPRINTF(EthernetSM, "TXS: Reserving %d bytes in FIFO and "
                    "beginning DMA of next packet\n", size);
            txFifo.reserve(size);
            txDescCache.getPacketData(txPacket);
        } else if (size == 0) {
            DPRINTF(EthernetSM, "TXS: getPacketSize returned: %d\n", size);
            DPRINTF(EthernetSM,
                    "TXS: No packets to get, writing back used descriptors\n");
            anBegin("TXS", "Desc Writeback");
            txDescCache.writeback(0);
        } else {
            anWf("TXS", "TX FIFO Q");
            DPRINTF(EthernetSM, "TXS: FIFO full, stopping ticking until space "
                    "available in FIFO\n");
            txTick = false;
        }


        return;
    }
    DPRINTF(EthernetSM, "TXS: Nothing to do, stopping ticking\n");
    txTick = false;
}

bool
IGbE::ethRxPkt(EthPacketPtr pkt)
{
    rxBytes += pkt->length;
    rxPackets++;

    DPRINTF(Ethernet, "RxFIFO: Receiving pcakte from wire\n");
    anBegin("RXQ", "Wire Recv");


    if (!regs.rctl.en()) {
        DPRINTF(Ethernet, "RxFIFO: RX not enabled, dropping\n");
        anBegin("RXQ", "FIFO Drop", CPA::FL_BAD);
        return true;
    }

    // restart the state machines if they are stopped
    rxTick = true && drainState() != DrainState::Draining;
    if ((rxTick || txTick) && !tickEvent.scheduled()) {
        DPRINTF(EthernetSM,
                "RXS: received packet into fifo, starting ticking\n");
        restartClock();
    }

    if (!rxFifo.push(pkt)) {
        DPRINTF(Ethernet, "RxFIFO: Packet won't fit in fifo... dropped\n");
        postInterrupt(IT_RXO, true);
        anBegin("RXQ", "FIFO Drop", CPA::FL_BAD);
        return false;
    }

    if (CPA::available() && cpa->enabled()) {
        assert(sys->numSystemsRunning <= 2);
        System *other_sys;
        if (sys->systemList[0] == sys)
            other_sys = sys->systemList[1];
        else
            other_sys = sys->systemList[0];

        cpa->hwDq(CPA::FL_NONE, sys, macAddr, "RXQ", "WireQ", 0, other_sys);
        anQ("RXQ", "RX FIFO Q");
        cpa->hwWe(CPA::FL_NONE, sys, macAddr, "RXQ", "WireQ", 0, other_sys);
    }

    return true;
}


void
IGbE::rxStateMachine()
{
    if (!regs.rctl.en()) {
        rxTick = false;
        DPRINTF(EthernetSM, "RXS: RX disabled, stopping ticking\n");
        return;
    }

    // If the packet is done check for interrupts/descriptors/etc
    if (rxDescCache.packetDone()) {
        rxDmaPacket = false;
        DPRINTF(EthernetSM, "RXS: Packet completed DMA to memory\n");
        int descLeft = rxDescCache.descLeft();
        DPRINTF(EthernetSM, "RXS: descLeft: %d rdmts: %d rdlen: %d\n",
                descLeft, regs.rctl.rdmts(), regs.rdlen());

        // rdmts 2->1/8, 1->1/4, 0->1/2
        int ratio = (1ULL << (regs.rctl.rdmts() + 1));
        if (descLeft * ratio <= regs.rdlen()) {
            DPRINTF(Ethernet, "RXS: Interrupting (RXDMT) "
                    "because of descriptors left\n");
            postInterrupt(IT_RXDMT);
        }

        if (rxFifo.empty())
            rxDescCache.writeback(0);

        if (descLeft == 0) {
            anBegin("RXS", "Writeback Descriptors");
            rxDescCache.writeback(0);
            DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing"
                    " writeback and stopping ticking\n");
            rxTick = false;
        }

        // only support descriptor granulaties
        assert(regs.rxdctl.gran());

        if (regs.rxdctl.wthresh() >= rxDescCache.descUsed()) {
            DPRINTF(EthernetSM,
                    "RXS: Writing back because WTHRESH >= descUsed\n");
            anBegin("RXS", "Writeback Descriptors");
            if (regs.rxdctl.wthresh() < (cacheBlockSize()>>4))
                rxDescCache.writeback(regs.rxdctl.wthresh()-1);
            else
                rxDescCache.writeback((cacheBlockSize()-1)>>4);
        }

        if ((rxDescCache.descUnused() < regs.rxdctl.pthresh()) &&
            ((rxDescCache.descLeft() - rxDescCache.descUnused()) >
             regs.rxdctl.hthresh())) {
            DPRINTF(EthernetSM, "RXS: Fetching descriptors because "
                    "descUnused < PTHRESH\n");
            anBegin("RXS", "Fetch Descriptors");
            rxDescCache.fetchDescriptors();
        }

        if (rxDescCache.descUnused() == 0) {
            anBegin("RXS", "Fetch Descriptors");
            rxDescCache.fetchDescriptors();
            anWe("RXS", rxDescCache.annUnusedCacheQ);
            DPRINTF(EthernetSM, "RXS: No descriptors available in cache, "
                    "fetching descriptors and stopping ticking\n");
            rxTick = false;
        }
        return;
    }

    if (rxDmaPacket) {
        DPRINTF(EthernetSM,
                "RXS: stopping ticking until packet DMA completes\n");
        rxTick = false;
        return;
    }

    if (!rxDescCache.descUnused()) {
        anBegin("RXS", "Fetch Descriptors");
        rxDescCache.fetchDescriptors();
        anWe("RXS", rxDescCache.annUnusedCacheQ);
        DPRINTF(EthernetSM, "RXS: No descriptors available in cache, "
                "stopping ticking\n");
        rxTick = false;
        DPRINTF(EthernetSM, "RXS: No descriptors available, fetching\n");
        return;
    }
    anPq("RXS", rxDescCache.annUnusedCacheQ);

    if (rxFifo.empty()) {
        anWe("RXS", "RX FIFO Q");
        DPRINTF(EthernetSM, "RXS: RxFIFO empty, stopping ticking\n");
        rxTick = false;
        return;
    }
    anPq("RXS", "RX FIFO Q");
    anBegin("RXS", "Get Desc");

    EthPacketPtr pkt;
    pkt = rxFifo.front();


    pktOffset = rxDescCache.writePacket(pkt, pktOffset);
    DPRINTF(EthernetSM, "RXS: Writing packet into memory\n");
    if (pktOffset == pkt->length) {
        anBegin( "RXS", "FIFO Dequeue");
        DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n");
        pktOffset = 0;
        anDq("RXS", "RX FIFO Q");
        rxFifo.pop();
    }

    DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
    rxTick = false;
    rxDmaPacket = true;
    anBegin("RXS", "DMA Packet");
}

void
IGbE::txWire()
{
    txFifoTick = false;

    if (txFifo.empty()) {
        anWe("TXQ", "TX FIFO Q");
        return;
    }


    anPq("TXQ", "TX FIFO Q");
    if (etherInt->sendPacket(txFifo.front())) {
        anQ("TXQ", "WireQ");
        if (DTRACE(EthernetSM)) {
            IpPtr ip(txFifo.front());
            if (ip)
                DPRINTF(EthernetSM, "Transmitting Ip packet with Id=%d\n",
                        ip->id());
            else
                DPRINTF(EthernetSM, "Transmitting Non-Ip packet\n");
        }
        anDq("TXQ", "TX FIFO Q");
        anBegin("TXQ", "Wire Send");
        DPRINTF(EthernetSM,
                "TxFIFO: Successful transmit, bytes available in fifo: %d\n",
                txFifo.avail());

        txBytes += txFifo.front()->length;
        txPackets++;

        txFifo.pop();
    }
}

void
IGbE::tick()
{
    DPRINTF(EthernetSM, "IGbE: -------------- Cycle --------------\n");

    inTick = true;

    if (rxTick)
        rxStateMachine();

    if (txTick)
        txStateMachine();

    // If txWire returns and txFifoTick is still set, that means the data we
    // sent to the other end was already accepted and we can send another
    // frame right away. This is consistent with the previous behavior which
    // would send another frame if one was ready in ethTxDone. This version
    // avoids growing the stack with each frame sent which can cause stack
    // overflow.
    while (txFifoTick)
        txWire();

    if (rxTick || txTick || txFifoTick)
        schedule(tickEvent, curTick() + clockPeriod());

    inTick = false;
}

void
IGbE::ethTxDone()
{
    anBegin("TXQ", "Send Done");
    // restart the tx state machines if they are stopped
    // fifo to send another packet
    // tx sm to put more data into the fifo
    txFifoTick = true && drainState() != DrainState::Draining;
    if (txDescCache.descLeft() != 0 && drainState() != DrainState::Draining)
        txTick = true;

    if (!inTick)
        restartClock();
    DPRINTF(EthernetSM, "TxFIFO: Transmission complete\n");
}

void
IGbE::serialize(CheckpointOut &cp) const
{
    PciDevice::serialize(cp);

    regs.serialize(cp);
    SERIALIZE_SCALAR(eeOpBits);
    SERIALIZE_SCALAR(eeAddrBits);
    SERIALIZE_SCALAR(eeDataBits);
    SERIALIZE_SCALAR(eeOpcode);
    SERIALIZE_SCALAR(eeAddr);
    SERIALIZE_SCALAR(lastInterrupt);
    SERIALIZE_ARRAY(flash,iGbReg::EEPROM_SIZE);

    rxFifo.serialize("rxfifo", cp);
    txFifo.serialize("txfifo", cp);

    bool txPktExists = txPacket != nullptr;
    SERIALIZE_SCALAR(txPktExists);
    if (txPktExists)
        txPacket->serialize("txpacket", cp);

    Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0,
        inter_time = 0;

    if (rdtrEvent.scheduled())
        rdtr_time = rdtrEvent.when();
    SERIALIZE_SCALAR(rdtr_time);

    if (radvEvent.scheduled())
        radv_time = radvEvent.when();
    SERIALIZE_SCALAR(radv_time);

    if (tidvEvent.scheduled())
        tidv_time = tidvEvent.when();
    SERIALIZE_SCALAR(tidv_time);

    if (tadvEvent.scheduled())
        tadv_time = tadvEvent.when();
    SERIALIZE_SCALAR(tadv_time);

    if (interEvent.scheduled())
        inter_time = interEvent.when();
    SERIALIZE_SCALAR(inter_time);

    SERIALIZE_SCALAR(pktOffset);

    txDescCache.serializeSection(cp, "TxDescCache");
    rxDescCache.serializeSection(cp, "RxDescCache");
}

void
IGbE::unserialize(CheckpointIn &cp)
{
    PciDevice::unserialize(cp);

    regs.unserialize(cp);
    UNSERIALIZE_SCALAR(eeOpBits);
    UNSERIALIZE_SCALAR(eeAddrBits);
    UNSERIALIZE_SCALAR(eeDataBits);
    UNSERIALIZE_SCALAR(eeOpcode);
    UNSERIALIZE_SCALAR(eeAddr);
    UNSERIALIZE_SCALAR(lastInterrupt);
    UNSERIALIZE_ARRAY(flash,iGbReg::EEPROM_SIZE);

    rxFifo.unserialize("rxfifo", cp);
    txFifo.unserialize("txfifo", cp);

    bool txPktExists;
    UNSERIALIZE_SCALAR(txPktExists);
    if (txPktExists) {
        txPacket = std::make_shared<EthPacketData>(16384);
        txPacket->unserialize("txpacket", cp);
    }

    rxTick = true;
    txTick = true;
    txFifoTick = true;

    Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time;
    UNSERIALIZE_SCALAR(rdtr_time);
    UNSERIALIZE_SCALAR(radv_time);
    UNSERIALIZE_SCALAR(tidv_time);
    UNSERIALIZE_SCALAR(tadv_time);
    UNSERIALIZE_SCALAR(inter_time);

    if (rdtr_time)
        schedule(rdtrEvent, rdtr_time);

    if (radv_time)
        schedule(radvEvent, radv_time);

    if (tidv_time)
        schedule(tidvEvent, tidv_time);

    if (tadv_time)
        schedule(tadvEvent, tadv_time);

    if (inter_time)
        schedule(interEvent, inter_time);

    UNSERIALIZE_SCALAR(pktOffset);

    txDescCache.unserializeSection(cp, "TxDescCache");
    rxDescCache.unserializeSection(cp, "RxDescCache");
}

IGbE *
IGbEParams::create()
{
    return new IGbE(this);
}
