5f023dcccd35aeaf2978b3f0c54e21c5f84855f0
[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 "mem/bus/bus.hh"
45 #include "sim/eventq.hh"
46
47 /**
48 * Ethernet device registers
49 */
50 struct dp_regs {
51 uint32_t command;
52 uint32_t config;
53 uint32_t mear;
54 uint32_t ptscr;
55 uint32_t isr;
56 uint32_t imr;
57 uint32_t ier;
58 uint32_t ihr;
59 uint32_t txdp;
60 uint32_t txdp_hi;
61 uint32_t txcfg;
62 uint32_t gpior;
63 uint32_t rxdp;
64 uint32_t rxdp_hi;
65 uint32_t rxcfg;
66 uint32_t pqcr;
67 uint32_t wcsr;
68 uint32_t pcr;
69 uint32_t rfcr;
70 uint32_t rfdr;
71 uint32_t srr;
72 uint32_t mibc;
73 uint32_t vrcr;
74 uint32_t vtcr;
75 uint32_t vdr;
76 uint32_t ccsr;
77 uint32_t tbicr;
78 uint32_t tbisr;
79 uint32_t tanar;
80 uint32_t tanlpar;
81 uint32_t taner;
82 uint32_t tesr;
83 };
84
85 struct dp_rom {
86 /**
87 * for perfect match memory.
88 * the linux driver doesn't use any other ROM
89 */
90 uint8_t perfectMatch[ETH_ADDR_LEN];
91 };
92
93 class IntrControl;
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 pktbuf_t txFifo;
162 uint32_t maxTxFifoSize;
163 pktbuf_t rxFifo;
164 uint32_t maxRxFifoSize;
165
166 /** various helper vars */
167 PacketPtr txPacket;
168 PacketPtr rxPacket;
169 uint8_t *txPacketBufPtr;
170 uint8_t *rxPacketBufPtr;
171 uint32_t txXferLen;
172 uint32_t rxXferLen;
173 bool rxDmaFree;
174 bool txDmaFree;
175
176 /** DescCaches */
177 ns_desc txDescCache;
178 ns_desc rxDescCache;
179
180 /* tx State Machine */
181 TxState txState;
182 bool txEnable;
183
184 /** Current Transmit Descriptor Done */
185 bool CTDD;
186 /** current amt of free space in txDataFifo in bytes */
187 uint32_t txFifoAvail;
188 /** halt the tx state machine after next packet */
189 bool txHalt;
190 /** ptr to the next byte in the current fragment */
191 Addr txFragPtr;
192 /** count of bytes remaining in the current descriptor */
193 uint32_t txDescCnt;
194 DmaState txDmaState;
195
196 /** rx State Machine */
197 RxState rxState;
198 bool rxEnable;
199
200 /** Current Receive Descriptor Done */
201 bool CRDD;
202 /** num of bytes in the current packet being drained from rxDataFifo */
203 uint32_t rxPktBytes;
204 /** number of bytes in the rxFifo */
205 uint32_t rxFifoCnt;
206 /** halt the rx state machine after current packet */
207 bool rxHalt;
208 /** ptr to the next byte in current fragment */
209 Addr rxFragPtr;
210 /** count of bytes remaining in the current descriptor */
211 uint32_t rxDescCnt;
212 DmaState rxDmaState;
213
214 bool extstsEnable;
215
216 protected:
217 Tick dmaReadDelay;
218 Tick dmaWriteDelay;
219
220 Tick dmaReadFactor;
221 Tick dmaWriteFactor;
222
223 void *rxDmaData;
224 Addr rxDmaAddr;
225 int rxDmaLen;
226 bool doRxDmaRead();
227 bool doRxDmaWrite();
228 void rxDmaReadCopy();
229 void rxDmaWriteCopy();
230
231 void *txDmaData;
232 Addr txDmaAddr;
233 int txDmaLen;
234 bool doTxDmaRead();
235 bool doTxDmaWrite();
236 void txDmaReadCopy();
237 void txDmaWriteCopy();
238
239 void rxDmaReadDone();
240 friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
241 EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
242
243 void rxDmaWriteDone();
244 friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
245 EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
246
247 void txDmaReadDone();
248 friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
249 EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
250
251 void txDmaWriteDone();
252 friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
253 EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
254
255 bool dmaDescFree;
256 bool dmaDataFree;
257
258
259 protected:
260 Tick txDelay;
261 Tick rxDelay;
262
263 void txReset();
264 void rxReset();
265 void regsReset();
266
267 void rxKick();
268 Tick rxKickTick;
269 typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
270 friend class RxKickEvent;
271
272 void txKick();
273 Tick txKickTick;
274 typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
275 friend class TxKickEvent;
276
277 /**
278 * Retransmit event
279 */
280 void transmit();
281 void txEventTransmit()
282 {
283 transmit();
284 if (txState == txFifoBlock)
285 txKick();
286 }
287 typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
288 friend class TxEvent;
289 TxEvent txEvent;
290
291 void txDump() const;
292 void rxDump() const;
293
294 /**
295 * receive address filter
296 */
297 bool rxFilterEnable;
298 bool rxFilter(PacketPtr &packet);
299 bool acceptBroadcast;
300 bool acceptMulticast;
301 bool acceptUnicast;
302 bool acceptPerfect;
303 bool acceptArp;
304
305 PhysicalMemory *physmem;
306
307 /**
308 * Interrupt management
309 */
310 IntrControl *intctrl;
311 void devIntrPost(uint32_t interrupts);
312 void devIntrClear(uint32_t interrupts);
313 void devIntrChangeMask();
314
315 Tick intrDelay;
316 Tick intrTick;
317 bool cpuPendingIntr;
318 void cpuIntrPost(Tick when);
319 void cpuInterrupt();
320 void cpuIntrClear();
321
322 typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
323 friend class IntrEvent;
324 IntrEvent *intrEvent;
325 NSGigEInt *interface;
326
327 public:
328 struct Params : public PciDev::Params
329 {
330 PhysicalMemory *pmem;
331 HierParams *hier;
332 Bus *header_bus;
333 Bus *payload_bus;
334 Tick intr_delay;
335 Tick tx_delay;
336 Tick rx_delay;
337 Tick pio_latency;
338 bool dma_desc_free;
339 bool dma_data_free;
340 Tick dma_read_delay;
341 Tick dma_write_delay;
342 Tick dma_read_factor;
343 Tick dma_write_factor;
344 bool rx_filter;
345 Net::EthAddr eaddr;
346 uint32_t tx_fifo_size;
347 uint32_t rx_fifo_size;
348 };
349
350 NSGigE(Params *params);
351 ~NSGigE();
352 const Params *params() const { return (const Params *)_params; }
353
354 virtual void WriteConfig(int offset, int size, uint32_t data);
355 virtual void ReadConfig(int offset, int size, uint8_t *data);
356
357 virtual Fault read(MemReqPtr &req, uint8_t *data);
358 virtual Fault write(MemReqPtr &req, const uint8_t *data);
359
360 bool cpuIntrPending() const;
361 void cpuIntrAck() { cpuIntrClear(); }
362
363 bool recvPacket(PacketPtr &packet);
364 void transferDone();
365
366 void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
367
368 virtual void serialize(std::ostream &os);
369 virtual void unserialize(Checkpoint *cp, const std::string &section);
370
371 public:
372 void regStats();
373
374 private:
375 Stats::Scalar<> txBytes;
376 Stats::Scalar<> rxBytes;
377 Stats::Scalar<> txPackets;
378 Stats::Scalar<> rxPackets;
379 Stats::Scalar<> txIpChecksums;
380 Stats::Scalar<> rxIpChecksums;
381 Stats::Scalar<> txTcpChecksums;
382 Stats::Scalar<> rxTcpChecksums;
383 Stats::Scalar<> txUdpChecksums;
384 Stats::Scalar<> rxUdpChecksums;
385 Stats::Scalar<> descDmaReads;
386 Stats::Scalar<> descDmaWrites;
387 Stats::Scalar<> descDmaRdBytes;
388 Stats::Scalar<> descDmaWrBytes;
389 Stats::Formula txBandwidth;
390 Stats::Formula rxBandwidth;
391 Stats::Formula txPacketRate;
392 Stats::Formula rxPacketRate;
393
394 public:
395 Tick cacheAccess(MemReqPtr &req);
396 };
397
398 /*
399 * Ethernet Interface for an Ethernet Device
400 */
401 class NSGigEInt : public EtherInt
402 {
403 private:
404 NSGigE *dev;
405
406 public:
407 NSGigEInt(const std::string &name, NSGigE *d)
408 : EtherInt(name), dev(d) { dev->setInterface(this); }
409
410 virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
411 virtual void sendDone() { dev->transferDone(); }
412 };
413
414 #endif // __DEV_NS_GIGE_HH__