/*
 * Copyright (c) 2004-2005 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.
 */

/** @file
 * Device module for modelling the National Semiconductor
 * DP83820 ethernet controller.  Does not support priority queueing
 */

#include "dev/net/ns_gige.hh"

#include <deque>
#include <memory>
#include <string>

#include "base/debug.hh"
#include "base/inet.hh"
#include "base/types.hh"
#include "debug/EthernetAll.hh"
#include "dev/net/etherlink.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/NSGigE.hh"
#include "sim/system.hh"

// clang complains about std::set being overloaded with Packet::set if
// we open up the entire namespace std
using std::make_shared;
using std::min;
using std::ostream;
using std::string;

const char *NsRxStateStrings[] =
{
    "rxIdle",
    "rxDescRefr",
    "rxDescRead",
    "rxFifoBlock",
    "rxFragWrite",
    "rxDescWrite",
    "rxAdvance"
};

const char *NsTxStateStrings[] =
{
    "txIdle",
    "txDescRefr",
    "txDescRead",
    "txFifoBlock",
    "txFragRead",
    "txDescWrite",
    "txAdvance"
};

const char *NsDmaState[] =
{
    "dmaIdle",
    "dmaReading",
    "dmaWriting",
    "dmaReadWaiting",
    "dmaWriteWaiting"
};

using namespace Net;

///////////////////////////////////////////////////////////////////////
//
// NSGigE PCI Device
//
NSGigE::NSGigE(const Params &p)
    : EtherDevBase(p), ioEnable(false),
      txFifo(p.tx_fifo_size), rxFifo(p.rx_fifo_size),
      txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
      txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
      txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
      txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
      rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
      rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
      eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
      eepromOpcode(0), eepromAddress(0), eepromData(0),
      dmaReadDelay(p.dma_read_delay), dmaWriteDelay(p.dma_write_delay),
      dmaReadFactor(p.dma_read_factor), dmaWriteFactor(p.dma_write_factor),
      rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
      txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
      rxDmaReadEvent([this]{ rxDmaReadDone(); }, name()),
      rxDmaWriteEvent([this]{ rxDmaWriteDone(); }, name()),
      txDmaReadEvent([this]{ txDmaReadDone(); }, name()),
      txDmaWriteEvent([this]{ txDmaWriteDone(); }, name()),
      dmaDescFree(p.dma_desc_free), dmaDataFree(p.dma_data_free),
      txDelay(p.tx_delay), rxDelay(p.rx_delay),
      rxKickTick(0),
      rxKickEvent([this]{ rxKick(); }, name()),
      txKickTick(0),
      txKickEvent([this]{ txKick(); }, name()),
      txEvent([this]{ txEventTransmit(); }, name()),
      rxFilterEnable(p.rx_filter),
      acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
      acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
      intrDelay(p.intr_delay), intrTick(0), cpuPendingIntr(false),
      intrEvent(0), interface(0)
{


    interface = new NSGigEInt(name() + ".int0", this);

    regsReset();
    memcpy(&rom.perfectMatch, p.hardware_address.bytes(), ETH_ADDR_LEN);

    memset(&rxDesc32, 0, sizeof(rxDesc32));
    memset(&txDesc32, 0, sizeof(txDesc32));
    memset(&rxDesc64, 0, sizeof(rxDesc64));
    memset(&txDesc64, 0, sizeof(txDesc64));
}

NSGigE::~NSGigE()
{
    delete interface;
}

/**
 * This is to write to the PCI general configuration registers
 */
Tick
NSGigE::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");

    switch (offset) {
        // seems to work fine without all these PCI settings, but i
        // put in the IO to double check, an assertion will fail if we
        // need to properly implement it
      case PCI_COMMAND:
        if (config.data[offset] & PCI_CMD_IOSE)
            ioEnable = true;
        else
            ioEnable = false;
        break;
    }

    return configDelay;
}

Port &
NSGigE::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "interface")
       return *interface;
    return EtherDevBase::getPort(if_name, idx);
}

/**
 * This reads the device registers, which are detailed in the NS83820
 * spec sheet
 */
