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