ns_gige.hh revision 2566
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 "sim/eventq.hh"
46
47// Hash filtering constants
48const uint16_t FHASH_ADDR  = 0x100;
49const uint16_t FHASH_SIZE  = 0x100;
50
51// EEPROM constants
52const uint8_t  EEPROM_READ = 0x2;
53const uint8_t  EEPROM_SIZE = 64; // Size in words of NSC93C46 EEPROM
54const uint8_t  EEPROM_PMATCH2_ADDR = 0xA; // EEPROM Address of PMATCH word 2
55const uint8_t  EEPROM_PMATCH1_ADDR = 0xB; // EEPROM Address of PMATCH word 1
56const uint8_t  EEPROM_PMATCH0_ADDR = 0xC; // EEPROM Address of PMATCH word 0
57
58/**
59 * Ethernet device registers
60 */
61struct dp_regs {
62    uint32_t	command;
63    uint32_t	config;
64    uint32_t	mear;
65    uint32_t	ptscr;
66    uint32_t    isr;
67    uint32_t    imr;
68    uint32_t    ier;
69    uint32_t    ihr;
70    uint32_t    txdp;
71    uint32_t    txdp_hi;
72    uint32_t    txcfg;
73    uint32_t    gpior;
74    uint32_t    rxdp;
75    uint32_t    rxdp_hi;
76    uint32_t    rxcfg;
77    uint32_t    pqcr;
78    uint32_t    wcsr;
79    uint32_t    pcr;
80    uint32_t    rfcr;
81    uint32_t    rfdr;
82    uint32_t    brar;
83    uint32_t    brdr;
84    uint32_t    srr;
85    uint32_t    mibc;
86    uint32_t    vrcr;
87    uint32_t    vtcr;
88    uint32_t    vdr;
89    uint32_t    ccsr;
90    uint32_t    tbicr;
91    uint32_t    tbisr;
92    uint32_t    tanar;
93    uint32_t    tanlpar;
94    uint32_t    taner;
95    uint32_t    tesr;
96};
97
98struct dp_rom {
99    /**
100     * for perfect match memory.
101     * the linux driver doesn't use any other ROM
102     */
103    uint8_t perfectMatch[ETH_ADDR_LEN];
104
105    /**
106     * for hash table memory.
107     * used by the freebsd driver
108     */
109    uint8_t filterHash[FHASH_SIZE];
110};
111
112class NSGigEInt;
113class Packet;
114class PciConfigAll;
115
116/**
117 * NS DP83820 Ethernet device model
118 */
119class NSGigE : public PciDev
120{
121  public:
122    /** Transmit State Machine states */
123    enum TxState
124    {
125        txIdle,
126        txDescRefr,
127        txDescRead,
128        txFifoBlock,
129        txFragRead,
130        txDescWrite,
131        txAdvance
132    };
133
134    /** Receive State Machine States */
135    enum RxState
136    {
137        rxIdle,
138        rxDescRefr,
139        rxDescRead,
140        rxFifoBlock,
141        rxFragWrite,
142        rxDescWrite,
143        rxAdvance
144    };
145
146    enum DmaState
147    {
148        dmaIdle,
149        dmaReading,
150        dmaWriting,
151        dmaReadWaiting,
152        dmaWriteWaiting
153    };
154
155    /** EEPROM State Machine States */
156    enum EEPROMState
157    {
158        eepromStart,
159        eepromGetOpcode,
160        eepromGetAddress,
161        eepromRead
162    };
163
164  protected:
165    /** device register file */
166    dp_regs regs;
167    dp_rom rom;
168
169    /** pci settings */
170    bool ioEnable;
171#if 0
172    bool memEnable;
173    bool bmEnable;
174#endif
175
176    /*** BASIC STRUCTURES FOR TX/RX ***/
177    /* Data FIFOs */
178    PacketFifo txFifo;
179    PacketFifo rxFifo;
180
181    /** various helper vars */
182    EthPacketPtr txPacket;
183    EthPacketPtr rxPacket;
184    uint8_t *txPacketBufPtr;
185    uint8_t *rxPacketBufPtr;
186    uint32_t txXferLen;
187    uint32_t rxXferLen;
188    bool rxDmaFree;
189    bool txDmaFree;
190
191    /** DescCaches */
192    ns_desc32 txDesc32;
193    ns_desc32 rxDesc32;
194    ns_desc64 txDesc64;
195    ns_desc64 rxDesc64;
196
197    /* state machine cycle time */
198    Tick clock;
199    inline Tick cycles(int numCycles) const { return numCycles * clock; }
200
201    /* tx State Machine */
202    TxState txState;
203    bool txEnable;
204
205    /** Current Transmit Descriptor Done */
206    bool CTDD;
207    /** halt the tx state machine after next packet */
208    bool txHalt;
209    /** ptr to the next byte in the current fragment */
210    Addr txFragPtr;
211    /** count of bytes remaining in the current descriptor */
212    uint32_t txDescCnt;
213    DmaState txDmaState;
214
215    /** rx State Machine */
216    RxState rxState;
217    bool rxEnable;
218
219    /** Current Receive Descriptor Done */
220    bool CRDD;
221    /** num of bytes in the current packet being drained from rxDataFifo */
222    uint32_t rxPktBytes;
223    /** halt the rx state machine after current packet */
224    bool rxHalt;
225    /** ptr to the next byte in current fragment */
226    Addr rxFragPtr;
227    /** count of bytes remaining in the current descriptor */
228    uint32_t rxDescCnt;
229    DmaState rxDmaState;
230
231    bool extstsEnable;
232
233    /** EEPROM State Machine */
234    EEPROMState eepromState;
235    bool eepromClk;
236    uint8_t eepromBitsToRx;
237    uint8_t eepromOpcode;
238    uint8_t eepromAddress;
239    uint16_t eepromData;
240
241  protected:
242    Tick dmaReadDelay;
243    Tick dmaWriteDelay;
244
245    Tick dmaReadFactor;
246    Tick dmaWriteFactor;
247
248    void *rxDmaData;
249    Addr  rxDmaAddr;
250    int   rxDmaLen;
251    bool  doRxDmaRead();
252    bool  doRxDmaWrite();
253
254    void *txDmaData;
255    Addr  txDmaAddr;
256    int   txDmaLen;
257    bool  doTxDmaRead();
258    bool  doTxDmaWrite();
259
260    void rxDmaReadDone();
261    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
262    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
263
264    void rxDmaWriteDone();
265    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
266    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
267
268    void txDmaReadDone();
269    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
270    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
271
272    void txDmaWriteDone();
273    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
274    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
275
276    bool dmaDescFree;
277    bool dmaDataFree;
278
279  protected:
280    Tick txDelay;
281    Tick rxDelay;
282
283    void txReset();
284    void rxReset();
285    void regsReset();
286
287    void rxKick();
288    Tick rxKickTick;
289    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
290    friend void RxKickEvent::process();
291    RxKickEvent rxKickEvent;
292
293    void txKick();
294    Tick txKickTick;
295    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
296    friend void TxKickEvent::process();
297    TxKickEvent txKickEvent;
298
299    void eepromKick();
300
301    /**
302     * Retransmit event
303     */
304    void transmit();
305    void txEventTransmit()
306    {
307        transmit();
308        if (txState == txFifoBlock)
309            txKick();
310    }
311    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
312    friend void TxEvent::process();
313    TxEvent txEvent;
314
315    void txDump() const;
316    void rxDump() const;
317
318    /**
319     * receive address filter
320     */
321    bool rxFilterEnable;
322    bool rxFilter(const EthPacketPtr &packet);
323    bool acceptBroadcast;
324    bool acceptMulticast;
325    bool acceptUnicast;
326    bool acceptPerfect;
327    bool acceptArp;
328    bool multicastHashEnable;
329
330    /**
331     * Interrupt management
332     */
333    void devIntrPost(uint32_t interrupts);
334    void devIntrClear(uint32_t interrupts);
335    void devIntrChangeMask();
336
337    Tick intrDelay;
338    Tick intrTick;
339    bool cpuPendingIntr;
340    void cpuIntrPost(Tick when);
341    void cpuInterrupt();
342    void cpuIntrClear();
343
344    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
345    friend void IntrEvent::process();
346    IntrEvent *intrEvent;
347    NSGigEInt *interface;
348
349  public:
350    struct Params : public PciDev::Params
351    {
352        Tick clock;
353        Tick intr_delay;
354        Tick tx_delay;
355        Tick rx_delay;
356        bool dma_desc_free;
357        bool dma_data_free;
358        Tick dma_read_delay;
359        Tick dma_write_delay;
360        Tick dma_read_factor;
361        Tick dma_write_factor;
362        bool rx_filter;
363        Net::EthAddr eaddr;
364        uint32_t tx_fifo_size;
365        uint32_t rx_fifo_size;
366        bool rx_thread;
367        bool tx_thread;
368        bool rss;
369        bool dma_no_allocate;
370    };
371
372    NSGigE(Params *params);
373    ~NSGigE();
374    const Params *params() const { return (const Params *)_params; }
375
376    virtual void writeConfig(int offset, const uint16_t data);
377
378    virtual Tick read(Packet &pkt);
379    virtual Tick write(Packet &pkt);
380
381    bool cpuIntrPending() const;
382    void cpuIntrAck() { cpuIntrClear(); }
383
384    bool recvPacket(EthPacketPtr packet);
385    void transferDone();
386
387    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
388
389    virtual void serialize(std::ostream &os);
390    virtual void unserialize(Checkpoint *cp, const std::string &section);
391
392  public:
393    void regStats();
394
395  private:
396    Stats::Scalar<> txBytes;
397    Stats::Scalar<> rxBytes;
398    Stats::Scalar<> txPackets;
399    Stats::Scalar<> rxPackets;
400    Stats::Scalar<> txIpChecksums;
401    Stats::Scalar<> rxIpChecksums;
402    Stats::Scalar<> txTcpChecksums;
403    Stats::Scalar<> rxTcpChecksums;
404    Stats::Scalar<> txUdpChecksums;
405    Stats::Scalar<> rxUdpChecksums;
406    Stats::Scalar<> descDmaReads;
407    Stats::Scalar<> descDmaWrites;
408    Stats::Scalar<> descDmaRdBytes;
409    Stats::Scalar<> descDmaWrBytes;
410    Stats::Formula totBandwidth;
411    Stats::Formula totPackets;
412    Stats::Formula totBytes;
413    Stats::Formula totPacketRate;
414    Stats::Formula txBandwidth;
415    Stats::Formula rxBandwidth;
416    Stats::Formula txPacketRate;
417    Stats::Formula rxPacketRate;
418    Stats::Scalar<> postedSwi;
419    Stats::Formula coalescedSwi;
420    Stats::Scalar<> totalSwi;
421    Stats::Scalar<> postedRxIdle;
422    Stats::Formula coalescedRxIdle;
423    Stats::Scalar<> totalRxIdle;
424    Stats::Scalar<> postedRxOk;
425    Stats::Formula coalescedRxOk;
426    Stats::Scalar<> totalRxOk;
427    Stats::Scalar<> postedRxDesc;
428    Stats::Formula coalescedRxDesc;
429    Stats::Scalar<> totalRxDesc;
430    Stats::Scalar<> postedTxOk;
431    Stats::Formula coalescedTxOk;
432    Stats::Scalar<> totalTxOk;
433    Stats::Scalar<> postedTxIdle;
434    Stats::Formula coalescedTxIdle;
435    Stats::Scalar<> totalTxIdle;
436    Stats::Scalar<> postedTxDesc;
437    Stats::Formula coalescedTxDesc;
438    Stats::Scalar<> totalTxDesc;
439    Stats::Scalar<> postedRxOrn;
440    Stats::Formula coalescedRxOrn;
441    Stats::Scalar<> totalRxOrn;
442    Stats::Formula coalescedTotal;
443    Stats::Scalar<> postedInterrupts;
444    Stats::Scalar<> droppedPackets;
445};
446
447/*
448 * Ethernet Interface for an Ethernet Device
449 */
450class NSGigEInt : public EtherInt
451{
452  private:
453    NSGigE *dev;
454
455  public:
456    NSGigEInt(const std::string &name, NSGigE *d)
457        : EtherInt(name), dev(d) { dev->setInterface(this); }
458
459    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
460    virtual void sendDone() { dev->transferDone(); }
461};
462
463#endif // __DEV_NS_GIGE_HH__
464