Tick
NSGigE::read(PacketPtr pkt)
{
    assert(ioEnable);

    //The mask is to give you only the offset into the device register file
    Addr daddr = pkt->getAddr() & 0xfff;
    DPRINTF(EthernetPIO, "read  da=%#x pa=%#x size=%d\n",
            daddr, pkt->getAddr(), pkt->getSize());


    // there are some reserved registers, you can see ns_gige_reg.h and
    // the spec sheet for details
    if (daddr > LAST && daddr <=  RESERVED) {
        panic("Accessing reserved register");
    } else if (daddr > RESERVED && daddr <= 0x3FC) {
        return readConfig(pkt);
    } else if (daddr >= MIB_START && daddr <= MIB_END) {
        // don't implement all the MIB's.  hopefully the kernel
        // doesn't actually DEPEND upon their values
        // MIB are just hardware stats keepers
        pkt->setLE<uint32_t>(0);
        pkt->makeAtomicResponse();
        return pioDelay;
    } else if (daddr > 0x3FC)
        panic("Something is messed up!\n");

    assert(pkt->getSize() == sizeof(uint32_t));
        uint32_t &reg = *pkt->getPtr<uint32_t>();
        uint16_t rfaddr;

        switch (daddr) {
          case CR:
            reg = regs.command;
            //these are supposed to be cleared on a read
            reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);
            break;

          case CFGR:
            reg = regs.config;
            break;

          case MEAR:
            reg = regs.mear;
            break;

          case PTSCR:
            reg = regs.ptscr;
            break;

          case ISR:
            reg = regs.isr;
            devIntrClear(ISR_ALL);
            break;

          case IMR:
            reg = regs.imr;
            break;

          case IER:
            reg = regs.ier;
            break;

          case IHR:
            reg = regs.ihr;
            break;

          case TXDP:
            reg = regs.txdp;
            break;

          case TXDP_HI:
            reg = regs.txdp_hi;
            break;

          case TX_CFG:
            reg = regs.txcfg;
            break;

          case GPIOR:
            reg = regs.gpior;
            break;

          case RXDP:
            reg = regs.rxdp;
            break;

          case RXDP_HI:
            reg = regs.rxdp_hi;
            break;

          case RX_CFG:
            reg = regs.rxcfg;
            break;

          case PQCR:
            reg = regs.pqcr;
            break;

          case WCSR:
            reg = regs.wcsr;
            break;

          case PCR:
            reg = regs.pcr;
            break;

            // see the spec sheet for how RFCR and RFDR work
            // basically, you write to RFCR to tell the machine
            // what you want to do next, then you act upon RFDR,
            // and the device will be prepared b/c of what you
            // wrote to RFCR
          case RFCR:
            reg = regs.rfcr;
            break;

          case RFDR:
            rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
            switch (rfaddr) {
              // Read from perfect match ROM octets
              case 0x000:
                reg = rom.perfectMatch[1];
                reg = reg << 8;
                reg += rom.perfectMatch[0];
                break;
              case 0x002:
                reg = rom.perfectMatch[3] << 8;
                reg += rom.perfectMatch[2];
                break;
              case 0x004:
                reg = rom.perfectMatch[5] << 8;
                reg += rom.perfectMatch[4];
                break;
              default:
                // Read filter hash table
                if (rfaddr >= FHASH_ADDR &&
                    rfaddr < FHASH_ADDR + FHASH_SIZE) {

                    // Only word-aligned reads supported
                    if (rfaddr % 2)
                        panic("unaligned read from filter hash table!");

                    reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8;
                    reg += rom.filterHash[rfaddr - FHASH_ADDR];
                    break;
                }

                panic("reading RFDR for something other than pattern"
                      " matching or hashing! %#x\n", rfaddr);
            }
            break;

          case SRR:
            reg = regs.srr;
            break;

          case MIBC:
            reg = regs.mibc;
            reg &= ~(MIBC_MIBS | MIBC_ACLR);
            break;

          case VRCR:
            reg = regs.vrcr;
            break;

          case VTCR:
            reg = regs.vtcr;
            break;

          case VDR:
            reg = regs.vdr;
            break;

          case CCSR:
            reg = regs.ccsr;
            break;

          case TBICR:
            reg = regs.tbicr;
            break;

          case TBISR:
            reg = regs.tbisr;
            break;

          case TANAR:
            reg = regs.tanar;
            break;

          case TANLPAR:
            reg = regs.tanlpar;
            break;

          case TANER:
            reg = regs.taner;
            break;

          case TESR:
            reg = regs.tesr;
            break;

          case M5REG:
            reg = 0;
            if (params().rx_thread)
                reg |= M5REG_RX_THREAD;
            if (params().tx_thread)
                reg |= M5REG_TX_THREAD;
            if (params().rss)
                reg |= M5REG_RSS;
            break;

          default:
            panic("reading unimplemented register: addr=%#x", daddr);
        }

        DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
                daddr, reg, reg);

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
NSGigE::write(PacketPtr pkt)
{
    assert(ioEnable);

    Addr daddr = pkt->getAddr() & 0xfff;
    DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
            daddr, pkt->getAddr(), pkt->getSize());

    if (daddr > LAST && daddr <=  RESERVED) {
        panic("Accessing reserved register");
    } else if (daddr > RESERVED && daddr <= 0x3FC) {
        return writeConfig(pkt);
    } else if (daddr > 0x3FC)
        panic("Something is messed up!\n");

    if (pkt->getSize() == sizeof(uint32_t)) {
        uint32_t reg = pkt->getLE<uint32_t>();
        uint16_t rfaddr;

        DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg);

        switch (daddr) {
          case CR:
            regs.command = reg;
            if (reg & CR_TXD) {
                txEnable = false;
            } else if (reg & CR_TXE) {
                txEnable = true;

                // the kernel is enabling the transmit machine
                if (txState == txIdle)
                    txKick();
            }

            if (reg & CR_RXD) {
                rxEnable = false;
            } else if (reg & CR_RXE) {
                rxEnable = true;

                if (rxState == rxIdle)
                    rxKick();
            }

            if (reg & CR_TXR)
                txReset();

            if (reg & CR_RXR)
                rxReset();

            if (reg & CR_SWI)
                devIntrPost(ISR_SWI);

            if (reg & CR_RST) {
                txReset();
                rxReset();

                regsReset();
            }
            break;

          case CFGR:
            if (reg & CFGR_LNKSTS ||
                reg & CFGR_SPDSTS ||
                reg & CFGR_DUPSTS ||
                reg & CFGR_RESERVED ||
                reg & CFGR_T64ADDR ||
                reg & CFGR_PCI64_DET) {
                // First clear all writable bits
                regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
                    CFGR_RESERVED | CFGR_T64ADDR |
                    CFGR_PCI64_DET;
                // Now set the appropriate writable bits
                regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
                                       CFGR_RESERVED | CFGR_T64ADDR |
                                       CFGR_PCI64_DET);
            }

            if (reg & CFGR_AUTO_1000)
                panic("CFGR_AUTO_1000 not implemented!\n");

            if (reg & CFGR_PCI64_DET)
                panic("CFGR_PCI64_DET is read only register!\n");

            if (reg & CFGR_EXTSTS_EN)
                extstsEnable = true;
            else
                extstsEnable = false;
            break;

          case MEAR:
            // Clear writable bits
            regs.mear &= MEAR_EEDO;
            // Set appropriate writable bits
            regs.mear |= reg & ~MEAR_EEDO;

            // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
            // even though it could get it through RFDR
            if (reg & MEAR_EESEL) {
                // Rising edge of clock
                if (reg & MEAR_EECLK && !eepromClk)
                    eepromKick();
            }
            else {
                eepromState = eepromStart;
                regs.mear &= ~MEAR_EEDI;
            }

            eepromClk = reg & MEAR_EECLK;

            // since phy is completely faked, MEAR_MD* don't matter
            break;

          case PTSCR:
            regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY);
            // these control BISTs for various parts of chip - we
            // don't care or do just fake that the BIST is done
            if (reg & PTSCR_RBIST_EN)
                regs.ptscr |= PTSCR_RBIST_DONE;
            if (reg & PTSCR_EEBIST_EN)
                regs.ptscr &= ~PTSCR_EEBIST_EN;
            if (reg & PTSCR_EELOAD_EN)
                regs.ptscr &= ~PTSCR_EELOAD_EN;
            break;

          case ISR: /* writing to the ISR has no effect */
            panic("ISR is a read only register!\n");

          case IMR:
            regs.imr = reg;
            devIntrChangeMask();
            break;

          case IER:
            regs.ier = reg;
            break;

          case IHR:
            regs.ihr = reg;
            /* not going to implement real interrupt holdoff */
            break;

          case TXDP:
            regs.txdp = (reg & 0xFFFFFFFC);
            assert(txState == txIdle);
            CTDD = false;
            break;

          case TXDP_HI:
            regs.txdp_hi = reg;
            break;

          case TX_CFG:
            regs.txcfg = reg;

            // also, we currently don't care about fill/drain
            // thresholds though this may change in the future with
            // more realistic networks or a driver which changes it
            // according to feedback

            break;

          case GPIOR:
            // Only write writable bits
            regs.gpior &= GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN
                        | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN;
            regs.gpior |= reg & ~(GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN
                                | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN);
            /* these just control general purpose i/o pins, don't matter */
            break;

          case RXDP:
            regs.rxdp = reg;
            CRDD = false;
            break;

          case RXDP_HI:
            regs.rxdp_hi = reg;
            break;

          case RX_CFG:
            regs.rxcfg = reg;
            break;

          case PQCR:
            /* there is no priority queueing used in the linux 2.6 driver */
            regs.pqcr = reg;
            break;

          case WCSR:
            /* not going to implement wake on LAN */
            regs.wcsr = reg;
            break;

          case PCR:
            /* not going to implement pause control */
            regs.pcr = reg;
            break;

          case RFCR:
            regs.rfcr = reg;

            rxFilterEnable = (reg & RFCR_RFEN) ? true : false;
            acceptBroadcast = (reg & RFCR_AAB) ? true : false;
            acceptMulticast = (reg & RFCR_AAM) ? true : false;
            acceptUnicast = (reg & RFCR_AAU) ? true : false;
            acceptPerfect = (reg & RFCR_APM) ? true : false;
            acceptArp = (reg & RFCR_AARP) ? true : false;
            multicastHashEnable = (reg & RFCR_MHEN) ? true : false;

            if (reg & RFCR_UHEN)
                panic("Unicast hash filtering not used by drivers!\n");

            if (reg & RFCR_ULM)
                panic("RFCR_ULM not implemented!\n");

            break;

          case RFDR:
            rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
            switch (rfaddr) {
              case 0x000:
                rom.perfectMatch[0] = (uint8_t)reg;
                rom.perfectMatch[1] = (uint8_t)(reg >> 8);
                break;
              case 0x002:
                rom.perfectMatch[2] = (uint8_t)reg;
                rom.perfectMatch[3] = (uint8_t)(reg >> 8);
                break;
              case 0x004:
                rom.perfectMatch[4] = (uint8_t)reg;
                rom.perfectMatch[5] = (uint8_t)(reg >> 8);
                break;
              default:

                if (rfaddr >= FHASH_ADDR &&
                    rfaddr < FHASH_ADDR + FHASH_SIZE) {

                    // Only word-aligned writes supported
                    if (rfaddr % 2)
                        panic("unaligned write to filter hash table!");

                    rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg;
                    rom.filterHash[rfaddr - FHASH_ADDR + 1]
                        = (uint8_t)(reg >> 8);
                    break;
                }
                panic("writing RFDR for something other than pattern matching "
                    "or hashing! %#x\n", rfaddr);
            }
            break;

          case BRAR:
            regs.brar = reg;
            break;

          case BRDR:
            panic("the driver never uses BRDR, something is wrong!\n");

          case SRR:
            panic("SRR is read only register!\n");

          case MIBC:
            panic("the driver never uses MIBC, something is wrong!\n");

          case VRCR:
            regs.vrcr = reg;
            break;

          case VTCR:
            regs.vtcr = reg;
            break;

          case VDR:
            panic("the driver never uses VDR, something is wrong!\n");

          case CCSR:
            /* not going to implement clockrun stuff */
            regs.ccsr = reg;
            break;

          case TBICR:
            regs.tbicr = reg;
            if (reg & TBICR_MR_LOOPBACK)
                panic("TBICR_MR_LOOPBACK never used, something wrong!\n");

            if (reg & TBICR_MR_AN_ENABLE) {
                regs.tanlpar = regs.tanar;
                regs.tbisr |= (TBISR_MR_AN_COMPLETE | TBISR_MR_LINK_STATUS);
            }

            break;

          case TBISR:
            panic("TBISR is read only register!\n");

          case TANAR:
            // Only write the writable bits
            regs.tanar &= TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED;
            regs.tanar |= reg & ~(TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED);

            // Pause capability unimplemented
            break;

          case TANLPAR:
            panic("this should only be written to by the fake phy!\n");

          case TANER:
            panic("TANER is read only register!\n");

          case TESR:
            regs.tesr = reg;
            break;

          default:
            panic("invalid register access daddr=%#x", daddr);
        }
    } else {
        panic("Invalid Request Size");
    }
    pkt->makeAtomicResponse();
    return pioDelay;
}

