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