ns_gige.hh revision 1023
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/range.hh"
38#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//these are now params for the device
50//#define MAX_TX_FIFO_SIZE 8192
51//#define MAX_RX_FIFO_SIZE 32768
52
53/** length of ethernet address in bytes */
54#define EADDR_LEN 6
55
56/**
57 * Ethernet device registers
58 */
59struct dp_regs {
60    uint32_t	command;
61    uint32_t	config;
62    uint32_t	mear;
63    uint32_t	ptscr;
64    uint32_t    isr;
65    uint32_t    imr;
66    uint32_t    ier;
67    uint32_t    ihr;
68    uint32_t    txdp;
69    uint32_t    txdp_hi;
70    uint32_t    txcfg;
71    uint32_t    gpior;
72    uint32_t    rxdp;
73    uint32_t    rxdp_hi;
74    uint32_t    rxcfg;
75    uint32_t    pqcr;
76    uint32_t    wcsr;
77    uint32_t    pcr;
78    uint32_t    rfcr;
79    uint32_t    rfdr;
80    uint32_t    srr;
81    uint32_t    mibc;
82    uint32_t    vrcr;
83    uint32_t    vtcr;
84    uint32_t    vdr;
85    uint32_t    ccsr;
86    uint32_t    tbicr;
87    uint32_t    tbisr;
88    uint32_t    tanar;
89    uint32_t    tanlpar;
90    uint32_t    taner;
91    uint32_t    tesr;
92};
93
94struct dp_rom {
95    /** for perfect match memory.  the linux driver doesn't use any other ROM */
96    uint8_t perfectMatch[EADDR_LEN];
97};
98
99class IntrControl;
100class NSGigEInt;
101class PhysicalMemory;
102class BaseInterface;
103class HierParams;
104class Bus;
105class PciConfigAll;
106
107/**
108 * NS DP82830 Ethernet device model
109 */
110class NSGigE : public PciDev
111{
112  public:
113    /** Transmit State Machine states */
114    enum TxState
115    {
116        txIdle,
117        txDescRefr,
118        txDescRead,
119        txFifoBlock,
120        txFragRead,
121        txDescWrite,
122        txAdvance
123    };
124
125    /** Receive State Machine States */
126    enum RxState
127    {
128        rxIdle,
129        rxDescRefr,
130        rxDescRead,
131        rxFifoBlock,
132        rxFragWrite,
133        rxDescWrite,
134        rxAdvance
135    };
136
137    enum DmaState
138    {
139        dmaIdle,
140        dmaReading,
141        dmaWriting,
142        dmaReadWaiting,
143        dmaWriteWaiting
144    };
145
146  private:
147    /** pointer to the chipset */
148    Tsunami *tsunami;
149
150  private:
151    Addr addr;
152    static const Addr size = sizeof(dp_regs);
153
154  protected:
155    typedef std::deque<PacketPtr> pktbuf_t;
156    typedef pktbuf_t::iterator pktiter_t;
157
158    /** device register file */
159    dp_regs regs;
160    dp_rom rom;
161
162    /** pci settings */
163    bool ioEnable;
164#if 0
165    bool memEnable;
166    bool bmEnable;
167#endif
168
169    /*** BASIC STRUCTURES FOR TX/RX ***/
170    /* Data FIFOs */
171    pktbuf_t txFifo;
172    uint32_t maxTxFifoSize;
173    pktbuf_t rxFifo;
174    uint32_t maxRxFifoSize;
175
176    /** various helper vars */
177    PacketPtr txPacket;
178    PacketPtr rxPacket;
179    uint8_t *txPacketBufPtr;
180    uint8_t *rxPacketBufPtr;
181    uint32_t txXferLen;
182    uint32_t rxXferLen;
183    bool rxDmaFree;
184    bool txDmaFree;
185
186    /** DescCaches */
187    ns_desc txDescCache;
188    ns_desc rxDescCache;
189
190    /* tx State Machine */
191    TxState txState;
192    /** Current Transmit Descriptor Done */
193    bool CTDD;
194    /** current amt of free space in txDataFifo in bytes */
195    uint32_t txFifoAvail;
196    /** halt the tx state machine after next packet */
197    bool txHalt;
198    /** ptr to the next byte in the current fragment */
199    Addr txFragPtr;
200    /** count of bytes remaining in the current descriptor */
201    uint32_t txDescCnt;
202    DmaState txDmaState;
203
204    /** rx State Machine */
205    RxState rxState;
206    /** Current Receive Descriptor Done */
207    bool CRDD;
208    /** num of bytes in the current packet being drained from rxDataFifo */
209    uint32_t rxPktBytes;
210    /** number of bytes in the rxFifo */
211    uint32_t rxFifoCnt;
212    /** halt the rx state machine after current packet */
213    bool rxHalt;
214    /** ptr to the next byte in current fragment */
215    Addr rxFragPtr;
216    /** count of bytes remaining in the current descriptor */
217    uint32_t rxDescCnt;
218    DmaState rxDmaState;
219
220    bool extstsEnable;
221
222  protected:
223    Tick dmaReadDelay;
224    Tick dmaWriteDelay;
225
226    Tick dmaReadFactor;
227    Tick dmaWriteFactor;
228
229    void *rxDmaData;
230    Addr  rxDmaAddr;
231    int   rxDmaLen;
232    bool  doRxDmaRead();
233    bool  doRxDmaWrite();
234    void  rxDmaReadCopy();
235    void  rxDmaWriteCopy();
236
237    void *txDmaData;
238    Addr  txDmaAddr;
239    int   txDmaLen;
240    bool  doTxDmaRead();
241    bool  doTxDmaWrite();
242    void  txDmaReadCopy();
243    void  txDmaWriteCopy();
244
245    void rxDmaReadDone();
246    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
247    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
248
249    void rxDmaWriteDone();
250    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
251    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
252
253    void txDmaReadDone();
254    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
255    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
256
257    void txDmaWriteDone();
258    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
259    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
260
261    bool dmaDescFree;
262    bool dmaDataFree;
263
264
265  protected:
266    Tick txDelay;
267    Tick rxDelay;
268
269    void txReset();
270    void rxReset();
271    void regsReset();
272
273    void rxKick();
274    Tick rxKickTick;
275    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
276    friend class RxKickEvent;
277
278    void txKick();
279    Tick txKickTick;
280    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
281    friend class TxKickEvent;
282
283    /**
284     * Retransmit event
285     */
286    void transmit();
287    void txEventTransmit()
288    {
289        transmit();
290        if (txState == txFifoBlock)
291            txKick();
292    }
293    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
294    friend class TxEvent;
295    TxEvent txEvent;
296
297    void txDump() const;
298    void rxDump() const;
299
300    /**
301     * receive address filter
302     */
303    bool rxFilterEnable;
304    bool rxFilter(PacketPtr packet);
305    bool acceptBroadcast;
306    bool acceptMulticast;
307    bool acceptUnicast;
308    bool acceptPerfect;
309    bool acceptArp;
310
311    PhysicalMemory *physmem;
312
313    /**
314     * Interrupt management
315     */
316    IntrControl *intctrl;
317    void devIntrPost(uint32_t interrupts);
318    void devIntrClear(uint32_t interrupts);
319    void devIntrChangeMask();
320
321    Tick intrDelay;
322    Tick intrTick;
323    bool cpuPendingIntr;
324    void cpuIntrPost(Tick when);
325    void cpuInterrupt();
326    void cpuIntrClear();
327
328    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
329    friend class IntrEvent;
330    IntrEvent *intrEvent;
331
332    /**
333     * Hardware checksum support
334     */
335    bool udpChecksum(PacketPtr packet, bool gen);
336    bool tcpChecksum(PacketPtr packet, bool gen);
337    bool ipChecksum(PacketPtr packet, bool gen);
338    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
339
340    NSGigEInt *interface;
341
342  public:
343    NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
344           PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
345           MemoryController *mmu, HierParams *hier, Bus *header_bus,
346           Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
347           bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
348           Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
349           PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
350           uint32_t func, bool rx_filter, const int eaddr[6],
351           uint32_t tx_fifo_size, uint32_t rx_fifo_size);
352    ~NSGigE();
353
354    virtual void WriteConfig(int offset, int size, uint32_t data);
355    virtual void ReadConfig(int offset, int size, uint8_t *data);
356
357    virtual Fault read(MemReqPtr &req, uint8_t *data);
358    virtual Fault write(MemReqPtr &req, const uint8_t *data);
359
360    bool cpuIntrPending() const;
361    void cpuIntrAck() { cpuIntrClear(); }
362
363    bool recvPacket(PacketPtr packet);
364    void transferDone();
365
366    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
367
368    virtual void serialize(std::ostream &os);
369    virtual void unserialize(Checkpoint *cp, const std::string &section);
370
371  public:
372    void regStats();
373
374  private:
375    Stats::Scalar<> txBytes;
376    Stats::Scalar<> rxBytes;
377    Stats::Scalar<> txPackets;
378    Stats::Scalar<> rxPackets;
379    Stats::Scalar<> txIPChecksums;
380    Stats::Scalar<> rxIPChecksums;
381    Stats::Scalar<> txTCPChecksums;
382    Stats::Scalar<> rxTCPChecksums;
383    Stats::Scalar<> descDmaReads;
384    Stats::Scalar<> descDmaWrites;
385    Stats::Scalar<> descDmaRdBytes;
386    Stats::Scalar<> descDmaWrBytes;
387    Stats::Formula txBandwidth;
388    Stats::Formula rxBandwidth;
389    Stats::Formula txPacketRate;
390    Stats::Formula rxPacketRate;
391
392  public:
393    Tick cacheAccess(MemReqPtr &req);
394};
395
396/*
397 * Ethernet Interface for an Ethernet Device
398 */
399class NSGigEInt : public EtherInt
400{
401  private:
402    NSGigE *dev;
403
404  public:
405    NSGigEInt(const std::string &name, NSGigE *d)
406        : EtherInt(name), dev(d) { dev->setInterface(this); }
407
408    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
409    virtual void sendDone() { dev->transferDone(); }
410};
411
412#endif // __NS_GIGE_HH__
413