void
NSGigE::devIntrPost(uint32_t interrupts)
{
    if (interrupts & ISR_RESERVE)
        panic("Cannot set a reserved interrupt");

    if (interrupts & ISR_NOIMPL)
        warn("interrupt not implemented %#x\n", interrupts);

    interrupts &= ISR_IMPL;
    regs.isr |= interrupts;

    if (interrupts & regs.imr) {
        if (interrupts & ISR_SWI) {
            totalSwi++;
        }
        if (interrupts & ISR_RXIDLE) {
            totalRxIdle++;
        }
        if (interrupts & ISR_RXOK) {
            totalRxOk++;
        }
        if (interrupts & ISR_RXDESC) {
            totalRxDesc++;
        }
        if (interrupts & ISR_TXOK) {
            totalTxOk++;
        }
        if (interrupts & ISR_TXIDLE) {
            totalTxIdle++;
        }
        if (interrupts & ISR_TXDESC) {
            totalTxDesc++;
        }
        if (interrupts & ISR_RXORN) {
            totalRxOrn++;
        }
    }

    DPRINTF(EthernetIntr,
            "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
            interrupts, regs.isr, regs.imr);

    if ((regs.isr & regs.imr)) {
        Tick when = curTick();
        if ((regs.isr & regs.imr & ISR_NODELAY) == 0)
            when += intrDelay;
        postedInterrupts++;
        cpuIntrPost(when);
    }
}

/* writing this interrupt counting stats inside this means that this function
   is now limited to being used to clear all interrupts upon the kernel
   reading isr and servicing.  just telling you in case you were thinking
   of expanding use.
*/
void
NSGigE::devIntrClear(uint32_t interrupts)
{
    if (interrupts & ISR_RESERVE)
        panic("Cannot clear a reserved interrupt");

    if (regs.isr & regs.imr & ISR_SWI) {
        postedSwi++;
    }
    if (regs.isr & regs.imr & ISR_RXIDLE) {
        postedRxIdle++;
    }
    if (regs.isr & regs.imr & ISR_RXOK) {
        postedRxOk++;
    }
    if (regs.isr & regs.imr & ISR_RXDESC) {
            postedRxDesc++;
    }
    if (regs.isr & regs.imr & ISR_TXOK) {
        postedTxOk++;
    }
    if (regs.isr & regs.imr & ISR_TXIDLE) {
        postedTxIdle++;
    }
    if (regs.isr & regs.imr & ISR_TXDESC) {
        postedTxDesc++;
    }
    if (regs.isr & regs.imr & ISR_RXORN) {
        postedRxOrn++;
    }

    interrupts &= ~ISR_NOIMPL;
    regs.isr &= ~interrupts;

    DPRINTF(EthernetIntr,
            "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
            interrupts, regs.isr, regs.imr);

    if (!(regs.isr & regs.imr))
        cpuIntrClear();
}

void
NSGigE::devIntrChangeMask()
{
    DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
            regs.isr, regs.imr, regs.isr & regs.imr);

    if (regs.isr & regs.imr)
        cpuIntrPost(curTick());
    else
        cpuIntrClear();
}

void
NSGigE::cpuIntrPost(Tick when)
{
    // If the interrupt you want to post is later than an interrupt
    // already scheduled, just let it post in the coming one and don't
    // schedule another.
    // HOWEVER, must be sure that the scheduled intrTick is in the
    // future (this was formerly the source of a bug)
    /**
     * @todo this warning should be removed and the intrTick code should
     * be fixed.
     */
    assert(when >= curTick());
    assert(intrTick >= curTick() || intrTick == 0);
    if (when > intrTick && intrTick != 0) {
        DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n",
                intrTick);
        return;
    }

    intrTick = when;
    if (intrTick < curTick()) {
        intrTick = curTick();
    }

    DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n",
            intrTick);

    if (intrEvent)
        intrEvent->squash();

    intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
                                         name(), true);
    schedule(intrEvent, intrTick);
}

void
NSGigE::cpuInterrupt()
{
    assert(intrTick == curTick());

    // Whether or not there's a pending interrupt, we don't care about
    // it anymore
    intrEvent = 0;
    intrTick = 0;

    // Don't send an interrupt if there's already one
    if (cpuPendingIntr) {
        DPRINTF(EthernetIntr,
                "would send an interrupt now, but there's already pending\n");
    } else {
        // Send interrupt
        cpuPendingIntr = true;

        DPRINTF(EthernetIntr, "posting interrupt\n");
        intrPost();
    }
}

void
NSGigE::cpuIntrClear()
{
    if (!cpuPendingIntr)
        return;

    if (intrEvent) {
        intrEvent->squash();
        intrEvent = 0;
    }

    intrTick = 0;

    cpuPendingIntr = false;

    DPRINTF(EthernetIntr, "clearing interrupt\n");
    intrClear();
}

bool
NSGigE::cpuIntrPending() const
{ return cpuPendingIntr; }

void
NSGigE::txReset()
{

    DPRINTF(Ethernet, "transmit reset\n");

    CTDD = false;
    txEnable = false;;
    txFragPtr = 0;
    assert(txDescCnt == 0);
    txFifo.clear();
    txState = txIdle;
    assert(txDmaState == dmaIdle);
}

void
NSGigE::rxReset()
{
    DPRINTF(Ethernet, "receive reset\n");

    CRDD = false;
    assert(rxPktBytes == 0);
    rxEnable = false;
    rxFragPtr = 0;
    assert(rxDescCnt == 0);
    assert(rxDmaState == dmaIdle);
    rxFifo.clear();
    rxState = rxIdle;
}

void
NSGigE::regsReset()
{
    memset(&regs, 0, sizeof(regs));
    regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000);
    regs.mear = 0x12;
    regs.txcfg = 0x120; // set drain threshold to 1024 bytes and
                        // fill threshold to 32 bytes
    regs.rxcfg = 0x4;   // set drain threshold to 16 bytes
    regs.srr = 0x0103;  // set the silicon revision to rev B or 0x103
    regs.mibc = MIBC_FRZ;
    regs.vdr = 0x81;    // set the vlan tag type to 802.1q
    regs.tesr = 0xc000; // TBI capable of both full and half duplex
    regs.brar = 0xffffffff;

    extstsEnable = false;
    acceptBroadcast = false;
    acceptMulticast = false;
    acceptUnicast = false;
    acceptPerfect = false;
    acceptArp = false;
}

bool
NSGigE::doRxDmaRead()
{
    assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting);
    rxDmaState = dmaReading;

    if (dmaPending() || drainState() != DrainState::Running)
        rxDmaState = dmaReadWaiting;
    else
        dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData);

    return true;
}

void
NSGigE::rxDmaReadDone()
{
    assert(rxDmaState == dmaReading);
    rxDmaState = dmaIdle;

    DPRINTF(EthernetDMA, "rx dma read  paddr=%#x len=%d\n",
            rxDmaAddr, rxDmaLen);
    DDUMP(EthernetDMA, rxDmaData, rxDmaLen);

    // If the transmit state machine has a pending DMA, let it go first
    if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting)
        txKick();

    rxKick();
}

bool
NSGigE::doRxDmaWrite()
{
    assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting);
    rxDmaState = dmaWriting;

    if (dmaPending() || drainState() != DrainState::Running)
        rxDmaState = dmaWriteWaiting;
    else
        dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData);
    return true;
}

