gem5 v24.0.0.0
Loading...
Searching...
No Matches
ns_gige.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-2005 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
34#include "dev/net/ns_gige.hh"
35
36#include <deque>
37#include <memory>
38#include <string>
39
40#include "base/debug.hh"
41#include "base/inet.hh"
42#include "base/types.hh"
43#include "debug/EthernetAll.hh"
44#include "dev/net/etherlink.hh"
45#include "mem/packet.hh"
46#include "mem/packet_access.hh"
47#include "params/NSGigE.hh"
48#include "sim/system.hh"
49
50// clang complains about std::set being overloaded with Packet::set if
51// we open up the entire namespace std
52using std::make_shared;
53using std::min;
54using std::ostream;
55using std::string;
56
57namespace gem5
58{
59
60const char *NsRxStateStrings[] =
61{
62 "rxIdle",
63 "rxDescRefr",
64 "rxDescRead",
65 "rxFifoBlock",
66 "rxFragWrite",
67 "rxDescWrite",
68 "rxAdvance"
69};
70
71const char *NsTxStateStrings[] =
72{
73 "txIdle",
74 "txDescRefr",
75 "txDescRead",
76 "txFifoBlock",
77 "txFragRead",
78 "txDescWrite",
79 "txAdvance"
80};
81
82const char *NsDmaState[] =
83{
84 "dmaIdle",
85 "dmaReading",
86 "dmaWriting",
87 "dmaReadWaiting",
88 "dmaWriteWaiting"
89};
90
91using namespace networking;
92
94//
95// NSGigE PCI Device
96//
98 : EtherDevBase(p), ioEnable(false),
99 txFifo(p.tx_fifo_size), rxFifo(p.rx_fifo_size),
100 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
101 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
102 txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
103 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
104 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
105 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
106 eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
107 eepromOpcode(0), eepromAddress(0), eepromData(0),
108 dmaReadDelay(p.dma_read_delay), dmaWriteDelay(p.dma_write_delay),
109 dmaReadFactor(p.dma_read_factor), dmaWriteFactor(p.dma_write_factor),
110 rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
111 txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
112 rxDmaReadEvent([this]{ rxDmaReadDone(); }, name()),
113 rxDmaWriteEvent([this]{ rxDmaWriteDone(); }, name()),
114 txDmaReadEvent([this]{ txDmaReadDone(); }, name()),
115 txDmaWriteEvent([this]{ txDmaWriteDone(); }, name()),
116 dmaDescFree(p.dma_desc_free), dmaDataFree(p.dma_data_free),
117 txDelay(p.tx_delay), rxDelay(p.rx_delay),
118 rxKickTick(0),
119 rxKickEvent([this]{ rxKick(); }, name()),
120 txKickTick(0),
121 txKickEvent([this]{ txKick(); }, name()),
122 txEvent([this]{ txEventTransmit(); }, name()),
123 rxFilterEnable(p.rx_filter),
124 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
125 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
126 intrDelay(p.intr_delay), intrTick(0), cpuPendingIntr(false),
127 intrEvent(0), interface(0)
128{
129
130
131 interface = new NSGigEInt(name() + ".int0", this);
132
133 regsReset();
134 memcpy(&rom.perfectMatch, p.hardware_address.bytes(), ETH_ADDR_LEN);
135
136 memset(&rxDesc32, 0, sizeof(rxDesc32));
137 memset(&txDesc32, 0, sizeof(txDesc32));
138 memset(&rxDesc64, 0, sizeof(rxDesc64));
139 memset(&txDesc64, 0, sizeof(txDesc64));
140}
141
143{
144 delete interface;
145}
146
150Tick
152{
153 int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
156 else
157 panic("Device specific PCI config space not implemented!\n");
158
159 switch (offset) {
160 // seems to work fine without all these PCI settings, but i
161 // put in the IO to double check, an assertion will fail if we
162 // need to properly implement it
163 case PCI_COMMAND:
164 if (config.data[offset] & PCI_CMD_IOSE)
165 ioEnable = true;
166 else
167 ioEnable = false;
168 break;
169 }
170
171 return configDelay;
172}
173
174Port &
175NSGigE::getPort(const std::string &if_name, PortID idx)
176{
177 if (if_name == "interface")
178 return *interface;
179 return EtherDevBase::getPort(if_name, idx);
180}
181
186Tick
188{
189 assert(ioEnable);
190
191 //The mask is to give you only the offset into the device register file
192 Addr daddr = pkt->getAddr() & 0xfff;
193 DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n",
194 daddr, pkt->getAddr(), pkt->getSize());
195
196
197 // there are some reserved registers, you can see ns_gige_reg.h and
198 // the spec sheet for details
199 if (daddr > LAST && daddr <= RESERVED) {
200 panic("Accessing reserved register");
201 } else if (daddr > RESERVED && daddr <= 0x3FC) {
202 return readConfig(pkt);
203 } else if (daddr >= MIB_START && daddr <= MIB_END) {
204 // don't implement all the MIB's. hopefully the kernel
205 // doesn't actually DEPEND upon their values
206 // MIB are just hardware stats keepers
207 pkt->setLE<uint32_t>(0);
208 pkt->makeAtomicResponse();
209 return pioDelay;
210 } else if (daddr > 0x3FC)
211 panic("Something is messed up!\n");
212
213 assert(pkt->getSize() == sizeof(uint32_t));
214 uint32_t &reg = *pkt->getPtr<uint32_t>();
215 uint16_t rfaddr;
216
217 switch (daddr) {
218 case CR:
219 reg = regs.command;
220 //these are supposed to be cleared on a read
221 reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);
222 break;
223
224 case CFGR:
225 reg = regs.config;
226 break;
227
228 case MEAR:
229 reg = regs.mear;
230 break;
231
232 case PTSCR:
233 reg = regs.ptscr;
234 break;
235
236 case ISR:
237 reg = regs.isr;
239 break;
240
241 case IMR:
242 reg = regs.imr;
243 break;
244
245 case IER:
246 reg = regs.ier;
247 break;
248
249 case IHR:
250 reg = regs.ihr;
251 break;
252
253 case TXDP:
254 reg = regs.txdp;
255 break;
256
257 case TXDP_HI:
258 reg = regs.txdp_hi;
259 break;
260
261 case TX_CFG:
262 reg = regs.txcfg;
263 break;
264
265 case GPIOR:
266 reg = regs.gpior;
267 break;
268
269 case RXDP:
270 reg = regs.rxdp;
271 break;
272
273 case RXDP_HI:
274 reg = regs.rxdp_hi;
275 break;
276
277 case RX_CFG:
278 reg = regs.rxcfg;
279 break;
280
281 case PQCR:
282 reg = regs.pqcr;
283 break;
284
285 case WCSR:
286 reg = regs.wcsr;
287 break;
288
289 case PCR:
290 reg = regs.pcr;
291 break;
292
293 // see the spec sheet for how RFCR and RFDR work
294 // basically, you write to RFCR to tell the machine
295 // what you want to do next, then you act upon RFDR,
296 // and the device will be prepared b/c of what you
297 // wrote to RFCR
298 case RFCR:
299 reg = regs.rfcr;
300 break;
301
302 case RFDR:
303 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
304 switch (rfaddr) {
305 // Read from perfect match ROM octets
306 case 0x000:
307 reg = rom.perfectMatch[1];
308 reg = reg << 8;
309 reg += rom.perfectMatch[0];
310 break;
311 case 0x002:
312 reg = rom.perfectMatch[3] << 8;
313 reg += rom.perfectMatch[2];
314 break;
315 case 0x004:
316 reg = rom.perfectMatch[5] << 8;
317 reg += rom.perfectMatch[4];
318 break;
319 default:
320 // Read filter hash table
321 if (rfaddr >= FHASH_ADDR &&
322 rfaddr < FHASH_ADDR + FHASH_SIZE) {
323
324 // Only word-aligned reads supported
325 if (rfaddr % 2)
326 panic("unaligned read from filter hash table!");
327
328 reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8;
329 reg += rom.filterHash[rfaddr - FHASH_ADDR];
330 break;
331 }
332
333 panic("reading RFDR for something other than pattern"
334 " matching or hashing! %#x\n", rfaddr);
335 }
336 break;
337
338 case SRR:
339 reg = regs.srr;
340 break;
341
342 case MIBC:
343 reg = regs.mibc;
344 reg &= ~(MIBC_MIBS | MIBC_ACLR);
345 break;
346
347 case VRCR:
348 reg = regs.vrcr;
349 break;
350
351 case VTCR:
352 reg = regs.vtcr;
353 break;
354
355 case VDR:
356 reg = regs.vdr;
357 break;
358
359 case CCSR:
360 reg = regs.ccsr;
361 break;
362
363 case TBICR:
364 reg = regs.tbicr;
365 break;
366
367 case TBISR:
368 reg = regs.tbisr;
369 break;
370
371 case TANAR:
372 reg = regs.tanar;
373 break;
374
375 case TANLPAR:
376 reg = regs.tanlpar;
377 break;
378
379 case TANER:
380 reg = regs.taner;
381 break;
382
383 case TESR:
384 reg = regs.tesr;
385 break;
386
387 case M5REG:
388 reg = 0;
389 if (params().rx_thread)
391 if (params().tx_thread)
393 if (params().rss)
394 reg |= M5REG_RSS;
395 break;
396
397 default:
398 panic("reading unimplemented register: addr=%#x", daddr);
399 }
400
401 DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
402 daddr, reg, reg);
403
404 pkt->makeAtomicResponse();
405 return pioDelay;
406}
407
408Tick
410{
411 assert(ioEnable);
412
413 Addr daddr = pkt->getAddr() & 0xfff;
414 DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
415 daddr, pkt->getAddr(), pkt->getSize());
416
417 if (daddr > LAST && daddr <= RESERVED) {
418 panic("Accessing reserved register");
419 } else if (daddr > RESERVED && daddr <= 0x3FC) {
420 return writeConfig(pkt);
421 } else if (daddr > 0x3FC)
422 panic("Something is messed up!\n");
423
424 if (pkt->getSize() == sizeof(uint32_t)) {
425 uint32_t reg = pkt->getLE<uint32_t>();
426 uint16_t rfaddr;
427
428 DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg);
429
430 switch (daddr) {
431 case CR:
432 regs.command = reg;
433 if (reg & CR_TXD) {
434 txEnable = false;
435 } else if (reg & CR_TXE) {
436 txEnable = true;
437
438 // the kernel is enabling the transmit machine
439 if (txState == txIdle)
440 txKick();
441 }
442
443 if (reg & CR_RXD) {
444 rxEnable = false;
445 } else if (reg & CR_RXE) {
446 rxEnable = true;
447
448 if (rxState == rxIdle)
449 rxKick();
450 }
451
452 if (reg & CR_TXR)
453 txReset();
454
455 if (reg & CR_RXR)
456 rxReset();
457
458 if (reg & CR_SWI)
460
461 if (reg & CR_RST) {
462 txReset();
463 rxReset();
464
465 regsReset();
466 }
467 break;
468
469 case CFGR:
470 if (reg & CFGR_LNKSTS ||
471 reg & CFGR_SPDSTS ||
472 reg & CFGR_DUPSTS ||
473 reg & CFGR_RESERVED ||
474 reg & CFGR_T64ADDR ||
476 // First clear all writable bits
480 // Now set the appropriate writable bits
484 }
485
486 if (reg & CFGR_AUTO_1000)
487 panic("CFGR_AUTO_1000 not implemented!\n");
488
489 if (reg & CFGR_PCI64_DET)
490 panic("CFGR_PCI64_DET is read only register!\n");
491
492 if (reg & CFGR_EXTSTS_EN)
493 extstsEnable = true;
494 else
495 extstsEnable = false;
496 break;
497
498 case MEAR:
499 // Clear writable bits
501 // Set appropriate writable bits
502 regs.mear |= reg & ~MEAR_EEDO;
503
504 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
505 // even though it could get it through RFDR
506 if (reg & MEAR_EESEL) {
507 // Rising edge of clock
508 if (reg & MEAR_EECLK && !eepromClk)
509 eepromKick();
510 }
511 else {
513 regs.mear &= ~MEAR_EEDI;
514 }
515
517
518 // since phy is completely faked, MEAR_MD* don't matter
519 break;
520
521 case PTSCR:
523 // these control BISTs for various parts of chip - we
524 // don't care or do just fake that the BIST is done
525 if (reg & PTSCR_RBIST_EN)
527 if (reg & PTSCR_EEBIST_EN)
528 regs.ptscr &= ~PTSCR_EEBIST_EN;
529 if (reg & PTSCR_EELOAD_EN)
530 regs.ptscr &= ~PTSCR_EELOAD_EN;
531 break;
532
533 case ISR: /* writing to the ISR has no effect */
534 panic("ISR is a read only register!\n");
535
536 case IMR:
537 regs.imr = reg;
539 break;
540
541 case IER:
542 regs.ier = reg;
543 break;
544
545 case IHR:
546 regs.ihr = reg;
547 /* not going to implement real interrupt holdoff */
548 break;
549
550 case TXDP:
551 regs.txdp = (reg & 0xFFFFFFFC);
552 assert(txState == txIdle);
553 CTDD = false;
554 break;
555
556 case TXDP_HI:
557 regs.txdp_hi = reg;
558 break;
559
560 case TX_CFG:
561 regs.txcfg = reg;
562
563 // also, we currently don't care about fill/drain
564 // thresholds though this may change in the future with
565 // more realistic networks or a driver which changes it
566 // according to feedback
567
568 break;
569
570 case GPIOR:
571 // Only write writable bits
576 /* these just control general purpose i/o pins, don't matter */
577 break;
578
579 case RXDP:
580 regs.rxdp = reg;
581 CRDD = false;
582 break;
583
584 case RXDP_HI:
585 regs.rxdp_hi = reg;
586 break;
587
588 case RX_CFG:
589 regs.rxcfg = reg;
590 break;
591
592 case PQCR:
593 /* there is no priority queueing used in the linux 2.6 driver */
594 regs.pqcr = reg;
595 break;
596
597 case WCSR:
598 /* not going to implement wake on LAN */
599 regs.wcsr = reg;
600 break;
601
602 case PCR:
603 /* not going to implement pause control */
604 regs.pcr = reg;
605 break;
606
607 case RFCR:
608 regs.rfcr = reg;
609
610 rxFilterEnable = (reg & RFCR_RFEN) ? true : false;
611 acceptBroadcast = (reg & RFCR_AAB) ? true : false;
612 acceptMulticast = (reg & RFCR_AAM) ? true : false;
613 acceptUnicast = (reg & RFCR_AAU) ? true : false;
614 acceptPerfect = (reg & RFCR_APM) ? true : false;
615 acceptArp = (reg & RFCR_AARP) ? true : false;
616 multicastHashEnable = (reg & RFCR_MHEN) ? true : false;
617
618 if (reg & RFCR_UHEN)
619 panic("Unicast hash filtering not used by drivers!\n");
620
621 if (reg & RFCR_ULM)
622 panic("RFCR_ULM not implemented!\n");
623
624 break;
625
626 case RFDR:
627 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
628 switch (rfaddr) {
629 case 0x000:
630 rom.perfectMatch[0] = (uint8_t)reg;
631 rom.perfectMatch[1] = (uint8_t)(reg >> 8);
632 break;
633 case 0x002:
634 rom.perfectMatch[2] = (uint8_t)reg;
635 rom.perfectMatch[3] = (uint8_t)(reg >> 8);
636 break;
637 case 0x004:
638 rom.perfectMatch[4] = (uint8_t)reg;
639 rom.perfectMatch[5] = (uint8_t)(reg >> 8);
640 break;
641 default:
642
643 if (rfaddr >= FHASH_ADDR &&
644 rfaddr < FHASH_ADDR + FHASH_SIZE) {
645
646 // Only word-aligned writes supported
647 if (rfaddr % 2)
648 panic("unaligned write to filter hash table!");
649
650 rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg;
651 rom.filterHash[rfaddr - FHASH_ADDR + 1]
652 = (uint8_t)(reg >> 8);
653 break;
654 }
655 panic("writing RFDR for something other than pattern matching "
656 "or hashing! %#x\n", rfaddr);
657 }
658 break;
659
660 case BRAR:
661 regs.brar = reg;
662 break;
663
664 case BRDR:
665 panic("the driver never uses BRDR, something is wrong!\n");
666
667 case SRR:
668 panic("SRR is read only register!\n");
669
670 case MIBC:
671 panic("the driver never uses MIBC, something is wrong!\n");
672
673 case VRCR:
674 regs.vrcr = reg;
675 break;
676
677 case VTCR:
678 regs.vtcr = reg;
679 break;
680
681 case VDR:
682 panic("the driver never uses VDR, something is wrong!\n");
683
684 case CCSR:
685 /* not going to implement clockrun stuff */
686 regs.ccsr = reg;
687 break;
688
689 case TBICR:
690 regs.tbicr = reg;
692 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
693
694 if (reg & TBICR_MR_AN_ENABLE) {
697 }
698
699 break;
700
701 case TBISR:
702 panic("TBISR is read only register!\n");
703
704 case TANAR:
705 // Only write the writable bits
708
709 // Pause capability unimplemented
710 break;
711
712 case TANLPAR:
713 panic("this should only be written to by the fake phy!\n");
714
715 case TANER:
716 panic("TANER is read only register!\n");
717
718 case TESR:
719 regs.tesr = reg;
720 break;
721
722 default:
723 panic("invalid register access daddr=%#x", daddr);
724 }
725 } else {
726 panic("Invalid Request Size");
727 }
728 pkt->makeAtomicResponse();
729 return pioDelay;
730}
731
732void
733NSGigE::devIntrPost(uint32_t interrupts)
734{
735 if (interrupts & ISR_RESERVE)
736 panic("Cannot set a reserved interrupt");
737
738 if (interrupts & ISR_NOIMPL)
739 warn("interrupt not implemented %#x\n", interrupts);
740
741 interrupts &= ISR_IMPL;
742 regs.isr |= interrupts;
743
744 if (interrupts & regs.imr) {
745 if (interrupts & ISR_SWI) {
747 }
748 if (interrupts & ISR_RXIDLE) {
750 }
751 if (interrupts & ISR_RXOK) {
753 }
754 if (interrupts & ISR_RXDESC) {
756 }
757 if (interrupts & ISR_TXOK) {
759 }
760 if (interrupts & ISR_TXIDLE) {
762 }
763 if (interrupts & ISR_TXDESC) {
765 }
766 if (interrupts & ISR_RXORN) {
768 }
769 }
770
771 DPRINTF(EthernetIntr,
772 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
773 interrupts, regs.isr, regs.imr);
774
775 if ((regs.isr & regs.imr)) {
776 Tick when = curTick();
777 if ((regs.isr & regs.imr & ISR_NODELAY) == 0)
778 when += intrDelay;
780 cpuIntrPost(when);
781 }
782}
783
784/* writing this interrupt counting stats inside this means that this function
785 is now limited to being used to clear all interrupts upon the kernel
786 reading isr and servicing. just telling you in case you were thinking
787 of expanding use.
788*/
789void
790NSGigE::devIntrClear(uint32_t interrupts)
791{
792 if (interrupts & ISR_RESERVE)
793 panic("Cannot clear a reserved interrupt");
794
795 if (regs.isr & regs.imr & ISR_SWI) {
797 }
798 if (regs.isr & regs.imr & ISR_RXIDLE) {
800 }
801 if (regs.isr & regs.imr & ISR_RXOK) {
803 }
804 if (regs.isr & regs.imr & ISR_RXDESC) {
806 }
807 if (regs.isr & regs.imr & ISR_TXOK) {
809 }
810 if (regs.isr & regs.imr & ISR_TXIDLE) {
812 }
813 if (regs.isr & regs.imr & ISR_TXDESC) {
815 }
816 if (regs.isr & regs.imr & ISR_RXORN) {
818 }
819
820 interrupts &= ~ISR_NOIMPL;
821 regs.isr &= ~interrupts;
822
823 DPRINTF(EthernetIntr,
824 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
825 interrupts, regs.isr, regs.imr);
826
827 if (!(regs.isr & regs.imr))
828 cpuIntrClear();
829}
830
831void
833{
834 DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
836
837 if (regs.isr & regs.imr)
839 else
840 cpuIntrClear();
841}
842
843void
845{
846 // If the interrupt you want to post is later than an interrupt
847 // already scheduled, just let it post in the coming one and don't
848 // schedule another.
849 // HOWEVER, must be sure that the scheduled intrTick is in the
850 // future (this was formerly the source of a bug)
855 assert(when >= curTick());
856 assert(intrTick >= curTick() || intrTick == 0);
857 if (when > intrTick && intrTick != 0) {
858 DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n",
859 intrTick);
860 return;
861 }
862
863 intrTick = when;
864 if (intrTick < curTick()) {
865 intrTick = curTick();
866 }
867
868 DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n",
869 intrTick);
870
871 if (intrEvent)
872 intrEvent->squash();
873
875 name(), true);
877}
878
879void
881{
882 assert(intrTick == curTick());
883
884 // Whether or not there's a pending interrupt, we don't care about
885 // it anymore
886 intrEvent = 0;
887 intrTick = 0;
888
889 // Don't send an interrupt if there's already one
890 if (cpuPendingIntr) {
891 DPRINTF(EthernetIntr,
892 "would send an interrupt now, but there's already pending\n");
893 } else {
894 // Send interrupt
895 cpuPendingIntr = true;
896
897 DPRINTF(EthernetIntr, "posting interrupt\n");
898 intrPost();
899 }
900}
901
902void
904{
905 if (!cpuPendingIntr)
906 return;
907
908 if (intrEvent) {
909 intrEvent->squash();
910 intrEvent = 0;
911 }
912
913 intrTick = 0;
914
915 cpuPendingIntr = false;
916
917 DPRINTF(EthernetIntr, "clearing interrupt\n");
918 intrClear();
919}
920
921bool
924
925void
927{
928
929 DPRINTF(Ethernet, "transmit reset\n");
930
931 CTDD = false;
932 txEnable = false;;
933 txFragPtr = 0;
934 assert(txDescCnt == 0);
935 txFifo.clear();
936 txState = txIdle;
937 assert(txDmaState == dmaIdle);
938}
939
940void
942{
943 DPRINTF(Ethernet, "receive reset\n");
944
945 CRDD = false;
946 assert(rxPktBytes == 0);
947 rxEnable = false;
948 rxFragPtr = 0;
949 assert(rxDescCnt == 0);
950 assert(rxDmaState == dmaIdle);
951 rxFifo.clear();
952 rxState = rxIdle;
953}
954
955void
957{
958 memset(&regs, 0, sizeof(regs));
960 regs.mear = 0x12;
961 regs.txcfg = 0x120; // set drain threshold to 1024 bytes and
962 // fill threshold to 32 bytes
963 regs.rxcfg = 0x4; // set drain threshold to 16 bytes
964 regs.srr = 0x0103; // set the silicon revision to rev B or 0x103
966 regs.vdr = 0x81; // set the vlan tag type to 802.1q
967 regs.tesr = 0xc000; // TBI capable of both full and half duplex
968 regs.brar = 0xffffffff;
969
970 extstsEnable = false;
971 acceptBroadcast = false;
972 acceptMulticast = false;
973 acceptUnicast = false;
974 acceptPerfect = false;
975 acceptArp = false;
976}
977
978bool
980{
983
986 else
988
989 return true;
990}
991
992void
994{
995 assert(rxDmaState == dmaReading);
997
998 DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n",
1000 DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
1001
1002 // If the transmit state machine has a pending DMA, let it go first
1004 txKick();
1005
1006 rxKick();
1007}
1008
1009bool
1011{
1014
1017 else
1019 return true;
1020}
1021
1022void
1024{
1025 assert(rxDmaState == dmaWriting);
1027
1028 DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
1030 DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
1031
1032 // If the transmit state machine has a pending DMA, let it go first
1034 txKick();
1035
1036 rxKick();
1037}
1038
1039void
1041{
1042 bool is64bit = (bool)(regs.config & CFGR_M64ADDR);
1043
1044 DPRINTF(EthernetSM,
1045 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1046 NsRxStateStrings[rxState], rxFifo.size(), is64bit ? 64 : 32);
1047
1048 Addr link, bufptr;
1049 uint32_t &cmdsts = is64bit ? rxDesc64.cmdsts : rxDesc32.cmdsts;
1050 uint32_t &extsts = is64bit ? rxDesc64.extsts : rxDesc32.extsts;
1051
1052 next:
1053 if (rxKickTick > curTick()) {
1054 DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
1055 rxKickTick);
1056
1057 goto exit;
1058 }
1059
1060 // Go to the next state machine clock tick.
1062
1063 switch(rxDmaState) {
1064 case dmaReadWaiting:
1065 if (doRxDmaRead())
1066 goto exit;
1067 break;
1068 case dmaWriteWaiting:
1069 if (doRxDmaWrite())
1070 goto exit;
1071 break;
1072 default:
1073 break;
1074 }
1075
1076 link = is64bit ? (Addr)rxDesc64.link : (Addr)rxDesc32.link;
1077 bufptr = is64bit ? (Addr)rxDesc64.bufptr : (Addr)rxDesc32.bufptr;
1078
1079 // see state machine from spec for details
1080 // the way this works is, if you finish work on one state and can
1081 // go directly to another, you do that through jumping to the
1082 // label "next". however, if you have intermediate work, like DMA
1083 // so that you can't go to the next state yet, you go to exit and
1084 // exit the loop. however, when the DMA is done it will trigger
1085 // an event and come back to this loop.
1086 switch (rxState) {
1087 case rxIdle:
1088 if (!rxEnable) {
1089 DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n");
1090 goto exit;
1091 }
1092
1093 if (CRDD) {
1095
1096 rxDmaAddr = regs.rxdp & 0x3fffffff;
1097 rxDmaData =
1098 is64bit ? (void *)&rxDesc64.link : (void *)&rxDesc32.link;
1099 rxDmaLen = is64bit ? sizeof(rxDesc64.link) : sizeof(rxDesc32.link);
1101
1104
1105 if (doRxDmaRead())
1106 goto exit;
1107 } else {
1109
1110 rxDmaAddr = regs.rxdp & 0x3fffffff;
1111 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32;
1112 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32);
1114
1117
1118 if (doRxDmaRead())
1119 goto exit;
1120 }
1121 break;
1122
1123 case rxDescRefr:
1124 if (rxDmaState != dmaIdle)
1125 goto exit;
1126
1128 break;
1129
1130 case rxDescRead:
1131 if (rxDmaState != dmaIdle)
1132 goto exit;
1133
1134 DPRINTF(EthernetDesc, "rxDesc: addr=%08x read descriptor\n",
1135 regs.rxdp & 0x3fffffff);
1136 DPRINTF(EthernetDesc,
1137 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1138 link, bufptr, cmdsts, extsts);
1139
1140 if (cmdsts & CMDSTS_OWN) {
1142 rxState = rxIdle;
1143 goto exit;
1144 } else {
1146 rxFragPtr = bufptr;
1147 rxDescCnt = cmdsts & CMDSTS_LEN_MASK;
1148 }
1149 break;
1150
1151 case rxFifoBlock:
1152 if (!rxPacket) {
1158 if (rxFifo.empty())
1159 goto exit;
1160
1161 DPRINTF(EthernetSM, "****processing receive of new packet****\n");
1162
1163 // If we don't have a packet, grab a new one from the fifo.
1164 rxPacket = rxFifo.front();
1165 rxPktBytes = rxPacket->length;
1166 rxPacketBufPtr = rxPacket->data;
1167
1168#if TRACING_ON
1169 if (debug::Ethernet) {
1170 IpPtr ip(rxPacket);
1171 if (ip) {
1172 DPRINTF(Ethernet, "ID is %d\n", ip->id());
1173 TcpPtr tcp(ip);
1174 if (tcp) {
1175 DPRINTF(Ethernet,
1176 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1177 tcp->sport(), tcp->dport(), tcp->seq(),
1178 tcp->ack());
1179 }
1180 }
1181 }
1182#endif
1183
1184 // sanity check - i think the driver behaves like this
1185 assert(rxDescCnt >= rxPktBytes);
1186 rxFifo.pop();
1187 }
1188
1189
1190 // dont' need the && rxDescCnt > 0 if driver sanity check
1191 // above holds
1192 if (rxPktBytes > 0) {
1194 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1195 // check holds
1197
1198 rxDmaAddr = rxFragPtr & 0x3fffffff;
1202
1203 if (doRxDmaWrite())
1204 goto exit;
1205
1206 } else {
1208
1209 //if (rxPktBytes == 0) { /* packet is done */
1210 assert(rxPktBytes == 0);
1211 DPRINTF(EthernetSM, "done with receiving packet\n");
1212
1213 cmdsts |= CMDSTS_OWN;
1214 cmdsts &= ~CMDSTS_MORE;
1215 cmdsts |= CMDSTS_OK;
1216 cmdsts &= 0xffff0000;
1217 cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE
1218
1219 IpPtr ip(rxPacket);
1220 if (extstsEnable && ip) {
1221 extsts |= EXTSTS_IPPKT;
1223 if (cksum(ip) != 0) {
1224 DPRINTF(EthernetCksum, "Rx IP Checksum Error\n");
1225 extsts |= EXTSTS_IPERR;
1226 }
1227 TcpPtr tcp(ip);
1228 UdpPtr udp(ip);
1229 if (tcp) {
1230 extsts |= EXTSTS_TCPPKT;
1232 if (cksum(tcp) != 0) {
1233 DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n");
1234 extsts |= EXTSTS_TCPERR;
1235
1236 }
1237 } else if (udp) {
1238 extsts |= EXTSTS_UDPPKT;
1240 if (cksum(udp) != 0) {
1241 DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n");
1242 extsts |= EXTSTS_UDPERR;
1243 }
1244 }
1245 }
1246 rxPacket = 0;
1247
1248 /*
1249 * the driver seems to always receive into desc buffers
1250 * of size 1514, so you never have a pkt that is split
1251 * into multiple descriptors on the receive side, so
1252 * i don't implement that case, hence the assert above.
1253 */
1254
1255 DPRINTF(EthernetDesc,
1256 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1257 regs.rxdp & 0x3fffffff);
1258 DPRINTF(EthernetDesc,
1259 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1260 link, bufptr, cmdsts, extsts);
1261
1262 rxDmaAddr = regs.rxdp & 0x3fffffff;
1263 rxDmaData = &cmdsts;
1264 if (is64bit) {
1265 rxDmaAddr += offsetof(ns_desc64, cmdsts);
1266 rxDmaLen = sizeof(rxDesc64.cmdsts) + sizeof(rxDesc64.extsts);
1267 } else {
1268 rxDmaAddr += offsetof(ns_desc32, cmdsts);
1269 rxDmaLen = sizeof(rxDesc32.cmdsts) + sizeof(rxDesc32.extsts);
1270 }
1272
1275
1276 if (doRxDmaWrite())
1277 goto exit;
1278 }
1279 break;
1280
1281 case rxFragWrite:
1282 if (rxDmaState != dmaIdle)
1283 goto exit;
1284
1288
1290 break;
1291
1292 case rxDescWrite:
1293 if (rxDmaState != dmaIdle)
1294 goto exit;
1295
1296 assert(cmdsts & CMDSTS_OWN);
1297
1298 assert(rxPacket == 0);
1300
1301 if (cmdsts & CMDSTS_INTR)
1303
1304 if (!rxEnable) {
1305 DPRINTF(EthernetSM, "Halting the RX state machine\n");
1306 rxState = rxIdle;
1307 goto exit;
1308 } else
1310 break;
1311
1312 case rxAdvance:
1313 if (link == 0) {
1315 rxState = rxIdle;
1316 CRDD = true;
1317 goto exit;
1318 } else {
1319 if (rxDmaState != dmaIdle)
1320 goto exit;
1322 regs.rxdp = link;
1323 CRDD = false;
1324
1325 rxDmaAddr = regs.rxdp & 0x3fffffff;
1326 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32;
1327 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32);
1329
1330 if (doRxDmaRead())
1331 goto exit;
1332 }
1333 break;
1334
1335 default:
1336 panic("Invalid rxState!");
1337 }
1338
1339 DPRINTF(EthernetSM, "entering next rxState=%s\n",
1341 goto next;
1342
1343 exit:
1347 DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
1349
1350 if (!rxKickEvent.scheduled())
1352}
1353
1354void
1356{
1357 if (txFifo.empty()) {
1358 DPRINTF(Ethernet, "nothing to transmit\n");
1359 return;
1360 }
1361
1362 DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n",
1363 txFifo.size());
1364 if (interface->sendPacket(txFifo.front())) {
1365#if TRACING_ON
1366 if (debug::Ethernet) {
1367 IpPtr ip(txFifo.front());
1368 if (ip) {
1369 DPRINTF(Ethernet, "ID is %d\n", ip->id());
1370 TcpPtr tcp(ip);
1371 if (tcp) {
1372 DPRINTF(Ethernet,
1373 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1374 tcp->sport(), tcp->dport(), tcp->seq(),
1375 tcp->ack());
1376 }
1377 }
1378 }
1379#endif
1380
1381 DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length);
1382 etherDeviceStats.txBytes += txFifo.front()->length;
1384
1385 DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n",
1386 txFifo.avail());
1387 txFifo.pop();
1388
1389 /*
1390 * normally do a writeback of the descriptor here, and ONLY
1391 * after that is done, send this interrupt. but since our
1392 * stuff never actually fails, just do this interrupt here,
1393 * otherwise the code has to stray from this nice format.
1394 * besides, it's functionally the same.
1395 */
1397 }
1398
1399 if (!txFifo.empty() && !txEvent.scheduled()) {
1400 DPRINTF(Ethernet, "reschedule transmit\n");
1402 }
1403}
1404
1405bool
1407{
1410
1413 else
1415
1416 return true;
1417}
1418
1419void
1421{
1422 assert(txDmaState == dmaReading);
1424
1425 DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
1427 DDUMP(EthernetDMA, txDmaData, txDmaLen);
1428
1429 // If the receive state machine has a pending DMA, let it go first
1431 rxKick();
1432
1433 txKick();
1434}
1435
1436bool
1438{
1441
1444 else
1446 return true;
1447}
1448
1449void
1451{
1452 assert(txDmaState == dmaWriting);
1454
1455 DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n",
1457 DDUMP(EthernetDMA, txDmaData, txDmaLen);
1458
1459 // If the receive state machine has a pending DMA, let it go first
1461 rxKick();
1462
1463 txKick();
1464}
1465
1466void
1468{
1469 bool is64bit = (bool)(regs.config & CFGR_M64ADDR);
1470
1471 DPRINTF(EthernetSM, "transmit kick txState=%s %d-bit\n",
1472 NsTxStateStrings[txState], is64bit ? 64 : 32);
1473
1474 Addr link, bufptr;
1475 uint32_t &cmdsts = is64bit ? txDesc64.cmdsts : txDesc32.cmdsts;
1476 uint32_t &extsts = is64bit ? txDesc64.extsts : txDesc32.extsts;
1477
1478 next:
1479 if (txKickTick > curTick()) {
1480 DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
1481 txKickTick);
1482 goto exit;
1483 }
1484
1485 // Go to the next state machine clock tick.
1487
1488 switch(txDmaState) {
1489 case dmaReadWaiting:
1490 if (doTxDmaRead())
1491 goto exit;
1492 break;
1493 case dmaWriteWaiting:
1494 if (doTxDmaWrite())
1495 goto exit;
1496 break;
1497 default:
1498 break;
1499 }
1500
1501 link = is64bit ? (Addr)txDesc64.link : (Addr)txDesc32.link;
1502 bufptr = is64bit ? (Addr)txDesc64.bufptr : (Addr)txDesc32.bufptr;
1503 switch (txState) {
1504 case txIdle:
1505 if (!txEnable) {
1506 DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n");
1507 goto exit;
1508 }
1509
1510 if (CTDD) {
1512
1513 txDmaAddr = regs.txdp & 0x3fffffff;
1514 txDmaData =
1515 is64bit ? (void *)&txDesc64.link : (void *)&txDesc32.link;
1516 txDmaLen = is64bit ? sizeof(txDesc64.link) : sizeof(txDesc32.link);
1518
1521
1522 if (doTxDmaRead())
1523 goto exit;
1524
1525 } else {
1527
1528 txDmaAddr = regs.txdp & 0x3fffffff;
1529 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32;
1530 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32);
1532
1535
1536 if (doTxDmaRead())
1537 goto exit;
1538 }
1539 break;
1540
1541 case txDescRefr:
1542 if (txDmaState != dmaIdle)
1543 goto exit;
1544
1546 break;
1547
1548 case txDescRead:
1549 if (txDmaState != dmaIdle)
1550 goto exit;
1551
1552 DPRINTF(EthernetDesc, "txDesc: addr=%08x read descriptor\n",
1553 regs.txdp & 0x3fffffff);
1554 DPRINTF(EthernetDesc,
1555 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1556 link, bufptr, cmdsts, extsts);
1557
1558 if (cmdsts & CMDSTS_OWN) {
1560 txFragPtr = bufptr;
1561 txDescCnt = cmdsts & CMDSTS_LEN_MASK;
1562 } else {
1564 txState = txIdle;
1565 goto exit;
1566 }
1567 break;
1568
1569 case txFifoBlock:
1570 if (!txPacket) {
1571 DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
1572 txPacket = make_shared<EthPacketData>(16384);
1573 txPacketBufPtr = txPacket->data;
1574 }
1575
1576 if (txDescCnt == 0) {
1577 DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n");
1578 if (cmdsts & CMDSTS_MORE) {
1579 DPRINTF(EthernetSM, "there are more descriptors to come\n");
1581
1582 cmdsts &= ~CMDSTS_OWN;
1583
1584 txDmaAddr = regs.txdp & 0x3fffffff;
1585 txDmaData = &cmdsts;
1586 if (is64bit) {
1587 txDmaAddr += offsetof(ns_desc64, cmdsts);
1588 txDmaLen = sizeof(txDesc64.cmdsts);
1589 } else {
1590 txDmaAddr += offsetof(ns_desc32, cmdsts);
1591 txDmaLen = sizeof(txDesc32.cmdsts);
1592 }
1594
1595 if (doTxDmaWrite())
1596 goto exit;
1597
1598 } else { /* this packet is totally done */
1599 DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n");
1600 /* deal with the the packet that just finished */
1601 if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) {
1602 IpPtr ip(txPacket);
1603 if (extsts & EXTSTS_UDPPKT) {
1604 UdpPtr udp(ip);
1605 if (udp) {
1606 udp->sum(0);
1607 udp->sum(cksum(udp));
1609 } else {
1611 warn_once("UDPPKT set, but not UDP!\n");
1612 }
1613 } else if (extsts & EXTSTS_TCPPKT) {
1614 TcpPtr tcp(ip);
1615 if (tcp) {
1616 tcp->sum(0);
1617 tcp->sum(cksum(tcp));
1619 } else {
1620 warn_once("TCPPKT set, but not UDP!\n");
1621 }
1622 }
1623 if (extsts & EXTSTS_IPPKT) {
1624 if (ip) {
1625 ip->sum(0);
1626 ip->sum(cksum(ip));
1628 } else {
1629 warn_once("IPPKT set, but not UDP!\n");
1630 }
1631 }
1632 }
1633
1634 txPacket->simLength = txPacketBufPtr - txPacket->data;
1635 txPacket->length = txPacketBufPtr - txPacket->data;
1636 // this is just because the receive can't handle a
1637 // packet bigger want to make sure
1638 if (txPacket->length > 1514)
1639 panic("transmit packet too large, %s > 1514\n",
1640 txPacket->length);
1641
1642#ifndef NDEBUG
1643 bool success =
1644#endif
1646 assert(success);
1647
1648 /*
1649 * this following section is not tqo spec, but
1650 * functionally shouldn't be any different. normally,
1651 * the chip will wait til the transmit has occurred
1652 * before writing back the descriptor because it has
1653 * to wait to see that it was successfully transmitted
1654 * to decide whether to set CMDSTS_OK or not.
1655 * however, in the simulator since it is always
1656 * successfully transmitted, and writing it exactly to
1657 * spec would complicate the code, we just do it here
1658 */
1659
1660 cmdsts &= ~CMDSTS_OWN;
1661 cmdsts |= CMDSTS_OK;
1662
1663 DPRINTF(EthernetDesc,
1664 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1665 cmdsts, extsts);
1666
1668 txDmaAddr = regs.txdp & 0x3fffffff;
1669 txDmaData = &cmdsts;
1670 if (is64bit) {
1671 txDmaAddr += offsetof(ns_desc64, cmdsts);
1672 txDmaLen =
1673 sizeof(txDesc64.cmdsts) + sizeof(txDesc64.extsts);
1674 } else {
1675 txDmaAddr += offsetof(ns_desc32, cmdsts);
1676 txDmaLen =
1677 sizeof(txDesc32.cmdsts) + sizeof(txDesc32.extsts);
1678 }
1679
1682
1683 transmit();
1684 txPacket = 0;
1685
1686 if (!txEnable) {
1687 DPRINTF(EthernetSM, "halting TX state machine\n");
1688 txState = txIdle;
1689 goto exit;
1690 } else
1692
1693 if (doTxDmaWrite())
1694 goto exit;
1695 }
1696 } else {
1697 DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
1698 if (!txFifo.full()) {
1700
1701 /*
1702 * The number of bytes transferred is either whatever
1703 * is left in the descriptor (txDescCnt), or if there
1704 * is not enough room in the fifo, just whatever room
1705 * is left in the fifo
1706 */
1707 txXferLen = min<uint32_t>(txDescCnt, txFifo.avail());
1708
1709 txDmaAddr = txFragPtr & 0x3fffffff;
1713
1714 if (doTxDmaRead())
1715 goto exit;
1716 } else {
1718 transmit();
1719
1720 goto exit;
1721 }
1722
1723 }
1724 break;
1725
1726 case txFragRead:
1727 if (txDmaState != dmaIdle)
1728 goto exit;
1729
1734
1736 break;
1737
1738 case txDescWrite:
1739 if (txDmaState != dmaIdle)
1740 goto exit;
1741
1742 if (cmdsts & CMDSTS_INTR)
1744
1745 if (!txEnable) {
1746 DPRINTF(EthernetSM, "halting TX state machine\n");
1747 txState = txIdle;
1748 goto exit;
1749 } else
1751 break;
1752
1753 case txAdvance:
1754 if (link == 0) {
1756 txState = txIdle;
1757 goto exit;
1758 } else {
1759 if (txDmaState != dmaIdle)
1760 goto exit;
1762 regs.txdp = link;
1763 CTDD = false;
1764
1765 txDmaAddr = link & 0x3fffffff;
1766 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32;
1767 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32);
1769
1770 if (doTxDmaRead())
1771 goto exit;
1772 }
1773 break;
1774
1775 default:
1776 panic("invalid state");
1777 }
1778
1779 DPRINTF(EthernetSM, "entering next txState=%s\n",
1781 goto next;
1782
1783 exit:
1787 DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
1789
1790 if (!txKickEvent.scheduled())
1792}
1793
1798void
1800{
1801 switch (eepromState) {
1802
1803 case eepromStart:
1804
1805 // Wait for start bit
1806 if (regs.mear & MEAR_EEDI) {
1807 // Set up to get 2 opcode bits
1809 eepromBitsToRx = 2;
1810 eepromOpcode = 0;
1811 }
1812 break;
1813
1814 case eepromGetOpcode:
1815 eepromOpcode <<= 1;
1816 eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0;
1818
1819 // Done getting opcode
1820 if (eepromBitsToRx == 0) {
1822 panic("only EEPROM reads are implemented!");
1823
1824 // Set up to get address
1826 eepromBitsToRx = 6;
1827 eepromAddress = 0;
1828 }
1829 break;
1830
1831 case eepromGetAddress:
1832 eepromAddress <<= 1;
1833 eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0;
1835
1836 // Done getting address
1837 if (eepromBitsToRx == 0) {
1838
1840 panic("EEPROM read access out of range!");
1841
1842 switch (eepromAddress) {
1843
1846 eepromData <<= 8;
1848 break;
1849
1852 eepromData <<= 8;
1854 break;
1855
1858 eepromData <<= 8;
1860 break;
1861
1862 default:
1863 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1864 }
1865 // Set up to read data
1867 eepromBitsToRx = 16;
1868
1869 // Clear data in bit
1870 regs.mear &= ~MEAR_EEDI;
1871 }
1872 break;
1873
1874 case eepromRead:
1875 // Clear Data Out bit
1876 regs.mear &= ~MEAR_EEDO;
1877 // Set bit to value of current EEPROM bit
1878 regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0;
1879
1880 eepromData <<= 1;
1882
1883 // All done
1884 if (eepromBitsToRx == 0) {
1886 }
1887 break;
1888
1889 default:
1890 panic("invalid EEPROM state");
1891 }
1892
1893}
1894
1895void
1897{
1898 if (txFifo.empty()) {
1899 DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n");
1900 return;
1901 }
1902
1903 DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
1904
1905 reschedule(txEvent, clockEdge(Cycles(1)), true);
1906}
1907
1908bool
1910{
1911 EthPtr eth = packet;
1912 bool drop = true;
1913 string type;
1914
1915 const EthAddr &dst = eth->dst();
1916 if (dst.unicast()) {
1917 // If we're accepting all unicast addresses
1918 if (acceptUnicast)
1919 drop = false;
1920
1921 // If we make a perfect match
1922 if (acceptPerfect && dst == rom.perfectMatch)
1923 drop = false;
1924
1925 if (acceptArp && eth->type() == ETH_TYPE_ARP)
1926 drop = false;
1927
1928 } else if (dst.broadcast()) {
1929 // if we're accepting broadcasts
1930 if (acceptBroadcast)
1931 drop = false;
1932
1933 } else if (dst.multicast()) {
1934 // if we're accepting all multicasts
1935 if (acceptMulticast)
1936 drop = false;
1937
1938 // Multicast hashing faked - all packets accepted
1940 drop = false;
1941 }
1942
1943 if (drop) {
1944 DPRINTF(Ethernet, "rxFilter drop\n");
1945 DDUMP(EthernetData, packet->data, packet->length);
1946 }
1947
1948 return drop;
1949}
1950
1951bool
1953{
1954 etherDeviceStats.rxBytes += packet->length;
1956
1957 DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
1958 rxFifo.avail());
1959
1960 if (!rxEnable) {
1961 DPRINTF(Ethernet, "receive disabled...packet dropped\n");
1962 return true;
1963 }
1964
1965 if (!rxFilterEnable) {
1966 DPRINTF(Ethernet,
1967 "receive packet filtering disabled . . . packet dropped\n");
1968 return true;
1969 }
1970
1971 if (rxFilter(packet)) {
1972 DPRINTF(Ethernet, "packet filtered...dropped\n");
1973 return true;
1974 }
1975
1976 if (rxFifo.avail() < packet->length) {
1977#if TRACING_ON
1978 IpPtr ip(packet);
1979 TcpPtr tcp(ip);
1980 if (ip) {
1981 DPRINTF(Ethernet,
1982 "packet won't fit in receive buffer...pkt ID %d dropped\n",
1983 ip->id());
1984 if (tcp) {
1985 DPRINTF(Ethernet, "Seq=%d\n", tcp->seq());
1986 }
1987 }
1988#endif
1991 return false;
1992 }
1993
1994 rxFifo.push(packet);
1995
1996 rxKick();
1997 return true;
1998}
1999
2000
2001void
2003{
2005
2006 // During drain we could have left the state machines in a waiting state and
2007 // they wouldn't get out until some other event occured to kick them.
2008 // This way they'll get out immediately
2009 txKick();
2010 rxKick();
2011}
2012
2013
2014//=====================================================================
2015//
2016//
2017void
2019{
2020 // Serialize the PciDevice base class
2022
2023 /*
2024 * Finalize any DMA events now.
2025 */
2026 // @todo will mem system save pending dma?
2027
2028 /*
2029 * Serialize the device registers
2030 */
2065
2066 SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN);
2068
2070
2071 /*
2072 * Serialize the data Fifos
2073 */
2074 rxFifo.serialize("rxFifo", cp);
2075 txFifo.serialize("txFifo", cp);
2076
2077 /*
2078 * Serialize the various helper variables
2079 */
2080 bool txPacketExists = txPacket != nullptr;
2081 SERIALIZE_SCALAR(txPacketExists);
2082 if (txPacketExists) {
2083 txPacket->simLength = txPacketBufPtr - txPacket->data;
2084 txPacket->length = txPacketBufPtr - txPacket->data;
2085 txPacket->serialize("txPacket", cp);
2086 uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
2087 SERIALIZE_SCALAR(txPktBufPtr);
2088 }
2089
2090 bool rxPacketExists = rxPacket != nullptr;
2091 SERIALIZE_SCALAR(rxPacketExists);
2092 if (rxPacketExists) {
2093 rxPacket->serialize("rxPacket", cp);
2094 uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data);
2095 SERIALIZE_SCALAR(rxPktBufPtr);
2096 }
2097
2100
2101 /*
2102 * Serialize Cached Descriptors
2103 */
2121
2122 /*
2123 * Serialize tx state machine
2124 */
2125 int txState = this->txState;
2126 SERIALIZE_SCALAR(txState);
2131 int txDmaState = this->txDmaState;
2132 SERIALIZE_SCALAR(txDmaState);
2134
2135 /*
2136 * Serialize rx state machine
2137 */
2138 int rxState = this->rxState;
2139 SERIALIZE_SCALAR(rxState);
2145 int rxDmaState = this->rxDmaState;
2146 SERIALIZE_SCALAR(rxDmaState);
2148
2149 /*
2150 * Serialize EEPROM state machine
2151 */
2152 int eepromState = this->eepromState;
2153 SERIALIZE_SCALAR(eepromState);
2159
2160 /*
2161 * If there's a pending transmit, store the time so we can
2162 * reschedule it later
2163 */
2164 Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick() : 0;
2165 SERIALIZE_SCALAR(transmitTick);
2166
2167 /*
2168 * receive address filter settings
2169 */
2177
2178 /*
2179 * Keep track of pending interrupt status.
2180 */
2183 Tick intrEventTick = 0;
2184 if (intrEvent)
2185 intrEventTick = intrEvent->when();
2186 SERIALIZE_SCALAR(intrEventTick);
2187
2188}
2189
2190void
2192{
2193 // Unserialize the PciDevice base class
2195
2230
2231 UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN);
2233
2235
2236 /*
2237 * unserialize the data fifos
2238 */
2239 rxFifo.unserialize("rxFifo", cp);
2240 txFifo.unserialize("txFifo", cp);
2241
2242 /*
2243 * unserialize the various helper variables
2244 */
2245 bool txPacketExists;
2246 UNSERIALIZE_SCALAR(txPacketExists);
2247 if (txPacketExists) {
2248 txPacket = make_shared<EthPacketData>(16384);
2249 txPacket->unserialize("txPacket", cp);
2250 uint32_t txPktBufPtr;
2251 UNSERIALIZE_SCALAR(txPktBufPtr);
2252 txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr;
2253 } else
2254 txPacket = 0;
2255
2256 bool rxPacketExists;
2257 UNSERIALIZE_SCALAR(rxPacketExists);
2258 rxPacket = 0;
2259 if (rxPacketExists) {
2260 rxPacket = make_shared<EthPacketData>();
2261 rxPacket->unserialize("rxPacket", cp);
2262 uint32_t rxPktBufPtr;
2263 UNSERIALIZE_SCALAR(rxPktBufPtr);
2264 rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr;
2265 } else
2266 rxPacket = 0;
2267
2270
2271 /*
2272 * Unserialize Cached Descriptors
2273 */
2291
2292 /*
2293 * unserialize tx state machine
2294 */
2295 int txState;
2297 this->txState = (TxState) txState;
2302 int txDmaState;
2304 this->txDmaState = (DmaState) txDmaState;
2306 if (txKickTick)
2308
2309 /*
2310 * unserialize rx state machine
2311 */
2312 int rxState;
2314 this->rxState = (RxState) rxState;
2320 int rxDmaState;
2322 this->rxDmaState = (DmaState) rxDmaState;
2324 if (rxKickTick)
2326
2327 /*
2328 * Unserialize EEPROM state machine
2329 */
2330 int eepromState;
2332 this->eepromState = (EEPROMState) eepromState;
2338
2339 /*
2340 * If there's a pending transmit, reschedule it now
2341 */
2342 Tick transmitTick;
2343 UNSERIALIZE_SCALAR(transmitTick);
2344 if (transmitTick)
2345 schedule(txEvent, curTick() + transmitTick);
2346
2347 /*
2348 * unserialize receive address filter settings
2349 */
2357
2358 /*
2359 * Keep track of pending interrupt status.
2360 */
2363 Tick intrEventTick;
2364 UNSERIALIZE_SCALAR(intrEventTick);
2365 if (intrEventTick) {
2366 intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
2367 name(), true);
2368 schedule(intrEvent, intrEventTick);
2369 }
2370}
2371
2372} // namespace gem5
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition trace.hh:204
#define DPRINTF(x,...)
Definition trace.hh:210
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
bool dmaPending() const
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Dummy class to keep the Python class hierarchy in sync with the C++ object hierarchy.
EtherDevBaseParams Params
gem5::EtherDevice::EtherDeviceStats etherDeviceStats
bool sendPacket(EthPacketPtr packet)
Definition etherint.hh:73
void rxDmaReadDone()
Definition ns_gige.cc:993
uint32_t txDescCnt
count of bytes remaining in the current descriptor
Definition ns_gige.hh:208
uint32_t rxPktBytes
num of bytes in the current packet being drained from rxDataFifo
Definition ns_gige.hh:218
bool dmaDescFree
Definition ns_gige.hh:268
void eepromKick()
Advance the EEPROM state machine Called on rising edge of EEPROM clock bit in MEAR.
Definition ns_gige.cc:1799
void * txDmaData
Definition ns_gige.hh:250
Tick rxKickTick
Definition ns_gige.hh:280
bool CRDD
Current Receive Descriptor Done.
Definition ns_gige.hh:216
bool rxDmaFree
Definition ns_gige.hh:188
NSGigEInt * interface
Definition ns_gige.hh:331
uint32_t txXferLen
Definition ns_gige.hh:186
void cpuInterrupt()
Definition ns_gige.cc:880
EEPROMState eepromState
EEPROM State Machine.
Definition ns_gige.hh:230
bool rxFilterEnable
receive address filter
Definition ns_gige.hh:307
bool doRxDmaRead()
Definition ns_gige.cc:979
Addr rxDmaAddr
Definition ns_gige.hh:245
EventFunctionWrapper rxDmaWriteEvent
Definition ns_gige.hh:260
bool acceptBroadcast
Definition ns_gige.hh:309
void rxKick()
Definition ns_gige.cc:1040
uint8_t * rxPacketBufPtr
Definition ns_gige.hh:185
bool eepromClk
Definition ns_gige.hh:231
void txDmaWriteDone()
Definition ns_gige.cc:1450
RxState rxState
rx State Machine
Definition ns_gige.hh:212
bool acceptPerfect
Definition ns_gige.hh:312
DmaState txDmaState
Definition ns_gige.hh:209
void devIntrClear(uint32_t interrupts)
Definition ns_gige.cc:790
Tick intrTick
Definition ns_gige.hh:324
TxState txState
Definition ns_gige.hh:198
void devIntrChangeMask()
Definition ns_gige.cc:832
void drainResume() override
Resume execution after a successful drain.
Definition ns_gige.cc:2002
Tick writeConfig(PacketPtr pkt) override
This is to write to the PCI general configuration registers.
Definition ns_gige.cc:151
EthPacketPtr rxPacket
Definition ns_gige.hh:183
bool acceptUnicast
Definition ns_gige.hh:311
EventFunctionWrapper txDmaReadEvent
Definition ns_gige.hh:263
ns_desc64 rxDesc64
Definition ns_gige.hh:195
bool txEnable
Definition ns_gige.hh:199
bool acceptMulticast
Definition ns_gige.hh:310
void rxReset()
Definition ns_gige.cc:941
ns_desc32 txDesc32
DescCaches.
Definition ns_gige.hh:192
uint8_t * txPacketBufPtr
Definition ns_gige.hh:184
EventFunctionWrapper txEvent
Definition ns_gige.hh:299
bool cpuPendingIntr
Definition ns_gige.hh:325
ns_desc64 txDesc64
Definition ns_gige.hh:194
bool dmaDataFree
Definition ns_gige.hh:269
void transmit()
Retransmit event.
Definition ns_gige.cc:1355
Addr txDmaAddr
Definition ns_gige.hh:251
ns_desc32 rxDesc32
Definition ns_gige.hh:193
void cpuIntrPost(Tick when)
Definition ns_gige.cc:844
EventFunctionWrapper * intrEvent
Definition ns_gige.hh:330
dp_rom rom
Definition ns_gige.hh:171
bool txDmaFree
Definition ns_gige.hh:189
void txKick()
Definition ns_gige.cc:1467
bool extstsEnable
Definition ns_gige.hh:227
void cpuIntrClear()
Definition ns_gige.cc:903
Tick read(PacketPtr pkt) override
This reads the device registers, which are detailed in the NS83820 spec sheet.
Definition ns_gige.cc:187
bool doTxDmaWrite()
Definition ns_gige.cc:1437
EventFunctionWrapper txDmaWriteEvent
Definition ns_gige.hh:266
EEPROMState
EEPROM State Machine States.
Definition ns_gige.hh:161
uint32_t rxXferLen
Definition ns_gige.hh:187
Tick txKickTick
Definition ns_gige.hh:284
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition ns_gige.cc:2191
bool CTDD
Current Transmit Descriptor Done.
Definition ns_gige.hh:202
bool acceptArp
Definition ns_gige.hh:313
bool recvPacket(EthPacketPtr packet)
Definition ns_gige.cc:1952
Tick intrDelay
Definition ns_gige.hh:323
bool multicastHashEnable
Definition ns_gige.hh:314
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition ns_gige.cc:175
bool ioEnable
pci settings
Definition ns_gige.hh:174
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition ns_gige.cc:409
DmaState rxDmaState
Definition ns_gige.hh:225
EventFunctionWrapper rxDmaReadEvent
Definition ns_gige.hh:257
void * rxDmaData
Definition ns_gige.hh:244
void devIntrPost(uint32_t interrupts)
Interrupt management.
Definition ns_gige.cc:733
void txReset()
Definition ns_gige.cc:926
EventFunctionWrapper rxKickEvent
Definition ns_gige.hh:281
bool doTxDmaRead()
Definition ns_gige.cc:1406
void regsReset()
Definition ns_gige.cc:956
void transferDone()
Definition ns_gige.cc:1896
Addr rxFragPtr
ptr to the next byte in current fragment
Definition ns_gige.hh:222
Addr txFragPtr
ptr to the next byte in the current fragment
Definition ns_gige.hh:206
uint8_t eepromOpcode
Definition ns_gige.hh:233
void rxDmaWriteDone()
Definition ns_gige.cc:1023
uint8_t eepromAddress
Definition ns_gige.hh:234
bool rxEnable
Definition ns_gige.hh:213
bool doRxDmaWrite()
Definition ns_gige.cc:1010
dp_regs regs
device register file
Definition ns_gige.hh:170
bool rxFilter(const EthPacketPtr &packet)
Definition ns_gige.cc:1909
uint16_t eepromData
Definition ns_gige.hh:235
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition ns_gige.cc:2018
uint32_t rxDescCnt
count of bytes remaining in the current descriptor
Definition ns_gige.hh:224
PacketFifo rxFifo
Definition ns_gige.hh:179
TxState
Transmit State Machine states.
Definition ns_gige.hh:128
RxState
Receive State Machine States.
Definition ns_gige.hh:140
PacketFifo txFifo
Definition ns_gige.hh:178
bool cpuIntrPending() const
Definition ns_gige.cc:922
uint8_t eepromBitsToRx
Definition ns_gige.hh:232
NSGigE(const Params &params)
Definition ns_gige.cc:97
EthPacketPtr txPacket
various helper vars
Definition ns_gige.hh:182
EventFunctionWrapper txKickEvent
Definition ns_gige.hh:285
void txDmaReadDone()
Definition ns_gige.cc:1420
void serialize(const std::string &base, CheckpointOut &cp) const
Serialization stuff.
Definition pktfifo.cc:87
unsigned reserve(unsigned len=0)
Definition pktfifo.hh:109
unsigned avail() const
Definition pktfifo.hh:104
void unserialize(const std::string &base, CheckpointIn &cp)
Definition pktfifo.cc:100
EthPacketPtr front()
Definition pktfifo.hh:122
bool push(EthPacketPtr ptr)
Definition pktfifo.hh:125
bool empty() const
Definition pktfifo.hh:105
bool full() const
Definition pktfifo.hh:106
unsigned size() const
Definition pktfifo.hh:102
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
T * getPtr()
get a pointer to the data ptr.
Definition packet.hh:1225
unsigned getSize() const
Definition packet.hh:817
void makeAtomicResponse()
Definition packet.hh:1074
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PCIConfig config
The current config space.
Definition device.hh:275
void intrClear()
Definition device.hh:365
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:464
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition device.cc:401
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition device.cc:212
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition device.cc:283
void intrPost()
Definition device.hh:364
Ports are used to interface objects to each other.
Definition port.hh:62
virtual void drainResume()
Resume execution after a successful drain.
Definition drain.hh:293
DrainState drainState() const
Return the current drain state of an object.
Definition drain.hh:324
@ Running
Running normally.
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
void squash()
Squash the current event.
Definition eventq.hh:465
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
void reschedule(Event &event, Tick when, bool always=false)
Definition eventq.hh:1030
Tick when() const
Get the time that the event is scheduled.
Definition eventq.hh:501
bool broadcast() const
Definition inet.hh:116
uint16_t cksum(const IpPtr &ptr)
Definition inet.cc:208
bool multicast() const
Definition inet.hh:115
bool unicast() const
Definition inet.hh:114
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
const Params & params() const
#define warn(...)
Definition logging.hh:256
#define warn_once(...)
Definition logging.hh:260
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 0 > p
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 3 > exit
Definition misc.hh:883
void breakpoint()
Definition debug.cc:64
const uint8_t EEPROM_SIZE
Tick ns
nanosecond
Definition core.cc:68
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
@ EXTSTS_TCPERR
@ EXTSTS_IPERR
@ EXTSTS_TCPPKT
@ EXTSTS_UDPPKT
@ EXTSTS_UDPERR
@ EXTSTS_IPPKT
const char * NsRxStateStrings[]
Definition ns_gige.cc:60
@ TBISR_MR_AN_COMPLETE
@ TBISR_MR_LINK_STATUS
@ MEAR_EEDO
@ MEAR_EESEL
@ MEAR_EEDI
@ MEAR_EECLK
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
@ CR_RST
Definition ns_gige_reg.h:94
@ CR_TXD
Definition ns_gige_reg.h:88
@ CR_TXE
Definition ns_gige_reg.h:87
@ CR_TXR
Definition ns_gige_reg.h:91
@ CR_RXE
Definition ns_gige_reg.h:89
@ CR_SWI
Definition ns_gige_reg.h:93
@ CR_RXR
Definition ns_gige_reg.h:92
@ CR_RXD
Definition ns_gige_reg.h:90
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
@ TANAR_RF2
@ TANAR_RF1
@ TANAR_UNUSED
@ TBICR
Definition ns_gige_reg.h:73
@ GPIOR
Definition ns_gige_reg.h:54
@ TANLPAR
Definition ns_gige_reg.h:76
@ TXDP_HI
Definition ns_gige_reg.h:52
@ RXDP_HI
Definition ns_gige_reg.h:56
@ TANER
Definition ns_gige_reg.h:77
@ RESERVED
Definition ns_gige_reg.h:81
@ M5REG
Definition ns_gige_reg.h:79
@ RX_CFG
Definition ns_gige_reg.h:57
@ MIB_END
Definition ns_gige_reg.h:68
@ MIB_START
Definition ns_gige_reg.h:67
@ TANAR
Definition ns_gige_reg.h:75
@ TBISR
Definition ns_gige_reg.h:74
@ PTSCR
Definition ns_gige_reg.h:46
@ TX_CFG
Definition ns_gige_reg.h:53
@ PTSCR_RBIST_RDONLY
@ PTSCR_EELOAD_EN
@ PTSCR_RBIST_EN
@ PTSCR_EEBIST_EN
@ PTSCR_RBIST_DONE
@ MIBC_FRZ
@ MIBC_MIBS
@ MIBC_ACLR
@ CFGR_TBI_EN
@ CFGR_LNKSTS
@ CFGR_PCI64_DET
@ CFGR_DUPSTS
@ CFGR_M64ADDR
@ CFGR_SPDSTS
@ CFGR_T64ADDR
@ CFGR_MODE_1000
@ CFGR_AUTO_1000
@ CFGR_EXTSTS_EN
@ CFGR_RESERVED
uint64_t Tick
Tick count type.
Definition types.hh:58
@ M5REG_RX_THREAD
@ M5REG_TX_THREAD
@ M5REG_RSS
@ GPIOR_GP5_IN
@ GPIOR_GP2_IN
@ GPIOR_GP3_IN
@ GPIOR_UNUSED
@ GPIOR_GP4_IN
@ GPIOR_GP1_IN
const uint16_t FHASH_SIZE
Definition ns_gige.hh:52
const uint16_t FHASH_ADDR
Definition ns_gige.hh:51
const char * NsDmaState[]
Definition ns_gige.cc:82
@ ISR_RXDESC
@ ISR_IMPL
@ ISR_NODELAY
@ ISR_RXOK
@ ISR_TXIDLE
@ ISR_TXDESC
@ ISR_TXOK
@ ISR_SWI
@ ISR_RESERVE
@ ISR_RXORN
@ ISR_NOIMPL
@ ISR_ALL
@ ISR_RXIDLE
@ RFCR_UHEN
@ RFCR_APM
@ RFCR_ULM
@ RFCR_MHEN
@ RFCR_AARP
@ RFCR_AAM
@ RFCR_AAU
@ RFCR_RFADDR
@ RFCR_AAB
@ RFCR_RFEN
@ CMDSTS_OWN
@ CMDSTS_LEN_MASK
@ CMDSTS_OK
@ CMDSTS_INTR
@ CMDSTS_MORE
const uint8_t EEPROM_PMATCH2_ADDR
Definition ns_gige.hh:57
const uint8_t EEPROM_PMATCH0_ADDR
Definition ns_gige.hh:59
const uint8_t EEPROM_READ
Definition ns_gige.hh:55
const char * NsTxStateStrings[]
Definition ns_gige.cc:71
@ TBICR_MR_LOOPBACK
@ TBICR_MR_AN_ENABLE
const uint8_t EEPROM_PMATCH1_ADDR
Definition ns_gige.hh:58
@ VTCR_PPCHK
std::shared_ptr< EthPacketData > EthPacketPtr
Definition etherpkt.hh:90
Device module for modelling the National Semiconductor DP83820 ethernet controller.
Declaration of the Packet class.
#define PCI_CMD_IOSE
Definition pcireg.h:119
#define PCI_DEVICE_SPECIFIC
Definition pcireg.h:164
#define PCI_COMMAND
Definition pcireg.h:105
#define PCI_CONFIG_SIZE
Definition pcireg.h:165
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
uint32_t brar
Definition ns_gige.hh:86
uint32_t ihr
Definition ns_gige.hh:73
uint32_t rfdr
Definition ns_gige.hh:85
uint32_t isr
Definition ns_gige.hh:70
uint32_t tbicr
Definition ns_gige.hh:94
uint32_t rxdp
Definition ns_gige.hh:78
uint32_t rxcfg
Definition ns_gige.hh:80
uint32_t txdp
Definition ns_gige.hh:74
uint32_t vtcr
Definition ns_gige.hh:91
uint32_t pcr
Definition ns_gige.hh:83
uint32_t imr
Definition ns_gige.hh:71
uint32_t srr
Definition ns_gige.hh:88
uint32_t rfcr
Definition ns_gige.hh:84
uint32_t config
Definition ns_gige.hh:67
uint32_t mear
Definition ns_gige.hh:68
uint32_t txdp_hi
Definition ns_gige.hh:75
uint32_t vdr
Definition ns_gige.hh:92
uint32_t brdr
Definition ns_gige.hh:87
uint32_t tesr
Definition ns_gige.hh:99
uint32_t tbisr
Definition ns_gige.hh:95
uint32_t taner
Definition ns_gige.hh:98
uint32_t command
Definition ns_gige.hh:66
uint32_t wcsr
Definition ns_gige.hh:82
uint32_t rxdp_hi
Definition ns_gige.hh:79
uint32_t ptscr
Definition ns_gige.hh:69
uint32_t vrcr
Definition ns_gige.hh:90
uint32_t ccsr
Definition ns_gige.hh:93
uint32_t mibc
Definition ns_gige.hh:89
uint32_t gpior
Definition ns_gige.hh:77
uint32_t txcfg
Definition ns_gige.hh:76
uint32_t tanar
Definition ns_gige.hh:96
uint32_t tanlpar
Definition ns_gige.hh:97
uint32_t ier
Definition ns_gige.hh:72
uint32_t pqcr
Definition ns_gige.hh:81
uint8_t perfectMatch[ETH_ADDR_LEN]
for perfect match memory.
Definition ns_gige.hh:108
uint8_t filterHash[FHASH_SIZE]
for hash table memory.
Definition ns_gige.hh:114
const EthAddr & dst() const
Definition inet.hh:176
uint16_t type() const
Definition inet.hh:160
uint16_t sum() const
Definition inet.hh:747
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:03 for gem5 by doxygen 1.11.0