i8254xGBe.hh revision 11320
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? 784263SN/A bool rxTick; 794263SN/A bool txTick; 804291SN/A bool txFifoTick; 814263SN/A 824452SN/A bool rxDmaPacket; 834452SN/A 845783SN/A // Number of bytes copied from current RX packet 856227SN/A unsigned pktOffset; 865783SN/A 875535SN/A // Delays in managaging descriptors 885535SN/A Tick fetchDelay, wbDelay; 895535SN/A Tick fetchCompDelay, wbCompDelay; 905535SN/A Tick rxWriteDelay, txReadDelay; 915535SN/A 924263SN/A // Event and function to deal with RDTR timer expiring 934291SN/A void rdtrProcess() { 944291SN/A rxDescCache.writeback(0); 956124SN/A DPRINTF(EthernetIntr, 966124SN/A "Posting RXT interrupt because RDTR timer expired\n"); 975533SN/A postInterrupt(iGbReg::IT_RXT); 984291SN/A } 994291SN/A 1004263SN/A //friend class EventWrapper<IGbE, &IGbE::rdtrProcess>; 1014263SN/A EventWrapper<IGbE, &IGbE::rdtrProcess> 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 1114263SN/A //friend class EventWrapper<IGbE, &IGbE::radvProcess>; 1124263SN/A EventWrapper<IGbE, &IGbE::radvProcess> radvEvent; 1134263SN/A 1144263SN/A // Event and function to deal with TADV timer expiring 1154291SN/A void tadvProcess() { 1164291SN/A txDescCache.writeback(0); 1176124SN/A DPRINTF(EthernetIntr, 1186124SN/A "Posting TXDW interrupt because TADV timer expired\n"); 1195533SN/A postInterrupt(iGbReg::IT_TXDW); 1204291SN/A } 1214291SN/A 1224263SN/A //friend class EventWrapper<IGbE, &IGbE::tadvProcess>; 1234263SN/A EventWrapper<IGbE, &IGbE::tadvProcess> tadvEvent; 1244263SN/A 1254263SN/A // Event and function to deal with TIDV timer expiring 1264291SN/A void tidvProcess() { 1274291SN/A txDescCache.writeback(0); 1286124SN/A DPRINTF(EthernetIntr, 1296124SN/A "Posting TXDW interrupt because TIDV timer expired\n"); 1305533SN/A postInterrupt(iGbReg::IT_TXDW); 1314291SN/A } 1324263SN/A //friend class EventWrapper<IGbE, &IGbE::tidvProcess>; 1334263SN/A EventWrapper<IGbE, &IGbE::tidvProcess> tidvEvent; 1344263SN/A 1354263SN/A // Main event to tick the device 1364263SN/A void tick(); 1374263SN/A //friend class EventWrapper<IGbE, &IGbE::tick>; 1384263SN/A EventWrapper<IGbE, &IGbE::tick> tickEvent; 1394263SN/A 1404263SN/A 1415538SN/A uint64_t macAddr; 1425538SN/A 1434263SN/A void rxStateMachine(); 1444263SN/A void txStateMachine(); 1454263SN/A void txWire(); 1464263SN/A 1474263SN/A /** Write an interrupt into the interrupt pending register and check mask 1484263SN/A * and interrupt limit timer before sending interrupt to CPU 1494263SN/A * @param t the type of interrupt we are posting 1504263SN/A * @param now should we ignore the interrupt limiting timer 1514263SN/A */ 1524263SN/A void postInterrupt(iGbReg::IntTypes t, bool now = false); 1534263SN/A 1544263SN/A /** Check and see if changes to the mask register have caused an interrupt 1554263SN/A * to need to be sent or perhaps removed an interrupt cause. 1564263SN/A */ 1574263SN/A void chkInterrupt(); 1584263SN/A 1594263SN/A /** Send an interrupt to the cpu 1604263SN/A */ 1614987SN/A void delayIntEvent(); 1624263SN/A void cpuPostInt(); 1634263SN/A // Event to moderate interrupts 1644987SN/A EventWrapper<IGbE, &IGbE::delayIntEvent> interEvent; 1654263SN/A 1664263SN/A /** Clear the interupt line to the cpu 1674263SN/A */ 1684263SN/A void cpuClearInt(); 1694263SN/A 1707064SN/A Tick intClock() { return SimClock::Int::ns * 1024; } 1714263SN/A 1724294SN/A /** This function is used to restart the clock so it can handle things like 1734294SN/A * draining and resume in one place. */ 1744283SN/A void restartClock(); 1754283SN/A 1764294SN/A /** Check if all the draining things that need to occur have occured and 1774294SN/A * handle the drain event if so. 1784294SN/A */ 1794294SN/A void checkDrain(); 1804294SN/A 1815954SN/A void anBegin(std::string sm, std::string st, int flags = CPA::FL_NONE) { 18210702SN/A if (cpa) 18310702SN/A cpa->hwBegin((CPA::flags)flags, sys, macAddr, sm, st); 1845954SN/A } 1855954SN/A 18610702SN/A void anQ(std::string sm, std::string q) { 18710702SN/A if (cpa) 18810702SN/A cpa->hwQ(CPA::FL_NONE, sys, macAddr, sm, q, macAddr); 1895954SN/A } 1905954SN/A 1915954SN/A void anDq(std::string sm, std::string q) { 19210702SN/A if (cpa) 19310702SN/A cpa->hwDq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr); 1945954SN/A } 1955954SN/A 1965954SN/A void anPq(std::string sm, std::string q, int num = 1) { 19710702SN/A if (cpa) 19810702SN/A cpa->hwPq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr, NULL, num); 1995954SN/A } 2005954SN/A 2015954SN/A void anRq(std::string sm, std::string q, int num = 1) { 20210702SN/A if (cpa) 20310702SN/A cpa->hwRq(CPA::FL_NONE, sys, macAddr, sm, q, macAddr, NULL, num); 2045954SN/A } 2055954SN/A 2065954SN/A void anWe(std::string sm, std::string q) { 20710702SN/A if (cpa) 20810702SN/A cpa->hwWe(CPA::FL_NONE, sys, macAddr, sm, q, macAddr); 2095954SN/A } 2105954SN/A 2115954SN/A void anWf(std::string sm, std::string q) { 21210702SN/A if (cpa) 21310702SN/A cpa->hwWf(CPA::FL_NONE, sys, macAddr, sm, q, macAddr); 2145954SN/A } 2155954SN/A 2165954SN/A 2174263SN/A template<class T> 21810905SN/A class DescCache : public Serializable 2194263SN/A { 2204263SN/A protected: 2214263SN/A virtual Addr descBase() const = 0; 2224263SN/A virtual long descHead() const = 0; 2234263SN/A virtual long descTail() const = 0; 2244263SN/A virtual long descLen() const = 0; 2254263SN/A virtual void updateHead(long h) = 0; 2264263SN/A virtual void enableSm() = 0; 2275763SN/A virtual void actionAfterWb() {} 2284987SN/A virtual void fetchAfterWb() = 0; 2294263SN/A 2306227SN/A typedef std::deque<T *> CacheType; 2316227SN/A CacheType usedCache; 2326227SN/A CacheType unusedCache; 2334263SN/A 2344263SN/A T *fetchBuf; 2354263SN/A T *wbBuf; 2364263SN/A 2374263SN/A // Pointer to the device we cache for 2384263SN/A IGbE *igbe; 2394263SN/A 2404263SN/A // Name of this descriptor cache 2414263SN/A std::string _name; 2424263SN/A 2434263SN/A // How far we've cached 2444263SN/A int cachePnt; 2454263SN/A 2464263SN/A // The size of the descriptor cache 2474263SN/A int size; 2484263SN/A 2494263SN/A // How many descriptors we are currently fetching 2504263SN/A int curFetching; 2514263SN/A 2524263SN/A // How many descriptors we are currently writing back 2534263SN/A int wbOut; 2544263SN/A 2554263SN/A // if the we wrote back to the end of the descriptor ring and are going 2564263SN/A // to have to wrap and write more 2574263SN/A bool moreToWb; 2584263SN/A 2594263SN/A // What the alignment is of the next descriptor writeback 2604263SN/A Addr wbAlignment; 2614263SN/A 2626124SN/A /** The packet that is currently being dmad to memory if any */ 2634263SN/A EthPacketPtr pktPtr; 2644263SN/A 2656124SN/A /** Shortcut for DMA address translation */ 26611202SN/A Addr pciToDma(Addr a) { return igbe->pciToDma(a); } 2676124SN/A 2684263SN/A public: 2695954SN/A /** Annotate sm*/ 2705954SN/A std::string annSmFetch, annSmWb, annUnusedDescQ, annUsedCacheQ, 2715954SN/A annUsedDescQ, annUnusedCacheQ, annDescQ; 2725954SN/A 2736124SN/A DescCache(IGbE *i, const std::string n, int s); 2746124SN/A virtual ~DescCache(); 2754263SN/A 2764263SN/A std::string name() { return _name; } 2774263SN/A 2784263SN/A /** If the address/len/head change when we've got descriptors that are 2794263SN/A * dirty that is very bad. This function checks that we don't and if we 2804263SN/A * do panics. 2814263SN/A */ 2826124SN/A void areaChanged(); 2834291SN/A 2846124SN/A void writeback(Addr aMask); 2856124SN/A void writeback1(); 2865535SN/A EventWrapper<DescCache, &DescCache::writeback1> wbDelayEvent; 2874263SN/A 2884263SN/A /** Fetch a chunk of descriptors into the descriptor cache. 2894263SN/A * Calls fetchComplete when the memory system returns the data 2904263SN/A */ 2916124SN/A void fetchDescriptors(); 2926124SN/A void fetchDescriptors1(); 2935535SN/A EventWrapper<DescCache, &DescCache::fetchDescriptors1> fetchDelayEvent; 2944263SN/A 2954263SN/A /** Called by event when dma to read descriptors is completed 2964263SN/A */ 2976124SN/A void fetchComplete(); 2984263SN/A EventWrapper<DescCache, &DescCache::fetchComplete> fetchEvent; 2994263SN/A 3004263SN/A /** Called by event when dma to writeback descriptors is completed 3014263SN/A */ 3026124SN/A void wbComplete(); 3034263SN/A EventWrapper<DescCache, &DescCache::wbComplete> wbEvent; 3044263SN/A 3054263SN/A /* Return the number of descriptors left in the ring, so the device has 3064263SN/A * a way to figure out if it needs to interrupt. 3074263SN/A */ 3086227SN/A unsigned 3096227SN/A descLeft() const 3104263SN/A { 3116227SN/A unsigned left = unusedCache.size(); 3126217SN/A if (cachePnt > descTail()) 3135762SN/A left += (descLen() - cachePnt + descTail()); 3144263SN/A else 3154283SN/A left += (descTail() - cachePnt); 3164263SN/A 3174263SN/A return left; 3184263SN/A } 3194263SN/A 3204263SN/A /* Return the number of descriptors used and not written back. 3214263SN/A */ 3226227SN/A unsigned descUsed() const { return usedCache.size(); } 3234263SN/A 3244263SN/A /* Return the number of cache unused descriptors we have. */ 3256227SN/A unsigned descUnused() const { return unusedCache.size(); } 3264263SN/A 3274263SN/A /* Get into a state where the descriptor address/head/etc colud be 3284263SN/A * changed */ 3296124SN/A void reset(); 3304263SN/A 33110905SN/A 33211168SN/A void serialize(CheckpointOut &cp) const override; 33311168SN/A void unserialize(CheckpointIn &cp) override; 3344291SN/A 3354294SN/A virtual bool hasOutstandingEvents() { 3364294SN/A return wbEvent.scheduled() || fetchEvent.scheduled(); 3374294SN/A } 3384294SN/A 3396124SN/A }; 3404263SN/A 3414263SN/A 3424263SN/A class RxDescCache : public DescCache<iGbReg::RxDesc> 3434263SN/A { 3444263SN/A protected: 34511169SN/A Addr descBase() const override { return igbe->regs.rdba(); } 34611169SN/A long descHead() const override { return igbe->regs.rdh(); } 34711169SN/A long descLen() const override { return igbe->regs.rdlen() >> 4; } 34811169SN/A long descTail() const override { return igbe->regs.rdt(); } 34911169SN/A void updateHead(long h) override { igbe->regs.rdh(h); } 35011169SN/A void enableSm() override; 35111169SN/A void fetchAfterWb() override { 35210913SN/A if (!igbe->rxTick && igbe->drainState() == DrainState::Running) 3534987SN/A fetchDescriptors(); 3544987SN/A } 3554263SN/A 3564263SN/A bool pktDone; 3574263SN/A 3585783SN/A /** Variable to head with header/data completion events */ 3595783SN/A int splitCount; 3605783SN/A 3616124SN/A /** Bytes of packet that have been copied, so we know when to 3626124SN/A set EOP */ 3636227SN/A unsigned bytesCopied; 3645783SN/A 3654263SN/A public: 3664263SN/A RxDescCache(IGbE *i, std::string n, int s); 3674263SN/A 3684263SN/A /** Write the given packet into the buffer(s) pointed to by the 3694263SN/A * descriptor and update the book keeping. Should only be called when 3704263SN/A * there are no dma's pending. 3714263SN/A * @param packet ethernet packet to write 3725783SN/A * @param pkt_offset bytes already copied from the packet to memory 3735783SN/A * @return pkt_offset + number of bytes copied during this call 3744263SN/A */ 3755783SN/A int writePacket(EthPacketPtr packet, int pkt_offset); 3765783SN/A 3774263SN/A /** Called by event when dma to write packet is completed 3784263SN/A */ 3794263SN/A void pktComplete(); 3804263SN/A 3815783SN/A /** Check if the dma on the packet has completed and RX state machine 3825783SN/A * can continue 3834263SN/A */ 3844263SN/A bool packetDone(); 3854263SN/A 3864263SN/A EventWrapper<RxDescCache, &RxDescCache::pktComplete> pktEvent; 3874263SN/A 3885783SN/A // Event to handle issuing header and data write at the same time 3895783SN/A // and only callking pktComplete() when both are completed 3905783SN/A void pktSplitDone(); 3915783SN/A EventWrapper<RxDescCache, &RxDescCache::pktSplitDone> pktHdrEvent; 3925783SN/A EventWrapper<RxDescCache, &RxDescCache::pktSplitDone> pktDataEvent; 3935783SN/A 39411169SN/A bool hasOutstandingEvents() override; 3954294SN/A 39611168SN/A void serialize(CheckpointOut &cp) const override; 39711168SN/A void unserialize(CheckpointIn &cp) override; 3984263SN/A }; 3994263SN/A friend class RxDescCache; 4004263SN/A 4014263SN/A RxDescCache rxDescCache; 4024263SN/A 4034263SN/A class TxDescCache : public DescCache<iGbReg::TxDesc> 4044263SN/A { 4054263SN/A protected: 40611169SN/A Addr descBase() const override { return igbe->regs.tdba(); } 40711169SN/A long descHead() const override { return igbe->regs.tdh(); } 40811169SN/A long descTail() const override { return igbe->regs.tdt(); } 40911169SN/A long descLen() const override { return igbe->regs.tdlen() >> 4; } 41011169SN/A void updateHead(long h) override { igbe->regs.tdh(h); } 41111169SN/A void enableSm() override; 41211169SN/A void actionAfterWb() override; 41311169SN/A void fetchAfterWb() override { 41410913SN/A if (!igbe->txTick && igbe->drainState() == DrainState::Running) 4154987SN/A fetchDescriptors(); 4164987SN/A } 41711320Ssteve.reinhardt@amd.com 4185763SN/A 4194263SN/A 4204263SN/A bool pktDone; 4214263SN/A bool isTcp; 4224263SN/A bool pktWaiting; 4235404SN/A bool pktMultiDesc; 4245763SN/A Addr completionAddress; 4255763SN/A bool completionEnabled; 4265763SN/A uint32_t descEnd; 42711320Ssteve.reinhardt@amd.com 4284263SN/A 4295762SN/A // tso variables 4305762SN/A bool useTso; 4315762SN/A Addr tsoHeaderLen; 4325762SN/A Addr tsoMss; 4335762SN/A Addr tsoTotalLen; 4345762SN/A Addr tsoUsedLen; 4358902SN/A Addr tsoPrevSeq; 4365762SN/A Addr tsoPktPayloadBytes; 4375762SN/A bool tsoLoadedHeader; 4385762SN/A bool tsoPktHasHeader; 4395762SN/A uint8_t tsoHeader[256]; 4405762SN/A Addr tsoDescBytesUsed; 4415762SN/A Addr tsoCopyBytes; 4425762SN/A int tsoPkts; 4435762SN/A 4444263SN/A public: 4454263SN/A TxDescCache(IGbE *i, std::string n, int s); 4464263SN/A 4474263SN/A /** Tell the cache to DMA a packet from main memory into its buffer and 4484263SN/A * return the size the of the packet to reserve space in tx fifo. 4494263SN/A * @return size of the packet 4504263SN/A */ 4516227SN/A unsigned getPacketSize(EthPacketPtr p); 4524263SN/A void getPacketData(EthPacketPtr p); 4535762SN/A void processContextDesc(); 4544263SN/A 4555763SN/A /** Return the number of dsecriptors in a cache block for threshold 4565763SN/A * operations. 4575763SN/A */ 4586227SN/A unsigned 4596227SN/A descInBlock(unsigned num_desc) 4606227SN/A { 4616227SN/A return num_desc / igbe->cacheBlockSize() / sizeof(iGbReg::TxDesc); 4626227SN/A } 4636227SN/A 4644263SN/A /** Ask if the packet has been transfered so the state machine can give 4654263SN/A * it to the fifo. 4664263SN/A * @return packet available in descriptor cache 4674263SN/A */ 4684263SN/A bool packetAvailable(); 4694263SN/A 4704263SN/A /** Ask if we are still waiting for the packet to be transfered. 4714263SN/A * @return packet still in transit. 4724263SN/A */ 4734263SN/A bool packetWaiting() { return pktWaiting; } 4744263SN/A 4755404SN/A /** Ask if this packet is composed of multiple descriptors 4765404SN/A * so even if we've got data, we need to wait for more before 4775404SN/A * we can send it out. 4785404SN/A * @return packet can't be sent out because it's a multi-descriptor 4795404SN/A * packet 4805404SN/A */ 4815404SN/A bool packetMultiDesc() { return pktMultiDesc;} 4825404SN/A 4834263SN/A /** Called by event when dma to write packet is completed 4844263SN/A */ 4854263SN/A void pktComplete(); 4864263SN/A EventWrapper<TxDescCache, &TxDescCache::pktComplete> pktEvent; 4874263SN/A 4885762SN/A void headerComplete(); 4895762SN/A EventWrapper<TxDescCache, &TxDescCache::headerComplete> headerEvent; 4905762SN/A 4915763SN/A 4925763SN/A void completionWriteback(Addr a, bool enabled) { 4936124SN/A DPRINTF(EthernetDesc, 49411320Ssteve.reinhardt@amd.com "Completion writeback Addr: %#x enabled: %d\n", 4955763SN/A a, enabled); 4965763SN/A completionAddress = a; 4975763SN/A completionEnabled = enabled; 4985763SN/A } 4995763SN/A 50011169SN/A bool hasOutstandingEvents() override; 5014294SN/A 5026124SN/A void nullCallback() { 5036124SN/A DPRINTF(EthernetDesc, "Completion writeback complete\n"); 5046124SN/A } 5055763SN/A EventWrapper<TxDescCache, &TxDescCache::nullCallback> nullEvent; 5065763SN/A 50711168SN/A void serialize(CheckpointOut &cp) const override; 50811168SN/A void unserialize(CheckpointIn &cp) override; 50910905SN/A }; 5104294SN/A 5114263SN/A friend class TxDescCache; 5124263SN/A 5134263SN/A TxDescCache txDescCache; 5143116SN/A 5153116SN/A public: 5164762SN/A typedef IGbEParams Params; 5174762SN/A const Params * 5186124SN/A params() const { 5194762SN/A return dynamic_cast<const Params *>(_params); 5204762SN/A } 5216124SN/A 5224981SN/A IGbE(const Params *params); 5239086SN/A ~IGbE(); 52411169SN/A void init() override; 5253116SN/A 52611169SN/A EtherInt *getEthPort(const std::string &if_name, int idx) override; 5274981SN/A 5285500SN/A Tick lastInterrupt; 5294263SN/A 53011169SN/A Tick read(PacketPtr pkt) override; 53111169SN/A Tick write(PacketPtr pkt) override; 5323116SN/A 53311169SN/A Tick writeConfig(PacketPtr pkt) override; 5343116SN/A 5353116SN/A bool ethRxPkt(EthPacketPtr packet); 5363116SN/A void ethTxDone(); 5373116SN/A 53811168SN/A void serialize(CheckpointOut &cp) const override; 53911168SN/A void unserialize(CheckpointIn &cp) override; 5409342SN/A 54111168SN/A DrainState drain() override; 54211168SN/A void drainResume() override; 5433116SN/A 5443116SN/A}; 5453116SN/A 5463116SN/Aclass IGbEInt : public EtherInt 5473116SN/A{ 5483116SN/A private: 5493116SN/A IGbE *dev; 5503116SN/A 5513116SN/A public: 5523116SN/A IGbEInt(const std::string &name, IGbE *d) 5533116SN/A : EtherInt(name), dev(d) 5544981SN/A { } 5553116SN/A 5563116SN/A virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); } 5573116SN/A virtual void sendDone() { dev->ethTxDone(); } 5583116SN/A}; 5593116SN/A 56011263Sandreas.sandberg@arm.com#endif //__DEV_NET_I8254XGBE_HH__ 561