void
NSGigE::rxDmaWriteDone()
{
    assert(rxDmaState == dmaWriting);
    rxDmaState = dmaIdle;

    DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
            rxDmaAddr, rxDmaLen);
    DDUMP(EthernetDMA, rxDmaData, rxDmaLen);

    // If the transmit state machine has a pending DMA, let it go first
    if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting)
        txKick();

    rxKick();
}

void
NSGigE::rxKick()
{
    bool is64bit = (bool)(regs.config & CFGR_M64ADDR);

    DPRINTF(EthernetSM,
            "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
            NsRxStateStrings[rxState], rxFifo.size(), is64bit ? 64 : 32);

    Addr link, bufptr;
    uint32_t &cmdsts = is64bit ? rxDesc64.cmdsts : rxDesc32.cmdsts;
    uint32_t &extsts = is64bit ? rxDesc64.extsts : rxDesc32.extsts;

  next:
    if (rxKickTick > curTick()) {
        DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
                rxKickTick);

        goto exit;
    }

    // Go to the next state machine clock tick.
    rxKickTick = clockEdge(Cycles(1));

    switch(rxDmaState) {
      case dmaReadWaiting:
        if (doRxDmaRead())
            goto exit;
        break;
      case dmaWriteWaiting:
        if (doRxDmaWrite())
            goto exit;
        break;
      default:
        break;
    }

    link = is64bit ? (Addr)rxDesc64.link : (Addr)rxDesc32.link;
    bufptr = is64bit ? (Addr)rxDesc64.bufptr : (Addr)rxDesc32.bufptr;

    // see state machine from spec for details
    // the way this works is, if you finish work on one state and can
    // go directly to another, you do that through jumping to the
    // label "next".  however, if you have intermediate work, like DMA
    // so that you can't go to the next state yet, you go to exit and
    // exit the loop.  however, when the DMA is done it will trigger
    // an event and come back to this loop.
    switch (rxState) {
      case rxIdle:
        if (!rxEnable) {
            DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n");
            goto exit;
        }

        if (CRDD) {
            rxState = rxDescRefr;

            rxDmaAddr = regs.rxdp & 0x3fffffff;
            rxDmaData =
                is64bit ? (void *)&rxDesc64.link : (void *)&rxDesc32.link;
            rxDmaLen = is64bit ? sizeof(rxDesc64.link) : sizeof(rxDesc32.link);
            rxDmaFree = dmaDescFree;

            descDmaReads++;
            descDmaRdBytes += rxDmaLen;

            if (doRxDmaRead())
                goto exit;
        } else {
            rxState = rxDescRead;

            rxDmaAddr = regs.rxdp & 0x3fffffff;
            rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32;
            rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32);
            rxDmaFree = dmaDescFree;

            descDmaReads++;
            descDmaRdBytes += rxDmaLen;

            if (doRxDmaRead())
                goto exit;
        }
        break;

      case rxDescRefr:
        if (rxDmaState != dmaIdle)
            goto exit;

        rxState = rxAdvance;
        break;

     case rxDescRead:
        if (rxDmaState != dmaIdle)
            goto exit;

        DPRINTF(EthernetDesc, "rxDesc: addr=%08x read descriptor\n",
                regs.rxdp & 0x3fffffff);
        DPRINTF(EthernetDesc,
                "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
                link, bufptr, cmdsts, extsts);

        if (cmdsts & CMDSTS_OWN) {
            devIntrPost(ISR_RXIDLE);
            rxState = rxIdle;
            goto exit;
        } else {
            rxState = rxFifoBlock;
            rxFragPtr = bufptr;
            rxDescCnt = cmdsts & CMDSTS_LEN_MASK;
        }
        break;

      case rxFifoBlock:
        if (!rxPacket) {
            /**
             * @todo in reality, we should be able to start processing
             * the packet as it arrives, and not have to wait for the
             * full packet ot be in the receive fifo.
             */
            if (rxFifo.empty())
                goto exit;

            DPRINTF(EthernetSM, "****processing receive of new packet****\n");

            // If we don't have a packet, grab a new one from the fifo.
            rxPacket = rxFifo.front();
            rxPktBytes = rxPacket->length;
            rxPacketBufPtr = rxPacket->data;

#if TRACING_ON
            if (DTRACE(Ethernet)) {
                IpPtr ip(rxPacket);
                if (ip) {
                    DPRINTF(Ethernet, "ID is %d\n", ip->id());
                    TcpPtr tcp(ip);
                    if (tcp) {
                        DPRINTF(Ethernet,
                                "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
                                tcp->sport(), tcp->dport(), tcp->seq(),
                                tcp->ack());
                    }
                }
            }
#endif

            // sanity check - i think the driver behaves like this
            assert(rxDescCnt >= rxPktBytes);
            rxFifo.pop();
        }


        // dont' need the && rxDescCnt > 0 if driver sanity check
        // above holds
        if (rxPktBytes > 0) {
            rxState = rxFragWrite;
            // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
            // check holds
            rxXferLen = rxPktBytes;

            rxDmaAddr = rxFragPtr & 0x3fffffff;
            rxDmaData = rxPacketBufPtr;
            rxDmaLen = rxXferLen;
            rxDmaFree = dmaDataFree;

            if (doRxDmaWrite())
                goto exit;

        } else {
            rxState = rxDescWrite;

            //if (rxPktBytes == 0) {  /* packet is done */
            assert(rxPktBytes == 0);
            DPRINTF(EthernetSM, "done with receiving packet\n");

            cmdsts |= CMDSTS_OWN;
            cmdsts &= ~CMDSTS_MORE;
            cmdsts |= CMDSTS_OK;
            cmdsts &= 0xffff0000;
            cmdsts += rxPacket->length;   //i.e. set CMDSTS_SIZE

            IpPtr ip(rxPacket);
            if (extstsEnable && ip) {
                extsts |= EXTSTS_IPPKT;
                rxIpChecksums++;
                if (cksum(ip) != 0) {
                    DPRINTF(EthernetCksum, "Rx IP Checksum Error\n");
                    extsts |= EXTSTS_IPERR;
                }
                TcpPtr tcp(ip);
                UdpPtr udp(ip);
                if (tcp) {
                    extsts |= EXTSTS_TCPPKT;
                    rxTcpChecksums++;
                    if (cksum(tcp) != 0) {
                        DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n");
                        extsts |= EXTSTS_TCPERR;

                    }
                } else if (udp) {
                    extsts |= EXTSTS_UDPPKT;
                    rxUdpChecksums++;
                    if (cksum(udp) != 0) {
                        DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n");
                        extsts |= EXTSTS_UDPERR;
                    }
                }
            }
            rxPacket = 0;

            /*
             * the driver seems to always receive into desc buffers
             * of size 1514, so you never have a pkt that is split
             * into multiple descriptors on the receive side, so
             * i don't implement that case, hence the assert above.
             */

            DPRINTF(EthernetDesc,
                    "rxDesc: addr=%08x writeback cmdsts extsts\n",
                    regs.rxdp & 0x3fffffff);
            DPRINTF(EthernetDesc,
                    "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
                    link, bufptr, cmdsts, extsts);

            rxDmaAddr = regs.rxdp & 0x3fffffff;
            rxDmaData = &cmdsts;
            if (is64bit) {
                rxDmaAddr += offsetof(ns_desc64, cmdsts);
                rxDmaLen = sizeof(rxDesc64.cmdsts) + sizeof(rxDesc64.extsts);
            } else {
                rxDmaAddr += offsetof(ns_desc32, cmdsts);
                rxDmaLen = sizeof(rxDesc32.cmdsts) + sizeof(rxDesc32.extsts);
            }
            rxDmaFree = dmaDescFree;

            descDmaWrites++;
            descDmaWrBytes += rxDmaLen;

            if (doRxDmaWrite())
                goto exit;
        }
        break;

      case rxFragWrite:
        if (rxDmaState != dmaIdle)
            goto exit;

        rxPacketBufPtr += rxXferLen;
        rxFragPtr += rxXferLen;
        rxPktBytes -= rxXferLen;

        rxState = rxFifoBlock;
        break;

      case rxDescWrite:
        if (rxDmaState != dmaIdle)
            goto exit;

        assert(cmdsts & CMDSTS_OWN);

        assert(rxPacket == 0);
        devIntrPost(ISR_RXOK);

        if (cmdsts & CMDSTS_INTR)
            devIntrPost(ISR_RXDESC);

        if (!rxEnable) {
            DPRINTF(EthernetSM, "Halting the RX state machine\n");
            rxState = rxIdle;
            goto exit;
        } else
            rxState = rxAdvance;
        break;

      case rxAdvance:
        if (link == 0) {
            devIntrPost(ISR_RXIDLE);
            rxState = rxIdle;
            CRDD = true;
            goto exit;
        } else {
            if (rxDmaState != dmaIdle)
                goto exit;
            rxState = rxDescRead;
            regs.rxdp = link;
            CRDD = false;

            rxDmaAddr = regs.rxdp & 0x3fffffff;
            rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32;
            rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32);
            rxDmaFree = dmaDescFree;

            if (doRxDmaRead())
                goto exit;
        }
        break;

      default:
        panic("Invalid rxState!");
    }

    DPRINTF(EthernetSM, "entering next rxState=%s\n",
            NsRxStateStrings[rxState]);
    goto next;

  exit:
    /**
     * @todo do we want to schedule a future kick?
     */
    DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
            NsRxStateStrings[rxState]);

    if (!rxKickEvent.scheduled())
        schedule(rxKickEvent, rxKickTick);
}

