Merge zizzer:/bk/linux into zower.eecs.umich.edu:/z/hsul/work/bk/linux
[gem5.git] / dev / ns_gige.hh
1 /*
2 * Copyright (c) 2003 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 "dev/dma.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"
46
47 /** defined by the NS83820 data sheet */
48 #define MAX_TX_FIFO_SIZE 8192
49 #define MAX_RX_FIFO_SIZE 32768
50
51 /** length of ethernet address in bytes */
52 #define EADDR_LEN 6
53
54 /** Transmit State Machine states */
55 enum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead,
56 txDescWrite };
57
58 /** Receive State Machine States */
59 enum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite,
60 rxDescWrite, rxAdvance };
61
62 /**
63 * Ethernet device registers
64 */
65 struct dp_regs {
66 uint32_t command;
67 uint32_t config;
68 uint32_t mear;
69 uint32_t ptscr;
70 uint32_t isr;
71 uint32_t imr;
72 uint32_t ier;
73 uint32_t ihr;
74 uint32_t txdp;
75 uint32_t txdp_hi;
76 uint32_t txcfg;
77 uint32_t gpior;
78 uint32_t rxdp;
79 uint32_t rxdp_hi;
80 uint32_t rxcfg;
81 uint32_t pqcr;
82 uint32_t wcsr;
83 uint32_t pcr;
84 uint32_t rfcr;
85 uint32_t rfdr;
86 uint32_t srr;
87 uint32_t mibc;
88 uint32_t vrcr;
89 uint32_t vtcr;
90 uint32_t vdr;
91 uint32_t ccsr;
92 uint32_t tbicr;
93 uint32_t tbisr;
94 uint32_t tanar;
95 uint32_t tanlpar;
96 uint32_t taner;
97 uint32_t tesr;
98
99 /** for perfect match memory. the linux driver doesn't use any other ROM */
100 uint8_t perfectMatch[EADDR_LEN];
101
102 virtual void serialize(std::ostream &os);
103 virtual void unserialize(Checkpoint *cp, const std::string &section);
104 };
105
106 /** an enum indicating direction, transmit or receive, used as a param for
107 some fns */
108 enum dir_t { tx, rx };
109
110 class DmaEngine;
111 class IntrControl;
112 class EtherDevInt;
113 class PhysicalMemory;
114
115 /**
116 * NS DP82830 Ethernet device model
117 */
118 class EtherDev : public PciDev, public DmaHolder
119 {
120 private:
121 /** pointer to the chipset */
122 Tsunami *tsunami;
123
124 protected:
125 Addr addr;
126 Addr mask;
127
128 /** device register file */
129 dp_regs regs;
130
131 /*** BASIC STRUCTURES FOR TX/RX ***/
132 /* Data FIFOs */
133 typedef std::deque<PacketPtr> pktbuf_t;
134 typedef pktbuf_t::iterator pktiter_t;
135 pktbuf_t txFifo;
136 pktbuf_t rxFifo;
137
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;
141
142 /** various helper vars */
143 uint32_t txPacketLen;
144 uint8_t *txPacketBufPtr;
145 uint8_t *rxPacketBufPtr;
146 uint8_t *rxDescBufPtr;
147 uint32_t fragLen;
148 uint32_t rxCopied;
149
150 /** DescCaches */
151 ns_desc txDescCache;
152 ns_desc rxDescCache;
153
154 /* tx State Machine */
155 tx_state txState;
156 /** Current Transmit Descriptor Done */
157 bool CTDD;
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 */
160 bool txHalt;
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 */
164
165 /** rx State Machine */
166 rx_state rxState;
167 bool CRDD; /* Current Receive Descriptor Done */
168 uint32_t rxPktBytes; /* num of bytes in the current packet being drained
169 from rxDataFifo */
170 uint32_t rxFifoCnt; /* number of bytes in the rxFifo */
171 bool rxHalt;
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 */
175
176 bool extstsEnable;
177 uint32_t maxTxBurst;
178 uint32_t maxRxBurst;
179
180 PhysicalMemory *physmem;
181
182 protected:
183 /**
184 * Receive dma for descriptors done callback
185 */
186 class RxDescDone : public DmaCallback
187 {
188 public:
189 EtherDev *ethernet;
190
191 public:
192 RxDescDone(EtherDev *e);
193 std::string name() const;
194 virtual void process();
195 };
196
197 /**
198 * Receive dma done callback
199 */
200 class RxDone : public DmaCallback
201 {
202 public:
203 EtherDev *ethernet;
204
205 public:
206 RxDone(EtherDev *e);
207 std::string name() const;
208 virtual void process();
209 };
210
211 /**
212 * Transmit dma for descriptors done callback
213 */
214 class TxDescDone : public DmaCallback
215 {
216 public:
217 EtherDev *ethernet;
218
219 public:
220 TxDescDone(EtherDev *e);
221 std::string name() const;
222 virtual void process();
223 };
224
225 /*
226 * Transmit dma done callback
227 */
228 class TxDone : public DmaCallback
229 {
230 public:
231 EtherDev *ethernet;
232 PacketPtr packet;
233
234 public:
235 TxDone(EtherDev *e);
236 std::string name() const;
237 virtual void process();
238 };
239
240 friend class TxDescDone;
241 friend class TxDone;
242 friend class RxDescDone;
243 friend class RxDone;
244
245 RxDescDone rxDescDoneCB;
246 RxDone rxDoneCB;
247 TxDescDone txDescDoneCB;
248 TxDone txDoneCB;
249
250 DmaEngine *dma;
251 DmaRequest readRequest;
252 DmaRequest writeRequest;
253 DmaRequest readDescRequest;
254 DmaRequest writeDescRequest;
255 PacketPtr rxPacket;
256 DmaPhys readPhys;
257 DmaPhys writePhys;
258 DmaPhys readDescPhys;
259 DmaPhys writeDescPhys;
260
261 EtherDevInt *interface;
262
263 protected:
264 IntrControl *intctrl;
265 Tick txDelay;
266 Tick rxDelay;
267
268 void txReset();
269 void rxReset();
270 void regsReset() {
271 memset(&regs, 0, sizeof(regs));
272 regs.mear = 0x12;
273 regs.isr = 0x00608000;
274 regs.txcfg = 0x120;
275 regs.rxcfg = 0x4;
276 regs.srr = 0x0103;
277 regs.mibc = 0x2;
278 regs.vdr = 0x81;
279 regs.tesr = 0xc000;
280 }
281
282 void txKick();
283 void rxKick();
284
285 /*
286 * Retransmit event
287 */
288 class TxEvent : public Event
289 {
290 protected:
291 EtherDev *dev;
292
293 public:
294 TxEvent(EtherDev *_dev)
295 : Event(&mainEventQueue), dev(_dev) {}
296 void process() { dev->transmit(); }
297 virtual const char *description() { return "retransmit"; }
298 };
299 friend class TxEvent;
300 TxEvent txEvent;
301 void transmit();
302
303
304 void txDescDone();
305 void rxDescDone();
306 void txDone(PacketPtr packet);
307 void rxDone();
308
309 void txDump() const;
310 void rxDump() const;
311
312 void devIntrPost(uint32_t interrupts);
313 void devIntrClear(uint32_t interrupts);
314 void devIntrChangeMask();
315
316 bool cpuPendingIntr;
317 void cpuIntrPost();
318 void cpuIntrClear();
319
320 bool rxFilterEnable;
321 bool rxFilter(PacketPtr packet);
322 bool acceptBroadcast;
323 bool acceptMulticast;
324 bool acceptUnicast;
325 bool acceptPerfect;
326 bool acceptArp;
327
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);
332
333 public:
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);
339 ~EtherDev();
340
341 virtual void WriteConfig(int offset, int size, uint32_t data);
342 virtual void ReadConfig(int offset, int size, uint8_t *data);
343
344
345
346 Fault read(MemReqPtr req, uint8_t *data);
347 Fault write(MemReqPtr req, const uint8_t *data);
348
349 bool cpuIntrPending() const;
350 void cpuIntrAck() { cpuIntrClear(); }
351
352 bool recvPacket(PacketPtr packet);
353 void transferDone();
354
355 void setInterface(EtherDevInt *i) { assert(!interface); interface = i; }
356
357 virtual void serialize(std::ostream &os);
358 virtual void unserialize(Checkpoint *cp, const std::string &section);
359
360 virtual DmaRequest *find_dmareq(uint32_t &id) {
361 if (id == 0)
362 return(&readRequest);
363 else if (id == 1)
364 return(&writeRequest);
365 else
366 return(NULL);
367 }
368
369 public:
370 void regStats();
371
372 private:
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;
381
382 void readOneDesc(dir_t dir, uint32_t len = sizeof(ns_desc));
383 void readOneFrag();
384 void writeOneFrag();
385 };
386
387 /*
388 * Ethernet Interface for an Ethernet Device
389 */
390 class EtherDevInt : public EtherInt
391 {
392 private:
393 EtherDev *dev;
394
395 public:
396 EtherDevInt(const std::string &name, EtherDev *d)
397 : EtherInt(name), dev(d) { dev->setInterface(this); }
398
399 virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
400 virtual void sendDone() { dev->transferDone(); }
401 };
402
403 #endif // __NS_GIGE_HH__