ns_gige.hh revision 837
13855Sbinkertn@umich.edu/*
23855Sbinkertn@umich.edu * Copyright (c) 2003 The Regents of The University of Michigan
33855Sbinkertn@umich.edu * All rights reserved.
43855Sbinkertn@umich.edu *
53855Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
63855Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
73855Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
83855Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
93855Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
103855Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
113855Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
123855Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
133855Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
143855Sbinkertn@umich.edu * this software without specific prior written permission.
153855Sbinkertn@umich.edu *
163855Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173855Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183855Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193855Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203855Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213855Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223855Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233855Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243855Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253855Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263855Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273855Sbinkertn@umich.edu */
283855Sbinkertn@umich.edu
293855Sbinkertn@umich.edu/* @file
303855Sbinkertn@umich.edu * Device module for modelling the National Semiconductor
313855Sbinkertn@umich.edu * DP83820 ethernet controller
323855Sbinkertn@umich.edu */
333855Sbinkertn@umich.edu
343855Sbinkertn@umich.edu#ifndef __NS_GIGE_HH__
353855Sbinkertn@umich.edu#define __NS_GIGE_HH__
363855Sbinkertn@umich.edu
373855Sbinkertn@umich.edu#include "dev/dma.hh"
383855Sbinkertn@umich.edu#include "dev/etherint.hh"
393855Sbinkertn@umich.edu#include "dev/etherpkt.hh"
403855Sbinkertn@umich.edu#include "sim/eventq.hh"
413855Sbinkertn@umich.edu#include "dev/ns_gige_reg.h"
423855Sbinkertn@umich.edu#include "base/statistics.hh"
433855Sbinkertn@umich.edu#include "dev/pcidev.hh"
443855Sbinkertn@umich.edu#include "dev/tsunami.hh"
453855Sbinkertn@umich.edu#include "dev/pciconfigall.hh"
463855Sbinkertn@umich.edu
473855Sbinkertn@umich.edu/** defined by the NS83820 data sheet */
483855Sbinkertn@umich.edu#define MAX_TX_FIFO_SIZE 8192
493855Sbinkertn@umich.edu#define MAX_RX_FIFO_SIZE 32768
503855Sbinkertn@umich.edu
513855Sbinkertn@umich.edu/** length of ethernet address in bytes */
523855Sbinkertn@umich.edu#define EADDR_LEN 6
533855Sbinkertn@umich.edu
543855Sbinkertn@umich.edu/** Transmit State Machine states */
553855Sbinkertn@umich.eduenum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead,
563855Sbinkertn@umich.edu               txDescWrite };
573855Sbinkertn@umich.edu
583855Sbinkertn@umich.edu/** Receive State Machine States */
593855Sbinkertn@umich.eduenum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite,
603855Sbinkertn@umich.edu                rxDescWrite, rxAdvance };
613855Sbinkertn@umich.edu
623855Sbinkertn@umich.edu/**
633855Sbinkertn@umich.edu * Ethernet device registers
643855Sbinkertn@umich.edu */
653855Sbinkertn@umich.edustruct dp_regs {
663855Sbinkertn@umich.edu    uint32_t	command;
673855Sbinkertn@umich.edu    uint32_t	config;
683855Sbinkertn@umich.edu    uint32_t	mear;
693855Sbinkertn@umich.edu    uint32_t	ptscr;
703855Sbinkertn@umich.edu    uint32_t    isr;
713855Sbinkertn@umich.edu    uint32_t    imr;
723855Sbinkertn@umich.edu    uint32_t    ier;
733855Sbinkertn@umich.edu    uint32_t    ihr;
743855Sbinkertn@umich.edu    uint32_t    txdp;
753855Sbinkertn@umich.edu    uint32_t    txdp_hi;
763855Sbinkertn@umich.edu    uint32_t    txcfg;
773855Sbinkertn@umich.edu    uint32_t    gpior;
783855Sbinkertn@umich.edu    uint32_t    rxdp;
793855Sbinkertn@umich.edu    uint32_t    rxdp_hi;
803855Sbinkertn@umich.edu    uint32_t    rxcfg;
813855Sbinkertn@umich.edu    uint32_t    pqcr;
823855Sbinkertn@umich.edu    uint32_t    wcsr;
833855Sbinkertn@umich.edu    uint32_t    pcr;
843855Sbinkertn@umich.edu    uint32_t    rfcr;
853855Sbinkertn@umich.edu    uint32_t    rfdr;
863855Sbinkertn@umich.edu    uint32_t    srr;
873855Sbinkertn@umich.edu    uint32_t    mibc;
883855Sbinkertn@umich.edu    uint32_t    vrcr;
893855Sbinkertn@umich.edu    uint32_t    vtcr;
903855Sbinkertn@umich.edu    uint32_t    vdr;
913855Sbinkertn@umich.edu    uint32_t    ccsr;
923855Sbinkertn@umich.edu    uint32_t    tbicr;
933855Sbinkertn@umich.edu    uint32_t    tbisr;
943855Sbinkertn@umich.edu    uint32_t    tanar;
953855Sbinkertn@umich.edu    uint32_t    tanlpar;
963855Sbinkertn@umich.edu    uint32_t    taner;
973855Sbinkertn@umich.edu    uint32_t    tesr;
983855Sbinkertn@umich.edu
993855Sbinkertn@umich.edu    /** for perfect match memory.  the linux driver doesn't use any other ROM */
1003855Sbinkertn@umich.edu    uint8_t perfectMatch[EADDR_LEN];
1013855Sbinkertn@umich.edu
1023855Sbinkertn@umich.edu    virtual void serialize(std::ostream &os);
1033855Sbinkertn@umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
1043855Sbinkertn@umich.edu};
1053855Sbinkertn@umich.edu
1063855Sbinkertn@umich.edu/** an enum indicating direction, transmit or receive, used as a param for
1073855Sbinkertn@umich.edu    some fns */
1083855Sbinkertn@umich.eduenum dir_t { tx, rx };
1093855Sbinkertn@umich.edu
1103855Sbinkertn@umich.educlass DmaEngine;
1113855Sbinkertn@umich.educlass IntrControl;
1123855Sbinkertn@umich.educlass EtherDevInt;
1133855Sbinkertn@umich.educlass PhysicalMemory;
1143855Sbinkertn@umich.edu
1153855Sbinkertn@umich.edu/**
1163855Sbinkertn@umich.edu * NS DP82830 Ethernet device model
1173855Sbinkertn@umich.edu */
1183855Sbinkertn@umich.educlass EtherDev : public PciDev, public DmaHolder
1193855Sbinkertn@umich.edu{
1203855Sbinkertn@umich.edu  private:
1213855Sbinkertn@umich.edu    /** pointer to the chipset */
1223855Sbinkertn@umich.edu    Tsunami *tsunami;
1233855Sbinkertn@umich.edu
1243855Sbinkertn@umich.edu  protected:
1253855Sbinkertn@umich.edu    Addr addr;
1263855Sbinkertn@umich.edu    Addr mask;
1273855Sbinkertn@umich.edu
1283855Sbinkertn@umich.edu    /** device register file */
1293855Sbinkertn@umich.edu    dp_regs regs;
1303855Sbinkertn@umich.edu
1313855Sbinkertn@umich.edu     /*** BASIC STRUCTURES FOR TX/RX ***/
1323855Sbinkertn@umich.edu    /* Data FIFOs */
1333855Sbinkertn@umich.edu    typedef std::deque<PacketPtr> pktbuf_t;
1343855Sbinkertn@umich.edu    typedef pktbuf_t::iterator pktiter_t;
1353855Sbinkertn@umich.edu    pktbuf_t txFifo;
1363855Sbinkertn@umich.edu    pktbuf_t rxFifo;
1373855Sbinkertn@umich.edu
1383855Sbinkertn@umich.edu    /** for the tx side, to track addrs to write updated cmdsts to */
1393855Sbinkertn@umich.edu    typedef std::deque<uint32_t> txdpbuf_t; /* ASSUME32 */
1403855Sbinkertn@umich.edu    txdpbuf_t descAddrFifo;
1413855Sbinkertn@umich.edu
1423855Sbinkertn@umich.edu    /** various helper vars */
1433855Sbinkertn@umich.edu    uint32_t txPacketLen;
1443855Sbinkertn@umich.edu    uint8_t *txPacketBufPtr;
1453855Sbinkertn@umich.edu    uint8_t *rxPacketBufPtr;
1463855Sbinkertn@umich.edu    uint8_t *rxDescBufPtr;
1473855Sbinkertn@umich.edu    uint32_t fragLen;
1483855Sbinkertn@umich.edu    uint32_t rxCopied;
1493855Sbinkertn@umich.edu
15011320Ssteve.reinhardt@amd.com    /** DescCaches */
1513855Sbinkertn@umich.edu    ns_desc txDescCache;
1523855Sbinkertn@umich.edu    ns_desc rxDescCache;
1533855Sbinkertn@umich.edu
1543855Sbinkertn@umich.edu    /* tx State Machine */
1553855Sbinkertn@umich.edu    tx_state txState;
1563855Sbinkertn@umich.edu    /** Current Transmit Descriptor Done */
1573855Sbinkertn@umich.edu    bool CTDD;
1583855Sbinkertn@umich.edu    uint32_t txFifoCnt; /* amt of data in the txDataFifo in bytes (logical) */
1593855Sbinkertn@umich.edu    uint32_t txFifoAvail; /* current amt of free space in txDataFifo in byes */
1603855Sbinkertn@umich.edu    bool txHalt;
1613855Sbinkertn@umich.edu    bool txPacketFlag;  /* when set, indicates not working on a new packet */
1623855Sbinkertn@umich.edu    Addr txFragPtr; /* ptr to the next byte in the current fragment */
1633855Sbinkertn@umich.edu    uint32_t txDescCnt; /* count of bytes remaining in the current descriptor */
1643855Sbinkertn@umich.edu
1653855Sbinkertn@umich.edu    /** rx State Machine */
1663855Sbinkertn@umich.edu    rx_state rxState;
1673855Sbinkertn@umich.edu    bool CRDD; /* Current Receive Descriptor Done */
1683855Sbinkertn@umich.edu    uint32_t rxPktBytes; /* num of bytes in the current packet being drained
1693855Sbinkertn@umich.edu                            from rxDataFifo */
1703855Sbinkertn@umich.edu    uint32_t rxFifoCnt; /* number of bytes in the rxFifo */
1713855Sbinkertn@umich.edu    bool rxHalt;
1723855Sbinkertn@umich.edu    bool rxPacketFlag;  /* when set, indicates not working on a new packet */
1733855Sbinkertn@umich.edu    Addr rxFragPtr; /* ptr to the next byte in current fragment */
1743855Sbinkertn@umich.edu    uint32_t rxDescCnt; /* count of bytes remaining in the current descriptor */
1753855Sbinkertn@umich.edu
1763855Sbinkertn@umich.edu    bool extstsEnable;
1773855Sbinkertn@umich.edu    uint32_t maxTxBurst;
1783855Sbinkertn@umich.edu    uint32_t maxRxBurst;
1793855Sbinkertn@umich.edu
1803855Sbinkertn@umich.edu    PhysicalMemory *physmem;
1813855Sbinkertn@umich.edu
1823855Sbinkertn@umich.edu  protected:
1833855Sbinkertn@umich.edu    /**
1843855Sbinkertn@umich.edu     * Receive dma for descriptors done callback
1853855Sbinkertn@umich.edu     */
1863855Sbinkertn@umich.edu    class RxDescDone : public DmaCallback
1873855Sbinkertn@umich.edu    {
1883855Sbinkertn@umich.edu      public:
1893855Sbinkertn@umich.edu        EtherDev *ethernet;
1903855Sbinkertn@umich.edu
1913855Sbinkertn@umich.edu      public:
1923855Sbinkertn@umich.edu        RxDescDone(EtherDev *e);
1933855Sbinkertn@umich.edu        std::string name() const;
1943855Sbinkertn@umich.edu        virtual void process();
1953855Sbinkertn@umich.edu    };
1963855Sbinkertn@umich.edu
1973855Sbinkertn@umich.edu    /**
1983855Sbinkertn@umich.edu     * Receive dma done callback
1993855Sbinkertn@umich.edu     */
2003855Sbinkertn@umich.edu    class RxDone : public DmaCallback
2013855Sbinkertn@umich.edu    {
2023855Sbinkertn@umich.edu      public:
2033855Sbinkertn@umich.edu        EtherDev *ethernet;
2043855Sbinkertn@umich.edu
2053855Sbinkertn@umich.edu      public:
2063855Sbinkertn@umich.edu        RxDone(EtherDev *e);
2073855Sbinkertn@umich.edu        std::string name() const;
2083855Sbinkertn@umich.edu        virtual void process();
2093855Sbinkertn@umich.edu    };
2103855Sbinkertn@umich.edu
2113855Sbinkertn@umich.edu    /**
2123855Sbinkertn@umich.edu     * Transmit dma for descriptors done callback
2133855Sbinkertn@umich.edu     */
2143855Sbinkertn@umich.edu    class TxDescDone : public DmaCallback
2153855Sbinkertn@umich.edu    {
2163855Sbinkertn@umich.edu      public:
2173855Sbinkertn@umich.edu        EtherDev *ethernet;
2183855Sbinkertn@umich.edu
2193855Sbinkertn@umich.edu      public:
2203855Sbinkertn@umich.edu        TxDescDone(EtherDev *e);
2213855Sbinkertn@umich.edu        std::string name() const;
2223855Sbinkertn@umich.edu        virtual void process();
2233855Sbinkertn@umich.edu    };
2243855Sbinkertn@umich.edu
2253855Sbinkertn@umich.edu    /*
2263855Sbinkertn@umich.edu     * Transmit dma done callback
2273855Sbinkertn@umich.edu     */
2283855Sbinkertn@umich.edu    class TxDone : public DmaCallback
2293855Sbinkertn@umich.edu    {
2303855Sbinkertn@umich.edu      public:
2313855Sbinkertn@umich.edu        EtherDev *ethernet;
2323855Sbinkertn@umich.edu        PacketPtr packet;
2333855Sbinkertn@umich.edu
2343855Sbinkertn@umich.edu      public:
2353855Sbinkertn@umich.edu        TxDone(EtherDev *e);
2363855Sbinkertn@umich.edu        std::string name() const;
2373855Sbinkertn@umich.edu        virtual void process();
2383855Sbinkertn@umich.edu    };
2393855Sbinkertn@umich.edu
2403855Sbinkertn@umich.edu    friend class TxDescDone;
2413855Sbinkertn@umich.edu    friend class TxDone;
2423855Sbinkertn@umich.edu    friend class RxDescDone;
2433855Sbinkertn@umich.edu    friend class RxDone;
2443855Sbinkertn@umich.edu
2453855Sbinkertn@umich.edu    RxDescDone rxDescDoneCB;
2463855Sbinkertn@umich.edu    RxDone rxDoneCB;
2473855Sbinkertn@umich.edu    TxDescDone txDescDoneCB;
2483855Sbinkertn@umich.edu    TxDone txDoneCB;
2493855Sbinkertn@umich.edu
2503855Sbinkertn@umich.edu    DmaEngine *dma;
2513855Sbinkertn@umich.edu    DmaRequest readRequest;
2523855Sbinkertn@umich.edu    DmaRequest writeRequest;
2533855Sbinkertn@umich.edu    DmaRequest readDescRequest;
2543855Sbinkertn@umich.edu    DmaRequest writeDescRequest;
2553855Sbinkertn@umich.edu    PacketPtr rxPacket;
2563855Sbinkertn@umich.edu    DmaPhys readPhys;
2573855Sbinkertn@umich.edu    DmaPhys writePhys;
2583855Sbinkertn@umich.edu    DmaPhys readDescPhys;
2593855Sbinkertn@umich.edu    DmaPhys writeDescPhys;
2603855Sbinkertn@umich.edu
2613855Sbinkertn@umich.edu    EtherDevInt *interface;
2623855Sbinkertn@umich.edu
2633855Sbinkertn@umich.edu  protected:
2643855Sbinkertn@umich.edu    IntrControl *intctrl;
2653855Sbinkertn@umich.edu    Tick txDelay;
2663855Sbinkertn@umich.edu    Tick rxDelay;
2673855Sbinkertn@umich.edu
2683855Sbinkertn@umich.edu    void txReset();
2693855Sbinkertn@umich.edu    void rxReset();
2703855Sbinkertn@umich.edu    void regsReset() {
2713855Sbinkertn@umich.edu        memset(&regs, 0, sizeof(regs));
2723855Sbinkertn@umich.edu        regs.mear = 0x12;
2733855Sbinkertn@umich.edu        regs.isr = 0x00608000;
2743855Sbinkertn@umich.edu        regs.txcfg = 0x120;
2753855Sbinkertn@umich.edu        regs.rxcfg = 0x4;
2763855Sbinkertn@umich.edu        regs.srr = 0x0103;
2773855Sbinkertn@umich.edu        regs.mibc = 0x2;
2783855Sbinkertn@umich.edu        regs.vdr = 0x81;
2793855Sbinkertn@umich.edu        regs.tesr = 0xc000;
2803855Sbinkertn@umich.edu    }
2813855Sbinkertn@umich.edu
2823855Sbinkertn@umich.edu    void txKick();
2833855Sbinkertn@umich.edu    void rxKick();
2843855Sbinkertn@umich.edu
2853855Sbinkertn@umich.edu    /*
2863855Sbinkertn@umich.edu     * Retransmit event
2873855Sbinkertn@umich.edu     */
2883855Sbinkertn@umich.edu    class TxEvent : public Event
2893855Sbinkertn@umich.edu    {
2903855Sbinkertn@umich.edu      protected:
2913855Sbinkertn@umich.edu        EtherDev *dev;
2923855Sbinkertn@umich.edu
2933855Sbinkertn@umich.edu      public:
2943855Sbinkertn@umich.edu        TxEvent(EtherDev *_dev)
2953855Sbinkertn@umich.edu            : Event(&mainEventQueue), dev(_dev) {}
2963855Sbinkertn@umich.edu        void process() { dev->transmit(); }
2973855Sbinkertn@umich.edu        virtual const char *description() { return "retransmit"; }
2983855Sbinkertn@umich.edu    };
2993855Sbinkertn@umich.edu    friend class TxEvent;
3003855Sbinkertn@umich.edu    TxEvent txEvent;
3013855Sbinkertn@umich.edu    void transmit();
3023855Sbinkertn@umich.edu
3033855Sbinkertn@umich.edu
3043855Sbinkertn@umich.edu    void txDescDone();
3053855Sbinkertn@umich.edu    void rxDescDone();
3063855Sbinkertn@umich.edu    void txDone(PacketPtr packet);
3073855Sbinkertn@umich.edu    void rxDone();
3083855Sbinkertn@umich.edu
3093855Sbinkertn@umich.edu    void txDump() const;
3103855Sbinkertn@umich.edu    void rxDump() const;
3113855Sbinkertn@umich.edu
3123855Sbinkertn@umich.edu    void devIntrPost(uint32_t interrupts);
3133855Sbinkertn@umich.edu    void devIntrClear(uint32_t interrupts);
3143855Sbinkertn@umich.edu    void devIntrChangeMask();
3153855Sbinkertn@umich.edu
3163855Sbinkertn@umich.edu    bool cpuPendingIntr;
3173855Sbinkertn@umich.edu    void cpuIntrPost();
3183855Sbinkertn@umich.edu    void cpuIntrClear();
3193855Sbinkertn@umich.edu
3203855Sbinkertn@umich.edu    bool rxFilterEnable;
3213855Sbinkertn@umich.edu    bool rxFilter(PacketPtr packet);
3223855Sbinkertn@umich.edu    bool acceptBroadcast;
3233855Sbinkertn@umich.edu    bool acceptMulticast;
324    bool acceptUnicast;
325    bool acceptPerfect;
326    bool acceptArp;
327
328    bool udpChecksum(PacketPtr packet, bool gen);
329    bool tcpChecksum(PacketPtr packet, bool gen);
330    bool ipChecksum(PacketPtr packet, bool gen);
331    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
332
333  public:
334    EtherDev(const std::string &name, DmaEngine *de, bool use_interface,
335             IntrControl *i, MemoryController *mmu, PhysicalMemory *pmem,
336             PCIConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus,
337             uint32_t dev, uint32_t func, bool rx_filter, const int eaddr[6],
338             Tick tx_delay, Tick rx_delay, Addr addr, Addr mask);
339    ~EtherDev();
340
341    virtual void WriteConfig(int offset, int size, uint32_t data);
342    virtual void ReadConfig(int offset, int size, uint8_t *data);
343
344
345
346    Fault read(MemReqPtr req, uint8_t *data);
347    Fault write(MemReqPtr req, const uint8_t *data);
348
349    bool cpuIntrPending() const;
350    void cpuIntrAck() { cpuIntrClear(); }
351
352    bool recvPacket(PacketPtr packet);
353    void transferDone();
354
355    void setInterface(EtherDevInt *i) { assert(!interface); interface = i; }
356
357    virtual void serialize(std::ostream &os);
358    virtual void unserialize(Checkpoint *cp, const std::string &section);
359
360    virtual DmaRequest *find_dmareq(uint32_t &id) {
361        if (id == 0)
362            return(&readRequest);
363        else if (id == 1)
364            return(&writeRequest);
365        else
366            return(NULL);
367    }
368
369  public:
370    void regStats();
371
372  private:
373    Statistics::Scalar<> txBytes;
374    Statistics::Scalar<> rxBytes;
375    Statistics::Scalar<> txPackets;
376    Statistics::Scalar<> rxPackets;
377    Statistics::Formula txBandwidth;
378    Statistics::Formula rxBandwidth;
379    Statistics::Formula txPacketRate;
380    Statistics::Formula rxPacketRate;
381
382    void readOneDesc(dir_t dir, uint32_t len = sizeof(ns_desc));
383    void readOneFrag();
384    void writeOneFrag();
385};
386
387/*
388 * Ethernet Interface for an Ethernet Device
389 */
390class EtherDevInt : public EtherInt
391{
392  private:
393    EtherDev *dev;
394
395  public:
396    EtherDevInt(const std::string &name, EtherDev *d)
397        : EtherInt(name), dev(d) { dev->setInterface(this); }
398
399    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
400    virtual void sendDone() { dev->transferDone(); }
401};
402
403#endif // __NS_GIGE_HH__
404