/*
 * 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.
 */

#ifndef __DEV_NET_SINIC_HH__
#define __DEV_NET_SINIC_HH__

#include "base/compiler.hh"
#include "base/inet.hh"
#include "base/statistics.hh"
#include "dev/io_device.hh"
#include "dev/net/etherdevice.hh"
#include "dev/net/etherint.hh"
#include "dev/net/etherpkt.hh"
#include "dev/net/pktfifo.hh"
#include "dev/net/sinicreg.hh"
#include "dev/pci/device.hh"
#include "params/Sinic.hh"
#include "sim/eventq.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Sinic, sinic);
namespace sinic
{

class Interface;
class Base : public EtherDevBase
{
  protected:
    bool rxEnable;
    bool txEnable;

  protected:
    Tick intrDelay;
    Tick intrTick;
    bool cpuIntrEnable;
    bool cpuPendingIntr;
    void cpuIntrPost(Tick when);
    void cpuInterrupt();
    void cpuIntrClear();

    EventFunctionWrapper *intrEvent;
    Interface *interface;

    bool cpuIntrPending() const;
    void cpuIntrAck() { cpuIntrClear(); }

/**
 * Serialization stuff
 */
  public:
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

/**
 * Construction/Destruction/Parameters
 */
  public:
    PARAMS(Sinic);
    Base(const Params &p);
};

class Device : public Base
{
  protected:
    /** Receive State Machine States */
    enum RxState
    {
        rxIdle,
        rxFifoBlock,
        rxBeginCopy,
        rxCopy,
        rxCopyDone
    };

    /** Transmit State Machine states */
    enum TxState
    {
        txIdle,
        txFifoBlock,
        txBeginCopy,
        txCopy,
        txCopyDone
    };

    /** device register file */
    struct
    {
        uint32_t Config;       // 0x00
        uint32_t Command;      // 0x04
        uint32_t IntrStatus;   // 0x08
        uint32_t IntrMask;     // 0x0c
        uint32_t RxMaxCopy;    // 0x10
        uint32_t TxMaxCopy;    // 0x14
        uint32_t ZeroCopySize; // 0x18
        uint32_t ZeroCopyMark; // 0x1c
        uint32_t VirtualCount; // 0x20
        uint32_t RxMaxIntr;    // 0x24
        uint32_t RxFifoSize;   // 0x28
        uint32_t TxFifoSize;   // 0x2c
        uint32_t RxFifoLow;    // 0x30
        uint32_t TxFifoLow;    // 0x34
        uint32_t RxFifoHigh;   // 0x38
        uint32_t TxFifoHigh;   // 0x3c
        uint64_t RxData;       // 0x40
        uint64_t RxDone;       // 0x48
        uint64_t RxWait;       // 0x50
        uint64_t TxData;       // 0x58
        uint64_t TxDone;       // 0x60
        uint64_t TxWait;       // 0x68
        uint64_t HwAddr;       // 0x70
        uint64_t RxStatus;     // 0x78
    } regs;

    struct VirtualReg
    {
        uint64_t RxData;
        uint64_t RxDone;
        uint64_t TxData;
        uint64_t TxDone;

        PacketFifo::iterator rxIndex;
        unsigned rxPacketOffset;
        unsigned rxPacketBytes;
        uint64_t rxDoneData;

        Counter rxUnique;
        Counter txUnique;

        VirtualReg()
            : RxData(0), RxDone(0), TxData(0), TxDone(0),
              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
        { }
    };
    typedef std::vector<VirtualReg> VirtualRegs;
    typedef std::list<unsigned> VirtualList;
    Counter rxUnique;
    Counter txUnique;
    VirtualRegs virtualRegs;
    VirtualList rxList;
    VirtualList rxBusy;
    int rxActive;
    VirtualList txList;

    int rxBusyCount;
    int rxMappedCount;
    int rxDirtyCount;

    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }

  protected:
    RxState rxState;
    PacketFifo rxFifo;
    PacketFifo::iterator rxFifoPtr;
    bool rxEmpty;
    bool rxLow;
    Addr rxDmaAddr;
    uint8_t *rxDmaData;
    unsigned rxDmaLen;

    TxState txState;
    PacketFifo txFifo;
    bool txFull;
    EthPacketPtr txPacket;
    int txPacketOffset;
    int txPacketBytes;
    Addr txDmaAddr;
    uint8_t *txDmaData;
    int txDmaLen;

  protected:
    void reset();

    void rxKick();
    Tick rxKickTick;

    void txKick();
    Tick txKickTick;

    /**
     * Retransmit event
     */
    void transmit();
    void txEventTransmit()
    {
        transmit();
        if (txState == txFifoBlock)
            txKick();
    }
    EventFunctionWrapper txEvent;

    void txDump() const;
    void rxDump() const;

    /**
     * receive address filter
     */
    bool rxFilter(const EthPacketPtr &packet);

/**
 * device configuration
 */
    void changeConfig(uint32_t newconfig);
    void command(uint32_t command);

/**
 * device ethernet interface
 */
  public:
    bool recvPacket(EthPacketPtr packet);
    void transferDone();
    Port &getPort(const std::string &if_name,
                  PortID idx=InvalidPortID) override;

/**
 * DMA parameters
 */
  protected:
    void rxDmaDone();
    EventFunctionWrapper rxDmaEvent;

    void txDmaDone();
    EventFunctionWrapper txDmaEvent;

    Tick dmaReadDelay;
    Tick dmaReadFactor;
    Tick dmaWriteDelay;
    Tick dmaWriteFactor;

/**
 * Interrupt management
 */
  protected:
    void devIntrPost(uint32_t interrupts);
    void devIntrClear(uint32_t interrupts = registers::Intr_All);
    void devIntrChangeMask(uint32_t newmask);

/**
 * Memory Interface
 */
  public:
    Tick read(PacketPtr pkt) override;
    Tick write(PacketPtr pkt) override;
    virtual void drainResume() override;

    void prepareIO(ContextID cpu, int index);
    void prepareRead(ContextID cpu, int index);
    void prepareWrite(ContextID cpu, int index);
 //   Fault iprRead(Addr daddr, ContextID cpu, uint64_t &result);

/**
 * Statistics
 */
  private:
    struct DeviceStats : public statistics::Group
    {
        DeviceStats(statistics::Group *parent);

        statistics::Scalar totalVnicDistance;
        statistics::Scalar numVnicDistance;
        statistics::Scalar maxVnicDistance;
        statistics::Formula avgVnicDistance;

        int _maxVnicDistance;
    } sinicDeviceStats;


  public:
    void resetStats() override;

/**
 * Serialization stuff
 */
  public:
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

  public:
    Device(const Params &p);
    ~Device();
};

/*
 * Ethernet Interface for an Ethernet Device
 */
class Interface : public EtherInt
{
  private:
    Device *dev;

  public:
    Interface(const std::string &name, Device *d)
        : EtherInt(name), dev(d)
    { }

    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
    virtual void sendDone() { dev->transferDone(); }
};

} // namespace sinic
} // namespace gem5

#endif // __DEV_NET_SINIC_HH__