void
NSGigE::transmit()
{
    if (txFifo.empty()) {
        DPRINTF(Ethernet, "nothing to transmit\n");
        return;
    }

    DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n",
            txFifo.size());
    if (interface->sendPacket(txFifo.front())) {
#if TRACING_ON
        if (DTRACE(Ethernet)) {
            IpPtr ip(txFifo.front());
            if (ip) {
                DPRINTF(Ethernet, "ID is %d\n", ip->id());
                TcpPtr tcp(ip);
                if (tcp) {
                    DPRINTF(Ethernet,
                            "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
                            tcp->sport(), tcp->dport(), tcp->seq(),
                            tcp->ack());
                }
            }
        }
#endif

        DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length);
        txBytes += txFifo.front()->length;
        txPackets++;

        DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n",
                txFifo.avail());
        txFifo.pop();

        /*
         * normally do a writeback of the descriptor here, and ONLY
         * after that is done, send this interrupt.  but since our
         * stuff never actually fails, just do this interrupt here,
         * otherwise the code has to stray from this nice format.
         * besides, it's functionally the same.
         */
        devIntrPost(ISR_TXOK);
    }

   if (!txFifo.empty() && !txEvent.scheduled()) {
       DPRINTF(Ethernet, "reschedule transmit\n");
       schedule(txEvent, curTick() + SimClock::Int::ns);
   }
}

bool
NSGigE::doTxDmaRead()
{
    assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting);
    txDmaState = dmaReading;

    if (dmaPending() || drainState() != DrainState::Running)
        txDmaState = dmaReadWaiting;
    else
        dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData);

    return true;
}

void
NSGigE::txDmaReadDone()
{
    assert(txDmaState == dmaReading);
    txDmaState = dmaIdle;

    DPRINTF(EthernetDMA, "tx dma read  paddr=%#x len=%d\n",
            txDmaAddr, txDmaLen);
    DDUMP(EthernetDMA, txDmaData, txDmaLen);

    // If the receive state machine  has a pending DMA, let it go first
    if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting)
        rxKick();

    txKick();
}

bool
NSGigE::doTxDmaWrite()
{
    assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting);
    txDmaState = dmaWriting;

    if (dmaPending() || drainState() != DrainState::Running)
        txDmaState = dmaWriteWaiting;
    else
        dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData);
    return true;
}

void
NSGigE::txDmaWriteDone()
{
    assert(txDmaState == dmaWriting);
    txDmaState = dmaIdle;

    DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n",
            txDmaAddr, txDmaLen);
    DDUMP(EthernetDMA, txDmaData, txDmaLen);

    // If the receive state machine  has a pending DMA, let it go first
    if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting)
        rxKick();

    txKick();
}

