13116SN/A/*
23116SN/A * Copyright (c) 2006 The Regents of The University of Michigan
33116SN/A * All rights reserved.
43116SN/A *
53116SN/A * Redistribution and use in source and binary forms, with or without
63116SN/A * modification, are permitted provided that the following conditions are
73116SN/A * met: redistributions of source code must retain the above copyright
83116SN/A * notice, this list of conditions and the following disclaimer;
93116SN/A * redistributions in binary form must reproduce the above copyright
103116SN/A * notice, this list of conditions and the following disclaimer in the
113116SN/A * documentation and/or other materials provided with the distribution;
123116SN/A * neither the name of the copyright holders nor the names of its
133116SN/A * contributors may be used to endorse or promote products derived from
143116SN/A * this software without specific prior written permission.
153116SN/A *
163116SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173116SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183116SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193116SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203116SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213116SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223116SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233116SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243116SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253116SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263116SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273116SN/A *
283116SN/A * Authors: Ali Saidi
293116SN/A */
303116SN/A
313116SN/A/* @file
323116SN/A * Device model for Intel's 8254x line of gigabit ethernet controllers.
333116SN/A */
343116SN/A
3511263Sandreas.sandberg@arm.com#ifndef __DEV_NET_I8254XGBE_HH__
3611263Sandreas.sandberg@arm.com#define __DEV_NET_I8254XGBE_HH__
373116SN/A
384263SN/A#include <deque>
394263SN/A#include <string>
404263SN/A
415954SN/A#include "base/cp_annotate.hh"
423116SN/A#include "base/inet.hh"
438232SN/A#include "debug/EthernetDesc.hh"
448232SN/A#include "debug/EthernetIntr.hh"
4511263Sandreas.sandberg@arm.com#include "dev/net/etherdevice.hh"
4611263Sandreas.sandberg@arm.com#include "dev/net/etherint.hh"
4711263Sandreas.sandberg@arm.com#include "dev/net/etherpkt.hh"
4811263Sandreas.sandberg@arm.com#include "dev/net/i8254xGBe_defs.hh"
4911263Sandreas.sandberg@arm.com#include "dev/net/pktfifo.hh"
5011260SN/A#include "dev/pci/device.hh"
514762SN/A#include "params/IGbE.hh"
523116SN/A#include "sim/eventq.hh"
533116SN/A
543116SN/Aclass IGbEInt;
553116SN/A
564981SN/Aclass IGbE : public EtherDevice
573116SN/A{
583116SN/A  private:
593116SN/A    IGbEInt *etherInt;
605954SN/A    CPA *cpa;
614263SN/A
624263SN/A    // device registers
633318SN/A    iGbReg::Regs regs;
644263SN/A
654263SN/A    // eeprom data, status and control bits
663318SN/A    int eeOpBits, eeAddrBits, eeDataBits;
673318SN/A    uint8_t eeOpcode, eeAddr;
684263SN/A    uint16_t flash[iGbReg::EEPROM_SIZE];
693318SN/A
704263SN/A    // packet fifos
714263SN/A    PacketFifo rxFifo;
724263SN/A    PacketFifo txFifo;
733318SN/A
744263SN/A    // Packet that we are currently putting into the txFifo
754263SN/A    EthPacketPtr txPacket;
764263SN/A
774263SN/A    // Should to Rx/Tx State machine tick?
7812064Sgabeblack@google.com    bool inTick;
794263SN/A    bool rxTick;
804263SN/A    bool txTick;
814291SN/A    bool txFifoTick;
824263SN/A
834452SN/A    bool rxDmaPacket;
844452SN/A
855783SN/A    // Number of bytes copied from current RX packet
866227SN/A    unsigned pktOffset;
875783SN/A
885535SN/A    // Delays in managaging descriptors
895535SN/A    Tick fetchDelay, wbDelay;
905535SN/A    Tick fetchCompDelay, wbCompDelay;
915535SN/A    Tick rxWriteDelay, txReadDelay;
925535SN/A
934263SN/A    // Event and function to deal with RDTR timer expiring
944291SN/A    void rdtrProcess() {
954291SN/A        rxDescCache.writeback(0);
966124SN/A        DPRINTF(EthernetIntr,
976124SN/A                "Posting RXT interrupt because RDTR timer expired\n");
985533SN/A        postInterrupt(iGbReg::IT_RXT);
994291SN/A    }
1004291SN/A
10112087Sspwilson2@wisc.edu    EventFunctionWrapper rdtrEvent;
1024263SN/A
1034263SN/A    // Event and function to deal with RADV timer expiring
1044291SN/A    void radvProcess() {
1054291SN/A        rxDescCache.writeback(0);
1066124SN/A        DPRINTF(EthernetIntr,
1076124SN/A                "Posting RXT interrupt because RADV timer expired\n");
1085533SN/A        postInterrupt(iGbReg::IT_RXT);
1094291SN/A    }
1104291SN/A
11112087Sspwilson2@wisc.edu    EventFunctionWrapper radvEvent;
1124263SN/A
1134263SN/A    // Event and function to deal with TADV timer expiring
1144291SN/A    void tadvProcess() {
1154291SN/A        txDescCache.writeback(0);
1166124SN/A        DPRINTF(EthernetIntr,
1176124SN/A                "Posting TXDW interrupt because TADV timer expired\n");
1185533SN/A        postInterrupt(iGbReg::IT_TXDW);
1194291SN/A    }
1204291SN/A
12112087Sspwilson2@wisc.edu    EventFunctionWrapper tadvEvent;
1224263SN/A
1234263SN/A    // Event and function to deal with TIDV timer expiring
1244291SN/A    void tidvProcess() {
1254291SN/A        txDescCache.writeback(0);
1266124SN/A        DPRINTF(EthernetIntr,
1276124SN/A                "Posting TXDW interrupt because TIDV timer expired\n");
1285533SN/A        postInterrupt(iGbReg::IT_TXDW);
1294291SN/A    }
13012087Sspwilson2@wisc.edu    EventFunctionWrapper tidvEvent;
1314263SN/A
1324263SN/A    // Main event to tick the device
1334263SN/A    void tick();
13412087Sspwilson2@wisc.edu    EventFunctionWrapper tickEvent;
1354263SN/A
1364263SN/A
1375538SN/A    uint64_t macAddr;
1385538SN/A
1394263SN/A    void rxStateMachine();
1404263SN/A    void txStateMachine();
1414263SN/A    void txWire();
1424263SN/A
1434263SN/A    /** Write an interrupt into the interrupt pending register and check mask
1444263SN/A     * and interrupt limit timer before sending interrupt to CPU
1454263SN/A     * @param t the type of interrupt we are posting
1464263SN/A     * @param now should we ignore the interrupt limiting timer
1474263SN/A     */
1484263SN/A    void postInterrupt(iGbReg::IntTypes t, bool now = false);
1494263SN/A
1504263SN/A    /** Check and see if changes to the mask register have caused an interrupt
1514263SN/A     * to need to be sent or perhaps removed an interrupt cause.
1524263SN/A     */
1534263SN/A    void chkInterrupt();
1544263SN/A
1554263SN/A    /** Send an interrupt to the cpu
1564263SN/A     */
1574987SN/A    void delayIntEvent();
1584263SN/A    void cpuPostInt();
1594263SN/A    // Event to moderate interrupts
16012087Sspwilson2@wisc.edu    EventFunctionWrapper interEvent;
1614263SN/A
1624263SN/A    /** Clear the interupt line to the cpu
1634263SN/A     */
1644263SN/A    void cpuClearInt();
1654263SN/A
1667064SN/A    Tick intClock() { return SimClock::Int::ns * 1024; }
1674263SN/A
1684294SN/A    /** This function is used to restart the clock so it can handle things like
1694294SN/A     * draining and resume in one place. */
1704283SN/A    void restartClock();
1714283SN/A
1724294SN/A    /** Check if all the draining things that need to occur have occured and
1734294SN/A     * handle the drain event if so.
1744294SN/A     */
1754294SN/A    void checkDrain();
1764294SN/A
1775954SN/A    void anBegin(std::string sm, std::string st, int flags = CPA::FL_NONE) {
17810702SN/A        if (cpa)
17910702SN/A            cpa->hwBegin((CPA::flags)flags, sys, macAddr, sm, st);
1805954SN/A    }
1815954SN/A
18210702SN/A    void anQ(std::string sm, std::string q) {
18310702SN/A        if (cpa)
18410702SN/A            cpa->hwQ(CPA::FL_NONE, sys, macAddr, sm, q, macAddr);
1855954SN/A    }
1865954SN/A
1875954SN/A    void anDq(std::string sm, std::string q) {
18810702SN/A        if (cpa)
18910702SN/A            cpa->hwDq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr);
1905954SN/A    }
1915954SN/A
1925954SN/A    void anPq(std::string sm, std::string q, int num = 1) {
19310702SN/A        if (cpa)
19410702SN/A            cpa->hwPq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr, NULL, num);
1955954SN/A    }
1965954SN/A
1975954SN/A    void anRq(std::string sm, std::string q, int num = 1) {
19810702SN/A        if (cpa)
19910702SN/A            cpa->hwRq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr, NULL, num);
2005954SN/A    }
2015954SN/A
2025954SN/A    void anWe(std::string sm, std::string q) {
20310702SN/A        if (cpa)
20410702SN/A            cpa->hwWe(CPA::FL_NONE, sys, macAddr, sm, q, macAddr);
2055954SN/A    }
2065954SN/A
2075954SN/A    void anWf(std::string sm, std::string q) {
20810702SN/A        if (cpa)
20910702SN/A            cpa->hwWf(CPA::FL_NONE, sys, macAddr, sm, q, macAddr);
2105954SN/A    }
2115954SN/A
2125954SN/A
2134263SN/A    template<class T>
21410905SN/A    class DescCache : public Serializable
2154263SN/A    {
2164263SN/A      protected:
2174263SN/A        virtual Addr descBase() const = 0;
2184263SN/A        virtual long descHead() const = 0;
2194263SN/A        virtual long descTail() const = 0;
2204263SN/A        virtual long descLen() const = 0;
2214263SN/A        virtual void updateHead(long h) = 0;
2224263SN/A        virtual void enableSm() = 0;
2235763SN/A        virtual void actionAfterWb() {}
2244987SN/A        virtual void fetchAfterWb() = 0;
2254263SN/A
2266227SN/A        typedef std::deque<T *> CacheType;
2276227SN/A        CacheType usedCache;
2286227SN/A        CacheType unusedCache;
2294263SN/A
2304263SN/A        T *fetchBuf;
2314263SN/A        T *wbBuf;
2324263SN/A
2334263SN/A        // Pointer to the device we cache for
2344263SN/A        IGbE *igbe;
2354263SN/A
2364263SN/A        // Name of this  descriptor cache
2374263SN/A        std::string _name;
2384263SN/A
2394263SN/A        // How far we've cached
2404263SN/A        int cachePnt;
2414263SN/A
2424263SN/A        // The size of the descriptor cache
2434263SN/A        int size;
2444263SN/A
2454263SN/A        // How many descriptors we are currently fetching
2464263SN/A        int curFetching;
2474263SN/A
2484263SN/A        // How many descriptors we are currently writing back
2494263SN/A        int wbOut;
2504263SN/A
2514263SN/A        // if the we wrote back to the end of the descriptor ring and are going
2524263SN/A        // to have to wrap and write more
2534263SN/A        bool moreToWb;
2544263SN/A
2554263SN/A        // What the alignment is of the next descriptor writeback
2564263SN/A        Addr wbAlignment;
2574263SN/A
2586124SN/A        /** The packet that is currently being dmad to memory if any */
2594263SN/A        EthPacketPtr pktPtr;
2604263SN/A
2616124SN/A        /** Shortcut for DMA address translation */
26211202SN/A        Addr pciToDma(Addr a) { return igbe->pciToDma(a); }
2636124SN/A
2644263SN/A      public:
2655954SN/A        /** Annotate sm*/
2665954SN/A        std::string annSmFetch, annSmWb, annUnusedDescQ, annUsedCacheQ,
2675954SN/A            annUsedDescQ, annUnusedCacheQ, annDescQ;
2685954SN/A
2696124SN/A        DescCache(IGbE *i, const std::string n, int s);
2706124SN/A        virtual ~DescCache();
2714263SN/A
2724263SN/A        std::string name() { return _name; }
2734263SN/A
2744263SN/A        /** If the address/len/head change when we've got descriptors that are
2754263SN/A         * dirty that is very bad. This function checks that we don't and if we
2764263SN/A         * do panics.
2774263SN/A         */
2786124SN/A        void areaChanged();
2794291SN/A
2806124SN/A        void writeback(Addr aMask);
2816124SN/A        void writeback1();
28212087Sspwilson2@wisc.edu        EventFunctionWrapper wbDelayEvent;
2834263SN/A
2844263SN/A        /** Fetch a chunk of descriptors into the descriptor cache.
2854263SN/A         * Calls fetchComplete when the memory system returns the data
2864263SN/A         */
2876124SN/A        void fetchDescriptors();
2886124SN/A        void fetchDescriptors1();
28912087Sspwilson2@wisc.edu        EventFunctionWrapper fetchDelayEvent;
2904263SN/A
2914263SN/A        /** Called by event when dma to read descriptors is completed
2924263SN/A         */
2936124SN/A        void fetchComplete();
29412087Sspwilson2@wisc.edu        EventFunctionWrapper fetchEvent;
2954263SN/A
2964263SN/A        /** Called by event when dma to writeback descriptors is completed
2974263SN/A         */
2986124SN/A        void wbComplete();
29912087Sspwilson2@wisc.edu        EventFunctionWrapper wbEvent;
3004263SN/A
3014263SN/A        /* Return the number of descriptors left in the ring, so the device has
3024263SN/A         * a way to figure out if it needs to interrupt.
3034263SN/A         */
3046227SN/A        unsigned
3056227SN/A        descLeft() const
3064263SN/A        {
3076227SN/A            unsigned left = unusedCache.size();
3086217SN/A            if (cachePnt > descTail())
3095762SN/A                left += (descLen() - cachePnt + descTail());
3104263SN/A            else
3114283SN/A                left += (descTail() - cachePnt);
3124263SN/A
3134263SN/A            return left;
3144263SN/A        }
3154263SN/A
3164263SN/A        /* Return the number of descriptors used and not written back.
3174263SN/A         */
3186227SN/A        unsigned descUsed() const { return usedCache.size(); }
3194263SN/A
3204263SN/A        /* Return the number of cache unused descriptors we have. */
3216227SN/A        unsigned descUnused() const { return unusedCache.size(); }
3224263SN/A
3234263SN/A        /* Get into a state where the descriptor address/head/etc colud be
3244263SN/A         * changed */
3256124SN/A        void reset();
3264263SN/A
32710905SN/A
32811168SN/A        void serialize(CheckpointOut &cp) const override;
32911168SN/A        void unserialize(CheckpointIn &cp) override;
3304291SN/A
3314294SN/A        virtual bool hasOutstandingEvents() {
3324294SN/A            return wbEvent.scheduled() || fetchEvent.scheduled();
3334294SN/A        }
3344294SN/A
3356124SN/A    };
3364263SN/A
3374263SN/A
3384263SN/A    class RxDescCache : public DescCache<iGbReg::RxDesc>
3394263SN/A    {
3404263SN/A      protected:
34111169SN/A        Addr descBase() const override { return igbe->regs.rdba(); }
34211169SN/A        long descHead() const override { return igbe->regs.rdh(); }
34311169SN/A        long descLen() const override { return igbe->regs.rdlen() >> 4; }
34411169SN/A        long descTail() const override { return igbe->regs.rdt(); }
34511169SN/A        void updateHead(long h) override { igbe->regs.rdh(h); }
34611169SN/A        void enableSm() override;
34711169SN/A        void fetchAfterWb() override {
34810913SN/A            if (!igbe->rxTick && igbe->drainState() == DrainState::Running)
3494987SN/A                fetchDescriptors();
3504987SN/A        }
3514263SN/A
3524263SN/A        bool pktDone;
3534263SN/A
3545783SN/A        /** Variable to head with header/data completion events */
3555783SN/A        int splitCount;
3565783SN/A
3576124SN/A        /** Bytes of packet that have been copied, so we know when to
3586124SN/A            set EOP */
3596227SN/A        unsigned bytesCopied;
3605783SN/A
3614263SN/A      public:
3624263SN/A        RxDescCache(IGbE *i, std::string n, int s);
3634263SN/A
3644263SN/A        /** Write the given packet into the buffer(s) pointed to by the
3654263SN/A         * descriptor and update the book keeping. Should only be called when
3664263SN/A         * there are no dma's pending.
3674263SN/A         * @param packet ethernet packet to write
3685783SN/A         * @param pkt_offset bytes already copied from the packet to memory
3695783SN/A         * @return pkt_offset + number of bytes copied during this call
3704263SN/A         */
3715783SN/A        int writePacket(EthPacketPtr packet, int pkt_offset);
3725783SN/A
3734263SN/A        /** Called by event when dma to write packet is completed
3744263SN/A         */
3754263SN/A        void pktComplete();
3764263SN/A
3775783SN/A        /** Check if the dma on the packet has completed and RX state machine
3785783SN/A         * can continue
3794263SN/A         */
3804263SN/A        bool packetDone();
3814263SN/A
38212087Sspwilson2@wisc.edu        EventFunctionWrapper pktEvent;
3834263SN/A
3845783SN/A        // Event to handle issuing header and data write at the same time
3855783SN/A        // and only callking pktComplete() when both are completed
3865783SN/A        void pktSplitDone();
38712087Sspwilson2@wisc.edu        EventFunctionWrapper pktHdrEvent;
38812087Sspwilson2@wisc.edu        EventFunctionWrapper pktDataEvent;
3895783SN/A
39011169SN/A        bool hasOutstandingEvents() override;
3914294SN/A
39211168SN/A        void serialize(CheckpointOut &cp) const override;
39311168SN/A        void unserialize(CheckpointIn &cp) override;
3944263SN/A    };
3954263SN/A    friend class RxDescCache;
3964263SN/A
3974263SN/A    RxDescCache rxDescCache;
3984263SN/A
3994263SN/A    class TxDescCache  : public DescCache<iGbReg::TxDesc>
4004263SN/A    {
4014263SN/A      protected:
40211169SN/A        Addr descBase() const override { return igbe->regs.tdba(); }
40311169SN/A        long descHead() const override { return igbe->regs.tdh(); }
40411169SN/A        long descTail() const override { return igbe->regs.tdt(); }
40511169SN/A        long descLen() const override { return igbe->regs.tdlen() >> 4; }
40611169SN/A        void updateHead(long h) override { igbe->regs.tdh(h); }
40711169SN/A        void enableSm() override;
40811169SN/A        void actionAfterWb() override;
40911169SN/A        void fetchAfterWb() override {
41010913SN/A            if (!igbe->txTick && igbe->drainState() == DrainState::Running)
4114987SN/A                fetchDescriptors();
4124987SN/A        }
41311320Ssteve.reinhardt@amd.com
4145763SN/A
4154263SN/A
4164263SN/A        bool pktDone;
4174263SN/A        bool isTcp;
4184263SN/A        bool pktWaiting;
4195404SN/A        bool pktMultiDesc;
4205763SN/A        Addr completionAddress;
4215763SN/A        bool completionEnabled;
4225763SN/A        uint32_t descEnd;
42311320Ssteve.reinhardt@amd.com
4244263SN/A
4255762SN/A        // tso variables
4265762SN/A        bool useTso;
4275762SN/A        Addr tsoHeaderLen;
4285762SN/A        Addr tsoMss;
4295762SN/A        Addr tsoTotalLen;
4305762SN/A        Addr tsoUsedLen;
4318902SN/A        Addr tsoPrevSeq;
4325762SN/A        Addr tsoPktPayloadBytes;
4335762SN/A        bool tsoLoadedHeader;
4345762SN/A        bool tsoPktHasHeader;
4355762SN/A        uint8_t tsoHeader[256];
4365762SN/A        Addr tsoDescBytesUsed;
4375762SN/A        Addr tsoCopyBytes;
4385762SN/A        int tsoPkts;
4395762SN/A
4404263SN/A      public:
4414263SN/A        TxDescCache(IGbE *i, std::string n, int s);
4424263SN/A
4434263SN/A        /** Tell the cache to DMA a packet from main memory into its buffer and
4444263SN/A         * return the size the of the packet to reserve space in tx fifo.
4454263SN/A         * @return size of the packet
4464263SN/A         */
4476227SN/A        unsigned getPacketSize(EthPacketPtr p);
4484263SN/A        void getPacketData(EthPacketPtr p);
4495762SN/A        void processContextDesc();
4504263SN/A
4515763SN/A        /** Return the number of dsecriptors in a cache block for threshold
4525763SN/A         * operations.
4535763SN/A         */
4546227SN/A        unsigned
4556227SN/A        descInBlock(unsigned num_desc)
4566227SN/A        {
4576227SN/A            return num_desc / igbe->cacheBlockSize() / sizeof(iGbReg::TxDesc);
4586227SN/A        }
4596227SN/A
4604263SN/A        /** Ask if the packet has been transfered so the state machine can give
4614263SN/A         * it to the fifo.
4624263SN/A         * @return packet available in descriptor cache
4634263SN/A         */
4644263SN/A        bool packetAvailable();
4654263SN/A
4664263SN/A        /** Ask if we are still waiting for the packet to be transfered.
4674263SN/A         * @return packet still in transit.
4684263SN/A         */
4694263SN/A        bool packetWaiting() { return pktWaiting; }
4704263SN/A
4715404SN/A        /** Ask if this packet is composed of multiple descriptors
4725404SN/A         * so even if we've got data, we need to wait for more before
4735404SN/A         * we can send it out.
4745404SN/A         * @return packet can't be sent out because it's a multi-descriptor
4755404SN/A         * packet
4765404SN/A         */
4775404SN/A        bool packetMultiDesc() { return pktMultiDesc;}
4785404SN/A
4794263SN/A        /** Called by event when dma to write packet is completed
4804263SN/A         */
4814263SN/A        void pktComplete();
48212087Sspwilson2@wisc.edu        EventFunctionWrapper pktEvent;
4834263SN/A
4845762SN/A        void headerComplete();
48512087Sspwilson2@wisc.edu        EventFunctionWrapper headerEvent;
4865762SN/A
4875763SN/A
4885763SN/A        void completionWriteback(Addr a, bool enabled) {
4896124SN/A            DPRINTF(EthernetDesc,
49011320Ssteve.reinhardt@amd.com                    "Completion writeback Addr: %#x enabled: %d\n",
4915763SN/A                    a, enabled);
4925763SN/A            completionAddress = a;
4935763SN/A            completionEnabled = enabled;
4945763SN/A        }
4955763SN/A
49611169SN/A        bool hasOutstandingEvents() override;
4974294SN/A
4986124SN/A        void nullCallback() {
4996124SN/A            DPRINTF(EthernetDesc, "Completion writeback complete\n");
5006124SN/A        }
50112087Sspwilson2@wisc.edu        EventFunctionWrapper nullEvent;
5025763SN/A
50311168SN/A        void serialize(CheckpointOut &cp) const override;
50411168SN/A        void unserialize(CheckpointIn &cp) override;
50510905SN/A    };
5064294SN/A
5074263SN/A    friend class TxDescCache;
5084263SN/A
5094263SN/A    TxDescCache txDescCache;
5103116SN/A
5113116SN/A  public:
5124762SN/A    typedef IGbEParams Params;
5134762SN/A    const Params *
5146124SN/A    params() const {
5154762SN/A        return dynamic_cast<const Params *>(_params);
5164762SN/A    }
5176124SN/A
5184981SN/A    IGbE(const Params *params);
5199086SN/A    ~IGbE();
52011169SN/A    void init() override;
5213116SN/A
52213784Sgabeblack@google.com    Port &getPort(const std::string &if_name,
52313784Sgabeblack@google.com                  PortID idx=InvalidPortID) override;
5244981SN/A
5255500SN/A    Tick lastInterrupt;
5264263SN/A
52711169SN/A    Tick read(PacketPtr pkt) override;
52811169SN/A    Tick write(PacketPtr pkt) override;
5293116SN/A
53011169SN/A    Tick writeConfig(PacketPtr pkt) override;
5313116SN/A
5323116SN/A    bool ethRxPkt(EthPacketPtr packet);
5333116SN/A    void ethTxDone();
5343116SN/A
53511168SN/A    void serialize(CheckpointOut &cp) const override;
53611168SN/A    void unserialize(CheckpointIn &cp) override;
5379342SN/A
53811168SN/A    DrainState drain() override;
53911168SN/A    void drainResume() override;
5403116SN/A
5413116SN/A};
5423116SN/A
5433116SN/Aclass IGbEInt : public EtherInt
5443116SN/A{
5453116SN/A  private:
5463116SN/A    IGbE *dev;
5473116SN/A
5483116SN/A  public:
5493116SN/A    IGbEInt(const std::string &name, IGbE *d)
5503116SN/A        : EtherInt(name), dev(d)
5514981SN/A    { }
5523116SN/A
5533116SN/A    virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); }
5543116SN/A    virtual void sendDone() { dev->ethTxDone(); }
5553116SN/A};
5563116SN/A
55711263Sandreas.sandberg@arm.com#endif //__DEV_NET_I8254XGBE_HH__
558