ns_gige.hh revision 1154
19401SAndreas.Sandberg@ARM.com/*
29401SAndreas.Sandberg@ARM.com * Copyright (c) 2004 The Regents of The University of Michigan
39401SAndreas.Sandberg@ARM.com * All rights reserved.
49401SAndreas.Sandberg@ARM.com *
59401SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
69401SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
79401SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
89401SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
99401SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
109401SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
119401SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
129401SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
134977Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
142997Sstever@eecs.umich.edu * this software without specific prior written permission.
152997Sstever@eecs.umich.edu *
162997Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172997Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182997Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192997Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202997Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212997Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222997Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232997Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242997Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252997Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262997Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272997Sstever@eecs.umich.edu */
282997Sstever@eecs.umich.edu
292997Sstever@eecs.umich.edu/* @file
302997Sstever@eecs.umich.edu * Device module for modelling the National Semiconductor
312997Sstever@eecs.umich.edu * DP83820 ethernet controller
322997Sstever@eecs.umich.edu */
332997Sstever@eecs.umich.edu
342997Sstever@eecs.umich.edu#ifndef __DEV_NS_GIGE_HH__
352997Sstever@eecs.umich.edu#define __DEV_NS_GIGE_HH__
362997Sstever@eecs.umich.edu
372997Sstever@eecs.umich.edu#include "base/inet.hh"
382997Sstever@eecs.umich.edu#include "base/statistics.hh"
392997Sstever@eecs.umich.edu#include "dev/etherint.hh"
402997Sstever@eecs.umich.edu#include "dev/etherpkt.hh"
415523Snate@binkert.org#include "dev/io_device.hh"
425523Snate@binkert.org#include "dev/ns_gige_reg.h"
436928SBrad.Beckmann@amd.com#include "dev/pcidev.hh"
446928SBrad.Beckmann@amd.com#include "dev/pktfifo.hh"
456289Snate@binkert.org#include "mem/bus/bus.hh"
466289Snate@binkert.org#include "sim/eventq.hh"
476289Snate@binkert.org
485523Snate@binkert.org/**
495523Snate@binkert.org * Ethernet device registers
509401SAndreas.Sandberg@ARM.com */
519401SAndreas.Sandberg@ARM.comstruct dp_regs {
529401SAndreas.Sandberg@ARM.com    uint32_t	command;
539401SAndreas.Sandberg@ARM.com    uint32_t	config;
549401SAndreas.Sandberg@ARM.com    uint32_t	mear;
559401SAndreas.Sandberg@ARM.com    uint32_t	ptscr;
569401SAndreas.Sandberg@ARM.com    uint32_t    isr;
579401SAndreas.Sandberg@ARM.com    uint32_t    imr;
589401SAndreas.Sandberg@ARM.com    uint32_t    ier;
599401SAndreas.Sandberg@ARM.com    uint32_t    ihr;
609401SAndreas.Sandberg@ARM.com    uint32_t    txdp;
619401SAndreas.Sandberg@ARM.com    uint32_t    txdp_hi;
629401SAndreas.Sandberg@ARM.com    uint32_t    txcfg;
639401SAndreas.Sandberg@ARM.com    uint32_t    gpior;
649401SAndreas.Sandberg@ARM.com    uint32_t    rxdp;
659401SAndreas.Sandberg@ARM.com    uint32_t    rxdp_hi;
669401SAndreas.Sandberg@ARM.com    uint32_t    rxcfg;
679401SAndreas.Sandberg@ARM.com    uint32_t    pqcr;
689401SAndreas.Sandberg@ARM.com    uint32_t    wcsr;
699401SAndreas.Sandberg@ARM.com    uint32_t    pcr;
709401SAndreas.Sandberg@ARM.com    uint32_t    rfcr;
719401SAndreas.Sandberg@ARM.com    uint32_t    rfdr;
729401SAndreas.Sandberg@ARM.com    uint32_t    srr;
739401SAndreas.Sandberg@ARM.com    uint32_t    mibc;
749401SAndreas.Sandberg@ARM.com    uint32_t    vrcr;
759401SAndreas.Sandberg@ARM.com    uint32_t    vtcr;
769401SAndreas.Sandberg@ARM.com    uint32_t    vdr;
779401SAndreas.Sandberg@ARM.com    uint32_t    ccsr;
789401SAndreas.Sandberg@ARM.com    uint32_t    tbicr;
799401SAndreas.Sandberg@ARM.com    uint32_t    tbisr;
809401SAndreas.Sandberg@ARM.com    uint32_t    tanar;
819401SAndreas.Sandberg@ARM.com    uint32_t    tanlpar;
829401SAndreas.Sandberg@ARM.com    uint32_t    taner;
839401SAndreas.Sandberg@ARM.com    uint32_t    tesr;
849401SAndreas.Sandberg@ARM.com};
859401SAndreas.Sandberg@ARM.com
869401SAndreas.Sandberg@ARM.comstruct dp_rom {
879401SAndreas.Sandberg@ARM.com    /**
889401SAndreas.Sandberg@ARM.com     * for perfect match memory.
899401SAndreas.Sandberg@ARM.com     * the linux driver doesn't use any other ROM
909401SAndreas.Sandberg@ARM.com     */
919401SAndreas.Sandberg@ARM.com    uint8_t perfectMatch[ETH_ADDR_LEN];
929401SAndreas.Sandberg@ARM.com};
939401SAndreas.Sandberg@ARM.com
949401SAndreas.Sandberg@ARM.comclass IntrControl;
959401SAndreas.Sandberg@ARM.comclass NSGigEInt;
969447SAndreas.Sandberg@ARM.comclass PhysicalMemory;
979447SAndreas.Sandberg@ARM.comclass BaseInterface;
989447SAndreas.Sandberg@ARM.comclass HierParams;
999447SAndreas.Sandberg@ARM.comclass Bus;
1009447SAndreas.Sandberg@ARM.comclass PciConfigAll;
1019447SAndreas.Sandberg@ARM.com
1029447SAndreas.Sandberg@ARM.com/**
1039447SAndreas.Sandberg@ARM.com * NS DP82830 Ethernet device model
1049447SAndreas.Sandberg@ARM.com */
1059447SAndreas.Sandberg@ARM.comclass NSGigE : public PciDev
1065523Snate@binkert.org{
1075523Snate@binkert.org  public:
1082997Sstever@eecs.umich.edu    /** Transmit State Machine states */
1092997Sstever@eecs.umich.edu    enum TxState
1108802Sgblack@eecs.umich.edu    {
1112997Sstever@eecs.umich.edu        txIdle,
1122997Sstever@eecs.umich.edu        txDescRefr,
1132997Sstever@eecs.umich.edu        txDescRead,
1146874SSteve.Reinhardt@amd.com        txFifoBlock,
1156874SSteve.Reinhardt@amd.com        txFragRead,
1166289Snate@binkert.org        txDescWrite,
1172998Sstever@eecs.umich.edu        txAdvance
1182998Sstever@eecs.umich.edu    };
1192998Sstever@eecs.umich.edu
1202998Sstever@eecs.umich.edu    /** Receive State Machine States */
1212998Sstever@eecs.umich.edu    enum RxState
1222998Sstever@eecs.umich.edu    {
1236289Snate@binkert.org        rxIdle,
1242997Sstever@eecs.umich.edu        rxDescRefr,
1253475Sktlim@umich.edu        rxDescRead,
1263475Sktlim@umich.edu        rxFifoBlock,
1273475Sktlim@umich.edu        rxFragWrite,
1283475Sktlim@umich.edu        rxDescWrite,
1293475Sktlim@umich.edu        rxAdvance
1306289Snate@binkert.org    };
1313475Sktlim@umich.edu
1322997Sstever@eecs.umich.edu    enum DmaState
1336289Snate@binkert.org    {
1346928SBrad.Beckmann@amd.com        dmaIdle,
1356928SBrad.Beckmann@amd.com        dmaReading,
1366928SBrad.Beckmann@amd.com        dmaWriting,
1376928SBrad.Beckmann@amd.com        dmaReadWaiting,
1386928SBrad.Beckmann@amd.com        dmaWriteWaiting
1392997Sstever@eecs.umich.edu    };
1402997Sstever@eecs.umich.edu
1412998Sstever@eecs.umich.edu  private:
1425523Snate@binkert.org    Addr addr;
1432997Sstever@eecs.umich.edu    static const Addr size = sizeof(dp_regs);
1442997Sstever@eecs.umich.edu
1458802Sgblack@eecs.umich.edu  protected:
1468802Sgblack@eecs.umich.edu    typedef std::deque<PacketPtr> pktbuf_t;
1472997Sstever@eecs.umich.edu    typedef pktbuf_t::iterator pktiter_t;
1489384SAndreas.Sandberg@arm.com
1499384SAndreas.Sandberg@arm.com    /** device register file */
1509384SAndreas.Sandberg@arm.com    dp_regs regs;
1519384SAndreas.Sandberg@arm.com    dp_rom rom;
1529384SAndreas.Sandberg@arm.com
1539384SAndreas.Sandberg@arm.com    /** pci settings */
1549384SAndreas.Sandberg@arm.com    bool ioEnable;
1559384SAndreas.Sandberg@arm.com#if 0
1569384SAndreas.Sandberg@arm.com    bool memEnable;
1579384SAndreas.Sandberg@arm.com    bool bmEnable;
1589384SAndreas.Sandberg@arm.com#endif
1599384SAndreas.Sandberg@arm.com
1609384SAndreas.Sandberg@arm.com    /*** BASIC STRUCTURES FOR TX/RX ***/
1619384SAndreas.Sandberg@arm.com    /* Data FIFOs */
1629384SAndreas.Sandberg@arm.com    PacketFifo txFifo;
1639384SAndreas.Sandberg@arm.com    PacketFifo rxFifo;
1649384SAndreas.Sandberg@arm.com
1659384SAndreas.Sandberg@arm.com    /** various helper vars */
1669384SAndreas.Sandberg@arm.com    PacketPtr txPacket;
1679384SAndreas.Sandberg@arm.com    PacketPtr rxPacket;
1689384SAndreas.Sandberg@arm.com    uint8_t *txPacketBufPtr;
1699384SAndreas.Sandberg@arm.com    uint8_t *rxPacketBufPtr;
1709384SAndreas.Sandberg@arm.com    uint32_t txXferLen;
1719384SAndreas.Sandberg@arm.com    uint32_t rxXferLen;
1729384SAndreas.Sandberg@arm.com    bool rxDmaFree;
1739447SAndreas.Sandberg@ARM.com    bool txDmaFree;
174
175    /** DescCaches */
176    ns_desc txDescCache;
177    ns_desc rxDescCache;
178
179    /* tx State Machine */
180    TxState txState;
181    bool txEnable;
182
183    /** Current Transmit Descriptor Done */
184    bool CTDD;
185    /** halt the tx state machine after next packet */
186    bool txHalt;
187    /** ptr to the next byte in the current fragment */
188    Addr txFragPtr;
189    /** count of bytes remaining in the current descriptor */
190    uint32_t txDescCnt;
191    DmaState txDmaState;
192
193    /** rx State Machine */
194    RxState rxState;
195    bool rxEnable;
196
197    /** Current Receive Descriptor Done */
198    bool CRDD;
199    /** num of bytes in the current packet being drained from rxDataFifo */
200    uint32_t rxPktBytes;
201    /** halt the rx state machine after current packet */
202    bool rxHalt;
203    /** ptr to the next byte in current fragment */
204    Addr rxFragPtr;
205    /** count of bytes remaining in the current descriptor */
206    uint32_t rxDescCnt;
207    DmaState rxDmaState;
208
209    bool extstsEnable;
210
211  protected:
212    Tick dmaReadDelay;
213    Tick dmaWriteDelay;
214
215    Tick dmaReadFactor;
216    Tick dmaWriteFactor;
217
218    void *rxDmaData;
219    Addr  rxDmaAddr;
220    int   rxDmaLen;
221    bool  doRxDmaRead();
222    bool  doRxDmaWrite();
223    void  rxDmaReadCopy();
224    void  rxDmaWriteCopy();
225
226    void *txDmaData;
227    Addr  txDmaAddr;
228    int   txDmaLen;
229    bool  doTxDmaRead();
230    bool  doTxDmaWrite();
231    void  txDmaReadCopy();
232    void  txDmaWriteCopy();
233
234    void rxDmaReadDone();
235    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
236    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
237
238    void rxDmaWriteDone();
239    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
240    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
241
242    void txDmaReadDone();
243    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
244    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
245
246    void txDmaWriteDone();
247    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
248    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
249
250    bool dmaDescFree;
251    bool dmaDataFree;
252
253
254  protected:
255    Tick txDelay;
256    Tick rxDelay;
257
258    void txReset();
259    void rxReset();
260    void regsReset();
261
262    void rxKick();
263    Tick rxKickTick;
264    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
265    friend class RxKickEvent;
266
267    void txKick();
268    Tick txKickTick;
269    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
270    friend class TxKickEvent;
271
272    /**
273     * Retransmit event
274     */
275    void transmit();
276    void txEventTransmit()
277    {
278        transmit();
279        if (txState == txFifoBlock)
280            txKick();
281    }
282    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
283    friend class TxEvent;
284    TxEvent txEvent;
285
286    void txDump() const;
287    void rxDump() const;
288
289    /**
290     * receive address filter
291     */
292    bool rxFilterEnable;
293    bool rxFilter(const PacketPtr &packet);
294    bool acceptBroadcast;
295    bool acceptMulticast;
296    bool acceptUnicast;
297    bool acceptPerfect;
298    bool acceptArp;
299
300    PhysicalMemory *physmem;
301
302    /**
303     * Interrupt management
304     */
305    IntrControl *intctrl;
306    void devIntrPost(uint32_t interrupts);
307    void devIntrClear(uint32_t interrupts);
308    void devIntrChangeMask();
309
310    Tick intrDelay;
311    Tick intrTick;
312    bool cpuPendingIntr;
313    void cpuIntrPost(Tick when);
314    void cpuInterrupt();
315    void cpuIntrClear();
316
317    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
318    friend class IntrEvent;
319    IntrEvent *intrEvent;
320    NSGigEInt *interface;
321
322  public:
323    struct Params : public PciDev::Params
324    {
325        PhysicalMemory *pmem;
326        HierParams *hier;
327        Bus *header_bus;
328        Bus *payload_bus;
329        Tick intr_delay;
330        Tick tx_delay;
331        Tick rx_delay;
332        Tick pio_latency;
333        bool dma_desc_free;
334        bool dma_data_free;
335        Tick dma_read_delay;
336        Tick dma_write_delay;
337        Tick dma_read_factor;
338        Tick dma_write_factor;
339        bool rx_filter;
340        Net::EthAddr eaddr;
341        uint32_t tx_fifo_size;
342        uint32_t rx_fifo_size;
343    };
344
345    NSGigE(Params *params);
346    ~NSGigE();
347    const Params *params() const { return (const Params *)_params; }
348
349    virtual void WriteConfig(int offset, int size, uint32_t data);
350    virtual void ReadConfig(int offset, int size, uint8_t *data);
351
352    virtual Fault read(MemReqPtr &req, uint8_t *data);
353    virtual Fault write(MemReqPtr &req, const uint8_t *data);
354
355    bool cpuIntrPending() const;
356    void cpuIntrAck() { cpuIntrClear(); }
357
358    bool recvPacket(PacketPtr packet);
359    void transferDone();
360
361    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
362
363    virtual void serialize(std::ostream &os);
364    virtual void unserialize(Checkpoint *cp, const std::string &section);
365
366  public:
367    void regStats();
368
369  private:
370    Stats::Scalar<> txBytes;
371    Stats::Scalar<> rxBytes;
372    Stats::Scalar<> txPackets;
373    Stats::Scalar<> rxPackets;
374    Stats::Scalar<> txIpChecksums;
375    Stats::Scalar<> rxIpChecksums;
376    Stats::Scalar<> txTcpChecksums;
377    Stats::Scalar<> rxTcpChecksums;
378    Stats::Scalar<> txUdpChecksums;
379    Stats::Scalar<> rxUdpChecksums;
380    Stats::Scalar<> descDmaReads;
381    Stats::Scalar<> descDmaWrites;
382    Stats::Scalar<> descDmaRdBytes;
383    Stats::Scalar<> descDmaWrBytes;
384    Stats::Formula txBandwidth;
385    Stats::Formula rxBandwidth;
386    Stats::Formula txPacketRate;
387    Stats::Formula rxPacketRate;
388
389  public:
390    Tick cacheAccess(MemReqPtr &req);
391};
392
393/*
394 * Ethernet Interface for an Ethernet Device
395 */
396class NSGigEInt : public EtherInt
397{
398  private:
399    NSGigE *dev;
400
401  public:
402    NSGigEInt(const std::string &name, NSGigE *d)
403        : EtherInt(name), dev(d) { dev->setInterface(this); }
404
405    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
406    virtual void sendDone() { dev->transferDone(); }
407};
408
409#endif // __DEV_NS_GIGE_HH__
410