ns_gige.hh revision 915
13048Sstever@eecs.umich.edu/*
23048Sstever@eecs.umich.edu * Copyright (c) 2004 The Regents of The University of Michigan
33048Sstever@eecs.umich.edu * All rights reserved.
43048Sstever@eecs.umich.edu *
53048Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63048Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
73048Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83048Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93048Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103048Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113048Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123048Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133048Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143048Sstever@eecs.umich.edu * this software without specific prior written permission.
153048Sstever@eecs.umich.edu *
163048Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173048Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183048Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193048Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203048Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213048Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223048Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233048Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243048Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253048Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263048Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273048Sstever@eecs.umich.edu */
283048Sstever@eecs.umich.edu
293048Sstever@eecs.umich.edu/* @file
303048Sstever@eecs.umich.edu * Device module for modelling the National Semiconductor
313048Sstever@eecs.umich.edu * DP83820 ethernet controller
323048Sstever@eecs.umich.edu */
3312881Sjason@lowepower.com
343048Sstever@eecs.umich.edu#ifndef __NS_GIGE_HH__
353048Sstever@eecs.umich.edu#define __NS_GIGE_HH__
3612881Sjason@lowepower.com
373048Sstever@eecs.umich.edu//#include "base/range.hh"
383048Sstever@eecs.umich.edu#include "dev/etherint.hh"
39#include "dev/etherpkt.hh"
40#include "sim/eventq.hh"
41#include "dev/ns_gige_reg.h"
42#include "base/statistics.hh"
43#include "dev/pcidev.hh"
44#include "dev/tsunami.hh"
45#include "dev/io_device.hh"
46#include "mem/bus/bus.hh"
47
48/** defined by the NS83820 data sheet */
49#define MAX_TX_FIFO_SIZE 8192
50#define MAX_RX_FIFO_SIZE 32768
51
52/** length of ethernet address in bytes */
53#define EADDR_LEN 6
54
55/**
56 * Ethernet device registers
57 */
58struct dp_regs {
59    uint32_t	command;
60    uint32_t	config;
61    uint32_t	mear;
62    uint32_t	ptscr;
63    uint32_t    isr;
64    uint32_t    imr;
65    uint32_t    ier;
66    uint32_t    ihr;
67    uint32_t    txdp;
68    uint32_t    txdp_hi;
69    uint32_t    txcfg;
70    uint32_t    gpior;
71    uint32_t    rxdp;
72    uint32_t    rxdp_hi;
73    uint32_t    rxcfg;
74    uint32_t    pqcr;
75    uint32_t    wcsr;
76    uint32_t    pcr;
77    uint32_t    rfcr;
78    uint32_t    rfdr;
79    uint32_t    srr;
80    uint32_t    mibc;
81    uint32_t    vrcr;
82    uint32_t    vtcr;
83    uint32_t    vdr;
84    uint32_t    ccsr;
85    uint32_t    tbicr;
86    uint32_t    tbisr;
87    uint32_t    tanar;
88    uint32_t    tanlpar;
89    uint32_t    taner;
90    uint32_t    tesr;
91};
92
93struct dp_rom {
94    /** for perfect match memory.  the linux driver doesn't use any other ROM */
95    uint8_t perfectMatch[EADDR_LEN];
96};
97
98class IntrControl;
99class NSGigEInt;
100class PhysicalMemory;
101class BaseInterface;
102class HierParams;
103class Bus;
104class PciConfigAll;
105
106/**
107 * NS DP82830 Ethernet device model
108 */
109class NSGigE : public PciDev
110{
111  public:
112    /** Transmit State Machine states */
113    enum TxState
114    {
115        txIdle,
116        txDescRefr,
117        txDescRead,
118        txFifoBlock,
119        txFragRead,
120        txDescWrite,
121        txAdvance
122    };
123
124    /** Receive State Machine States */
125    enum RxState
126    {
127        rxIdle,
128        rxDescRefr,
129        rxDescRead,
130        rxFifoBlock,
131        rxFragWrite,
132        rxDescWrite,
133        rxAdvance
134    };
135
136    enum DmaState
137    {
138        dmaIdle,
139        dmaReading,
140        dmaWriting,
141        dmaReadWaiting,
142        dmaWriteWaiting
143    };
144
145  private:
146    /** pointer to the chipset */
147    Tsunami *tsunami;
148
149  private:
150    Addr addr;
151    static const Addr size = sizeof(dp_regs);
152
153  protected:
154    typedef std::deque<PacketPtr> pktbuf_t;
155    typedef pktbuf_t::iterator pktiter_t;
156
157    /** device register file */
158    dp_regs regs;
159    dp_rom rom;
160
161    /*** BASIC STRUCTURES FOR TX/RX ***/
162    /* Data FIFOs */
163    pktbuf_t txFifo;
164    pktbuf_t rxFifo;
165
166    /** various helper vars */
167    PacketPtr txPacket;
168    PacketPtr rxPacket;
169    uint8_t *txPacketBufPtr;
170    uint8_t *rxPacketBufPtr;
171    uint32_t txXferLen;
172    uint32_t rxXferLen;
173    uint32_t txPktXmitted;
174    bool rxDmaFree;
175    bool txDmaFree;
176
177    /** DescCaches */
178    ns_desc txDescCache;
179    ns_desc rxDescCache;
180
181    /* tx State Machine */
182    TxState txState;
183    /** Current Transmit Descriptor Done */
184    bool CTDD;
185    /** amt of data in the txDataFifo in bytes (logical) */
186    uint32_t txFifoCnt;
187    /** current amt of free space in txDataFifo in bytes */
188    uint32_t txFifoAvail;
189    /** halt the tx state machine after next packet */
190    bool txHalt;
191    /** ptr to the next byte in the current fragment */
192    Addr txFragPtr;
193    /** count of bytes remaining in the current descriptor */
194    uint32_t txDescCnt;
195    DmaState txDmaState;
196
197    /** rx State Machine */
198    RxState rxState;
199    /** Current Receive Descriptor Done */
200    bool CRDD;
201    /** num of bytes in the current packet being drained from rxDataFifo */
202    uint32_t rxPktBytes;
203    /** number of bytes in the rxFifo */
204    uint32_t rxFifoCnt;
205    /** halt the rx state machine after current packet */
206    bool rxHalt;
207    /** ptr to the next byte in current fragment */
208    Addr rxFragPtr;
209    /** count of bytes remaining in the current descriptor */
210    uint32_t rxDescCnt;
211    DmaState rxDmaState;
212
213    bool extstsEnable;
214
215  protected:
216    Tick dmaReadDelay;
217    Tick dmaWriteDelay;
218
219    Tick dmaReadFactor;
220    Tick dmaWriteFactor;
221
222    void *rxDmaData;
223    Addr  rxDmaAddr;
224    int   rxDmaLen;
225    bool  doRxDmaRead();
226    bool  doRxDmaWrite();
227    void  rxDmaReadCopy();
228    void  rxDmaWriteCopy();
229
230    void *txDmaData;
231    Addr  txDmaAddr;
232    int   txDmaLen;
233    bool  doTxDmaRead();
234    bool  doTxDmaWrite();
235    void  txDmaReadCopy();
236    void  txDmaWriteCopy();
237
238    void rxDmaReadDone();
239    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
240    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
241
242    void rxDmaWriteDone();
243    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
244    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
245
246    void txDmaReadDone();
247    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
248    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
249
250    void txDmaWriteDone();
251    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
252    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
253
254    bool dmaDescFree;
255    bool dmaDataFree;
256
257
258  protected:
259    Tick txDelay;
260    Tick rxDelay;
261
262    void txReset();
263    void rxReset();
264    void regsReset();
265
266    void rxKick();
267    Tick rxKickTick;
268    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
269    friend class RxKickEvent;
270
271    void txKick();
272    Tick txKickTick;
273    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
274    friend class TxKickEvent;
275
276    /**
277     * Retransmit event
278     */
279    void transmit();
280    typedef EventWrapper<NSGigE, &NSGigE::transmit> TxEvent;
281    friend class TxEvent;
282    TxEvent txEvent;
283
284    void txDump() const;
285    void rxDump() const;
286
287    /**
288     * receive address filter
289     */
290    bool rxFilterEnable;
291    bool rxFilter(PacketPtr packet);
292    bool acceptBroadcast;
293    bool acceptMulticast;
294    bool acceptUnicast;
295    bool acceptPerfect;
296    bool acceptArp;
297
298    PhysicalMemory *physmem;
299
300    /**
301     * Interrupt management
302     */
303    IntrControl *intctrl;
304    void devIntrPost(uint32_t interrupts);
305    void devIntrClear(uint32_t interrupts);
306    void devIntrChangeMask();
307
308    Tick intrDelay;
309    Tick intrTick;
310    bool cpuPendingIntr;
311    void cpuIntrPost(Tick when);
312    void cpuInterrupt();
313    void cpuIntrClear();
314
315    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
316    friend class IntrEvent;
317    IntrEvent *intrEvent;
318
319    /**
320     * Hardware checksum support
321     */
322    bool udpChecksum(PacketPtr packet, bool gen);
323    bool tcpChecksum(PacketPtr packet, bool gen);
324    bool ipChecksum(PacketPtr packet, bool gen);
325    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
326
327    NSGigEInt *interface;
328
329  public:
330    NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
331             PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
332             MemoryController *mmu, HierParams *hier, Bus *header_bus,
333             Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
334             bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
335             Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
336             PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
337             uint32_t func, bool rx_filter, const int eaddr[6]);
338    ~NSGigE();
339
340    virtual void WriteConfig(int offset, int size, uint32_t data);
341    virtual void ReadConfig(int offset, int size, uint8_t *data);
342
343    virtual Fault read(MemReqPtr &req, uint8_t *data);
344    virtual Fault write(MemReqPtr &req, const uint8_t *data);
345
346    bool cpuIntrPending() const;
347    void cpuIntrAck() { cpuIntrClear(); }
348
349    bool recvPacket(PacketPtr packet);
350    void transferDone();
351
352    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
353
354    virtual void serialize(std::ostream &os);
355    virtual void unserialize(Checkpoint *cp, const std::string &section);
356
357  public:
358    void regStats();
359
360  private:
361    Stats::Scalar<> txBytes;
362    Stats::Scalar<> rxBytes;
363    Stats::Scalar<> txPackets;
364    Stats::Scalar<> rxPackets;
365    Stats::Formula txBandwidth;
366    Stats::Formula rxBandwidth;
367    Stats::Formula txPacketRate;
368    Stats::Formula rxPacketRate;
369
370  private:
371    Tick pioLatency;
372
373  public:
374    Tick cacheAccess(MemReqPtr &req);
375};
376
377/*
378 * Ethernet Interface for an Ethernet Device
379 */
380class NSGigEInt : public EtherInt
381{
382  private:
383    NSGigE *dev;
384
385  public:
386    NSGigEInt(const std::string &name, NSGigE *d)
387        : EtherInt(name), dev(d) { dev->setInterface(this); }
388
389    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
390    virtual void sendDone() { dev->transferDone(); }
391};
392
393#endif // __NS_GIGE_HH__
394