void
NSGigE::txKick()
{
    bool is64bit = (bool)(regs.config & CFGR_M64ADDR);

    DPRINTF(EthernetSM, "transmit kick txState=%s %d-bit\n",
            NsTxStateStrings[txState], is64bit ? 64 : 32);

    Addr link, bufptr;
    uint32_t &cmdsts = is64bit ? txDesc64.cmdsts : txDesc32.cmdsts;
    uint32_t &extsts = is64bit ? txDesc64.extsts : txDesc32.extsts;

  next:
    if (txKickTick > curTick()) {
        DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
                txKickTick);
        goto exit;
    }

    // Go to the next state machine clock tick.
    txKickTick = clockEdge(Cycles(1));

    switch(txDmaState) {
      case dmaReadWaiting:
        if (doTxDmaRead())
            goto exit;
        break;
      case dmaWriteWaiting:
        if (doTxDmaWrite())
            goto exit;
        break;
      default:
        break;
    }

    link = is64bit ? (Addr)txDesc64.link : (Addr)txDesc32.link;
    bufptr = is64bit ? (Addr)txDesc64.bufptr : (Addr)txDesc32.bufptr;
    switch (txState) {
      case txIdle:
        if (!txEnable) {
            DPRINTF(EthernetSM, "Transmit disabled.  Nothing to do.\n");
            goto exit;
        }

        if (CTDD) {
            txState = txDescRefr;

            txDmaAddr = regs.txdp & 0x3fffffff;
            txDmaData =
                is64bit ? (void *)&txDesc64.link : (void *)&txDesc32.link;
            txDmaLen = is64bit ? sizeof(txDesc64.link) : sizeof(txDesc32.link);
            txDmaFree = dmaDescFree;

            descDmaReads++;
            descDmaRdBytes += txDmaLen;

            if (doTxDmaRead())
                goto exit;

        } else {
            txState = txDescRead;

            txDmaAddr = regs.txdp & 0x3fffffff;
            txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32;
            txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32);
            txDmaFree = dmaDescFree;

            descDmaReads++;
            descDmaRdBytes += txDmaLen;

            if (doTxDmaRead())
                goto exit;
        }
        break;

      case txDescRefr:
        if (txDmaState != dmaIdle)
            goto exit;

        txState = txAdvance;
        break;

      case txDescRead:
        if (txDmaState != dmaIdle)
            goto exit;

        DPRINTF(EthernetDesc, "txDesc: addr=%08x read descriptor\n",
                regs.txdp & 0x3fffffff);
        DPRINTF(EthernetDesc,
                "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
                link, bufptr, cmdsts, extsts);

        if (cmdsts & CMDSTS_OWN) {
            txState = txFifoBlock;
            txFragPtr = bufptr;
            txDescCnt = cmdsts & CMDSTS_LEN_MASK;
        } else {
            devIntrPost(ISR_TXIDLE);
            txState = txIdle;
            goto exit;
        }
        break;

      case txFifoBlock:
        if (!txPacket) {
            DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
            txPacket = make_shared<EthPacketData>(16384);
            txPacketBufPtr = txPacket->data;
        }

        if (txDescCnt == 0) {
            DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n");
            if (cmdsts & CMDSTS_MORE) {
                DPRINTF(EthernetSM, "there are more descriptors to come\n");
                txState = txDescWrite;

                cmdsts &= ~CMDSTS_OWN;

                txDmaAddr = regs.txdp & 0x3fffffff;
                txDmaData = &cmdsts;
                if (is64bit) {
                    txDmaAddr += offsetof(ns_desc64, cmdsts);
                    txDmaLen = sizeof(txDesc64.cmdsts);
                } else {
                    txDmaAddr += offsetof(ns_desc32, cmdsts);
                    txDmaLen = sizeof(txDesc32.cmdsts);
                }
                txDmaFree = dmaDescFree;

                if (doTxDmaWrite())
                    goto exit;

            } else { /* this packet is totally done */
                DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n");
                /* deal with the the packet that just finished */
                if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) {
                    IpPtr ip(txPacket);
                    if (extsts & EXTSTS_UDPPKT) {
                        UdpPtr udp(ip);
                        if (udp) {
                            udp->sum(0);
                            udp->sum(cksum(udp));
                            txUdpChecksums++;
                        } else {
                            Debug::breakpoint();
                            warn_once("UDPPKT set, but not UDP!\n");
                        }
                    } else if (extsts & EXTSTS_TCPPKT) {
                        TcpPtr tcp(ip);
                        if (tcp) {
                            tcp->sum(0);
                            tcp->sum(cksum(tcp));
                            txTcpChecksums++;
                        } else {
                            warn_once("TCPPKT set, but not UDP!\n");
                        }
                    }
                    if (extsts & EXTSTS_IPPKT) {
                        if (ip) {
                            ip->sum(0);
                            ip->sum(cksum(ip));
                            txIpChecksums++;
                        } else {
                            warn_once("IPPKT set, but not UDP!\n");
                        }
                    }
                }

                txPacket->simLength = txPacketBufPtr - txPacket->data;
                txPacket->length = txPacketBufPtr - txPacket->data;
                // this is just because the receive can't handle a
                // packet bigger want to make sure
                if (txPacket->length > 1514)
                    panic("transmit packet too large, %s > 1514\n",
                          txPacket->length);

#ifndef NDEBUG
                bool success =
#endif
                    txFifo.push(txPacket);
                assert(success);

                /*
                 * this following section is not tqo spec, but
                 * functionally shouldn't be any different.  normally,
                 * the chip will wait til the transmit has occurred
                 * before writing back the descriptor because it has
                 * to wait to see that it was successfully transmitted
                 * to decide whether to set CMDSTS_OK or not.
                 * however, in the simulator since it is always
                 * successfully transmitted, and writing it exactly to
                 * spec would complicate the code, we just do it here
                 */

                cmdsts &= ~CMDSTS_OWN;
                cmdsts |= CMDSTS_OK;

                DPRINTF(EthernetDesc,
                        "txDesc writeback: cmdsts=%08x extsts=%08x\n",
                        cmdsts, extsts);

                txDmaFree = dmaDescFree;
                txDmaAddr = regs.txdp & 0x3fffffff;
                txDmaData = &cmdsts;
                if (is64bit) {
                    txDmaAddr += offsetof(ns_desc64, cmdsts);
                    txDmaLen =
                        sizeof(txDesc64.cmdsts) + sizeof(txDesc64.extsts);
                } else {
                    txDmaAddr += offsetof(ns_desc32, cmdsts);
                    txDmaLen =
                        sizeof(txDesc32.cmdsts) + sizeof(txDesc32.extsts);
                }

                descDmaWrites++;
                descDmaWrBytes += txDmaLen;

                transmit();
                txPacket = 0;

                if (!txEnable) {
                    DPRINTF(EthernetSM, "halting TX state machine\n");
                    txState = txIdle;
                    goto exit;
                } else
                    txState = txAdvance;

                if (doTxDmaWrite())
                    goto exit;
            }
        } else {
            DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
            if (!txFifo.full()) {
                txState = txFragRead;

                /*
                 * The number of bytes transferred is either whatever
                 * is left in the descriptor (txDescCnt), or if there
                 * is not enough room in the fifo, just whatever room
                 * is left in the fifo
                 */
                txXferLen = min<uint32_t>(txDescCnt, txFifo.avail());

                txDmaAddr = txFragPtr & 0x3fffffff;
                txDmaData = txPacketBufPtr;
                txDmaLen = txXferLen;
                txDmaFree = dmaDataFree;

                if (doTxDmaRead())
                    goto exit;
            } else {
                txState = txFifoBlock;
                transmit();

                goto exit;
            }

        }
        break;

      case txFragRead:
        if (txDmaState != dmaIdle)
            goto exit;

        txPacketBufPtr += txXferLen;
        txFragPtr += txXferLen;
        txDescCnt -= txXferLen;
        txFifo.reserve(txXferLen);

        txState = txFifoBlock;
        break;

      case txDescWrite:
        if (txDmaState != dmaIdle)
            goto exit;

        if (cmdsts & CMDSTS_INTR)
            devIntrPost(ISR_TXDESC);

        if (!txEnable) {
            DPRINTF(EthernetSM, "halting TX state machine\n");
            txState = txIdle;
            goto exit;
        } else
            txState = txAdvance;
        break;

      case txAdvance:
        if (link == 0) {
            devIntrPost(ISR_TXIDLE);
            txState = txIdle;
            goto exit;
        } else {
            if (txDmaState != dmaIdle)
                goto exit;
            txState = txDescRead;
            regs.txdp = link;
            CTDD = false;

            txDmaAddr = link & 0x3fffffff;
            txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32;
            txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32);
            txDmaFree = dmaDescFree;

            if (doTxDmaRead())
                goto exit;
        }
        break;

      default:
        panic("invalid state");
    }

    DPRINTF(EthernetSM, "entering next txState=%s\n",
            NsTxStateStrings[txState]);
    goto next;

  exit:
    /**
     * @todo do we want to schedule a future kick?
     */
    DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
            NsTxStateStrings[txState]);

    if (!txKickEvent.scheduled())
        schedule(txKickEvent, txKickTick);
}

/**
 * Advance the EEPROM state machine
 * Called on rising edge of EEPROM clock bit in MEAR
 */
void
NSGigE::eepromKick()
{
    switch (eepromState) {

      case eepromStart:

        // Wait for start bit
        if (regs.mear & MEAR_EEDI) {
            // Set up to get 2 opcode bits
            eepromState = eepromGetOpcode;
            eepromBitsToRx = 2;
            eepromOpcode = 0;
        }
        break;

      case eepromGetOpcode:
        eepromOpcode <<= 1;
        eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;

        // Done getting opcode
        if (eepromBitsToRx == 0) {
            if (eepromOpcode != EEPROM_READ)
                panic("only EEPROM reads are implemented!");

            // Set up to get address
            eepromState = eepromGetAddress;
            eepromBitsToRx = 6;
            eepromAddress = 0;
        }
        break;

      case eepromGetAddress:
        eepromAddress <<= 1;
        eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;

        // Done getting address
        if (eepromBitsToRx == 0) {

            if (eepromAddress >= EEPROM_SIZE)
                panic("EEPROM read access out of range!");

            switch (eepromAddress) {

              case EEPROM_PMATCH2_ADDR:
                eepromData = rom.perfectMatch[5];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[4];
                break;

              case EEPROM_PMATCH1_ADDR:
                eepromData = rom.perfectMatch[3];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[2];
                break;

              case EEPROM_PMATCH0_ADDR:
                eepromData = rom.perfectMatch[1];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[0];
                break;

              default:
                panic("FreeBSD driver only uses EEPROM to read PMATCH!");
            }
            // Set up to read data
            eepromState = eepromRead;
            eepromBitsToRx = 16;

            // Clear data in bit
            regs.mear &= ~MEAR_EEDI;
        }
        break;

      case eepromRead:
        // Clear Data Out bit
        regs.mear &= ~MEAR_EEDO;
        // Set bit to value of current EEPROM bit
        regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0;

        eepromData <<= 1;
        --eepromBitsToRx;

        // All done
        if (eepromBitsToRx == 0) {
            eepromState = eepromStart;
        }
        break;

      default:
        panic("invalid EEPROM state");
    }

}

void
NSGigE::transferDone()
{
    if (txFifo.empty()) {
        DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n");
        return;
    }

    DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");

    reschedule(txEvent, clockEdge(Cycles(1)), true);
}

bool
NSGigE::rxFilter(const EthPacketPtr &packet)
{
    EthPtr eth = packet;
    bool drop = true;
    string type;

    const EthAddr &dst = eth->dst();
    if (dst.unicast()) {
        // If we're accepting all unicast addresses
        if (acceptUnicast)
            drop = false;

        // If we make a perfect match
        if (acceptPerfect && dst == rom.perfectMatch)
            drop = false;

        if (acceptArp && eth->type() == ETH_TYPE_ARP)
            drop = false;

    } else if (dst.broadcast()) {
        // if we're accepting broadcasts
        if (acceptBroadcast)
            drop = false;

    } else if (dst.multicast()) {
        // if we're accepting all multicasts
        if (acceptMulticast)
            drop = false;

        // Multicast hashing faked - all packets accepted
        if (multicastHashEnable)
            drop = false;
    }

    if (drop) {
        DPRINTF(Ethernet, "rxFilter drop\n");
        DDUMP(EthernetData, packet->data, packet->length);
    }

    return drop;
}

