ns_gige.hh revision 1817
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file
30 * Device module for modelling the National Semiconductor
31 * DP83820 ethernet controller
32 */
33
34#ifndef __DEV_NS_GIGE_HH__
35#define __DEV_NS_GIGE_HH__
36
37#include "base/inet.hh"
38#include "base/statistics.hh"
39#include "dev/etherint.hh"
40#include "dev/etherpkt.hh"
41#include "dev/io_device.hh"
42#include "dev/ns_gige_reg.h"
43#include "dev/pcidev.hh"
44#include "dev/pktfifo.hh"
45#include "mem/bus/bus.hh"
46#include "sim/eventq.hh"
47
48/**
49 * Ethernet device registers
50 */
51struct dp_regs {
52    uint32_t	command;
53    uint32_t	config;
54    uint32_t	mear;
55    uint32_t	ptscr;
56    uint32_t    isr;
57    uint32_t    imr;
58    uint32_t    ier;
59    uint32_t    ihr;
60    uint32_t    txdp;
61    uint32_t    txdp_hi;
62    uint32_t    txcfg;
63    uint32_t    gpior;
64    uint32_t    rxdp;
65    uint32_t    rxdp_hi;
66    uint32_t    rxcfg;
67    uint32_t    pqcr;
68    uint32_t    wcsr;
69    uint32_t    pcr;
70    uint32_t    rfcr;
71    uint32_t    rfdr;
72    uint32_t    srr;
73    uint32_t    mibc;
74    uint32_t    vrcr;
75    uint32_t    vtcr;
76    uint32_t    vdr;
77    uint32_t    ccsr;
78    uint32_t    tbicr;
79    uint32_t    tbisr;
80    uint32_t    tanar;
81    uint32_t    tanlpar;
82    uint32_t    taner;
83    uint32_t    tesr;
84};
85
86struct dp_rom {
87    /**
88     * for perfect match memory.
89     * the linux driver doesn't use any other ROM
90     */
91    uint8_t perfectMatch[ETH_ADDR_LEN];
92};
93
94class NSGigEInt;
95class PhysicalMemory;
96class BaseInterface;
97class HierParams;
98class Bus;
99class PciConfigAll;
100
101/**
102 * NS DP83820 Ethernet device model
103 */
104class NSGigE : public PciDev
105{
106  public:
107    /** Transmit State Machine states */
108    enum TxState
109    {
110        txIdle,
111        txDescRefr,
112        txDescRead,
113        txFifoBlock,
114        txFragRead,
115        txDescWrite,
116        txAdvance
117    };
118
119    /** Receive State Machine States */
120    enum RxState
121    {
122        rxIdle,
123        rxDescRefr,
124        rxDescRead,
125        rxFifoBlock,
126        rxFragWrite,
127        rxDescWrite,
128        rxAdvance
129    };
130
131    enum DmaState
132    {
133        dmaIdle,
134        dmaReading,
135        dmaWriting,
136        dmaReadWaiting,
137        dmaWriteWaiting
138    };
139
140  private:
141    Addr addr;
142    static const Addr size = sizeof(dp_regs);
143
144  protected:
145    typedef std::deque<PacketPtr> pktbuf_t;
146    typedef pktbuf_t::iterator pktiter_t;
147
148    /** device register file */
149    dp_regs regs;
150    dp_rom rom;
151
152    /** pci settings */
153    bool ioEnable;
154#if 0
155    bool memEnable;
156    bool bmEnable;
157#endif
158
159    /*** BASIC STRUCTURES FOR TX/RX ***/
160    /* Data FIFOs */
161    PacketFifo txFifo;
162    PacketFifo rxFifo;
163
164    /** various helper vars */
165    PacketPtr txPacket;
166    PacketPtr rxPacket;
167    uint8_t *txPacketBufPtr;
168    uint8_t *rxPacketBufPtr;
169    uint32_t txXferLen;
170    uint32_t rxXferLen;
171    bool rxDmaFree;
172    bool txDmaFree;
173
174    /** DescCaches */
175    ns_desc txDescCache;
176    ns_desc rxDescCache;
177
178    /* state machine cycle time */
179    Tick clock;
180    inline Tick cycles(int numCycles) const { return numCycles * clock; }
181
182    /* tx State Machine */
183    TxState txState;
184    bool txEnable;
185
186    /** Current Transmit Descriptor Done */
187    bool CTDD;
188    /** halt the tx state machine after next packet */
189    bool txHalt;
190    /** ptr to the next byte in the current fragment */
191    Addr txFragPtr;
192    /** count of bytes remaining in the current descriptor */
193    uint32_t txDescCnt;
194    DmaState txDmaState;
195
196    /** rx State Machine */
197    RxState rxState;
198    bool rxEnable;
199
200    /** Current Receive Descriptor Done */
201    bool CRDD;
202    /** num of bytes in the current packet being drained from rxDataFifo */
203    uint32_t rxPktBytes;
204    /** halt the rx state machine after current packet */
205    bool rxHalt;
206    /** ptr to the next byte in current fragment */
207    Addr rxFragPtr;
208    /** count of bytes remaining in the current descriptor */
209    uint32_t rxDescCnt;
210    DmaState rxDmaState;
211
212    bool extstsEnable;
213
214  protected:
215    Tick dmaReadDelay;
216    Tick dmaWriteDelay;
217
218    Tick dmaReadFactor;
219    Tick dmaWriteFactor;
220
221    void *rxDmaData;
222    Addr  rxDmaAddr;
223    int   rxDmaLen;
224    bool  doRxDmaRead();
225    bool  doRxDmaWrite();
226    void  rxDmaReadCopy();
227    void  rxDmaWriteCopy();
228
229    void *txDmaData;
230    Addr  txDmaAddr;
231    int   txDmaLen;
232    bool  doTxDmaRead();
233    bool  doTxDmaWrite();
234    void  txDmaReadCopy();
235    void  txDmaWriteCopy();
236
237    void rxDmaReadDone();
238    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
239    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
240
241    void rxDmaWriteDone();
242    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
243    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
244
245    void txDmaReadDone();
246    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
247    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
248
249    void txDmaWriteDone();
250    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
251    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
252
253    bool dmaDescFree;
254    bool dmaDataFree;
255
256
257  protected:
258    Tick txDelay;
259    Tick rxDelay;
260
261    void txReset();
262    void rxReset();
263    void regsReset();
264
265    void rxKick();
266    Tick rxKickTick;
267    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
268    friend void RxKickEvent::process();
269    RxKickEvent rxKickEvent;
270
271    void txKick();
272    Tick txKickTick;
273    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
274    friend void TxKickEvent::process();
275    TxKickEvent txKickEvent;
276
277    /**
278     * Retransmit event
279     */
280    void transmit();
281    void txEventTransmit()
282    {
283        transmit();
284        if (txState == txFifoBlock)
285            txKick();
286    }
287    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
288    friend void TxEvent::process();
289    TxEvent txEvent;
290
291    void txDump() const;
292    void rxDump() const;
293
294    /**
295     * receive address filter
296     */
297    bool rxFilterEnable;
298    bool rxFilter(const PacketPtr &packet);
299    bool acceptBroadcast;
300    bool acceptMulticast;
301    bool acceptUnicast;
302    bool acceptPerfect;
303    bool acceptArp;
304
305    PhysicalMemory *physmem;
306
307    /**
308     * Interrupt management
309     */
310    void devIntrPost(uint32_t interrupts);
311    void devIntrClear(uint32_t interrupts);
312    void devIntrChangeMask();
313
314    Tick intrDelay;
315    Tick intrTick;
316    bool cpuPendingIntr;
317    void cpuIntrPost(Tick when);
318    void cpuInterrupt();
319    void cpuIntrClear();
320
321    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
322    friend void IntrEvent::process();
323    IntrEvent *intrEvent;
324    NSGigEInt *interface;
325
326  public:
327    struct Params : public PciDev::Params
328    {
329        PhysicalMemory *pmem;
330        HierParams *hier;
331        Bus *header_bus;
332        Bus *payload_bus;
333        Tick clock;
334        Tick intr_delay;
335        Tick tx_delay;
336        Tick rx_delay;
337        Tick pio_latency;
338        bool dma_desc_free;
339        bool dma_data_free;
340        Tick dma_read_delay;
341        Tick dma_write_delay;
342        Tick dma_read_factor;
343        Tick dma_write_factor;
344        bool rx_filter;
345        Net::EthAddr eaddr;
346        uint32_t tx_fifo_size;
347        uint32_t rx_fifo_size;
348        uint32_t m5reg;
349        bool dma_no_allocate;
350    };
351
352    NSGigE(Params *params);
353    ~NSGigE();
354    const Params *params() const { return (const Params *)_params; }
355
356    virtual void writeConfig(int offset, int size, const uint8_t *data);
357    virtual void readConfig(int offset, int size, uint8_t *data);
358
359    virtual Fault read(MemReqPtr &req, uint8_t *data);
360    virtual Fault write(MemReqPtr &req, const uint8_t *data);
361
362    bool cpuIntrPending() const;
363    void cpuIntrAck() { cpuIntrClear(); }
364
365    bool recvPacket(PacketPtr packet);
366    void transferDone();
367
368    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
369
370    virtual void serialize(std::ostream &os);
371    virtual void unserialize(Checkpoint *cp, const std::string &section);
372
373  public:
374    void regStats();
375
376  private:
377    Stats::Scalar<> txBytes;
378    Stats::Scalar<> rxBytes;
379    Stats::Scalar<> txPackets;
380    Stats::Scalar<> rxPackets;
381    Stats::Scalar<> txIpChecksums;
382    Stats::Scalar<> rxIpChecksums;
383    Stats::Scalar<> txTcpChecksums;
384    Stats::Scalar<> rxTcpChecksums;
385    Stats::Scalar<> txUdpChecksums;
386    Stats::Scalar<> rxUdpChecksums;
387    Stats::Scalar<> descDmaReads;
388    Stats::Scalar<> descDmaWrites;
389    Stats::Scalar<> descDmaRdBytes;
390    Stats::Scalar<> descDmaWrBytes;
391    Stats::Formula totBandwidth;
392    Stats::Formula totPackets;
393    Stats::Formula totBytes;
394    Stats::Formula totPacketRate;
395    Stats::Formula txBandwidth;
396    Stats::Formula rxBandwidth;
397    Stats::Formula txPacketRate;
398    Stats::Formula rxPacketRate;
399    Stats::Scalar<> postedSwi;
400    Stats::Formula coalescedSwi;
401    Stats::Scalar<> totalSwi;
402    Stats::Scalar<> postedRxIdle;
403    Stats::Formula coalescedRxIdle;
404    Stats::Scalar<> totalRxIdle;
405    Stats::Scalar<> postedRxOk;
406    Stats::Formula coalescedRxOk;
407    Stats::Scalar<> totalRxOk;
408    Stats::Scalar<> postedRxDesc;
409    Stats::Formula coalescedRxDesc;
410    Stats::Scalar<> totalRxDesc;
411    Stats::Scalar<> postedTxOk;
412    Stats::Formula coalescedTxOk;
413    Stats::Scalar<> totalTxOk;
414    Stats::Scalar<> postedTxIdle;
415    Stats::Formula coalescedTxIdle;
416    Stats::Scalar<> totalTxIdle;
417    Stats::Scalar<> postedTxDesc;
418    Stats::Formula coalescedTxDesc;
419    Stats::Scalar<> totalTxDesc;
420    Stats::Scalar<> postedRxOrn;
421    Stats::Formula coalescedRxOrn;
422    Stats::Scalar<> totalRxOrn;
423    Stats::Formula coalescedTotal;
424    Stats::Scalar<> postedInterrupts;
425    Stats::Scalar<> droppedPackets;
426
427  public:
428    Tick cacheAccess(MemReqPtr &req);
429};
430
431/*
432 * Ethernet Interface for an Ethernet Device
433 */
434class NSGigEInt : public EtherInt
435{
436  private:
437    NSGigE *dev;
438
439  public:
440    NSGigEInt(const std::string &name, NSGigE *d)
441        : EtherInt(name), dev(d) { dev->setInterface(this); }
442
443    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
444    virtual void sendDone() { dev->transferDone(); }
445};
446
447#endif // __DEV_NS_GIGE_HH__
448