ns_gige.hh revision 927
111444Sm.alian1369@gmail.com/*
211444Sm.alian1369@gmail.com * Copyright (c) 2004 The Regents of The University of Michigan
311444Sm.alian1369@gmail.com * All rights reserved.
411444Sm.alian1369@gmail.com *
511444Sm.alian1369@gmail.com * Redistribution and use in source and binary forms, with or without
611444Sm.alian1369@gmail.com * modification, are permitted provided that the following conditions are
711444Sm.alian1369@gmail.com * met: redistributions of source code must retain the above copyright
811444Sm.alian1369@gmail.com * notice, this list of conditions and the following disclaimer;
911444Sm.alian1369@gmail.com * redistributions in binary form must reproduce the above copyright
1011444Sm.alian1369@gmail.com * notice, this list of conditions and the following disclaimer in the
1111444Sm.alian1369@gmail.com * documentation and/or other materials provided with the distribution;
1211444Sm.alian1369@gmail.com * neither the name of the copyright holders nor the names of its
1311444Sm.alian1369@gmail.com * contributors may be used to endorse or promote products derived from
1411444Sm.alian1369@gmail.com * this software without specific prior written permission.
1511444Sm.alian1369@gmail.com *
1611444Sm.alian1369@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711444Sm.alian1369@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811444Sm.alian1369@gmail.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911444Sm.alian1369@gmail.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011444Sm.alian1369@gmail.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111444Sm.alian1369@gmail.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211444Sm.alian1369@gmail.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311444Sm.alian1369@gmail.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411444Sm.alian1369@gmail.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511444Sm.alian1369@gmail.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611444Sm.alian1369@gmail.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711444Sm.alian1369@gmail.com */
2811444Sm.alian1369@gmail.com
2911444Sm.alian1369@gmail.com/* @file
3011444Sm.alian1369@gmail.com * Device module for modelling the National Semiconductor
3111444Sm.alian1369@gmail.com * DP83820 ethernet controller
3211444Sm.alian1369@gmail.com */
3311444Sm.alian1369@gmail.com
3411444Sm.alian1369@gmail.com#ifndef __NS_GIGE_HH__
3511444Sm.alian1369@gmail.com#define __NS_GIGE_HH__
3611444Sm.alian1369@gmail.com
3711444Sm.alian1369@gmail.com//#include "base/range.hh"
3811444Sm.alian1369@gmail.com#include "dev/etherint.hh"
3911444Sm.alian1369@gmail.com#include "dev/etherpkt.hh"
4011682Sandreas.hansson@arm.com#include "sim/eventq.hh"
4111444Sm.alian1369@gmail.com#include "dev/ns_gige_reg.h"
4211682Sandreas.hansson@arm.com#include "base/statistics.hh"
4311682Sandreas.hansson@arm.com#include "dev/pcidev.hh"
4411444Sm.alian1369@gmail.com#include "dev/tsunami.hh"
4511444Sm.alian1369@gmail.com#include "dev/io_device.hh"
4611444Sm.alian1369@gmail.com#include "mem/bus/bus.hh"
4711444Sm.alian1369@gmail.com
4811444Sm.alian1369@gmail.com/** defined by the NS83820 data sheet */
4911444Sm.alian1369@gmail.com#define MAX_TX_FIFO_SIZE 8192
5011444Sm.alian1369@gmail.com#define MAX_RX_FIFO_SIZE 32768
5111444Sm.alian1369@gmail.com
5211444Sm.alian1369@gmail.com/** length of ethernet address in bytes */
5311444Sm.alian1369@gmail.com#define EADDR_LEN 6
5411444Sm.alian1369@gmail.com
5511444Sm.alian1369@gmail.com/**
5611444Sm.alian1369@gmail.com * Ethernet device registers
5711444Sm.alian1369@gmail.com */
5811444Sm.alian1369@gmail.comstruct dp_regs {
5911444Sm.alian1369@gmail.com    uint32_t	command;
6011444Sm.alian1369@gmail.com    uint32_t	config;
6111444Sm.alian1369@gmail.com    uint32_t	mear;
6211444Sm.alian1369@gmail.com    uint32_t	ptscr;
6311444Sm.alian1369@gmail.com    uint32_t    isr;
6411444Sm.alian1369@gmail.com    uint32_t    imr;
6511444Sm.alian1369@gmail.com    uint32_t    ier;
6611444Sm.alian1369@gmail.com    uint32_t    ihr;
6711844Sgabor.dozsa@arm.com    uint32_t    txdp;
6811844Sgabor.dozsa@arm.com    uint32_t    txdp_hi;
6911844Sgabor.dozsa@arm.com    uint32_t    txcfg;
7011844Sgabor.dozsa@arm.com    uint32_t    gpior;
7111844Sgabor.dozsa@arm.com    uint32_t    rxdp;
7211844Sgabor.dozsa@arm.com    uint32_t    rxdp_hi;
7311444Sm.alian1369@gmail.com    uint32_t    rxcfg;
7411844Sgabor.dozsa@arm.com    uint32_t    pqcr;
7511844Sgabor.dozsa@arm.com    uint32_t    wcsr;
7611844Sgabor.dozsa@arm.com    uint32_t    pcr;
7711844Sgabor.dozsa@arm.com    uint32_t    rfcr;
7811844Sgabor.dozsa@arm.com    uint32_t    rfdr;
7911844Sgabor.dozsa@arm.com    uint32_t    srr;
80    uint32_t    mibc;
81    uint32_t    vrcr;
82    uint32_t    vtcr;
83    uint32_t    vdr;
84    uint32_t    ccsr;
85    uint32_t    tbicr;
86    uint32_t    tbisr;
87    uint32_t    tanar;
88    uint32_t    tanlpar;
89    uint32_t    taner;
90    uint32_t    tesr;
91};
92
93struct dp_rom {
94    /** for perfect match memory.  the linux driver doesn't use any other ROM */
95    uint8_t perfectMatch[EADDR_LEN];
96};
97
98class IntrControl;
99class NSGigEInt;
100class PhysicalMemory;
101class BaseInterface;
102class HierParams;
103class Bus;
104class PciConfigAll;
105
106/**
107 * NS DP82830 Ethernet device model
108 */
109class NSGigE : public PciDev
110{
111  public:
112    /** Transmit State Machine states */
113    enum TxState
114    {
115        txIdle,
116        txDescRefr,
117        txDescRead,
118        txFifoBlock,
119        txFragRead,
120        txDescWrite,
121        txAdvance
122    };
123
124    /** Receive State Machine States */
125    enum RxState
126    {
127        rxIdle,
128        rxDescRefr,
129        rxDescRead,
130        rxFifoBlock,
131        rxFragWrite,
132        rxDescWrite,
133        rxAdvance
134    };
135
136    enum DmaState
137    {
138        dmaIdle,
139        dmaReading,
140        dmaWriting,
141        dmaReadWaiting,
142        dmaWriteWaiting
143    };
144
145  private:
146    /** pointer to the chipset */
147    Tsunami *tsunami;
148
149  private:
150    Addr addr;
151    static const Addr size = sizeof(dp_regs);
152
153  protected:
154    typedef std::deque<PacketPtr> pktbuf_t;
155    typedef pktbuf_t::iterator pktiter_t;
156
157    /** device register file */
158    dp_regs regs;
159    dp_rom rom;
160
161    /** pci settings */
162    bool ioEnable;
163#if 0
164    bool memEnable;
165    bool bmEnable;
166#endif
167
168    /*** BASIC STRUCTURES FOR TX/RX ***/
169    /* Data FIFOs */
170    pktbuf_t txFifo;
171    pktbuf_t rxFifo;
172
173    /** various helper vars */
174    PacketPtr txPacket;
175    PacketPtr rxPacket;
176    uint8_t *txPacketBufPtr;
177    uint8_t *rxPacketBufPtr;
178    uint32_t txXferLen;
179    uint32_t rxXferLen;
180    bool rxDmaFree;
181    bool txDmaFree;
182
183    /** DescCaches */
184    ns_desc txDescCache;
185    ns_desc rxDescCache;
186
187    /* tx State Machine */
188    TxState txState;
189    /** Current Transmit Descriptor Done */
190    bool CTDD;
191    /** current amt of free space in txDataFifo in bytes */
192    uint32_t txFifoAvail;
193    /** halt the tx state machine after next packet */
194    bool txHalt;
195    /** ptr to the next byte in the current fragment */
196    Addr txFragPtr;
197    /** count of bytes remaining in the current descriptor */
198    uint32_t txDescCnt;
199    DmaState txDmaState;
200
201    /** rx State Machine */
202    RxState rxState;
203    /** Current Receive Descriptor Done */
204    bool CRDD;
205    /** num of bytes in the current packet being drained from rxDataFifo */
206    uint32_t rxPktBytes;
207    /** number of bytes in the rxFifo */
208    uint32_t rxFifoCnt;
209    /** halt the rx state machine after current packet */
210    bool rxHalt;
211    /** ptr to the next byte in current fragment */
212    Addr rxFragPtr;
213    /** count of bytes remaining in the current descriptor */
214    uint32_t rxDescCnt;
215    DmaState rxDmaState;
216
217    bool extstsEnable;
218
219  protected:
220    Tick dmaReadDelay;
221    Tick dmaWriteDelay;
222
223    Tick dmaReadFactor;
224    Tick dmaWriteFactor;
225
226    void *rxDmaData;
227    Addr  rxDmaAddr;
228    int   rxDmaLen;
229    bool  doRxDmaRead();
230    bool  doRxDmaWrite();
231    void  rxDmaReadCopy();
232    void  rxDmaWriteCopy();
233
234    void *txDmaData;
235    Addr  txDmaAddr;
236    int   txDmaLen;
237    bool  doTxDmaRead();
238    bool  doTxDmaWrite();
239    void  txDmaReadCopy();
240    void  txDmaWriteCopy();
241
242    void rxDmaReadDone();
243    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
244    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
245
246    void rxDmaWriteDone();
247    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
248    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
249
250    void txDmaReadDone();
251    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
252    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
253
254    void txDmaWriteDone();
255    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
256    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
257
258    bool dmaDescFree;
259    bool dmaDataFree;
260
261
262  protected:
263    Tick txDelay;
264    Tick rxDelay;
265
266    void txReset();
267    void rxReset();
268    void regsReset();
269
270    void rxKick();
271    Tick rxKickTick;
272    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
273    friend class RxKickEvent;
274
275    void txKick();
276    Tick txKickTick;
277    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
278    friend class TxKickEvent;
279
280    /**
281     * Retransmit event
282     */
283    void transmit();
284    typedef EventWrapper<NSGigE, &NSGigE::transmit> TxEvent;
285    friend class TxEvent;
286    TxEvent txEvent;
287
288    void txDump() const;
289    void rxDump() const;
290
291    /**
292     * receive address filter
293     */
294    bool rxFilterEnable;
295    bool rxFilter(PacketPtr packet);
296    bool acceptBroadcast;
297    bool acceptMulticast;
298    bool acceptUnicast;
299    bool acceptPerfect;
300    bool acceptArp;
301
302    PhysicalMemory *physmem;
303
304    /**
305     * Interrupt management
306     */
307    IntrControl *intctrl;
308    void devIntrPost(uint32_t interrupts);
309    void devIntrClear(uint32_t interrupts);
310    void devIntrChangeMask();
311
312    Tick intrDelay;
313    Tick intrTick;
314    bool cpuPendingIntr;
315    void cpuIntrPost(Tick when);
316    void cpuInterrupt();
317    void cpuIntrClear();
318
319    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
320    friend class IntrEvent;
321    IntrEvent *intrEvent;
322
323    /**
324     * Hardware checksum support
325     */
326    bool udpChecksum(PacketPtr packet, bool gen);
327    bool tcpChecksum(PacketPtr packet, bool gen);
328    bool ipChecksum(PacketPtr packet, bool gen);
329    uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
330
331    NSGigEInt *interface;
332
333  public:
334    NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
335             PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
336             MemoryController *mmu, HierParams *hier, Bus *header_bus,
337             Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
338             bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
339             Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
340             PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
341             uint32_t func, bool rx_filter, const int eaddr[6]);
342    ~NSGigE();
343
344    virtual void WriteConfig(int offset, int size, uint32_t data);
345    virtual void ReadConfig(int offset, int size, uint8_t *data);
346
347    virtual Fault read(MemReqPtr &req, uint8_t *data);
348    virtual Fault write(MemReqPtr &req, const uint8_t *data);
349
350    bool cpuIntrPending() const;
351    void cpuIntrAck() { cpuIntrClear(); }
352
353    bool recvPacket(PacketPtr packet);
354    void transferDone();
355
356    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
357
358    virtual void serialize(std::ostream &os);
359    virtual void unserialize(Checkpoint *cp, const std::string &section);
360
361  public:
362    void regStats();
363
364  private:
365    Stats::Scalar<> txBytes;
366    Stats::Scalar<> rxBytes;
367    Stats::Scalar<> txPackets;
368    Stats::Scalar<> rxPackets;
369    Stats::Formula txBandwidth;
370    Stats::Formula rxBandwidth;
371    Stats::Formula txPacketRate;
372    Stats::Formula rxPacketRate;
373
374  private:
375    Tick pioLatency;
376
377  public:
378    Tick cacheAccess(MemReqPtr &req);
379};
380
381/*
382 * Ethernet Interface for an Ethernet Device
383 */
384class NSGigEInt : public EtherInt
385{
386  private:
387    NSGigE *dev;
388
389  public:
390    NSGigEInt(const std::string &name, NSGigE *d)
391        : EtherInt(name), dev(d) { dev->setInterface(this); }
392
393    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
394    virtual void sendDone() { dev->transferDone(); }
395};
396
397#endif // __NS_GIGE_HH__
398