bool
NSGigE::recvPacket(EthPacketPtr packet)
{
    rxBytes += packet->length;
    rxPackets++;

    DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
            rxFifo.avail());

    if (!rxEnable) {
        DPRINTF(Ethernet, "receive disabled...packet dropped\n");
        return true;
    }

    if (!rxFilterEnable) {
        DPRINTF(Ethernet,
            "receive packet filtering disabled . . . packet dropped\n");
        return true;
    }

    if (rxFilter(packet)) {
        DPRINTF(Ethernet, "packet filtered...dropped\n");
        return true;
    }

    if (rxFifo.avail() < packet->length) {
#if TRACING_ON
        IpPtr ip(packet);
        TcpPtr tcp(ip);
        if (ip) {
            DPRINTF(Ethernet,
                    "packet won't fit in receive buffer...pkt ID %d dropped\n",
                    ip->id());
            if (tcp) {
                DPRINTF(Ethernet, "Seq=%d\n", tcp->seq());
            }
        }
#endif
        droppedPackets++;
        devIntrPost(ISR_RXORN);
        return false;
    }

    rxFifo.push(packet);

    rxKick();
    return true;
}


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

    // During drain we could have left the state machines in a waiting state and
    // they wouldn't get out until some other event occured to kick them.
    // This way they'll get out immediately
    txKick();
    rxKick();
}


//=====================================================================
//
//
void
NSGigE::serialize(CheckpointOut &cp) const
{
    // Serialize the PciDevice base class
    PciDevice::serialize(cp);

    /*
     * Finalize any DMA events now.
     */
    // @todo will mem system save pending dma?

    /*
     * Serialize the device registers
     */
    SERIALIZE_SCALAR(regs.command);
    SERIALIZE_SCALAR(regs.config);
    SERIALIZE_SCALAR(regs.mear);
    SERIALIZE_SCALAR(regs.ptscr);
    SERIALIZE_SCALAR(regs.isr);
    SERIALIZE_SCALAR(regs.imr);
    SERIALIZE_SCALAR(regs.ier);
    SERIALIZE_SCALAR(regs.ihr);
    SERIALIZE_SCALAR(regs.txdp);
    SERIALIZE_SCALAR(regs.txdp_hi);
    SERIALIZE_SCALAR(regs.txcfg);
    SERIALIZE_SCALAR(regs.gpior);
    SERIALIZE_SCALAR(regs.rxdp);
    SERIALIZE_SCALAR(regs.rxdp_hi);
    SERIALIZE_SCALAR(regs.rxcfg);
    SERIALIZE_SCALAR(regs.pqcr);
    SERIALIZE_SCALAR(regs.wcsr);
    SERIALIZE_SCALAR(regs.pcr);
    SERIALIZE_SCALAR(regs.rfcr);
    SERIALIZE_SCALAR(regs.rfdr);
    SERIALIZE_SCALAR(regs.brar);
    SERIALIZE_SCALAR(regs.brdr);
    SERIALIZE_SCALAR(regs.srr);
    SERIALIZE_SCALAR(regs.mibc);
    SERIALIZE_SCALAR(regs.vrcr);
    SERIALIZE_SCALAR(regs.vtcr);
    SERIALIZE_SCALAR(regs.vdr);
    SERIALIZE_SCALAR(regs.ccsr);
    SERIALIZE_SCALAR(regs.tbicr);
    SERIALIZE_SCALAR(regs.tbisr);
    SERIALIZE_SCALAR(regs.tanar);
    SERIALIZE_SCALAR(regs.tanlpar);
    SERIALIZE_SCALAR(regs.taner);
    SERIALIZE_SCALAR(regs.tesr);

    SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN);
    SERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE);

    SERIALIZE_SCALAR(ioEnable);

    /*
     * Serialize the data Fifos
     */
    rxFifo.serialize("rxFifo", cp);
    txFifo.serialize("txFifo", cp);

    /*
     * Serialize the various helper variables
     */
    bool txPacketExists = txPacket != nullptr;
    SERIALIZE_SCALAR(txPacketExists);
    if (txPacketExists) {
        txPacket->simLength = txPacketBufPtr - txPacket->data;
        txPacket->length = txPacketBufPtr - txPacket->data;
        txPacket->serialize("txPacket", cp);
        uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
        SERIALIZE_SCALAR(txPktBufPtr);
    }

    bool rxPacketExists = rxPacket != nullptr;
    SERIALIZE_SCALAR(rxPacketExists);
    if (rxPacketExists) {
        rxPacket->serialize("rxPacket", cp);
        uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data);
        SERIALIZE_SCALAR(rxPktBufPtr);
    }

    SERIALIZE_SCALAR(txXferLen);
    SERIALIZE_SCALAR(rxXferLen);

    /*
     * Serialize Cached Descriptors
     */
    SERIALIZE_SCALAR(rxDesc64.link);
    SERIALIZE_SCALAR(rxDesc64.bufptr);
    SERIALIZE_SCALAR(rxDesc64.cmdsts);
    SERIALIZE_SCALAR(rxDesc64.extsts);
    SERIALIZE_SCALAR(txDesc64.link);
    SERIALIZE_SCALAR(txDesc64.bufptr);
    SERIALIZE_SCALAR(txDesc64.cmdsts);
    SERIALIZE_SCALAR(txDesc64.extsts);
    SERIALIZE_SCALAR(rxDesc32.link);
    SERIALIZE_SCALAR(rxDesc32.bufptr);
    SERIALIZE_SCALAR(rxDesc32.cmdsts);
    SERIALIZE_SCALAR(rxDesc32.extsts);
    SERIALIZE_SCALAR(txDesc32.link);
    SERIALIZE_SCALAR(txDesc32.bufptr);
    SERIALIZE_SCALAR(txDesc32.cmdsts);
    SERIALIZE_SCALAR(txDesc32.extsts);
    SERIALIZE_SCALAR(extstsEnable);

    /*
     * Serialize tx state machine
     */
    int txState = this->txState;
    SERIALIZE_SCALAR(txState);
    SERIALIZE_SCALAR(txEnable);
    SERIALIZE_SCALAR(CTDD);
    SERIALIZE_SCALAR(txFragPtr);
    SERIALIZE_SCALAR(txDescCnt);
    int txDmaState = this->txDmaState;
    SERIALIZE_SCALAR(txDmaState);
    SERIALIZE_SCALAR(txKickTick);

    /*
     * Serialize rx state machine
     */
    int rxState = this->rxState;
    SERIALIZE_SCALAR(rxState);
    SERIALIZE_SCALAR(rxEnable);
    SERIALIZE_SCALAR(CRDD);
    SERIALIZE_SCALAR(rxPktBytes);
    SERIALIZE_SCALAR(rxFragPtr);
    SERIALIZE_SCALAR(rxDescCnt);
    int rxDmaState = this->rxDmaState;
    SERIALIZE_SCALAR(rxDmaState);
    SERIALIZE_SCALAR(rxKickTick);

    /*
     * Serialize EEPROM state machine
     */
    int eepromState = this->eepromState;
    SERIALIZE_SCALAR(eepromState);
    SERIALIZE_SCALAR(eepromClk);
    SERIALIZE_SCALAR(eepromBitsToRx);
    SERIALIZE_SCALAR(eepromOpcode);
    SERIALIZE_SCALAR(eepromAddress);
    SERIALIZE_SCALAR(eepromData);

    /*
     * If there's a pending transmit, store the time so we can
     * reschedule it later
     */
    Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick() : 0;
    SERIALIZE_SCALAR(transmitTick);

    /*
     * receive address filter settings
     */
    SERIALIZE_SCALAR(rxFilterEnable);
    SERIALIZE_SCALAR(acceptBroadcast);
    SERIALIZE_SCALAR(acceptMulticast);
    SERIALIZE_SCALAR(acceptUnicast);
    SERIALIZE_SCALAR(acceptPerfect);
    SERIALIZE_SCALAR(acceptArp);
    SERIALIZE_SCALAR(multicastHashEnable);

    /*
     * Keep track of pending interrupt status.
     */
    SERIALIZE_SCALAR(intrTick);
    SERIALIZE_SCALAR(cpuPendingIntr);
    Tick intrEventTick = 0;
    if (intrEvent)
        intrEventTick = intrEvent->when();
    SERIALIZE_SCALAR(intrEventTick);

}

