ns_gige.hh revision 1154
11689SN/A/*
22329SN/A * Copyright (c) 2004 The Regents of The University of Michigan
31689SN/A * All rights reserved.
41689SN/A *
51689SN/A * Redistribution and use in source and binary forms, with or without
61689SN/A * modification, are permitted provided that the following conditions are
71689SN/A * met: redistributions of source code must retain the above copyright
81689SN/A * notice, this list of conditions and the following disclaimer;
91689SN/A * redistributions in binary form must reproduce the above copyright
101689SN/A * notice, this list of conditions and the following disclaimer in the
111689SN/A * documentation and/or other materials provided with the distribution;
121689SN/A * neither the name of the copyright holders nor the names of its
131689SN/A * contributors may be used to endorse or promote products derived from
141689SN/A * this software without specific prior written permission.
151689SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292935Sksewell@umich.edu/* @file
301689SN/A * Device module for modelling the National Semiconductor
311689SN/A * DP83820 ethernet controller
321060SN/A */
331060SN/A
343773Sgblack@eecs.umich.edu#ifndef __DEV_NS_GIGE_HH__
353773Sgblack@eecs.umich.edu#define __DEV_NS_GIGE_HH__
361858SN/A
371717SN/A#include "base/inet.hh"
381060SN/A#include "base/statistics.hh"
391061SN/A#include "dev/etherint.hh"
404329Sktlim@umich.edu#include "dev/etherpkt.hh"
414329Sktlim@umich.edu#include "dev/io_device.hh"
424329Sktlim@umich.edu#include "dev/ns_gige_reg.h"
432292SN/A#include "dev/pcidev.hh"
442292SN/A#include "dev/pktfifo.hh"
452292SN/A#include "mem/bus/bus.hh"
462292SN/A#include "sim/eventq.hh"
473788Sgblack@eecs.umich.edu
483798Sgblack@eecs.umich.edu/**
492361SN/A * Ethernet device registers
502361SN/A */
511060SN/Astruct dp_regs {
522292SN/A    uint32_t	command;
532292SN/A    uint32_t	config;
542292SN/A    uint32_t	mear;
552292SN/A    uint32_t	ptscr;
562292SN/A    uint32_t    isr;
572292SN/A    uint32_t    imr;
582292SN/A    uint32_t    ier;
592292SN/A    uint32_t    ihr;
602292SN/A    uint32_t    txdp;
612292SN/A    uint32_t    txdp_hi;
622292SN/A    uint32_t    txcfg;
632301SN/A    uint32_t    gpior;
642292SN/A    uint32_t    rxdp;
652292SN/A    uint32_t    rxdp_hi;
662292SN/A    uint32_t    rxcfg;
672292SN/A    uint32_t    pqcr;
682292SN/A    uint32_t    wcsr;
692292SN/A    uint32_t    pcr;
702292SN/A    uint32_t    rfcr;
712292SN/A    uint32_t    rfdr;
722292SN/A    uint32_t    srr;
732292SN/A    uint32_t    mibc;
742292SN/A    uint32_t    vrcr;
752292SN/A    uint32_t    vtcr;
762292SN/A    uint32_t    vdr;
772292SN/A    uint32_t    ccsr;
782292SN/A    uint32_t    tbicr;
792292SN/A    uint32_t    tbisr;
802292SN/A    uint32_t    tanar;
811060SN/A    uint32_t    tanlpar;
821060SN/A    uint32_t    taner;
831061SN/A    uint32_t    tesr;
841060SN/A};
852292SN/A
861062SN/Astruct dp_rom {
871062SN/A    /**
882301SN/A     * for perfect match memory.
891062SN/A     * the linux driver doesn't use any other ROM
901062SN/A     */
911062SN/A    uint8_t perfectMatch[ETH_ADDR_LEN];
922301SN/A};
931062SN/A
941062SN/Aclass IntrControl;
951062SN/Aclass NSGigEInt;
962301SN/Aclass PhysicalMemory;
971062SN/Aclass BaseInterface;
981062SN/Aclass HierParams;
992301SN/Aclass Bus;
1002301SN/Aclass PciConfigAll;
1012301SN/A
1022301SN/A/**
1032292SN/A * NS DP82830 Ethernet device model
1042301SN/A */
1052292SN/Aclass NSGigE : public PciDev
1062292SN/A{
1071062SN/A  public:
1082301SN/A    /** Transmit State Machine states */
1091062SN/A    enum TxState
1101062SN/A    {
1111062SN/A        txIdle,
1122301SN/A        txDescRefr,
1131062SN/A        txDescRead,
1141062SN/A        txFifoBlock,
1151062SN/A        txFragRead,
1162301SN/A        txDescWrite,
1171062SN/A        txAdvance
1181062SN/A    };
1191062SN/A
1202301SN/A    /** Receive State Machine States */
1212292SN/A    enum RxState
1221062SN/A    {
1231062SN/A        rxIdle,
1242301SN/A        rxDescRefr,
1252292SN/A        rxDescRead,
1261062SN/A        rxFifoBlock,
1272292SN/A        rxFragWrite,
1282301SN/A        rxDescWrite,
1292292SN/A        rxAdvance
1302292SN/A    };
1311062SN/A
1322301SN/A    enum DmaState
1331062SN/A    {
1341062SN/A        dmaIdle,
1351062SN/A        dmaReading,
1362301SN/A        dmaWriting,
1371062SN/A        dmaReadWaiting,
1381062SN/A        dmaWriteWaiting
1391062SN/A    };
1402301SN/A
1411062SN/A  private:
1421062SN/A    Addr addr;
1431062SN/A    static const Addr size = sizeof(dp_regs);
1442301SN/A
1451062SN/A  protected:
1461062SN/A    typedef std::deque<PacketPtr> pktbuf_t;
1471062SN/A    typedef pktbuf_t::iterator pktiter_t;
1482301SN/A
1491062SN/A    /** device register file */
1501062SN/A    dp_regs regs;
1512301SN/A    dp_rom rom;
1522301SN/A
1532301SN/A    /** pci settings */
1542301SN/A    bool ioEnable;
1552301SN/A#if 0
1562301SN/A    bool memEnable;
1572301SN/A    bool bmEnable;
1582301SN/A#endif
1592301SN/A
1602301SN/A    /*** BASIC STRUCTURES FOR TX/RX ***/
1612307SN/A    /* Data FIFOs */
1622307SN/A    PacketFifo txFifo;
1632307SN/A    PacketFifo rxFifo;
1642307SN/A
1652307SN/A    /** various helper vars */
1661062SN/A    PacketPtr txPacket;
1671062SN/A    PacketPtr rxPacket;
1681062SN/A    uint8_t *txPacketBufPtr;
1691062SN/A    uint8_t *rxPacketBufPtr;
1702292SN/A    uint32_t txXferLen;
1711060SN/A    uint32_t rxXferLen;
1721060SN/A    bool rxDmaFree;
1731060SN/A    bool txDmaFree;
1741060SN/A
1751060SN/A    /** DescCaches */
1761060SN/A    ns_desc txDescCache;
1771060SN/A    ns_desc rxDescCache;
1781060SN/A
1791060SN/A    /* tx State Machine */
1801060SN/A    TxState txState;
1811060SN/A    bool txEnable;
1821060SN/A
1831060SN/A    /** Current Transmit Descriptor Done */
1841061SN/A    bool CTDD;
1851060SN/A    /** halt the tx state machine after next packet */
1862292SN/A    bool txHalt;
1871060SN/A    /** ptr to the next byte in the current fragment */
1881060SN/A    Addr txFragPtr;
1891060SN/A    /** count of bytes remaining in the current descriptor */
1901060SN/A    uint32_t txDescCnt;
1911060SN/A    DmaState txDmaState;
1921060SN/A
1931060SN/A    /** rx State Machine */
1941061SN/A    RxState rxState;
1951060SN/A    bool rxEnable;
1962292SN/A
1971060SN/A    /** Current Receive Descriptor Done */
1981060SN/A    bool CRDD;
1991060SN/A    /** num of bytes in the current packet being drained from rxDataFifo */
2001060SN/A    uint32_t rxPktBytes;
2011060SN/A    /** halt the rx state machine after current packet */
2021060SN/A    bool rxHalt;
2031060SN/A    /** ptr to the next byte in current fragment */
2041061SN/A    Addr rxFragPtr;
2051060SN/A    /** count of bytes remaining in the current descriptor */
2062292SN/A    uint32_t rxDescCnt;
2071060SN/A    DmaState rxDmaState;
2082329SN/A
2092292SN/A    bool extstsEnable;
2102292SN/A
2112292SN/A  protected:
2122292SN/A    Tick dmaReadDelay;
2132292SN/A    Tick dmaWriteDelay;
2142292SN/A
2151060SN/A    Tick dmaReadFactor;
2161060SN/A    Tick dmaWriteFactor;
2172292SN/A
2182292SN/A    void *rxDmaData;
2192980Sgblack@eecs.umich.edu    Addr  rxDmaAddr;
2202292SN/A    int   rxDmaLen;
2212292SN/A    bool  doRxDmaRead();
2222292SN/A    bool  doRxDmaWrite();
2232292SN/A    void  rxDmaReadCopy();
2242292SN/A    void  rxDmaWriteCopy();
2251061SN/A
2261060SN/A    void *txDmaData;
2272292SN/A    Addr  txDmaAddr;
2281060SN/A    int   txDmaLen;
2292292SN/A    bool  doTxDmaRead();
2302292SN/A    bool  doTxDmaWrite();
2311060SN/A    void  txDmaReadCopy();
2321060SN/A    void  txDmaWriteCopy();
2331060SN/A
2341061SN/A    void rxDmaReadDone();
2351060SN/A    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
2362292SN/A    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
2371060SN/A
2382292SN/A    void rxDmaWriteDone();
2392292SN/A    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
2401060SN/A    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
2412292SN/A
2422292SN/A    void txDmaReadDone();
2432292SN/A    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
2442292SN/A    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
2452292SN/A
2461060SN/A    void txDmaWriteDone();
2471060SN/A    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
2481061SN/A    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
2492863Sktlim@umich.edu
2502843Sktlim@umich.edu    bool dmaDescFree;
2511060SN/A    bool dmaDataFree;
2522348SN/A
2532843Sktlim@umich.edu
2542863Sktlim@umich.edu  protected:
2552316SN/A    Tick txDelay;
2561060SN/A    Tick rxDelay;
2572316SN/A
2582316SN/A    void txReset();
2592843Sktlim@umich.edu    void rxReset();
2602316SN/A    void regsReset();
2612348SN/A
2622307SN/A    void rxKick();
2632980Sgblack@eecs.umich.edu    Tick rxKickTick;
2642980Sgblack@eecs.umich.edu    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
2652307SN/A    friend class RxKickEvent;
2662307SN/A
2672307SN/A    void txKick();
2682307SN/A    Tick txKickTick;
2692307SN/A    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
2702307SN/A    friend class TxKickEvent;
2712307SN/A
2722307SN/A    /**
2732307SN/A     * Retransmit event
2742307SN/A     */
2752307SN/A    void transmit();
2762307SN/A    void txEventTransmit()
2772307SN/A    {
2782307SN/A        transmit();
2792361SN/A        if (txState == txFifoBlock)
2802361SN/A            txKick();
2812361SN/A    }
2822361SN/A    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
2832361SN/A    friend class TxEvent;
2842307SN/A    TxEvent txEvent;
2852307SN/A
2862307SN/A    void txDump() const;
2872307SN/A    void rxDump() const;
2881060SN/A
2891060SN/A    /**
2901060SN/A     * receive address filter
2911061SN/A     */
2921060SN/A    bool rxFilterEnable;
2932307SN/A    bool rxFilter(const PacketPtr &packet);
2941060SN/A    bool acceptBroadcast;
2952307SN/A    bool acceptMulticast;
2962307SN/A    bool acceptUnicast;
2971060SN/A    bool acceptPerfect;
2982329SN/A    bool acceptArp;
2992307SN/A
3002307SN/A    PhysicalMemory *physmem;
3011060SN/A
3022307SN/A    /**
3032307SN/A     * Interrupt management
3042307SN/A     */
3052307SN/A    IntrControl *intctrl;
3062307SN/A    void devIntrPost(uint32_t interrupts);
3072307SN/A    void devIntrClear(uint32_t interrupts);
3082307SN/A    void devIntrChangeMask();
3092307SN/A
3102307SN/A    Tick intrDelay;
3112307SN/A    Tick intrTick;
3122307SN/A    bool cpuPendingIntr;
3132307SN/A    void cpuIntrPost(Tick when);
3142307SN/A    void cpuInterrupt();
3152307SN/A    void cpuIntrClear();
3162935Sksewell@umich.edu
3171858SN/A    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
3182292SN/A    friend class IntrEvent;
3191858SN/A    IntrEvent *intrEvent;
3202292SN/A    NSGigEInt *interface;
3212292SN/A
3222292SN/A  public:
3232292SN/A    struct Params : public PciDev::Params
3243788Sgblack@eecs.umich.edu    {
3252292SN/A        PhysicalMemory *pmem;
3262698Sktlim@umich.edu        HierParams *hier;
3273788Sgblack@eecs.umich.edu        Bus *header_bus;
3282301SN/A        Bus *payload_bus;
3293788Sgblack@eecs.umich.edu        Tick intr_delay;
3303788Sgblack@eecs.umich.edu        Tick tx_delay;
3313788Sgblack@eecs.umich.edu        Tick rx_delay;
3323788Sgblack@eecs.umich.edu        Tick pio_latency;
3333788Sgblack@eecs.umich.edu        bool dma_desc_free;
3343788Sgblack@eecs.umich.edu        bool dma_data_free;
3353788Sgblack@eecs.umich.edu        Tick dma_read_delay;
3363788Sgblack@eecs.umich.edu        Tick dma_write_delay;
3373788Sgblack@eecs.umich.edu        Tick dma_read_factor;
3383788Sgblack@eecs.umich.edu        Tick dma_write_factor;
3393788Sgblack@eecs.umich.edu        bool rx_filter;
3402292SN/A        Net::EthAddr eaddr;
3412292SN/A        uint32_t tx_fifo_size;
3422292SN/A        uint32_t rx_fifo_size;
3432292SN/A    };
3442292SN/A
3452329SN/A    NSGigE(Params *params);
3462292SN/A    ~NSGigE();
3472292SN/A    const Params *params() const { return (const Params *)_params; }
3482292SN/A
3492935Sksewell@umich.edu    virtual void WriteConfig(int offset, int size, uint32_t data);
3502935Sksewell@umich.edu    virtual void ReadConfig(int offset, int size, uint8_t *data);
3512731Sktlim@umich.edu
3522292SN/A    virtual Fault read(MemReqPtr &req, uint8_t *data);
3532292SN/A    virtual Fault write(MemReqPtr &req, const uint8_t *data);
3542292SN/A
3552935Sksewell@umich.edu    bool cpuIntrPending() const;
3562292SN/A    void cpuIntrAck() { cpuIntrClear(); }
3572292SN/A
3582935Sksewell@umich.edu    bool recvPacket(PacketPtr packet);
3592935Sksewell@umich.edu    void transferDone();
3602935Sksewell@umich.edu
3612935Sksewell@umich.edu    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
3622935Sksewell@umich.edu
3633093Sksewell@umich.edu    virtual void serialize(std::ostream &os);
3642935Sksewell@umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
3652935Sksewell@umich.edu
3662935Sksewell@umich.edu  public:
3672935Sksewell@umich.edu    void regStats();
3682935Sksewell@umich.edu
3692935Sksewell@umich.edu  private:
3702935Sksewell@umich.edu    Stats::Scalar<> txBytes;
3712935Sksewell@umich.edu    Stats::Scalar<> rxBytes;
3722935Sksewell@umich.edu    Stats::Scalar<> txPackets;
3732935Sksewell@umich.edu    Stats::Scalar<> rxPackets;
3742935Sksewell@umich.edu    Stats::Scalar<> txIpChecksums;
3753093Sksewell@umich.edu    Stats::Scalar<> rxIpChecksums;
3763093Sksewell@umich.edu    Stats::Scalar<> txTcpChecksums;
3772935Sksewell@umich.edu    Stats::Scalar<> rxTcpChecksums;
3782292SN/A    Stats::Scalar<> txUdpChecksums;
3792292SN/A    Stats::Scalar<> rxUdpChecksums;
3802935Sksewell@umich.edu    Stats::Scalar<> descDmaReads;
3812935Sksewell@umich.edu    Stats::Scalar<> descDmaWrites;
3823093Sksewell@umich.edu    Stats::Scalar<> descDmaRdBytes;
3832935Sksewell@umich.edu    Stats::Scalar<> descDmaWrBytes;
3842935Sksewell@umich.edu    Stats::Formula txBandwidth;
3852935Sksewell@umich.edu    Stats::Formula rxBandwidth;
3862935Sksewell@umich.edu    Stats::Formula txPacketRate;
3872935Sksewell@umich.edu    Stats::Formula rxPacketRate;
3882935Sksewell@umich.edu
3892935Sksewell@umich.edu  public:
3902935Sksewell@umich.edu    Tick cacheAccess(MemReqPtr &req);
3912935Sksewell@umich.edu};
3922935Sksewell@umich.edu
3932935Sksewell@umich.edu/*
3943798Sgblack@eecs.umich.edu * Ethernet Interface for an Ethernet Device
3953798Sgblack@eecs.umich.edu */
3963798Sgblack@eecs.umich.educlass NSGigEInt : public EtherInt
3973093Sksewell@umich.edu{
3983093Sksewell@umich.edu  private:
3992935Sksewell@umich.edu    NSGigE *dev;
4002935Sksewell@umich.edu
4012292SN/A  public:
4022292SN/A    NSGigEInt(const std::string &name, NSGigE *d)
4032292SN/A        : EtherInt(name), dev(d) { dev->setInterface(this); }
4042292SN/A
4052292SN/A    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
4062292SN/A    virtual void sendDone() { dev->transferDone(); }
4072292SN/A};
4082292SN/A
4092292SN/A#endif // __DEV_NS_GIGE_HH__
4102292SN/A