2 * Copyright (c) 2003 The Regents of The University of Michigan
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.
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.
30 * Device module for modelling the National Semiconductor
31 * DP83820 ethernet controller
34 #ifndef __NS_GIGE_HH__
35 #define __NS_GIGE_HH__
38 #include "dev/etherint.hh"
39 #include "dev/etherpkt.hh"
40 #include "sim/eventq.hh"
41 #include "dev/ns_gige_reg.h"
42 #include "base/statistics.hh"
43 #include "dev/pcidev.hh"
44 #include "dev/tsunami.hh"
45 #include "dev/pciconfigall.hh"
47 /** defined by the NS83820 data sheet */
48 #define MAX_TX_FIFO_SIZE 8192
49 #define MAX_RX_FIFO_SIZE 32768
51 /** length of ethernet address in bytes */
54 /** Transmit State Machine states */
55 enum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead,
58 /** Receive State Machine States */
59 enum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite,
60 rxDescWrite, rxAdvance };
63 * Ethernet device registers
99 /** for perfect match memory. the linux driver doesn't use any other ROM */
100 uint8_t perfectMatch[EADDR_LEN];
102 virtual void serialize(std::ostream &os);
103 virtual void unserialize(Checkpoint *cp, const std::string §ion);
106 /** an enum indicating direction, transmit or receive, used as a param for
108 enum dir_t { tx, rx };
113 class PhysicalMemory;
116 * NS DP82830 Ethernet device model
118 class EtherDev : public PciDev, public DmaHolder
121 /** pointer to the chipset */
128 /** device register file */
131 /*** BASIC STRUCTURES FOR TX/RX ***/
133 typedef std::deque<PacketPtr> pktbuf_t;
134 typedef pktbuf_t::iterator pktiter_t;
138 /** for the tx side, to track addrs to write updated cmdsts to */
139 typedef std::deque<uint32_t> txdpbuf_t; /* ASSUME32 */
140 txdpbuf_t descAddrFifo;
142 /** various helper vars */
143 uint32_t txPacketLen;
144 uint8_t *txPacketBufPtr;
145 uint8_t *rxPacketBufPtr;
146 uint8_t *rxDescBufPtr;
154 /* tx State Machine */
156 /** Current Transmit Descriptor Done */
158 uint32_t txFifoCnt; /* amt of data in the txDataFifo in bytes (logical) */
159 uint32_t txFifoAvail; /* current amt of free space in txDataFifo in byes */
161 bool txPacketFlag; /* when set, indicates not working on a new packet */
162 Addr txFragPtr; /* ptr to the next byte in the current fragment */
163 uint32_t txDescCnt; /* count of bytes remaining in the current descriptor */
165 /** rx State Machine */
167 bool CRDD; /* Current Receive Descriptor Done */
168 uint32_t rxPktBytes; /* num of bytes in the current packet being drained
170 uint32_t rxFifoCnt; /* number of bytes in the rxFifo */
172 bool rxPacketFlag; /* when set, indicates not working on a new packet */
173 Addr rxFragPtr; /* ptr to the next byte in current fragment */
174 uint32_t rxDescCnt; /* count of bytes remaining in the current descriptor */
180 PhysicalMemory *physmem;
184 * Receive dma for descriptors done callback
186 class RxDescDone : public DmaCallback
192 RxDescDone(EtherDev *e);
193 std::string name() const;
194 virtual void process();
198 * Receive dma done callback
200 class RxDone : public DmaCallback
207 std::string name() const;
208 virtual void process();
212 * Transmit dma for descriptors done callback
214 class TxDescDone : public DmaCallback
220 TxDescDone(EtherDev *e);
221 std::string name() const;
222 virtual void process();
226 * Transmit dma done callback
228 class TxDone : public DmaCallback
236 std::string name() const;
237 virtual void process();
240 friend class TxDescDone;
242 friend class RxDescDone;
245 RxDescDone rxDescDoneCB;
247 TxDescDone txDescDoneCB;
251 DmaRequest readRequest;
252 DmaRequest writeRequest;
253 DmaRequest readDescRequest;
254 DmaRequest writeDescRequest;
258 DmaPhys readDescPhys;
259 DmaPhys writeDescPhys;
261 EtherDevInt *interface;
264 IntrControl *intctrl;
271 memset(®s, 0, sizeof(regs));
273 regs.isr = 0x00608000;
288 class TxEvent : public Event
294 TxEvent(EtherDev *_dev)
295 : Event(&mainEventQueue), dev(_dev) {}
296 void process() { dev->transmit(); }
297 virtual const char *description() { return "retransmit"; }
299 friend class TxEvent;
306 void txDone(PacketPtr packet);
312 void devIntrPost(uint32_t interrupts);
313 void devIntrClear(uint32_t interrupts);
314 void devIntrChangeMask();
321 bool rxFilter(PacketPtr packet);
322 bool acceptBroadcast;
323 bool acceptMulticast;
328 bool udpChecksum(PacketPtr packet, bool gen);
329 bool tcpChecksum(PacketPtr packet, bool gen);
330 bool ipChecksum(PacketPtr packet, bool gen);
331 uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
334 EtherDev(const std::string &name, DmaEngine *de, bool use_interface,
335 IntrControl *i, MemoryController *mmu, PhysicalMemory *pmem,
336 PCIConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus,
337 uint32_t dev, uint32_t func, bool rx_filter, const int eaddr[6],
338 Tick tx_delay, Tick rx_delay, Addr addr, Addr mask);
341 virtual void WriteConfig(int offset, int size, uint32_t data);
342 virtual void ReadConfig(int offset, int size, uint8_t *data);
346 Fault read(MemReqPtr req, uint8_t *data);
347 Fault write(MemReqPtr req, const uint8_t *data);
349 bool cpuIntrPending() const;
350 void cpuIntrAck() { cpuIntrClear(); }
352 bool recvPacket(PacketPtr packet);
355 void setInterface(EtherDevInt *i) { assert(!interface); interface = i; }
357 virtual void serialize(std::ostream &os);
358 virtual void unserialize(Checkpoint *cp, const std::string §ion);
360 virtual DmaRequest *find_dmareq(uint32_t &id) {
362 return(&readRequest);
364 return(&writeRequest);
373 Statistics::Scalar<> txBytes;
374 Statistics::Scalar<> rxBytes;
375 Statistics::Scalar<> txPackets;
376 Statistics::Scalar<> rxPackets;
377 Statistics::Formula txBandwidth;
378 Statistics::Formula rxBandwidth;
379 Statistics::Formula txPacketRate;
380 Statistics::Formula rxPacketRate;
382 void readOneDesc(dir_t dir, uint32_t len = sizeof(ns_desc));
388 * Ethernet Interface for an Ethernet Device
390 class EtherDevInt : public EtherInt
396 EtherDevInt(const std::string &name, EtherDev *d)
397 : EtherInt(name), dev(d) { dev->setInterface(this); }
399 virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
400 virtual void sendDone() { dev->transferDone(); }
403 #endif // __NS_GIGE_HH__