void
NSGigE::unserialize(CheckpointIn &cp)
{
    // Unserialize the PciDevice base class
    PciDevice::unserialize(cp);

    UNSERIALIZE_SCALAR(regs.command);
    UNSERIALIZE_SCALAR(regs.config);
    UNSERIALIZE_SCALAR(regs.mear);
    UNSERIALIZE_SCALAR(regs.ptscr);
    UNSERIALIZE_SCALAR(regs.isr);
    UNSERIALIZE_SCALAR(regs.imr);
    UNSERIALIZE_SCALAR(regs.ier);
    UNSERIALIZE_SCALAR(regs.ihr);
    UNSERIALIZE_SCALAR(regs.txdp);
    UNSERIALIZE_SCALAR(regs.txdp_hi);
    UNSERIALIZE_SCALAR(regs.txcfg);
    UNSERIALIZE_SCALAR(regs.gpior);
    UNSERIALIZE_SCALAR(regs.rxdp);
    UNSERIALIZE_SCALAR(regs.rxdp_hi);
    UNSERIALIZE_SCALAR(regs.rxcfg);
    UNSERIALIZE_SCALAR(regs.pqcr);
    UNSERIALIZE_SCALAR(regs.wcsr);
    UNSERIALIZE_SCALAR(regs.pcr);
    UNSERIALIZE_SCALAR(regs.rfcr);
    UNSERIALIZE_SCALAR(regs.rfdr);
    UNSERIALIZE_SCALAR(regs.brar);
    UNSERIALIZE_SCALAR(regs.brdr);
    UNSERIALIZE_SCALAR(regs.srr);
    UNSERIALIZE_SCALAR(regs.mibc);
    UNSERIALIZE_SCALAR(regs.vrcr);
    UNSERIALIZE_SCALAR(regs.vtcr);
    UNSERIALIZE_SCALAR(regs.vdr);
    UNSERIALIZE_SCALAR(regs.ccsr);
    UNSERIALIZE_SCALAR(regs.tbicr);
    UNSERIALIZE_SCALAR(regs.tbisr);
    UNSERIALIZE_SCALAR(regs.tanar);
    UNSERIALIZE_SCALAR(regs.tanlpar);
    UNSERIALIZE_SCALAR(regs.taner);
    UNSERIALIZE_SCALAR(regs.tesr);

    UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN);
    UNSERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE);

    UNSERIALIZE_SCALAR(ioEnable);

    /*
     * unserialize the data fifos
     */
    rxFifo.unserialize("rxFifo", cp);
    txFifo.unserialize("txFifo", cp);

    /*
     * unserialize the various helper variables
     */
    bool txPacketExists;
    UNSERIALIZE_SCALAR(txPacketExists);
    if (txPacketExists) {
        txPacket = make_shared<EthPacketData>(16384);
        txPacket->unserialize("txPacket", cp);
        uint32_t txPktBufPtr;
        UNSERIALIZE_SCALAR(txPktBufPtr);
        txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr;
    } else
        txPacket = 0;

    bool rxPacketExists;
    UNSERIALIZE_SCALAR(rxPacketExists);
    rxPacket = 0;
    if (rxPacketExists) {
        rxPacket = make_shared<EthPacketData>();
        rxPacket->unserialize("rxPacket", cp);
        uint32_t rxPktBufPtr;
        UNSERIALIZE_SCALAR(rxPktBufPtr);
        rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr;
    } else
        rxPacket = 0;

    UNSERIALIZE_SCALAR(txXferLen);
    UNSERIALIZE_SCALAR(rxXferLen);

    /*
     * Unserialize Cached Descriptors
     */
    UNSERIALIZE_SCALAR(rxDesc64.link);
    UNSERIALIZE_SCALAR(rxDesc64.bufptr);
    UNSERIALIZE_SCALAR(rxDesc64.cmdsts);
    UNSERIALIZE_SCALAR(rxDesc64.extsts);
    UNSERIALIZE_SCALAR(txDesc64.link);
    UNSERIALIZE_SCALAR(txDesc64.bufptr);
    UNSERIALIZE_SCALAR(txDesc64.cmdsts);
    UNSERIALIZE_SCALAR(txDesc64.extsts);
    UNSERIALIZE_SCALAR(rxDesc32.link);
    UNSERIALIZE_SCALAR(rxDesc32.bufptr);
    UNSERIALIZE_SCALAR(rxDesc32.cmdsts);
    UNSERIALIZE_SCALAR(rxDesc32.extsts);
    UNSERIALIZE_SCALAR(txDesc32.link);
    UNSERIALIZE_SCALAR(txDesc32.bufptr);
    UNSERIALIZE_SCALAR(txDesc32.cmdsts);
    UNSERIALIZE_SCALAR(txDesc32.extsts);
    UNSERIALIZE_SCALAR(extstsEnable);

    /*
     * unserialize tx state machine
     */
    int txState;
    UNSERIALIZE_SCALAR(txState);
    this->txState = (TxState) txState;
    UNSERIALIZE_SCALAR(txEnable);
    UNSERIALIZE_SCALAR(CTDD);
    UNSERIALIZE_SCALAR(txFragPtr);
    UNSERIALIZE_SCALAR(txDescCnt);
    int txDmaState;
    UNSERIALIZE_SCALAR(txDmaState);
    this->txDmaState = (DmaState) txDmaState;
    UNSERIALIZE_SCALAR(txKickTick);
    if (txKickTick)
        schedule(txKickEvent, txKickTick);

    /*
     * unserialize rx state machine
     */
    int rxState;
    UNSERIALIZE_SCALAR(rxState);
    this->rxState = (RxState) rxState;
    UNSERIALIZE_SCALAR(rxEnable);
    UNSERIALIZE_SCALAR(CRDD);
    UNSERIALIZE_SCALAR(rxPktBytes);
    UNSERIALIZE_SCALAR(rxFragPtr);
    UNSERIALIZE_SCALAR(rxDescCnt);
    int rxDmaState;
    UNSERIALIZE_SCALAR(rxDmaState);
    this->rxDmaState = (DmaState) rxDmaState;
    UNSERIALIZE_SCALAR(rxKickTick);
    if (rxKickTick)
        schedule(rxKickEvent, rxKickTick);

    /*
     * Unserialize EEPROM state machine
     */
    int eepromState;
    UNSERIALIZE_SCALAR(eepromState);
    this->eepromState = (EEPROMState) eepromState;
    UNSERIALIZE_SCALAR(eepromClk);
    UNSERIALIZE_SCALAR(eepromBitsToRx);
    UNSERIALIZE_SCALAR(eepromOpcode);
    UNSERIALIZE_SCALAR(eepromAddress);
    UNSERIALIZE_SCALAR(eepromData);

    /*
     * If there's a pending transmit, reschedule it now
     */
    Tick transmitTick;
    UNSERIALIZE_SCALAR(transmitTick);
    if (transmitTick)
        schedule(txEvent, curTick() + transmitTick);

    /*
     * unserialize receive address filter settings
     */
    UNSERIALIZE_SCALAR(rxFilterEnable);
    UNSERIALIZE_SCALAR(acceptBroadcast);
    UNSERIALIZE_SCALAR(acceptMulticast);
    UNSERIALIZE_SCALAR(acceptUnicast);
    UNSERIALIZE_SCALAR(acceptPerfect);
    UNSERIALIZE_SCALAR(acceptArp);
    UNSERIALIZE_SCALAR(multicastHashEnable);

    /*
     * Keep track of pending interrupt status.
     */
    UNSERIALIZE_SCALAR(intrTick);
    UNSERIALIZE_SCALAR(cpuPendingIntr);
    Tick intrEventTick;
    UNSERIALIZE_SCALAR(intrEventTick);
    if (intrEventTick) {
        intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
                                             name(), true);
        schedule(intrEvent, intrEventTick);
    }
}

NSGigE *
NSGigEParams::create() const
{
    return new NSGigE(*this);
}
