ns_gige.hh revision 837
1/*
2 * Copyright (c) 2003 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 "dev/dma.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/pciconfigall.hh"
46
47/** defined by the NS83820 data sheet */
48#define MAX_TX_FIFO_SIZE 8192
49#define MAX_RX_FIFO_SIZE 32768
50
51/** length of ethernet address in bytes */
52#define EADDR_LEN 6
53
54/** Transmit State Machine states */
55enum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead,
56               txDescWrite };
57
58/** Receive State Machine States */
59enum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite,
60                rxDescWrite, rxAdvance };
61
62/**
63 * Ethernet device registers
64 */
65struct dp_regs {
66    uint32_t	command;
67    uint32_t	config;
68    uint32_t	mear;
69    uint32_t	ptscr;
70    uint32_t    isr;
71    uint32_t    imr;
72    uint32_t    ier;
73    uint32_t    ihr;
74    uint32_t    txdp;
75    uint32_t    txdp_hi;
76    uint32_t    txcfg;
77    uint32_t    gpior;
78    uint32_t    rxdp;
79    uint32_t    rxdp_hi;
80    uint32_t    rxcfg;
81    uint32_t    pqcr;
82    uint32_t    wcsr;
83    uint32_t    pcr;
84    uint32_t    rfcr;
85    uint32_t    rfdr;
86    uint32_t    srr;
87    uint32_t    mibc;
88    uint32_t    vrcr;
89    uint32_t    vtcr;
90    uint32_t    vdr;
91    uint32_t    ccsr;
92    uint32_t    tbicr;
93    uint32_t    tbisr;
94    uint32_t    tanar;
95    uint32_t    tanlpar;
96    uint32_t    taner;
97    uint32_t    tesr;
98
99    /** for perfect match memory.  the linux driver doesn't use any other ROM */
100    uint8_t perfectMatch[EADDR_LEN];
101
102    virtual void serialize(std::ostream &os);
103    virtual void unserialize(Checkpoint *cp, const std::string &section);
104};
105
106/** an enum indicating direction, transmit or receive, used as a param for
107    some fns */
108enum dir_t { tx, rx };
109
110class DmaEngine;
111class IntrControl;
112class EtherDevInt;
113class PhysicalMemory;
114
115/**
116 * NS DP82830 Ethernet device model
117 */
118class EtherDev : public PciDev, public DmaHolder
119{
120  private:
121    /** pointer to the chipset */
122    Tsunami *tsunami;
123
124  protected:
125    Addr addr;
126    Addr mask;
127
128    /** device register file */
129    dp_regs regs;
130
131     /*** BASIC STRUCTURES FOR TX/RX ***/
132    /* Data FIFOs */
133    typedef std::deque<PacketPtr> pktbuf_t;
134    typedef pktbuf_t::iterator pktiter_t;
135    pktbuf_t txFifo;
136    pktbuf_t rxFifo;
137
138    /** for the tx side, to track addrs to write updated cmdsts to */
139    typedef std::deque<uint32_t> txdpbuf_t; /* ASSUME32 */
140    txdpbuf_t descAddrFifo;
141
142    /** various helper vars */
143    uint32_t txPacketLen;
144    uint8_t *txPacketBufPtr;
145    uint8_t *rxPacketBufPtr;
146    uint8_t *rxDescBufPtr;
147    uint32_t fragLen;
148    uint32_t rxCopied;
149
150    /** DescCaches */
151    ns_desc txDescCache;
152    ns_desc rxDescCache;
153
154    /* tx State Machine */
155    tx_state txState;
156    /** Current Transmit Descriptor Done */
157    bool CTDD;
158    uint32_t txFifoCnt; /* amt of data in the txDataFifo in bytes (logical) */
159    uint32_t txFifoAvail; /* current amt of free space in txDataFifo in byes */
160    bool txHalt;
161    bool txPacketFlag;  /* when set, indicates not working on a new packet */
162    Addr txFragPtr; /* ptr to the next byte in the current fragment */
163    uint32_t txDescCnt; /* count of bytes remaining in the current descriptor */
164
165    /** rx State Machine */
166    rx_state rxState;
167    bool CRDD; /* Current Receive Descriptor Done */
168    uint32_t rxPktBytes; /* num of bytes in the current packet being drained
169                            from rxDataFifo */
170    uint32_t rxFifoCnt; /* number of bytes in the rxFifo */
171    bool rxHalt;
172    bool rxPacketFlag;  /* when set, indicates not working on a new packet */
173    Addr rxFragPtr; /* ptr to the next byte in current fragment */
174    uint32_t rxDescCnt; /* count of bytes remaining in the current descriptor */
175
176    bool extstsEnable;
177    uint32_t maxTxBurst;
178    uint32_t maxRxBurst;
179
180    PhysicalMemory *physmem;
181
182  protected:
183    /**
184     * Receive dma for descriptors done callback
185     */
186    class RxDescDone : public DmaCallback
187    {
188      public:
189        EtherDev *ethernet;
190
191      public:
192        RxDescDone(EtherDev *e);
193        std::string name() const;
194        virtual void process();
195    };
196
197    /**
198     * Receive dma done callback
199     */
200    class RxDone : public DmaCallback
201    {
202      public:
203        EtherDev *ethernet;
204
205      public:
206        RxDone(EtherDev *e);
207        std::string name() const;
208        virtual void process();
209    };
210
211    /**
212     * Transmit dma for descriptors done callback
213     */
214    class TxDescDone : public DmaCallback
215    {
216      public:
217        EtherDev *ethernet;
218
219      public:
220        TxDescDone(EtherDev *e);
221        std::string name() const;
222        virtual void process();
223    };
224
225    /*
226     * Transmit dma done callback
227     */
228    class TxDone : public DmaCallback
229    {
230      public:
231        EtherDev *ethernet;
232        PacketPtr packet;
233
234      public:
235        TxDone(EtherDev *e);
236        std::string name() const;
237        virtual void process();
238    };
239
240    friend class TxDescDone;
241    friend class TxDone;
242    friend class RxDescDone;
243    friend class RxDone;
244
245    RxDescDone rxDescDoneCB;
246    RxDone rxDoneCB;
247    TxDescDone txDescDoneCB;
248    TxDone txDoneCB;
249
250    DmaEngine *dma;
251    DmaRequest readRequest;
252    DmaRequest writeRequest;
253    DmaRequest readDescRequest;
254    DmaRequest writeDescRequest;
255    PacketPtr rxPacket;
256    DmaPhys readPhys;
257    DmaPhys writePhys;
258    DmaPhys readDescPhys;
259    DmaPhys writeDescPhys;
260
261    EtherDevInt *interface;
262
263  protected:
264    IntrControl *intctrl;
265    Tick txDelay;
266    Tick rxDelay;
267
268    void txReset();
269    void rxReset();
270    void regsReset() {
271        memset(&regs, 0, sizeof(regs));
272        regs.mear = 0x12;
273        regs.isr = 0x00608000;
274        regs.txcfg = 0x120;
275        regs.rxcfg = 0x4;
276        regs.srr = 0x0103;
277        regs.mibc = 0x2;
278        regs.vdr = 0x81;
279        regs.tesr = 0xc000;
280    }
281
282    void txKick();
283    void rxKick();
284
285    /*
286     * Retransmit event
287     */
288    class TxEvent : public Event
289    {
290      protected:
291        EtherDev *dev;
292
293      public:
294        TxEvent(EtherDev *_dev)
295            : Event(&mainEventQueue), dev(_dev) {}
296        void process() { dev->transmit(); }
297        virtual const char *description() { return "retransmit"; }
298    };
299    friend class TxEvent;
300    TxEvent txEvent;
301    void transmit();
302
303
304    void txDescDone();
305    void rxDescDone();
306    void txDone(PacketPtr packet);
307    void rxDone();
308
309    void txDump() const;
310    void rxDump() const;
311
312    void devIntrPost(uint32_t interrupts);
313    void devIntrClear(uint32_t interrupts);
314    void devIntrChangeMask();
315
316    bool cpuPendingIntr;
317    void cpuIntrPost();
318    void cpuIntrClear();
319
320    bool rxFilterEnable;
321    bool rxFilter(PacketPtr packet);
322    bool acceptBroadcast;
323    bool acceptMulticast;
324    bool acceptUnicast;
325    bool acceptPerfect;
326    bool acceptArp;
327
328    bool udpChecksum(PacketPtr packet, bool gen);
329    bool tcpChecksum(PacketPtr packet, bool gen);
330    bool ipChecksum(PacketPtr packet, bool gen);
331    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
332
333  public:
334    EtherDev(const std::string &name, DmaEngine *de, bool use_interface,
335             IntrControl *i, MemoryController *mmu, PhysicalMemory *pmem,
336             PCIConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus,
337             uint32_t dev, uint32_t func, bool rx_filter, const int eaddr[6],
338             Tick tx_delay, Tick rx_delay, Addr addr, Addr mask);
339    ~EtherDev();
340
341    virtual void WriteConfig(int offset, int size, uint32_t data);
342    virtual void ReadConfig(int offset, int size, uint8_t *data);
343
344
345
346    Fault read(MemReqPtr req, uint8_t *data);
347    Fault write(MemReqPtr req, const uint8_t *data);
348
349    bool cpuIntrPending() const;
350    void cpuIntrAck() { cpuIntrClear(); }
351
352    bool recvPacket(PacketPtr packet);
353    void transferDone();
354
355    void setInterface(EtherDevInt *i) { assert(!interface); interface = i; }
356
357    virtual void serialize(std::ostream &os);
358    virtual void unserialize(Checkpoint *cp, const std::string &section);
359
360    virtual DmaRequest *find_dmareq(uint32_t &id) {
361        if (id == 0)
362            return(&readRequest);
363        else if (id == 1)
364            return(&writeRequest);
365        else
366            return(NULL);
367    }
368
369  public:
370    void regStats();
371
372  private:
373    Statistics::Scalar<> txBytes;
374    Statistics::Scalar<> rxBytes;
375    Statistics::Scalar<> txPackets;
376    Statistics::Scalar<> rxPackets;
377    Statistics::Formula txBandwidth;
378    Statistics::Formula rxBandwidth;
379    Statistics::Formula txPacketRate;
380    Statistics::Formula rxPacketRate;
381
382    void readOneDesc(dir_t dir, uint32_t len = sizeof(ns_desc));
383    void readOneFrag();
384    void writeOneFrag();
385};
386
387/*
388 * Ethernet Interface for an Ethernet Device
389 */
390class EtherDevInt : public EtherInt
391{
392  private:
393    EtherDev *dev;
394
395  public:
396    EtherDevInt(const std::string &name, EtherDev *d)
397        : EtherInt(name), dev(d) { dev->setInterface(this); }
398
399    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
400    virtual void sendDone() { dev->transferDone(); }
401};
402
403#endif // __NS_GIGE_HH__
404