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