ns_gige.hh revision 1035
15369Ssaidi@eecs.umich.edu/*
23005Sstever@eecs.umich.edu * Copyright (c) 2004 The Regents of The University of Michigan
33005Sstever@eecs.umich.edu * All rights reserved.
43005Sstever@eecs.umich.edu *
53005Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63005Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
73005Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83005Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93005Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103005Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113005Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123005Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133005Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143005Sstever@eecs.umich.edu * this software without specific prior written permission.
153005Sstever@eecs.umich.edu *
163005Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173005Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183005Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193005Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203005Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213005Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223005Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233005Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243005Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253005Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263005Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273005Sstever@eecs.umich.edu */
283005Sstever@eecs.umich.edu
292710SN/A/* @file
302710SN/A * Device module for modelling the National Semiconductor
313005Sstever@eecs.umich.edu * DP83820 ethernet controller
322889SN/A */
332667SN/A
345457Ssaidi@eecs.umich.edu#ifndef __NS_GIGE_HH__
355457Ssaidi@eecs.umich.edu#define __NS_GIGE_HH__
365457Ssaidi@eecs.umich.edu
375457Ssaidi@eecs.umich.edu#include "base/statistics.hh"
383005Sstever@eecs.umich.edu#include "dev/etherint.hh"
392856SN/A#include "dev/etherpkt.hh"
402917SN/A#include "dev/io_device.hh"
413395Shsul@eecs.umich.edu#include "dev/ns_gige_reg.h"
423448Shsul@eecs.umich.edu#include "dev/pcidev.hh"
435369Ssaidi@eecs.umich.edu#include "dev/tsunami.hh"
443394Shsul@eecs.umich.edu#include "mem/bus/bus.hh"
453444Sktlim@umich.edu#include "sim/eventq.hh"
463444Sktlim@umich.edu
473444Sktlim@umich.edu/** length of ethernet address in bytes */
483444Sktlim@umich.edu#define EADDR_LEN 6
492424SN/A
502957SN/A/**
512957SN/A * Ethernet device registers
523323Shsul@eecs.umich.edu */
533005Sstever@eecs.umich.edustruct dp_regs {
543444Sktlim@umich.edu    uint32_t	command;
552957SN/A    uint32_t	config;
562957SN/A    uint32_t	mear;
572957SN/A    uint32_t	ptscr;
582957SN/A    uint32_t    isr;
592957SN/A    uint32_t    imr;
602957SN/A    uint32_t    ier;
613323Shsul@eecs.umich.edu    uint32_t    ihr;
623444Sktlim@umich.edu    uint32_t    txdp;
632957SN/A    uint32_t    txdp_hi;
642957SN/A    uint32_t    txcfg;
652957SN/A    uint32_t    gpior;
662957SN/A    uint32_t    rxdp;
672957SN/A    uint32_t    rxdp_hi;
682957SN/A    uint32_t    rxcfg;
692957SN/A    uint32_t    pqcr;
705369Ssaidi@eecs.umich.edu    uint32_t    wcsr;
715369Ssaidi@eecs.umich.edu    uint32_t    pcr;
725369Ssaidi@eecs.umich.edu    uint32_t    rfcr;
735369Ssaidi@eecs.umich.edu    uint32_t    rfdr;
745369Ssaidi@eecs.umich.edu    uint32_t    srr;
755369Ssaidi@eecs.umich.edu    uint32_t    mibc;
765369Ssaidi@eecs.umich.edu    uint32_t    vrcr;
775369Ssaidi@eecs.umich.edu    uint32_t    vtcr;
785369Ssaidi@eecs.umich.edu    uint32_t    vdr;
795369Ssaidi@eecs.umich.edu    uint32_t    ccsr;
805369Ssaidi@eecs.umich.edu    uint32_t    tbicr;
815369Ssaidi@eecs.umich.edu    uint32_t    tbisr;
825369Ssaidi@eecs.umich.edu    uint32_t    tanar;
835369Ssaidi@eecs.umich.edu    uint32_t    tanlpar;
845369Ssaidi@eecs.umich.edu    uint32_t    taner;
855369Ssaidi@eecs.umich.edu    uint32_t    tesr;
862801SN/A};
872801SN/A
882418SN/Astruct dp_rom {
892917SN/A    /**
902833SN/A     * for perfect match memory.
912833SN/A     * the linux driver doesn't use any other ROM
922833SN/A     */
932833SN/A    uint8_t perfectMatch[EADDR_LEN];
942833SN/A};
952833SN/A
962833SN/Aclass IntrControl;
972833SN/Aclass NSGigEInt;
982833SN/Aclass PhysicalMemory;
992833SN/Aclass BaseInterface;
1002833SN/Aclass HierParams;
1012833SN/Aclass Bus;
1023005Sstever@eecs.umich.educlass PciConfigAll;
1032833SN/A
1042833SN/A/**
1052833SN/A * NS DP82830 Ethernet device model
1062833SN/A */
1072833SN/Aclass NSGigE : public PciDev
1082833SN/A{
1093481Shsul@eecs.umich.edu  public:
1102957SN/A    /** Transmit State Machine states */
1113395Shsul@eecs.umich.edu    enum TxState
1123005Sstever@eecs.umich.edu    {
1133395Shsul@eecs.umich.edu        txIdle,
1143395Shsul@eecs.umich.edu        txDescRefr,
1153395Shsul@eecs.umich.edu        txDescRead,
1163323Shsul@eecs.umich.edu        txFifoBlock,
1173395Shsul@eecs.umich.edu        txFragRead,
1183395Shsul@eecs.umich.edu        txDescWrite,
1193005Sstever@eecs.umich.edu        txAdvance
1203395Shsul@eecs.umich.edu    };
1215056Ssaidi@eecs.umich.edu
1225056Ssaidi@eecs.umich.edu    /** Receive State Machine States */
1235056Ssaidi@eecs.umich.edu    enum RxState
1245056Ssaidi@eecs.umich.edu    {
1255056Ssaidi@eecs.umich.edu        rxIdle,
1265056Ssaidi@eecs.umich.edu        rxDescRefr,
1273395Shsul@eecs.umich.edu        rxDescRead,
1283514Sktlim@umich.edu        rxFifoBlock,
1293395Shsul@eecs.umich.edu        rxFragWrite,
1303448Shsul@eecs.umich.edu        rxDescWrite,
1314455Ssaidi@eecs.umich.edu        rxAdvance
1324455Ssaidi@eecs.umich.edu    };
1334455Ssaidi@eecs.umich.edu
1344455Ssaidi@eecs.umich.edu    enum DmaState
1353395Shsul@eecs.umich.edu    {
1363005Sstever@eecs.umich.edu        dmaIdle,
1374968Sacolyte@umich.edu        dmaReading,
1384968Sacolyte@umich.edu        dmaWriting,
1394968Sacolyte@umich.edu        dmaReadWaiting,
1403005Sstever@eecs.umich.edu        dmaWriteWaiting
1412902SN/A    };
1423481Shsul@eecs.umich.edu
143  private:
144    /** pointer to the chipset */
145    Tsunami *tsunami;
146
147  private:
148    Addr addr;
149    static const Addr size = sizeof(dp_regs);
150
151  protected:
152    typedef std::deque<PacketPtr> pktbuf_t;
153    typedef pktbuf_t::iterator pktiter_t;
154
155    /** device register file */
156    dp_regs regs;
157    dp_rom rom;
158
159    /** pci settings */
160    bool ioEnable;
161#if 0
162    bool memEnable;
163    bool bmEnable;
164#endif
165
166    /*** BASIC STRUCTURES FOR TX/RX ***/
167    /* Data FIFOs */
168    pktbuf_t txFifo;
169    uint32_t maxTxFifoSize;
170    pktbuf_t rxFifo;
171    uint32_t maxRxFifoSize;
172
173    /** various helper vars */
174    PacketPtr txPacket;
175    PacketPtr rxPacket;
176    uint8_t *txPacketBufPtr;
177    uint8_t *rxPacketBufPtr;
178    uint32_t txXferLen;
179    uint32_t rxXferLen;
180    bool rxDmaFree;
181    bool txDmaFree;
182
183    /** DescCaches */
184    ns_desc txDescCache;
185    ns_desc rxDescCache;
186
187    /* tx State Machine */
188    TxState txState;
189    bool txEnable;
190
191    /** Current Transmit Descriptor Done */
192    bool CTDD;
193    /** current amt of free space in txDataFifo in bytes */
194    uint32_t txFifoAvail;
195    /** halt the tx state machine after next packet */
196    bool txHalt;
197    /** ptr to the next byte in the current fragment */
198    Addr txFragPtr;
199    /** count of bytes remaining in the current descriptor */
200    uint32_t txDescCnt;
201    DmaState txDmaState;
202
203    /** rx State Machine */
204    RxState rxState;
205    bool rxEnable;
206
207    /** Current Receive Descriptor Done */
208    bool CRDD;
209    /** num of bytes in the current packet being drained from rxDataFifo */
210    uint32_t rxPktBytes;
211    /** number of bytes in the rxFifo */
212    uint32_t rxFifoCnt;
213    /** halt the rx state machine after current packet */
214    bool rxHalt;
215    /** ptr to the next byte in current fragment */
216    Addr rxFragPtr;
217    /** count of bytes remaining in the current descriptor */
218    uint32_t rxDescCnt;
219    DmaState rxDmaState;
220
221    bool extstsEnable;
222
223  protected:
224    Tick dmaReadDelay;
225    Tick dmaWriteDelay;
226
227    Tick dmaReadFactor;
228    Tick dmaWriteFactor;
229
230    void *rxDmaData;
231    Addr  rxDmaAddr;
232    int   rxDmaLen;
233    bool  doRxDmaRead();
234    bool  doRxDmaWrite();
235    void  rxDmaReadCopy();
236    void  rxDmaWriteCopy();
237
238    void *txDmaData;
239    Addr  txDmaAddr;
240    int   txDmaLen;
241    bool  doTxDmaRead();
242    bool  doTxDmaWrite();
243    void  txDmaReadCopy();
244    void  txDmaWriteCopy();
245
246    void rxDmaReadDone();
247    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
248    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
249
250    void rxDmaWriteDone();
251    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
252    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
253
254    void txDmaReadDone();
255    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
256    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
257
258    void txDmaWriteDone();
259    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
260    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
261
262    bool dmaDescFree;
263    bool dmaDataFree;
264
265
266  protected:
267    Tick txDelay;
268    Tick rxDelay;
269
270    void txReset();
271    void rxReset();
272    void regsReset();
273
274    void rxKick();
275    Tick rxKickTick;
276    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
277    friend class RxKickEvent;
278
279    void txKick();
280    Tick txKickTick;
281    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
282    friend class TxKickEvent;
283
284    /**
285     * Retransmit event
286     */
287    void transmit();
288    void txEventTransmit()
289    {
290        transmit();
291        if (txState == txFifoBlock)
292            txKick();
293    }
294    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
295    friend class TxEvent;
296    TxEvent txEvent;
297
298    void txDump() const;
299    void rxDump() const;
300
301    /**
302     * receive address filter
303     */
304    bool rxFilterEnable;
305    bool rxFilter(PacketPtr packet);
306    bool acceptBroadcast;
307    bool acceptMulticast;
308    bool acceptUnicast;
309    bool acceptPerfect;
310    bool acceptArp;
311
312    PhysicalMemory *physmem;
313
314    /**
315     * Interrupt management
316     */
317    IntrControl *intctrl;
318    void devIntrPost(uint32_t interrupts);
319    void devIntrClear(uint32_t interrupts);
320    void devIntrChangeMask();
321
322    Tick intrDelay;
323    Tick intrTick;
324    bool cpuPendingIntr;
325    void cpuIntrPost(Tick when);
326    void cpuInterrupt();
327    void cpuIntrClear();
328
329    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
330    friend class IntrEvent;
331    IntrEvent *intrEvent;
332
333    /**
334     * Hardware checksum support
335     */
336    bool udpChecksum(PacketPtr packet, bool gen);
337    bool tcpChecksum(PacketPtr packet, bool gen);
338    bool ipChecksum(PacketPtr packet, bool gen);
339    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
340
341    NSGigEInt *interface;
342
343  public:
344    NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
345           PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
346           MemoryController *mmu, HierParams *hier, Bus *header_bus,
347           Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
348           bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
349           Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
350           PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
351           uint32_t func, bool rx_filter, const int eaddr[6],
352           uint32_t tx_fifo_size, uint32_t rx_fifo_size);
353    ~NSGigE();
354
355    virtual void WriteConfig(int offset, int size, uint32_t data);
356    virtual void ReadConfig(int offset, int size, uint8_t *data);
357
358    virtual Fault read(MemReqPtr &req, uint8_t *data);
359    virtual Fault write(MemReqPtr &req, const uint8_t *data);
360
361    bool cpuIntrPending() const;
362    void cpuIntrAck() { cpuIntrClear(); }
363
364    bool recvPacket(PacketPtr packet);
365    void transferDone();
366
367    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
368
369    virtual void serialize(std::ostream &os);
370    virtual void unserialize(Checkpoint *cp, const std::string &section);
371
372  public:
373    void regStats();
374
375  private:
376    Stats::Scalar<> txBytes;
377    Stats::Scalar<> rxBytes;
378    Stats::Scalar<> txPackets;
379    Stats::Scalar<> rxPackets;
380    Stats::Scalar<> txIPChecksums;
381    Stats::Scalar<> rxIPChecksums;
382    Stats::Scalar<> txTCPChecksums;
383    Stats::Scalar<> rxTCPChecksums;
384    Stats::Scalar<> descDmaReads;
385    Stats::Scalar<> descDmaWrites;
386    Stats::Scalar<> descDmaRdBytes;
387    Stats::Scalar<> descDmaWrBytes;
388    Stats::Formula txBandwidth;
389    Stats::Formula rxBandwidth;
390    Stats::Formula txPacketRate;
391    Stats::Formula rxPacketRate;
392
393  public:
394    Tick cacheAccess(MemReqPtr &req);
395};
396
397/*
398 * Ethernet Interface for an Ethernet Device
399 */
400class NSGigEInt : public EtherInt
401{
402  private:
403    NSGigE *dev;
404
405  public:
406    NSGigEInt(const std::string &name, NSGigE *d)
407        : EtherInt(name), dev(d) { dev->setInterface(this); }
408
409    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
410    virtual void sendDone() { dev->transferDone(); }
411};
412
413#endif // __NS_GIGE_HH__
414