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_NET_NS_GIGE_HH__
38#define __DEV_NET_NS_GIGE_HH__
39
40#include "base/inet.hh"
41#include "dev/io_device.hh"
42#include "dev/net/etherdevice.hh"
43#include "dev/net/etherint.hh"
44#include "dev/net/etherpkt.hh"
45#include "dev/net/ns_gige_reg.h"
46#include "dev/net/pktfifo.hh"
47#include "params/NSGigE.hh"
48#include "sim/eventq.hh"
49
50// Hash filtering constants
51const uint16_t FHASH_ADDR  = 0x100;
52const uint16_t FHASH_SIZE  = 0x100;
53
54// EEPROM constants
55const uint8_t  EEPROM_READ = 0x2;
56const uint8_t  EEPROM_SIZE = 64; // Size in words of NSC93C46 EEPROM
57const uint8_t  EEPROM_PMATCH2_ADDR = 0xA; // EEPROM Address of PMATCH word 2
58const uint8_t  EEPROM_PMATCH1_ADDR = 0xB; // EEPROM Address of PMATCH word 1
59const uint8_t  EEPROM_PMATCH0_ADDR = 0xC; // EEPROM Address of PMATCH word 0
60
61/**
62 * Ethernet device registers
63 */
64struct dp_regs {
65    uint32_t    command;
66    uint32_t    config;
67    uint32_t    mear;
68    uint32_t    ptscr;
69    uint32_t    isr;
70    uint32_t    imr;
71    uint32_t    ier;
72    uint32_t    ihr;
73    uint32_t    txdp;
74    uint32_t    txdp_hi;
75    uint32_t    txcfg;
76    uint32_t    gpior;
77    uint32_t    rxdp;
78    uint32_t    rxdp_hi;
79    uint32_t    rxcfg;
80    uint32_t    pqcr;
81    uint32_t    wcsr;
82    uint32_t    pcr;
83    uint32_t    rfcr;
84    uint32_t    rfdr;
85    uint32_t    brar;
86    uint32_t    brdr;
87    uint32_t    srr;
88    uint32_t    mibc;
89    uint32_t    vrcr;
90    uint32_t    vtcr;
91    uint32_t    vdr;
92    uint32_t    ccsr;
93    uint32_t    tbicr;
94    uint32_t    tbisr;
95    uint32_t    tanar;
96    uint32_t    tanlpar;
97    uint32_t    taner;
98    uint32_t    tesr;
99};
100
101struct dp_rom {
102    /**
103     * for perfect match memory.
104     * the linux driver doesn't use any other ROM
105     */
106    uint8_t perfectMatch[ETH_ADDR_LEN];
107
108    /**
109     * for hash table memory.
110     * used by the freebsd driver
111     */
112    uint8_t filterHash[FHASH_SIZE];
113};
114
115class NSGigEInt;
116class Packet;
117
118/**
119 * NS DP83820 Ethernet device model
120 */
121class NSGigE : public EtherDevBase
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
174    /*** BASIC STRUCTURES FOR TX/RX ***/
175    /* Data FIFOs */
176    PacketFifo txFifo;
177    PacketFifo rxFifo;
178
179    /** various helper vars */
180    EthPacketPtr txPacket;
181    EthPacketPtr rxPacket;
182    uint8_t *txPacketBufPtr;
183    uint8_t *rxPacketBufPtr;
184    uint32_t txXferLen;
185    uint32_t rxXferLen;
186    bool rxDmaFree;
187    bool txDmaFree;
188
189    /** DescCaches */
190    ns_desc32 txDesc32;
191    ns_desc32 rxDesc32;
192    ns_desc64 txDesc64;
193    ns_desc64 rxDesc64;
194
195    /* tx State Machine */
196    TxState txState;
197    bool txEnable;
198
199    /** Current Transmit Descriptor Done */
200    bool CTDD;
201    /** halt the tx state machine after next packet */
202    bool txHalt;
203    /** ptr to the next byte in the current fragment */
204    Addr txFragPtr;
205    /** count of bytes remaining in the current descriptor */
206    uint32_t txDescCnt;
207    DmaState txDmaState;
208
209    /** rx State Machine */
210    RxState rxState;
211    bool rxEnable;
212
213    /** Current Receive Descriptor Done */
214    bool CRDD;
215    /** num of bytes in the current packet being drained from rxDataFifo */
216    uint32_t rxPktBytes;
217    /** halt the rx state machine after current packet */
218    bool rxHalt;
219    /** ptr to the next byte in current fragment */
220    Addr rxFragPtr;
221    /** count of bytes remaining in the current descriptor */
222    uint32_t rxDescCnt;
223    DmaState rxDmaState;
224
225    bool extstsEnable;
226
227    /** EEPROM State Machine */
228    EEPROMState eepromState;
229    bool eepromClk;
230    uint8_t eepromBitsToRx;
231    uint8_t eepromOpcode;
232    uint8_t eepromAddress;
233    uint16_t eepromData;
234
235  protected:
236    Tick dmaReadDelay;
237    Tick dmaWriteDelay;
238
239    Tick dmaReadFactor;
240    Tick dmaWriteFactor;
241
242    void *rxDmaData;
243    Addr  rxDmaAddr;
244    int   rxDmaLen;
245    bool  doRxDmaRead();
246    bool  doRxDmaWrite();
247
248    void *txDmaData;
249    Addr  txDmaAddr;
250    int   txDmaLen;
251    bool  doTxDmaRead();
252    bool  doTxDmaWrite();
253
254    void rxDmaReadDone();
255    EventFunctionWrapper rxDmaReadEvent;
256
257    void rxDmaWriteDone();
258    EventFunctionWrapper rxDmaWriteEvent;
259
260    void txDmaReadDone();
261    EventFunctionWrapper txDmaReadEvent;
262
263    void txDmaWriteDone();
264    EventFunctionWrapper txDmaWriteEvent;
265
266    bool dmaDescFree;
267    bool dmaDataFree;
268
269  protected:
270    Tick txDelay;
271    Tick rxDelay;
272
273    void txReset();
274    void rxReset();
275    void regsReset();
276
277    void rxKick();
278    Tick rxKickTick;
279    EventFunctionWrapper rxKickEvent;
280
281    void txKick();
282    Tick txKickTick;
283    EventFunctionWrapper txKickEvent;
284
285    void eepromKick();
286
287    /**
288     * Retransmit event
289     */
290    void transmit();
291    void txEventTransmit()
292    {
293        transmit();
294        if (txState == txFifoBlock)
295            txKick();
296    }
297    EventFunctionWrapper txEvent;
298
299    void txDump() const;
300    void rxDump() const;
301
302    /**
303     * receive address filter
304     */
305    bool rxFilterEnable;
306    bool rxFilter(const EthPacketPtr &packet);
307    bool acceptBroadcast;
308    bool acceptMulticast;
309    bool acceptUnicast;
310    bool acceptPerfect;
311    bool acceptArp;
312    bool multicastHashEnable;
313
314    /**
315     * Interrupt management
316     */
317    void devIntrPost(uint32_t interrupts);
318    void devIntrClear(uint32_t interrupts);
319    void devIntrChangeMask();
320
321    Tick intrDelay;
322    Tick intrTick;
323    bool cpuPendingIntr;
324    void cpuIntrPost(Tick when);
325    void cpuInterrupt();
326    void cpuIntrClear();
327
328    EventFunctionWrapper *intrEvent;
329    NSGigEInt *interface;
330
331  public:
332    typedef NSGigEParams Params;
333    const Params *params() const {
334        return dynamic_cast<const Params *>(_params);
335    }
336
337    NSGigE(Params *params);
338    ~NSGigE();
339
340    Port &getPort(const std::string &if_name,
341                  PortID idx=InvalidPortID) override;
342
343    Tick writeConfig(PacketPtr pkt) override;
344
345    Tick read(PacketPtr pkt) override;
346    Tick write(PacketPtr pkt) override;
347
348    bool cpuIntrPending() const;
349    void cpuIntrAck() { cpuIntrClear(); }
350
351    bool recvPacket(EthPacketPtr packet);
352    void transferDone();
353
354    void serialize(CheckpointOut &cp) const override;
355    void unserialize(CheckpointIn &cp) override;
356
357    void drainResume() override;
358};
359
360/*
361 * Ethernet Interface for an Ethernet Device
362 */
363class NSGigEInt : public EtherInt
364{
365  private:
366    NSGigE *dev;
367
368  public:
369    NSGigEInt(const std::string &name, NSGigE *d)
370        : EtherInt(name), dev(d)
371    { }
372
373    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
374    virtual void sendDone() { dev->transferDone(); }
375};
376
377#endif // __DEV_NET_NS_GIGE_HH__
378