Merge zizzer.eecs.umich.edu:/bk/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 NSGigEInt;
95 class PhysicalMemory;
96 class BaseInterface;
97 class HierParams;
98 class Bus;
99 class PciConfigAll;
100
101 /**
102 * NS DP82830 Ethernet device model
103 */
104 class NSGigE : public PciDev
105 {
106 public:
107 /** Transmit State Machine states */
108 enum TxState
109 {
110 txIdle,
111 txDescRefr,
112 txDescRead,
113 txFifoBlock,
114 txFragRead,
115 txDescWrite,
116 txAdvance
117 };
118
119 /** Receive State Machine States */
120 enum RxState
121 {
122 rxIdle,
123 rxDescRefr,
124 rxDescRead,
125 rxFifoBlock,
126 rxFragWrite,
127 rxDescWrite,
128 rxAdvance
129 };
130
131 enum DmaState
132 {
133 dmaIdle,
134 dmaReading,
135 dmaWriting,
136 dmaReadWaiting,
137 dmaWriteWaiting
138 };
139
140 private:
141 Addr addr;
142 static const Addr size = sizeof(dp_regs);
143
144 protected:
145 typedef std::deque<PacketPtr> pktbuf_t;
146 typedef pktbuf_t::iterator pktiter_t;
147
148 /** device register file */
149 dp_regs regs;
150 dp_rom rom;
151
152 /** pci settings */
153 bool ioEnable;
154 #if 0
155 bool memEnable;
156 bool bmEnable;
157 #endif
158
159 /*** BASIC STRUCTURES FOR TX/RX ***/
160 /* Data FIFOs */
161 PacketFifo txFifo;
162 PacketFifo rxFifo;
163
164 /** various helper vars */
165 PacketPtr txPacket;
166 PacketPtr rxPacket;
167 uint8_t *txPacketBufPtr;
168 uint8_t *rxPacketBufPtr;
169 uint32_t txXferLen;
170 uint32_t rxXferLen;
171 bool rxDmaFree;
172 bool txDmaFree;
173
174 /** DescCaches */
175 ns_desc txDescCache;
176 ns_desc rxDescCache;
177
178 /* tx State Machine */
179 TxState txState;
180 bool txEnable;
181
182 /** Current Transmit Descriptor Done */
183 bool CTDD;
184 /** halt the tx state machine after next packet */
185 bool txHalt;
186 /** ptr to the next byte in the current fragment */
187 Addr txFragPtr;
188 /** count of bytes remaining in the current descriptor */
189 uint32_t txDescCnt;
190 DmaState txDmaState;
191
192 /** rx State Machine */
193 RxState rxState;
194 bool rxEnable;
195
196 /** Current Receive Descriptor Done */
197 bool CRDD;
198 /** num of bytes in the current packet being drained from rxDataFifo */
199 uint32_t rxPktBytes;
200 /** halt the rx state machine after current packet */
201 bool rxHalt;
202 /** ptr to the next byte in current fragment */
203 Addr rxFragPtr;
204 /** count of bytes remaining in the current descriptor */
205 uint32_t rxDescCnt;
206 DmaState rxDmaState;
207
208 bool extstsEnable;
209
210 protected:
211 Tick dmaReadDelay;
212 Tick dmaWriteDelay;
213
214 Tick dmaReadFactor;
215 Tick dmaWriteFactor;
216
217 void *rxDmaData;
218 Addr rxDmaAddr;
219 int rxDmaLen;
220 bool doRxDmaRead();
221 bool doRxDmaWrite();
222 void rxDmaReadCopy();
223 void rxDmaWriteCopy();
224
225 void *txDmaData;
226 Addr txDmaAddr;
227 int txDmaLen;
228 bool doTxDmaRead();
229 bool doTxDmaWrite();
230 void txDmaReadCopy();
231 void txDmaWriteCopy();
232
233 void rxDmaReadDone();
234 friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
235 EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
236
237 void rxDmaWriteDone();
238 friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
239 EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
240
241 void txDmaReadDone();
242 friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
243 EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
244
245 void txDmaWriteDone();
246 friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
247 EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
248
249 bool dmaDescFree;
250 bool dmaDataFree;
251
252
253 protected:
254 Tick txDelay;
255 Tick rxDelay;
256
257 void txReset();
258 void rxReset();
259 void regsReset();
260
261 void rxKick();
262 Tick rxKickTick;
263 typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
264 friend void RxKickEvent::process();
265
266 void txKick();
267 Tick txKickTick;
268 typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
269 friend void TxKickEvent::process();
270
271 /**
272 * Retransmit event
273 */
274 void transmit();
275 void txEventTransmit()
276 {
277 transmit();
278 if (txState == txFifoBlock)
279 txKick();
280 }
281 typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
282 friend void TxEvent::process();
283 TxEvent txEvent;
284
285 void txDump() const;
286 void rxDump() const;
287
288 /**
289 * receive address filter
290 */
291 bool rxFilterEnable;
292 bool rxFilter(const PacketPtr &packet);
293 bool acceptBroadcast;
294 bool acceptMulticast;
295 bool acceptUnicast;
296 bool acceptPerfect;
297 bool acceptArp;
298
299 PhysicalMemory *physmem;
300
301 /**
302 * Interrupt management
303 */
304 void devIntrPost(uint32_t interrupts);
305 void devIntrClear(uint32_t interrupts);
306 void devIntrChangeMask();
307
308 Tick intrDelay;
309 Tick intrTick;
310 bool cpuPendingIntr;
311 void cpuIntrPost(Tick when);
312 void cpuInterrupt();
313 void cpuIntrClear();
314
315 typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
316 friend void IntrEvent::process();
317 IntrEvent *intrEvent;
318 NSGigEInt *interface;
319
320 public:
321 struct Params : public PciDev::Params
322 {
323 PhysicalMemory *pmem;
324 HierParams *hier;
325 Bus *header_bus;
326 Bus *payload_bus;
327 Tick intr_delay;
328 Tick tx_delay;
329 Tick rx_delay;
330 Tick pio_latency;
331 bool dma_desc_free;
332 bool dma_data_free;
333 Tick dma_read_delay;
334 Tick dma_write_delay;
335 Tick dma_read_factor;
336 Tick dma_write_factor;
337 bool rx_filter;
338 Net::EthAddr eaddr;
339 uint32_t tx_fifo_size;
340 uint32_t rx_fifo_size;
341 };
342
343 NSGigE(Params *params);
344 ~NSGigE();
345 const Params *params() const { return (const Params *)_params; }
346
347 virtual void WriteConfig(int offset, int size, uint32_t data);
348 virtual void ReadConfig(int offset, int size, uint8_t *data);
349
350 virtual Fault read(MemReqPtr &req, uint8_t *data);
351 virtual Fault write(MemReqPtr &req, const uint8_t *data);
352
353 bool cpuIntrPending() const;
354 void cpuIntrAck() { cpuIntrClear(); }
355
356 bool recvPacket(PacketPtr packet);
357 void transferDone();
358
359 void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
360
361 virtual void serialize(std::ostream &os);
362 virtual void unserialize(Checkpoint *cp, const std::string &section);
363
364 public:
365 void regStats();
366
367 private:
368 Stats::Scalar<> txBytes;
369 Stats::Scalar<> rxBytes;
370 Stats::Scalar<> txPackets;
371 Stats::Scalar<> rxPackets;
372 Stats::Scalar<> txIpChecksums;
373 Stats::Scalar<> rxIpChecksums;
374 Stats::Scalar<> txTcpChecksums;
375 Stats::Scalar<> rxTcpChecksums;
376 Stats::Scalar<> txUdpChecksums;
377 Stats::Scalar<> rxUdpChecksums;
378 Stats::Scalar<> descDmaReads;
379 Stats::Scalar<> descDmaWrites;
380 Stats::Scalar<> descDmaRdBytes;
381 Stats::Scalar<> descDmaWrBytes;
382 Stats::Formula txBandwidth;
383 Stats::Formula rxBandwidth;
384 Stats::Formula txPacketRate;
385 Stats::Formula rxPacketRate;
386 Stats::Scalar<> postedSwi;
387 Stats::Formula coalescedSwi;
388 Stats::Scalar<> totalSwi;
389 Stats::Scalar<> postedRxIdle;
390 Stats::Formula coalescedRxIdle;
391 Stats::Scalar<> totalRxIdle;
392 Stats::Scalar<> postedRxOk;
393 Stats::Formula coalescedRxOk;
394 Stats::Scalar<> totalRxOk;
395 Stats::Scalar<> postedRxDesc;
396 Stats::Formula coalescedRxDesc;
397 Stats::Scalar<> totalRxDesc;
398 Stats::Scalar<> postedTxOk;
399 Stats::Formula coalescedTxOk;
400 Stats::Scalar<> totalTxOk;
401 Stats::Scalar<> postedTxIdle;
402 Stats::Formula coalescedTxIdle;
403 Stats::Scalar<> totalTxIdle;
404 Stats::Scalar<> postedTxDesc;
405 Stats::Formula coalescedTxDesc;
406 Stats::Scalar<> totalTxDesc;
407 Stats::Scalar<> postedRxOrn;
408 Stats::Formula coalescedRxOrn;
409 Stats::Scalar<> totalRxOrn;
410 Stats::Formula coalescedTotal;
411 Stats::Scalar<> postedInterrupts;
412 Stats::Scalar<> droppedPackets;
413
414 public:
415 Tick cacheAccess(MemReqPtr &req);
416 };
417
418 /*
419 * Ethernet Interface for an Ethernet Device
420 */
421 class NSGigEInt : public EtherInt
422 {
423 private:
424 NSGigE *dev;
425
426 public:
427 NSGigEInt(const std::string &name, NSGigE *d)
428 : EtherInt(name), dev(d) { dev->setInterface(this); }
429
430 virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
431 virtual void sendDone() { dev->transferDone(); }
432 };
433
434 #endif // __DEV_NS_GIGE_HH__