c326d0921f3c36f92a188a36ea5268bdff6a5060
[gem5.git] / dev / ns_gige.hh
1 /*
2 * Copyright (c) 2004 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
29 /* @file
30 * Device module for modelling the National Semiconductor
31 * DP83820 ethernet controller
32 */
33
34 #ifndef __NS_GIGE_HH__
35 #define __NS_GIGE_HH__
36
37 #include "base/statistics.hh"
38 #include "dev/etherint.hh"
39 #include "dev/etherpkt.hh"
40 #include "dev/io_device.hh"
41 #include "dev/ns_gige_reg.h"
42 #include "dev/pcidev.hh"
43 #include "dev/tsunami.hh"
44 #include "mem/bus/bus.hh"
45 #include "sim/eventq.hh"
46
47 /** length of ethernet address in bytes */
48 #define EADDR_LEN 6
49
50 /**
51 * Ethernet device registers
52 */
53 struct dp_regs {
54 uint32_t command;
55 uint32_t config;
56 uint32_t mear;
57 uint32_t ptscr;
58 uint32_t isr;
59 uint32_t imr;
60 uint32_t ier;
61 uint32_t ihr;
62 uint32_t txdp;
63 uint32_t txdp_hi;
64 uint32_t txcfg;
65 uint32_t gpior;
66 uint32_t rxdp;
67 uint32_t rxdp_hi;
68 uint32_t rxcfg;
69 uint32_t pqcr;
70 uint32_t wcsr;
71 uint32_t pcr;
72 uint32_t rfcr;
73 uint32_t rfdr;
74 uint32_t srr;
75 uint32_t mibc;
76 uint32_t vrcr;
77 uint32_t vtcr;
78 uint32_t vdr;
79 uint32_t ccsr;
80 uint32_t tbicr;
81 uint32_t tbisr;
82 uint32_t tanar;
83 uint32_t tanlpar;
84 uint32_t taner;
85 uint32_t tesr;
86 };
87
88 struct dp_rom {
89 /**
90 * for perfect match memory.
91 * the linux driver doesn't use any other ROM
92 */
93 uint8_t perfectMatch[EADDR_LEN];
94 };
95
96 class IntrControl;
97 class NSGigEInt;
98 class PhysicalMemory;
99 class BaseInterface;
100 class HierParams;
101 class Bus;
102 class PciConfigAll;
103
104 /**
105 * NS DP82830 Ethernet device model
106 */
107 class NSGigE : public PciDev
108 {
109 public:
110 /** Transmit State Machine states */
111 enum TxState
112 {
113 txIdle,
114 txDescRefr,
115 txDescRead,
116 txFifoBlock,
117 txFragRead,
118 txDescWrite,
119 txAdvance
120 };
121
122 /** Receive State Machine States */
123 enum RxState
124 {
125 rxIdle,
126 rxDescRefr,
127 rxDescRead,
128 rxFifoBlock,
129 rxFragWrite,
130 rxDescWrite,
131 rxAdvance
132 };
133
134 enum DmaState
135 {
136 dmaIdle,
137 dmaReading,
138 dmaWriting,
139 dmaReadWaiting,
140 dmaWriteWaiting
141 };
142
143 private:
144 /** pointer to the chipset */
145 Tsunami *tsunami;
146
147 private:
148 Addr addr;
149 static const Addr size = sizeof(dp_regs);
150
151 protected:
152 typedef std::deque<PacketPtr> pktbuf_t;
153 typedef pktbuf_t::iterator pktiter_t;
154
155 /** device register file */
156 dp_regs regs;
157 dp_rom rom;
158
159 /** pci settings */
160 bool ioEnable;
161 #if 0
162 bool memEnable;
163 bool bmEnable;
164 #endif
165
166 /*** BASIC STRUCTURES FOR TX/RX ***/
167 /* Data FIFOs */
168 pktbuf_t txFifo;
169 uint32_t maxTxFifoSize;
170 pktbuf_t rxFifo;
171 uint32_t maxRxFifoSize;
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 void txEventTransmit()
285 {
286 transmit();
287 if (txState == txFifoBlock)
288 txKick();
289 }
290 typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
291 friend class TxEvent;
292 TxEvent txEvent;
293
294 void txDump() const;
295 void rxDump() const;
296
297 /**
298 * receive address filter
299 */
300 bool rxFilterEnable;
301 bool rxFilter(PacketPtr packet);
302 bool acceptBroadcast;
303 bool acceptMulticast;
304 bool acceptUnicast;
305 bool acceptPerfect;
306 bool acceptArp;
307
308 PhysicalMemory *physmem;
309
310 /**
311 * Interrupt management
312 */
313 IntrControl *intctrl;
314 void devIntrPost(uint32_t interrupts);
315 void devIntrClear(uint32_t interrupts);
316 void devIntrChangeMask();
317
318 Tick intrDelay;
319 Tick intrTick;
320 bool cpuPendingIntr;
321 void cpuIntrPost(Tick when);
322 void cpuInterrupt();
323 void cpuIntrClear();
324
325 typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
326 friend class IntrEvent;
327 IntrEvent *intrEvent;
328
329 /**
330 * Hardware checksum support
331 */
332 bool udpChecksum(PacketPtr packet, bool gen);
333 bool tcpChecksum(PacketPtr packet, bool gen);
334 bool ipChecksum(PacketPtr packet, bool gen);
335 uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
336
337 NSGigEInt *interface;
338
339 public:
340 NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
341 PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
342 MemoryController *mmu, HierParams *hier, Bus *header_bus,
343 Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
344 bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
345 Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
346 PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
347 uint32_t func, bool rx_filter, const int eaddr[6],
348 uint32_t tx_fifo_size, uint32_t rx_fifo_size);
349 ~NSGigE();
350
351 virtual void WriteConfig(int offset, int size, uint32_t data);
352 virtual void ReadConfig(int offset, int size, uint8_t *data);
353
354 virtual Fault read(MemReqPtr &req, uint8_t *data);
355 virtual Fault write(MemReqPtr &req, const uint8_t *data);
356
357 bool cpuIntrPending() const;
358 void cpuIntrAck() { cpuIntrClear(); }
359
360 bool recvPacket(PacketPtr packet);
361 void transferDone();
362
363 void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
364
365 virtual void serialize(std::ostream &os);
366 virtual void unserialize(Checkpoint *cp, const std::string &section);
367
368 public:
369 void regStats();
370
371 private:
372 Stats::Scalar<> txBytes;
373 Stats::Scalar<> rxBytes;
374 Stats::Scalar<> txPackets;
375 Stats::Scalar<> rxPackets;
376 Stats::Scalar<> txIPChecksums;
377 Stats::Scalar<> rxIPChecksums;
378 Stats::Scalar<> txTCPChecksums;
379 Stats::Scalar<> rxTCPChecksums;
380 Stats::Scalar<> descDmaReads;
381 Stats::Scalar<> descDmaWrites;
382 Stats::Scalar<> descDmaRdBytes;
383 Stats::Scalar<> descDmaWrBytes;
384 Stats::Formula txBandwidth;
385 Stats::Formula rxBandwidth;
386 Stats::Formula txPacketRate;
387 Stats::Formula rxPacketRate;
388
389 public:
390 Tick cacheAccess(MemReqPtr &req);
391 };
392
393 /*
394 * Ethernet Interface for an Ethernet Device
395 */
396 class NSGigEInt : public EtherInt
397 {
398 private:
399 NSGigE *dev;
400
401 public:
402 NSGigEInt(const std::string &name, NSGigE *d)
403 : EtherInt(name), dev(d) { dev->setInterface(this); }
404
405 virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
406 virtual void sendDone() { dev->transferDone(); }
407 };
408
409 #endif // __NS_GIGE_HH__