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