ns_gige.hh revision 1909
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_desc32 txDesc32;
204    ns_desc32 rxDesc32;
205    ns_desc64 txDesc64;
206    ns_desc64 rxDesc64;
207
208    /* state machine cycle time */
209    Tick clock;
210    inline Tick cycles(int numCycles) const { return numCycles * clock; }
211
212    /* tx State Machine */
213    TxState txState;
214    bool txEnable;
215
216    /** Current Transmit Descriptor Done */
217    bool CTDD;
218    /** halt the tx state machine after next packet */
219    bool txHalt;
220    /** ptr to the next byte in the current fragment */
221    Addr txFragPtr;
222    /** count of bytes remaining in the current descriptor */
223    uint32_t txDescCnt;
224    DmaState txDmaState;
225
226    /** rx State Machine */
227    RxState rxState;
228    bool rxEnable;
229
230    /** Current Receive Descriptor Done */
231    bool CRDD;
232    /** num of bytes in the current packet being drained from rxDataFifo */
233    uint32_t rxPktBytes;
234    /** halt the rx state machine after current packet */
235    bool rxHalt;
236    /** ptr to the next byte in current fragment */
237    Addr rxFragPtr;
238    /** count of bytes remaining in the current descriptor */
239    uint32_t rxDescCnt;
240    DmaState rxDmaState;
241
242    bool extstsEnable;
243
244    /** EEPROM State Machine */
245    EEPROMState eepromState;
246    bool eepromClk;
247    uint8_t eepromBitsToRx;
248    uint8_t eepromOpcode;
249    uint8_t eepromAddress;
250    uint16_t eepromData;
251
252  protected:
253    Tick dmaReadDelay;
254    Tick dmaWriteDelay;
255
256    Tick dmaReadFactor;
257    Tick dmaWriteFactor;
258
259    void *rxDmaData;
260    Addr  rxDmaAddr;
261    int   rxDmaLen;
262    bool  doRxDmaRead();
263    bool  doRxDmaWrite();
264    void  rxDmaReadCopy();
265    void  rxDmaWriteCopy();
266
267    void *txDmaData;
268    Addr  txDmaAddr;
269    int   txDmaLen;
270    bool  doTxDmaRead();
271    bool  doTxDmaWrite();
272    void  txDmaReadCopy();
273    void  txDmaWriteCopy();
274
275    void rxDmaReadDone();
276    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
277    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
278
279    void rxDmaWriteDone();
280    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
281    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
282
283    void txDmaReadDone();
284    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
285    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
286
287    void txDmaWriteDone();
288    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
289    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
290
291    bool dmaDescFree;
292    bool dmaDataFree;
293
294  protected:
295    Tick txDelay;
296    Tick rxDelay;
297
298    void txReset();
299    void rxReset();
300    void regsReset();
301
302    void rxKick();
303    Tick rxKickTick;
304    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
305    friend void RxKickEvent::process();
306    RxKickEvent rxKickEvent;
307
308    void txKick();
309    Tick txKickTick;
310    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
311    friend void TxKickEvent::process();
312    TxKickEvent txKickEvent;
313
314    void eepromKick();
315
316    /**
317     * Retransmit event
318     */
319    void transmit();
320    void txEventTransmit()
321    {
322        transmit();
323        if (txState == txFifoBlock)
324            txKick();
325    }
326    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
327    friend void TxEvent::process();
328    TxEvent txEvent;
329
330    void txDump() const;
331    void rxDump() const;
332
333    /**
334     * receive address filter
335     */
336    bool rxFilterEnable;
337    bool rxFilter(const PacketPtr &packet);
338    bool acceptBroadcast;
339    bool acceptMulticast;
340    bool acceptUnicast;
341    bool acceptPerfect;
342    bool acceptArp;
343    bool multicastHashEnable;
344
345    PhysicalMemory *physmem;
346
347    /**
348     * Interrupt management
349     */
350    void devIntrPost(uint32_t interrupts);
351    void devIntrClear(uint32_t interrupts);
352    void devIntrChangeMask();
353
354    Tick intrDelay;
355    Tick intrTick;
356    bool cpuPendingIntr;
357    void cpuIntrPost(Tick when);
358    void cpuInterrupt();
359    void cpuIntrClear();
360
361    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
362    friend void IntrEvent::process();
363    IntrEvent *intrEvent;
364    NSGigEInt *interface;
365
366  public:
367    struct Params : public PciDev::Params
368    {
369        PhysicalMemory *pmem;
370        HierParams *hier;
371        Bus *header_bus;
372        Bus *payload_bus;
373        Tick clock;
374        Tick intr_delay;
375        Tick tx_delay;
376        Tick rx_delay;
377        Tick pio_latency;
378        bool dma_desc_free;
379        bool dma_data_free;
380        Tick dma_read_delay;
381        Tick dma_write_delay;
382        Tick dma_read_factor;
383        Tick dma_write_factor;
384        bool rx_filter;
385        Net::EthAddr eaddr;
386        uint32_t tx_fifo_size;
387        uint32_t rx_fifo_size;
388        uint32_t m5reg;
389        bool dma_no_allocate;
390    };
391
392    NSGigE(Params *params);
393    ~NSGigE();
394    const Params *params() const { return (const Params *)_params; }
395
396    virtual void writeConfig(int offset, int size, const uint8_t *data);
397    virtual void readConfig(int offset, int size, uint8_t *data);
398
399    virtual Fault read(MemReqPtr &req, uint8_t *data);
400    virtual Fault write(MemReqPtr &req, const uint8_t *data);
401
402    bool cpuIntrPending() const;
403    void cpuIntrAck() { cpuIntrClear(); }
404
405    bool recvPacket(PacketPtr packet);
406    void transferDone();
407
408    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
409
410    virtual void serialize(std::ostream &os);
411    virtual void unserialize(Checkpoint *cp, const std::string &section);
412
413  public:
414    void regStats();
415
416  private:
417    Stats::Scalar<> txBytes;
418    Stats::Scalar<> rxBytes;
419    Stats::Scalar<> txPackets;
420    Stats::Scalar<> rxPackets;
421    Stats::Scalar<> txIpChecksums;
422    Stats::Scalar<> rxIpChecksums;
423    Stats::Scalar<> txTcpChecksums;
424    Stats::Scalar<> rxTcpChecksums;
425    Stats::Scalar<> txUdpChecksums;
426    Stats::Scalar<> rxUdpChecksums;
427    Stats::Scalar<> descDmaReads;
428    Stats::Scalar<> descDmaWrites;
429    Stats::Scalar<> descDmaRdBytes;
430    Stats::Scalar<> descDmaWrBytes;
431    Stats::Formula totBandwidth;
432    Stats::Formula totPackets;
433    Stats::Formula totBytes;
434    Stats::Formula totPacketRate;
435    Stats::Formula txBandwidth;
436    Stats::Formula rxBandwidth;
437    Stats::Formula txPacketRate;
438    Stats::Formula rxPacketRate;
439    Stats::Scalar<> postedSwi;
440    Stats::Formula coalescedSwi;
441    Stats::Scalar<> totalSwi;
442    Stats::Scalar<> postedRxIdle;
443    Stats::Formula coalescedRxIdle;
444    Stats::Scalar<> totalRxIdle;
445    Stats::Scalar<> postedRxOk;
446    Stats::Formula coalescedRxOk;
447    Stats::Scalar<> totalRxOk;
448    Stats::Scalar<> postedRxDesc;
449    Stats::Formula coalescedRxDesc;
450    Stats::Scalar<> totalRxDesc;
451    Stats::Scalar<> postedTxOk;
452    Stats::Formula coalescedTxOk;
453    Stats::Scalar<> totalTxOk;
454    Stats::Scalar<> postedTxIdle;
455    Stats::Formula coalescedTxIdle;
456    Stats::Scalar<> totalTxIdle;
457    Stats::Scalar<> postedTxDesc;
458    Stats::Formula coalescedTxDesc;
459    Stats::Scalar<> totalTxDesc;
460    Stats::Scalar<> postedRxOrn;
461    Stats::Formula coalescedRxOrn;
462    Stats::Scalar<> totalRxOrn;
463    Stats::Formula coalescedTotal;
464    Stats::Scalar<> postedInterrupts;
465    Stats::Scalar<> droppedPackets;
466
467  public:
468    Tick cacheAccess(MemReqPtr &req);
469};
470
471/*
472 * Ethernet Interface for an Ethernet Device
473 */
474class NSGigEInt : public EtherInt
475{
476  private:
477    NSGigE *dev;
478
479  public:
480    NSGigEInt(const std::string &name, NSGigE *d)
481        : EtherInt(name), dev(d) { dev->setInterface(this); }
482
483    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
484    virtual void sendDone() { dev->transferDone(); }
485};
486
487#endif // __DEV_NS_GIGE_HH__
488