Merge zizzer:/z/m5/Bitkeeper/m5
[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 __DEV_NS_GIGE_HH__
35 #define __DEV_NS_GIGE_HH__
36
37 #include "base/inet.hh"
38 #include "base/statistics.hh"
39 #include "dev/etherint.hh"
40 #include "dev/etherpkt.hh"
41 #include "dev/io_device.hh"
42 #include "dev/ns_gige_reg.h"
43 #include "dev/pcidev.hh"
44 #include "dev/pktfifo.hh"
45 #include "mem/bus/bus.hh"
46 #include "sim/eventq.hh"
47
48 /**
49 * Ethernet device registers
50 */
51 struct dp_regs {
52 uint32_t command;
53 uint32_t config;
54 uint32_t mear;
55 uint32_t ptscr;
56 uint32_t isr;
57 uint32_t imr;
58 uint32_t ier;
59 uint32_t ihr;
60 uint32_t txdp;
61 uint32_t txdp_hi;
62 uint32_t txcfg;
63 uint32_t gpior;
64 uint32_t rxdp;
65 uint32_t rxdp_hi;
66 uint32_t rxcfg;
67 uint32_t pqcr;
68 uint32_t wcsr;
69 uint32_t pcr;
70 uint32_t rfcr;
71 uint32_t rfdr;
72 uint32_t srr;
73 uint32_t mibc;
74 uint32_t vrcr;
75 uint32_t vtcr;
76 uint32_t vdr;
77 uint32_t ccsr;
78 uint32_t tbicr;
79 uint32_t tbisr;
80 uint32_t tanar;
81 uint32_t tanlpar;
82 uint32_t taner;
83 uint32_t tesr;
84 };
85
86 struct dp_rom {
87 /**
88 * for perfect match memory.
89 * the linux driver doesn't use any other ROM
90 */
91 uint8_t perfectMatch[ETH_ADDR_LEN];
92 };
93
94 class IntrControl;
95 class NSGigEInt;
96 class PhysicalMemory;
97 class BaseInterface;
98 class HierParams;
99 class Bus;
100 class PciConfigAll;
101
102 /**
103 * NS DP82830 Ethernet device model
104 */
105 class NSGigE : public PciDev
106 {
107 public:
108 /** Transmit State Machine states */
109 enum TxState
110 {
111 txIdle,
112 txDescRefr,
113 txDescRead,
114 txFifoBlock,
115 txFragRead,
116 txDescWrite,
117 txAdvance
118 };
119
120 /** Receive State Machine States */
121 enum RxState
122 {
123 rxIdle,
124 rxDescRefr,
125 rxDescRead,
126 rxFifoBlock,
127 rxFragWrite,
128 rxDescWrite,
129 rxAdvance
130 };
131
132 enum DmaState
133 {
134 dmaIdle,
135 dmaReading,
136 dmaWriting,
137 dmaReadWaiting,
138 dmaWriteWaiting
139 };
140
141 private:
142 Addr addr;
143 static const Addr size = sizeof(dp_regs);
144
145 protected:
146 typedef std::deque<PacketPtr> pktbuf_t;
147 typedef pktbuf_t::iterator pktiter_t;
148
149 /** device register file */
150 dp_regs regs;
151 dp_rom rom;
152
153 /** pci settings */
154 bool ioEnable;
155 #if 0
156 bool memEnable;
157 bool bmEnable;
158 #endif
159
160 /*** BASIC STRUCTURES FOR TX/RX ***/
161 /* Data FIFOs */
162 PacketFifo txFifo;
163 PacketFifo rxFifo;
164
165 /** various helper vars */
166 PacketPtr txPacket;
167 PacketPtr rxPacket;
168 uint8_t *txPacketBufPtr;
169 uint8_t *rxPacketBufPtr;
170 uint32_t txXferLen;
171 uint32_t rxXferLen;
172 bool rxDmaFree;
173 bool txDmaFree;
174
175 /** DescCaches */
176 ns_desc txDescCache;
177 ns_desc rxDescCache;
178
179 /* tx State Machine */
180 TxState txState;
181 bool txEnable;
182
183 /** Current Transmit Descriptor Done */
184 bool CTDD;
185 /** halt the tx state machine after next packet */
186 bool txHalt;
187 /** ptr to the next byte in the current fragment */
188 Addr txFragPtr;
189 /** count of bytes remaining in the current descriptor */
190 uint32_t txDescCnt;
191 DmaState txDmaState;
192
193 /** rx State Machine */
194 RxState rxState;
195 bool rxEnable;
196
197 /** Current Receive Descriptor Done */
198 bool CRDD;
199 /** num of bytes in the current packet being drained from rxDataFifo */
200 uint32_t rxPktBytes;
201 /** halt the rx state machine after current packet */
202 bool rxHalt;
203 /** ptr to the next byte in current fragment */
204 Addr rxFragPtr;
205 /** count of bytes remaining in the current descriptor */
206 uint32_t rxDescCnt;
207 DmaState rxDmaState;
208
209 bool extstsEnable;
210
211 protected:
212 Tick dmaReadDelay;
213 Tick dmaWriteDelay;
214
215 Tick dmaReadFactor;
216 Tick dmaWriteFactor;
217
218 void *rxDmaData;
219 Addr rxDmaAddr;
220 int rxDmaLen;
221 bool doRxDmaRead();
222 bool doRxDmaWrite();
223 void rxDmaReadCopy();
224 void rxDmaWriteCopy();
225
226 void *txDmaData;
227 Addr txDmaAddr;
228 int txDmaLen;
229 bool doTxDmaRead();
230 bool doTxDmaWrite();
231 void txDmaReadCopy();
232 void txDmaWriteCopy();
233
234 void rxDmaReadDone();
235 friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
236 EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
237
238 void rxDmaWriteDone();
239 friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
240 EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
241
242 void txDmaReadDone();
243 friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
244 EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
245
246 void txDmaWriteDone();
247 friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
248 EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
249
250 bool dmaDescFree;
251 bool dmaDataFree;
252
253
254 protected:
255 Tick txDelay;
256 Tick rxDelay;
257
258 void txReset();
259 void rxReset();
260 void regsReset();
261
262 void rxKick();
263 Tick rxKickTick;
264 typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
265 friend class RxKickEvent;
266
267 void txKick();
268 Tick txKickTick;
269 typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
270 friend class TxKickEvent;
271
272 /**
273 * Retransmit event
274 */
275 void transmit();
276 void txEventTransmit()
277 {
278 transmit();
279 if (txState == txFifoBlock)
280 txKick();
281 }
282 typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
283 friend class TxEvent;
284 TxEvent txEvent;
285
286 void txDump() const;
287 void rxDump() const;
288
289 /**
290 * receive address filter
291 */
292 bool rxFilterEnable;
293 bool rxFilter(const PacketPtr &packet);
294 bool acceptBroadcast;
295 bool acceptMulticast;
296 bool acceptUnicast;
297 bool acceptPerfect;
298 bool acceptArp;
299
300 PhysicalMemory *physmem;
301
302 /**
303 * Interrupt management
304 */
305 IntrControl *intctrl;
306 void devIntrPost(uint32_t interrupts);
307 void devIntrClear(uint32_t interrupts);
308 void devIntrChangeMask();
309
310 Tick intrDelay;
311 Tick intrTick;
312 bool cpuPendingIntr;
313 void cpuIntrPost(Tick when);
314 void cpuInterrupt();
315 void cpuIntrClear();
316
317 typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
318 friend class IntrEvent;
319 IntrEvent *intrEvent;
320 NSGigEInt *interface;
321
322 public:
323 struct Params : public PciDev::Params
324 {
325 PhysicalMemory *pmem;
326 HierParams *hier;
327 Bus *header_bus;
328 Bus *payload_bus;
329 Tick intr_delay;
330 Tick tx_delay;
331 Tick rx_delay;
332 Tick pio_latency;
333 bool dma_desc_free;
334 bool dma_data_free;
335 Tick dma_read_delay;
336 Tick dma_write_delay;
337 Tick dma_read_factor;
338 Tick dma_write_factor;
339 bool rx_filter;
340 Net::EthAddr eaddr;
341 uint32_t tx_fifo_size;
342 uint32_t rx_fifo_size;
343 };
344
345 NSGigE(Params *params);
346 ~NSGigE();
347 const Params *params() const { return (const Params *)_params; }
348
349 virtual void WriteConfig(int offset, int size, uint32_t data);
350 virtual void ReadConfig(int offset, int size, uint8_t *data);
351
352 virtual Fault read(MemReqPtr &req, uint8_t *data);
353 virtual Fault write(MemReqPtr &req, const uint8_t *data);
354
355 bool cpuIntrPending() const;
356 void cpuIntrAck() { cpuIntrClear(); }
357
358 bool recvPacket(PacketPtr packet);
359 void transferDone();
360
361 void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
362
363 virtual void serialize(std::ostream &os);
364 virtual void unserialize(Checkpoint *cp, const std::string &section);
365
366 public:
367 void regStats();
368
369 private:
370 Stats::Scalar<> txBytes;
371 Stats::Scalar<> rxBytes;
372 Stats::Scalar<> txPackets;
373 Stats::Scalar<> rxPackets;
374 Stats::Scalar<> txIpChecksums;
375 Stats::Scalar<> rxIpChecksums;
376 Stats::Scalar<> txTcpChecksums;
377 Stats::Scalar<> rxTcpChecksums;
378 Stats::Scalar<> txUdpChecksums;
379 Stats::Scalar<> rxUdpChecksums;
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 // __DEV_NS_GIGE_HH__