ns_gige.hh revision 1035
1/*
2 * Copyright (c) 2004 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 __NS_GIGE_HH__
35#define __NS_GIGE_HH__
36
37#include "base/statistics.hh"
38#include "dev/etherint.hh"
39#include "dev/etherpkt.hh"
40#include "dev/io_device.hh"
41#include "dev/ns_gige_reg.h"
42#include "dev/pcidev.hh"
43#include "dev/tsunami.hh"
44#include "mem/bus/bus.hh"
45#include "sim/eventq.hh"
46
47/** length of ethernet address in bytes */
48#define EADDR_LEN 6
49
50/**
51 * Ethernet device registers
52 */
53struct dp_regs {
54    uint32_t	command;
55    uint32_t	config;
56    uint32_t	mear;
57    uint32_t	ptscr;
58    uint32_t    isr;
59    uint32_t    imr;
60    uint32_t    ier;
61    uint32_t    ihr;
62    uint32_t    txdp;
63    uint32_t    txdp_hi;
64    uint32_t    txcfg;
65    uint32_t    gpior;
66    uint32_t    rxdp;
67    uint32_t    rxdp_hi;
68    uint32_t    rxcfg;
69    uint32_t    pqcr;
70    uint32_t    wcsr;
71    uint32_t    pcr;
72    uint32_t    rfcr;
73    uint32_t    rfdr;
74    uint32_t    srr;
75    uint32_t    mibc;
76    uint32_t    vrcr;
77    uint32_t    vtcr;
78    uint32_t    vdr;
79    uint32_t    ccsr;
80    uint32_t    tbicr;
81    uint32_t    tbisr;
82    uint32_t    tanar;
83    uint32_t    tanlpar;
84    uint32_t    taner;
85    uint32_t    tesr;
86};
87
88struct dp_rom {
89    /**
90     * for perfect match memory.
91     * the linux driver doesn't use any other ROM
92     */
93    uint8_t perfectMatch[EADDR_LEN];
94};
95
96class IntrControl;
97class NSGigEInt;
98class PhysicalMemory;
99class BaseInterface;
100class HierParams;
101class Bus;
102class PciConfigAll;
103
104/**
105 * NS DP82830 Ethernet device model
106 */
107class NSGigE : public PciDev
108{
109  public:
110    /** Transmit State Machine states */
111    enum TxState
112    {
113        txIdle,
114        txDescRefr,
115        txDescRead,
116        txFifoBlock,
117        txFragRead,
118        txDescWrite,
119        txAdvance
120    };
121
122    /** Receive State Machine States */
123    enum RxState
124    {
125        rxIdle,
126        rxDescRefr,
127        rxDescRead,
128        rxFifoBlock,
129        rxFragWrite,
130        rxDescWrite,
131        rxAdvance
132    };
133
134    enum DmaState
135    {
136        dmaIdle,
137        dmaReading,
138        dmaWriting,
139        dmaReadWaiting,
140        dmaWriteWaiting
141    };
142
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