2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
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.
30 * Device module for modelling the National Semiconductor
31 * DP83820 ethernet controller. Does not support priority queueing
34 #include "dev/net/ns_gige.hh"
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"
50 // clang complains about std::set being overloaded with Packet::set if
51 // we open up the entire namespace std
52 using std::make_shared
;
57 const char *NsRxStateStrings
[] =
68 const char *NsTxStateStrings
[] =
79 const char *NsDmaState
[] =
90 ///////////////////////////////////////////////////////////////////////
94 NSGigE::NSGigE(Params
*p
)
95 : EtherDevBase(p
), ioEnable(false),
96 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
97 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
98 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
99 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
100 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
101 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
102 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
103 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
104 eepromOpcode(0), eepromAddress(0), eepromData(0),
105 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
106 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
107 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
108 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
109 rxDmaReadEvent([this]{ rxDmaReadDone(); }, name()),
110 rxDmaWriteEvent([this]{ rxDmaWriteDone(); }, name()),
111 txDmaReadEvent([this]{ txDmaReadDone(); }, name()),
112 txDmaWriteEvent([this]{ txDmaWriteDone(); }, name()),
113 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
114 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
116 rxKickEvent([this]{ rxKick(); }, name()),
118 txKickEvent([this]{ txKick(); }, name()),
119 txEvent([this]{ txEventTransmit(); }, name()),
120 rxFilterEnable(p
->rx_filter
),
121 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
122 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
123 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
124 intrEvent(0), interface(0)
128 interface
= new NSGigEInt(name() + ".int0", this);
131 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
133 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
134 memset(&txDesc32
, 0, sizeof(txDesc32
));
135 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
136 memset(&txDesc64
, 0, sizeof(txDesc64
));
145 * This is to write to the PCI general configuration registers
148 NSGigE::writeConfig(PacketPtr pkt
)
150 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
151 if (offset
< PCI_DEVICE_SPECIFIC
)
152 PciDevice::writeConfig(pkt
);
154 panic("Device specific PCI config space not implemented!\n");
157 // seems to work fine without all these PCI settings, but i
158 // put in the IO to double check, an assertion will fail if we
159 // need to properly implement it
161 if (config
.data
[offset
] & PCI_CMD_IOSE
)
172 NSGigE::getPort(const std::string
&if_name
, PortID idx
)
174 if (if_name
== "interface")
176 return EtherDevBase::getPort(if_name
, idx
);
180 * This reads the device registers, which are detailed in the NS83820
184 NSGigE::read(PacketPtr pkt
)
188 //The mask is to give you only the offset into the device register file
189 Addr daddr
= pkt
->getAddr() & 0xfff;
190 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
191 daddr
, pkt
->getAddr(), pkt
->getSize());
194 // there are some reserved registers, you can see ns_gige_reg.h and
195 // the spec sheet for details
196 if (daddr
> LAST
&& daddr
<= RESERVED
) {
197 panic("Accessing reserved register");
198 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
199 return readConfig(pkt
);
200 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
201 // don't implement all the MIB's. hopefully the kernel
202 // doesn't actually DEPEND upon their values
203 // MIB are just hardware stats keepers
204 pkt
->setLE
<uint32_t>(0);
205 pkt
->makeAtomicResponse();
207 } else if (daddr
> 0x3FC)
208 panic("Something is messed up!\n");
210 assert(pkt
->getSize() == sizeof(uint32_t));
211 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
217 //these are supposed to be cleared on a read
218 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
235 devIntrClear(ISR_ALL
);
290 // see the spec sheet for how RFCR and RFDR work
291 // basically, you write to RFCR to tell the machine
292 // what you want to do next, then you act upon RFDR,
293 // and the device will be prepared b/c of what you
300 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
302 // Read from perfect match ROM octets
304 reg
= rom
.perfectMatch
[1];
306 reg
+= rom
.perfectMatch
[0];
309 reg
= rom
.perfectMatch
[3] << 8;
310 reg
+= rom
.perfectMatch
[2];
313 reg
= rom
.perfectMatch
[5] << 8;
314 reg
+= rom
.perfectMatch
[4];
317 // Read filter hash table
318 if (rfaddr
>= FHASH_ADDR
&&
319 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
321 // Only word-aligned reads supported
323 panic("unaligned read from filter hash table!");
325 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
326 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
330 panic("reading RFDR for something other than pattern"
331 " matching or hashing! %#x\n", rfaddr
);
341 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
386 if (params()->rx_thread
)
387 reg
|= M5REG_RX_THREAD
;
388 if (params()->tx_thread
)
389 reg
|= M5REG_TX_THREAD
;
395 panic("reading unimplemented register: addr=%#x", daddr
);
398 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
401 pkt
->makeAtomicResponse();
406 NSGigE::write(PacketPtr pkt
)
410 Addr daddr
= pkt
->getAddr() & 0xfff;
411 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
412 daddr
, pkt
->getAddr(), pkt
->getSize());
414 if (daddr
> LAST
&& daddr
<= RESERVED
) {
415 panic("Accessing reserved register");
416 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
417 return writeConfig(pkt
);
418 } else if (daddr
> 0x3FC)
419 panic("Something is messed up!\n");
421 if (pkt
->getSize() == sizeof(uint32_t)) {
422 uint32_t reg
= pkt
->getLE
<uint32_t>();
425 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
432 } else if (reg
& CR_TXE
) {
435 // the kernel is enabling the transmit machine
436 if (txState
== txIdle
)
442 } else if (reg
& CR_RXE
) {
445 if (rxState
== rxIdle
)
456 devIntrPost(ISR_SWI
);
467 if (reg
& CFGR_LNKSTS
||
470 reg
& CFGR_RESERVED
||
471 reg
& CFGR_T64ADDR
||
472 reg
& CFGR_PCI64_DET
) {
473 // First clear all writable bits
474 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
475 CFGR_RESERVED
| CFGR_T64ADDR
|
477 // Now set the appropriate writable bits
478 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
479 CFGR_RESERVED
| CFGR_T64ADDR
|
483 if (reg
& CFGR_AUTO_1000
)
484 panic("CFGR_AUTO_1000 not implemented!\n");
486 if (reg
& CFGR_PCI64_DET
)
487 panic("CFGR_PCI64_DET is read only register!\n");
489 if (reg
& CFGR_EXTSTS_EN
)
492 extstsEnable
= false;
496 // Clear writable bits
497 regs
.mear
&= MEAR_EEDO
;
498 // Set appropriate writable bits
499 regs
.mear
|= reg
& ~MEAR_EEDO
;
501 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
502 // even though it could get it through RFDR
503 if (reg
& MEAR_EESEL
) {
504 // Rising edge of clock
505 if (reg
& MEAR_EECLK
&& !eepromClk
)
509 eepromState
= eepromStart
;
510 regs
.mear
&= ~MEAR_EEDI
;
513 eepromClk
= reg
& MEAR_EECLK
;
515 // since phy is completely faked, MEAR_MD* don't matter
519 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
520 // these control BISTs for various parts of chip - we
521 // don't care or do just fake that the BIST is done
522 if (reg
& PTSCR_RBIST_EN
)
523 regs
.ptscr
|= PTSCR_RBIST_DONE
;
524 if (reg
& PTSCR_EEBIST_EN
)
525 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
526 if (reg
& PTSCR_EELOAD_EN
)
527 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
530 case ISR
: /* writing to the ISR has no effect */
531 panic("ISR is a read only register!\n");
544 /* not going to implement real interrupt holdoff */
548 regs
.txdp
= (reg
& 0xFFFFFFFC);
549 assert(txState
== txIdle
);
560 // also, we currently don't care about fill/drain
561 // thresholds though this may change in the future with
562 // more realistic networks or a driver which changes it
563 // according to feedback
568 // Only write writable bits
569 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
570 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
571 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
572 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
573 /* these just control general purpose i/o pins, don't matter */
590 /* there is no priority queueing used in the linux 2.6 driver */
595 /* not going to implement wake on LAN */
600 /* not going to implement pause control */
607 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
608 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
609 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
610 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
611 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
612 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
613 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
616 panic("Unicast hash filtering not used by drivers!\n");
619 panic("RFCR_ULM not implemented!\n");
624 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
627 rom
.perfectMatch
[0] = (uint8_t)reg
;
628 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
631 rom
.perfectMatch
[2] = (uint8_t)reg
;
632 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
635 rom
.perfectMatch
[4] = (uint8_t)reg
;
636 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
640 if (rfaddr
>= FHASH_ADDR
&&
641 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
643 // Only word-aligned writes supported
645 panic("unaligned write to filter hash table!");
647 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
648 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
649 = (uint8_t)(reg
>> 8);
652 panic("writing RFDR for something other than pattern matching "
653 "or hashing! %#x\n", rfaddr
);
662 panic("the driver never uses BRDR, something is wrong!\n");
665 panic("SRR is read only register!\n");
668 panic("the driver never uses MIBC, something is wrong!\n");
679 panic("the driver never uses VDR, something is wrong!\n");
682 /* not going to implement clockrun stuff */
688 if (reg
& TBICR_MR_LOOPBACK
)
689 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
691 if (reg
& TBICR_MR_AN_ENABLE
) {
692 regs
.tanlpar
= regs
.tanar
;
693 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
699 panic("TBISR is read only register!\n");
702 // Only write the writable bits
703 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
704 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
706 // Pause capability unimplemented
710 panic("this should only be written to by the fake phy!\n");
713 panic("TANER is read only register!\n");
720 panic("invalid register access daddr=%#x", daddr
);
723 panic("Invalid Request Size");
725 pkt
->makeAtomicResponse();
730 NSGigE::devIntrPost(uint32_t interrupts
)
732 if (interrupts
& ISR_RESERVE
)
733 panic("Cannot set a reserved interrupt");
735 if (interrupts
& ISR_NOIMPL
)
736 warn("interrupt not implemented %#x\n", interrupts
);
738 interrupts
&= ISR_IMPL
;
739 regs
.isr
|= interrupts
;
741 if (interrupts
& regs
.imr
) {
742 if (interrupts
& ISR_SWI
) {
745 if (interrupts
& ISR_RXIDLE
) {
748 if (interrupts
& ISR_RXOK
) {
751 if (interrupts
& ISR_RXDESC
) {
754 if (interrupts
& ISR_TXOK
) {
757 if (interrupts
& ISR_TXIDLE
) {
760 if (interrupts
& ISR_TXDESC
) {
763 if (interrupts
& ISR_RXORN
) {
768 DPRINTF(EthernetIntr
,
769 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
770 interrupts
, regs
.isr
, regs
.imr
);
772 if ((regs
.isr
& regs
.imr
)) {
773 Tick when
= curTick();
774 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
781 /* writing this interrupt counting stats inside this means that this function
782 is now limited to being used to clear all interrupts upon the kernel
783 reading isr and servicing. just telling you in case you were thinking
787 NSGigE::devIntrClear(uint32_t interrupts
)
789 if (interrupts
& ISR_RESERVE
)
790 panic("Cannot clear a reserved interrupt");
792 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
795 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
798 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
801 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
804 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
807 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
810 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
813 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
817 interrupts
&= ~ISR_NOIMPL
;
818 regs
.isr
&= ~interrupts
;
820 DPRINTF(EthernetIntr
,
821 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
822 interrupts
, regs
.isr
, regs
.imr
);
824 if (!(regs
.isr
& regs
.imr
))
829 NSGigE::devIntrChangeMask()
831 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
832 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
834 if (regs
.isr
& regs
.imr
)
835 cpuIntrPost(curTick());
841 NSGigE::cpuIntrPost(Tick when
)
843 // If the interrupt you want to post is later than an interrupt
844 // already scheduled, just let it post in the coming one and don't
846 // HOWEVER, must be sure that the scheduled intrTick is in the
847 // future (this was formerly the source of a bug)
849 * @todo this warning should be removed and the intrTick code should
852 assert(when
>= curTick());
853 assert(intrTick
>= curTick() || intrTick
== 0);
854 if (when
> intrTick
&& intrTick
!= 0) {
855 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
861 if (intrTick
< curTick()) {
862 intrTick
= curTick();
865 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
871 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
873 schedule(intrEvent
, intrTick
);
877 NSGigE::cpuInterrupt()
879 assert(intrTick
== curTick());
881 // Whether or not there's a pending interrupt, we don't care about
886 // Don't send an interrupt if there's already one
887 if (cpuPendingIntr
) {
888 DPRINTF(EthernetIntr
,
889 "would send an interrupt now, but there's already pending\n");
892 cpuPendingIntr
= true;
894 DPRINTF(EthernetIntr
, "posting interrupt\n");
900 NSGigE::cpuIntrClear()
912 cpuPendingIntr
= false;
914 DPRINTF(EthernetIntr
, "clearing interrupt\n");
919 NSGigE::cpuIntrPending() const
920 { return cpuPendingIntr
; }
926 DPRINTF(Ethernet
, "transmit reset\n");
931 assert(txDescCnt
== 0);
934 assert(txDmaState
== dmaIdle
);
940 DPRINTF(Ethernet
, "receive reset\n");
943 assert(rxPktBytes
== 0);
946 assert(rxDescCnt
== 0);
947 assert(rxDmaState
== dmaIdle
);
955 memset(®s
, 0, sizeof(regs
));
956 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
958 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
959 // fill threshold to 32 bytes
960 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
961 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
962 regs
.mibc
= MIBC_FRZ
;
963 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
964 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
965 regs
.brar
= 0xffffffff;
967 extstsEnable
= false;
968 acceptBroadcast
= false;
969 acceptMulticast
= false;
970 acceptUnicast
= false;
971 acceptPerfect
= false;
976 NSGigE::doRxDmaRead()
978 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
979 rxDmaState
= dmaReading
;
981 if (dmaPending() || drainState() != DrainState::Running
)
982 rxDmaState
= dmaReadWaiting
;
984 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
990 NSGigE::rxDmaReadDone()
992 assert(rxDmaState
== dmaReading
);
993 rxDmaState
= dmaIdle
;
995 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
996 rxDmaAddr
, rxDmaLen
);
997 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
999 // If the transmit state machine has a pending DMA, let it go first
1000 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1007 NSGigE::doRxDmaWrite()
1009 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1010 rxDmaState
= dmaWriting
;
1012 if (dmaPending() || drainState() != DrainState::Running
)
1013 rxDmaState
= dmaWriteWaiting
;
1015 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1020 NSGigE::rxDmaWriteDone()
1022 assert(rxDmaState
== dmaWriting
);
1023 rxDmaState
= dmaIdle
;
1025 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1026 rxDmaAddr
, rxDmaLen
);
1027 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1029 // If the transmit state machine has a pending DMA, let it go first
1030 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1039 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1042 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1043 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1046 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1047 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1050 if (rxKickTick
> curTick()) {
1051 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1057 // Go to the next state machine clock tick.
1058 rxKickTick
= clockEdge(Cycles(1));
1060 switch(rxDmaState
) {
1061 case dmaReadWaiting
:
1065 case dmaWriteWaiting
:
1073 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1074 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1076 // see state machine from spec for details
1077 // the way this works is, if you finish work on one state and can
1078 // go directly to another, you do that through jumping to the
1079 // label "next". however, if you have intermediate work, like DMA
1080 // so that you can't go to the next state yet, you go to exit and
1081 // exit the loop. however, when the DMA is done it will trigger
1082 // an event and come back to this loop.
1086 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1091 rxState
= rxDescRefr
;
1093 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1095 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1096 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1097 rxDmaFree
= dmaDescFree
;
1100 descDmaRdBytes
+= rxDmaLen
;
1105 rxState
= rxDescRead
;
1107 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1108 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1109 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1110 rxDmaFree
= dmaDescFree
;
1113 descDmaRdBytes
+= rxDmaLen
;
1121 if (rxDmaState
!= dmaIdle
)
1124 rxState
= rxAdvance
;
1128 if (rxDmaState
!= dmaIdle
)
1131 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1132 regs
.rxdp
& 0x3fffffff);
1133 DPRINTF(EthernetDesc
,
1134 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1135 link
, bufptr
, cmdsts
, extsts
);
1137 if (cmdsts
& CMDSTS_OWN
) {
1138 devIntrPost(ISR_RXIDLE
);
1142 rxState
= rxFifoBlock
;
1144 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1151 * @todo in reality, we should be able to start processing
1152 * the packet as it arrives, and not have to wait for the
1153 * full packet ot be in the receive fifo.
1158 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1160 // If we don't have a packet, grab a new one from the fifo.
1161 rxPacket
= rxFifo
.front();
1162 rxPktBytes
= rxPacket
->length
;
1163 rxPacketBufPtr
= rxPacket
->data
;
1166 if (DTRACE(Ethernet
)) {
1169 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1173 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1174 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1181 // sanity check - i think the driver behaves like this
1182 assert(rxDescCnt
>= rxPktBytes
);
1187 // dont' need the && rxDescCnt > 0 if driver sanity check
1189 if (rxPktBytes
> 0) {
1190 rxState
= rxFragWrite
;
1191 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1193 rxXferLen
= rxPktBytes
;
1195 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1196 rxDmaData
= rxPacketBufPtr
;
1197 rxDmaLen
= rxXferLen
;
1198 rxDmaFree
= dmaDataFree
;
1204 rxState
= rxDescWrite
;
1206 //if (rxPktBytes == 0) { /* packet is done */
1207 assert(rxPktBytes
== 0);
1208 DPRINTF(EthernetSM
, "done with receiving packet\n");
1210 cmdsts
|= CMDSTS_OWN
;
1211 cmdsts
&= ~CMDSTS_MORE
;
1212 cmdsts
|= CMDSTS_OK
;
1213 cmdsts
&= 0xffff0000;
1214 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1217 if (extstsEnable
&& ip
) {
1218 extsts
|= EXTSTS_IPPKT
;
1220 if (cksum(ip
) != 0) {
1221 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1222 extsts
|= EXTSTS_IPERR
;
1227 extsts
|= EXTSTS_TCPPKT
;
1229 if (cksum(tcp
) != 0) {
1230 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1231 extsts
|= EXTSTS_TCPERR
;
1235 extsts
|= EXTSTS_UDPPKT
;
1237 if (cksum(udp
) != 0) {
1238 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1239 extsts
|= EXTSTS_UDPERR
;
1246 * the driver seems to always receive into desc buffers
1247 * of size 1514, so you never have a pkt that is split
1248 * into multiple descriptors on the receive side, so
1249 * i don't implement that case, hence the assert above.
1252 DPRINTF(EthernetDesc
,
1253 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1254 regs
.rxdp
& 0x3fffffff);
1255 DPRINTF(EthernetDesc
,
1256 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1257 link
, bufptr
, cmdsts
, extsts
);
1259 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1260 rxDmaData
= &cmdsts
;
1262 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1263 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1265 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1266 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1268 rxDmaFree
= dmaDescFree
;
1271 descDmaWrBytes
+= rxDmaLen
;
1279 if (rxDmaState
!= dmaIdle
)
1282 rxPacketBufPtr
+= rxXferLen
;
1283 rxFragPtr
+= rxXferLen
;
1284 rxPktBytes
-= rxXferLen
;
1286 rxState
= rxFifoBlock
;
1290 if (rxDmaState
!= dmaIdle
)
1293 assert(cmdsts
& CMDSTS_OWN
);
1295 assert(rxPacket
== 0);
1296 devIntrPost(ISR_RXOK
);
1298 if (cmdsts
& CMDSTS_INTR
)
1299 devIntrPost(ISR_RXDESC
);
1302 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1306 rxState
= rxAdvance
;
1311 devIntrPost(ISR_RXIDLE
);
1316 if (rxDmaState
!= dmaIdle
)
1318 rxState
= rxDescRead
;
1322 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1323 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1324 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1325 rxDmaFree
= dmaDescFree
;
1333 panic("Invalid rxState!");
1336 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1337 NsRxStateStrings
[rxState
]);
1342 * @todo do we want to schedule a future kick?
1344 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1345 NsRxStateStrings
[rxState
]);
1347 if (!rxKickEvent
.scheduled())
1348 schedule(rxKickEvent
, rxKickTick
);
1354 if (txFifo
.empty()) {
1355 DPRINTF(Ethernet
, "nothing to transmit\n");
1359 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1361 if (interface
->sendPacket(txFifo
.front())) {
1363 if (DTRACE(Ethernet
)) {
1364 IpPtr
ip(txFifo
.front());
1366 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1370 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1371 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1378 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1379 txBytes
+= txFifo
.front()->length
;
1382 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1387 * normally do a writeback of the descriptor here, and ONLY
1388 * after that is done, send this interrupt. but since our
1389 * stuff never actually fails, just do this interrupt here,
1390 * otherwise the code has to stray from this nice format.
1391 * besides, it's functionally the same.
1393 devIntrPost(ISR_TXOK
);
1396 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1397 DPRINTF(Ethernet
, "reschedule transmit\n");
1398 schedule(txEvent
, curTick() + SimClock::Int::ns
);
1403 NSGigE::doTxDmaRead()
1405 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1406 txDmaState
= dmaReading
;
1408 if (dmaPending() || drainState() != DrainState::Running
)
1409 txDmaState
= dmaReadWaiting
;
1411 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1417 NSGigE::txDmaReadDone()
1419 assert(txDmaState
== dmaReading
);
1420 txDmaState
= dmaIdle
;
1422 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1423 txDmaAddr
, txDmaLen
);
1424 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1426 // If the receive state machine has a pending DMA, let it go first
1427 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1434 NSGigE::doTxDmaWrite()
1436 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1437 txDmaState
= dmaWriting
;
1439 if (dmaPending() || drainState() != DrainState::Running
)
1440 txDmaState
= dmaWriteWaiting
;
1442 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1447 NSGigE::txDmaWriteDone()
1449 assert(txDmaState
== dmaWriting
);
1450 txDmaState
= dmaIdle
;
1452 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1453 txDmaAddr
, txDmaLen
);
1454 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1456 // If the receive state machine has a pending DMA, let it go first
1457 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1466 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1468 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1469 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1472 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1473 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1476 if (txKickTick
> curTick()) {
1477 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1482 // Go to the next state machine clock tick.
1483 txKickTick
= clockEdge(Cycles(1));
1485 switch(txDmaState
) {
1486 case dmaReadWaiting
:
1490 case dmaWriteWaiting
:
1498 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1499 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1503 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1508 txState
= txDescRefr
;
1510 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1512 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1513 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1514 txDmaFree
= dmaDescFree
;
1517 descDmaRdBytes
+= txDmaLen
;
1523 txState
= txDescRead
;
1525 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1526 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1527 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1528 txDmaFree
= dmaDescFree
;
1531 descDmaRdBytes
+= txDmaLen
;
1539 if (txDmaState
!= dmaIdle
)
1542 txState
= txAdvance
;
1546 if (txDmaState
!= dmaIdle
)
1549 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1550 regs
.txdp
& 0x3fffffff);
1551 DPRINTF(EthernetDesc
,
1552 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1553 link
, bufptr
, cmdsts
, extsts
);
1555 if (cmdsts
& CMDSTS_OWN
) {
1556 txState
= txFifoBlock
;
1558 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1560 devIntrPost(ISR_TXIDLE
);
1568 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1569 txPacket
= make_shared
<EthPacketData
>(16384);
1570 txPacketBufPtr
= txPacket
->data
;
1573 if (txDescCnt
== 0) {
1574 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1575 if (cmdsts
& CMDSTS_MORE
) {
1576 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
1577 txState
= txDescWrite
;
1579 cmdsts
&= ~CMDSTS_OWN
;
1581 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1582 txDmaData
= &cmdsts
;
1584 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1585 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1587 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1588 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1590 txDmaFree
= dmaDescFree
;
1595 } else { /* this packet is totally done */
1596 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
1597 /* deal with the the packet that just finished */
1598 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
1600 if (extsts
& EXTSTS_UDPPKT
) {
1604 udp
->sum(cksum(udp
));
1607 Debug::breakpoint();
1608 warn_once("UDPPKT set, but not UDP!\n");
1610 } else if (extsts
& EXTSTS_TCPPKT
) {
1614 tcp
->sum(cksum(tcp
));
1617 warn_once("TCPPKT set, but not UDP!\n");
1620 if (extsts
& EXTSTS_IPPKT
) {
1626 warn_once("IPPKT set, but not UDP!\n");
1631 txPacket
->simLength
= txPacketBufPtr
- txPacket
->data
;
1632 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
1633 // this is just because the receive can't handle a
1634 // packet bigger want to make sure
1635 if (txPacket
->length
> 1514)
1636 panic("transmit packet too large, %s > 1514\n",
1642 txFifo
.push(txPacket
);
1646 * this following section is not tqo spec, but
1647 * functionally shouldn't be any different. normally,
1648 * the chip will wait til the transmit has occurred
1649 * before writing back the descriptor because it has
1650 * to wait to see that it was successfully transmitted
1651 * to decide whether to set CMDSTS_OK or not.
1652 * however, in the simulator since it is always
1653 * successfully transmitted, and writing it exactly to
1654 * spec would complicate the code, we just do it here
1657 cmdsts
&= ~CMDSTS_OWN
;
1658 cmdsts
|= CMDSTS_OK
;
1660 DPRINTF(EthernetDesc
,
1661 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1664 txDmaFree
= dmaDescFree
;
1665 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1666 txDmaData
= &cmdsts
;
1668 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1670 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1672 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1674 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1678 descDmaWrBytes
+= txDmaLen
;
1684 DPRINTF(EthernetSM
, "halting TX state machine\n");
1688 txState
= txAdvance
;
1694 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1695 if (!txFifo
.full()) {
1696 txState
= txFragRead
;
1699 * The number of bytes transferred is either whatever
1700 * is left in the descriptor (txDescCnt), or if there
1701 * is not enough room in the fifo, just whatever room
1702 * is left in the fifo
1704 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1706 txDmaAddr
= txFragPtr
& 0x3fffffff;
1707 txDmaData
= txPacketBufPtr
;
1708 txDmaLen
= txXferLen
;
1709 txDmaFree
= dmaDataFree
;
1714 txState
= txFifoBlock
;
1724 if (txDmaState
!= dmaIdle
)
1727 txPacketBufPtr
+= txXferLen
;
1728 txFragPtr
+= txXferLen
;
1729 txDescCnt
-= txXferLen
;
1730 txFifo
.reserve(txXferLen
);
1732 txState
= txFifoBlock
;
1736 if (txDmaState
!= dmaIdle
)
1739 if (cmdsts
& CMDSTS_INTR
)
1740 devIntrPost(ISR_TXDESC
);
1743 DPRINTF(EthernetSM
, "halting TX state machine\n");
1747 txState
= txAdvance
;
1752 devIntrPost(ISR_TXIDLE
);
1756 if (txDmaState
!= dmaIdle
)
1758 txState
= txDescRead
;
1762 txDmaAddr
= link
& 0x3fffffff;
1763 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1764 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1765 txDmaFree
= dmaDescFree
;
1773 panic("invalid state");
1776 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1777 NsTxStateStrings
[txState
]);
1782 * @todo do we want to schedule a future kick?
1784 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1785 NsTxStateStrings
[txState
]);
1787 if (!txKickEvent
.scheduled())
1788 schedule(txKickEvent
, txKickTick
);
1792 * Advance the EEPROM state machine
1793 * Called on rising edge of EEPROM clock bit in MEAR
1796 NSGigE::eepromKick()
1798 switch (eepromState
) {
1802 // Wait for start bit
1803 if (regs
.mear
& MEAR_EEDI
) {
1804 // Set up to get 2 opcode bits
1805 eepromState
= eepromGetOpcode
;
1811 case eepromGetOpcode
:
1813 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1816 // Done getting opcode
1817 if (eepromBitsToRx
== 0) {
1818 if (eepromOpcode
!= EEPROM_READ
)
1819 panic("only EEPROM reads are implemented!");
1821 // Set up to get address
1822 eepromState
= eepromGetAddress
;
1828 case eepromGetAddress
:
1829 eepromAddress
<<= 1;
1830 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1833 // Done getting address
1834 if (eepromBitsToRx
== 0) {
1836 if (eepromAddress
>= EEPROM_SIZE
)
1837 panic("EEPROM read access out of range!");
1839 switch (eepromAddress
) {
1841 case EEPROM_PMATCH2_ADDR
:
1842 eepromData
= rom
.perfectMatch
[5];
1844 eepromData
+= rom
.perfectMatch
[4];
1847 case EEPROM_PMATCH1_ADDR
:
1848 eepromData
= rom
.perfectMatch
[3];
1850 eepromData
+= rom
.perfectMatch
[2];
1853 case EEPROM_PMATCH0_ADDR
:
1854 eepromData
= rom
.perfectMatch
[1];
1856 eepromData
+= rom
.perfectMatch
[0];
1860 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1862 // Set up to read data
1863 eepromState
= eepromRead
;
1864 eepromBitsToRx
= 16;
1866 // Clear data in bit
1867 regs
.mear
&= ~MEAR_EEDI
;
1872 // Clear Data Out bit
1873 regs
.mear
&= ~MEAR_EEDO
;
1874 // Set bit to value of current EEPROM bit
1875 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
1881 if (eepromBitsToRx
== 0) {
1882 eepromState
= eepromStart
;
1887 panic("invalid EEPROM state");
1893 NSGigE::transferDone()
1895 if (txFifo
.empty()) {
1896 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
1900 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
1902 reschedule(txEvent
, clockEdge(Cycles(1)), true);
1906 NSGigE::rxFilter(const EthPacketPtr
&packet
)
1908 EthPtr eth
= packet
;
1912 const EthAddr
&dst
= eth
->dst();
1913 if (dst
.unicast()) {
1914 // If we're accepting all unicast addresses
1918 // If we make a perfect match
1919 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
1922 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
1925 } else if (dst
.broadcast()) {
1926 // if we're accepting broadcasts
1927 if (acceptBroadcast
)
1930 } else if (dst
.multicast()) {
1931 // if we're accepting all multicasts
1932 if (acceptMulticast
)
1935 // Multicast hashing faked - all packets accepted
1936 if (multicastHashEnable
)
1941 DPRINTF(Ethernet
, "rxFilter drop\n");
1942 DDUMP(EthernetData
, packet
->data
, packet
->length
);
1949 NSGigE::recvPacket(EthPacketPtr packet
)
1951 rxBytes
+= packet
->length
;
1954 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
1958 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
1962 if (!rxFilterEnable
) {
1964 "receive packet filtering disabled . . . packet dropped\n");
1968 if (rxFilter(packet
)) {
1969 DPRINTF(Ethernet
, "packet filtered...dropped\n");
1973 if (rxFifo
.avail() < packet
->length
) {
1979 "packet won't fit in receive buffer...pkt ID %d dropped\n",
1982 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
1987 devIntrPost(ISR_RXORN
);
1991 rxFifo
.push(packet
);
1999 NSGigE::drainResume()
2001 Drainable::drainResume();
2003 // During drain we could have left the state machines in a waiting state and
2004 // they wouldn't get out until some other event occured to kick them.
2005 // This way they'll get out immediately
2011 //=====================================================================
2015 NSGigE::serialize(CheckpointOut
&cp
) const
2017 // Serialize the PciDevice base class
2018 PciDevice::serialize(cp
);
2021 * Finalize any DMA events now.
2023 // @todo will mem system save pending dma?
2026 * Serialize the device registers
2028 SERIALIZE_SCALAR(regs
.command
);
2029 SERIALIZE_SCALAR(regs
.config
);
2030 SERIALIZE_SCALAR(regs
.mear
);
2031 SERIALIZE_SCALAR(regs
.ptscr
);
2032 SERIALIZE_SCALAR(regs
.isr
);
2033 SERIALIZE_SCALAR(regs
.imr
);
2034 SERIALIZE_SCALAR(regs
.ier
);
2035 SERIALIZE_SCALAR(regs
.ihr
);
2036 SERIALIZE_SCALAR(regs
.txdp
);
2037 SERIALIZE_SCALAR(regs
.txdp_hi
);
2038 SERIALIZE_SCALAR(regs
.txcfg
);
2039 SERIALIZE_SCALAR(regs
.gpior
);
2040 SERIALIZE_SCALAR(regs
.rxdp
);
2041 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2042 SERIALIZE_SCALAR(regs
.rxcfg
);
2043 SERIALIZE_SCALAR(regs
.pqcr
);
2044 SERIALIZE_SCALAR(regs
.wcsr
);
2045 SERIALIZE_SCALAR(regs
.pcr
);
2046 SERIALIZE_SCALAR(regs
.rfcr
);
2047 SERIALIZE_SCALAR(regs
.rfdr
);
2048 SERIALIZE_SCALAR(regs
.brar
);
2049 SERIALIZE_SCALAR(regs
.brdr
);
2050 SERIALIZE_SCALAR(regs
.srr
);
2051 SERIALIZE_SCALAR(regs
.mibc
);
2052 SERIALIZE_SCALAR(regs
.vrcr
);
2053 SERIALIZE_SCALAR(regs
.vtcr
);
2054 SERIALIZE_SCALAR(regs
.vdr
);
2055 SERIALIZE_SCALAR(regs
.ccsr
);
2056 SERIALIZE_SCALAR(regs
.tbicr
);
2057 SERIALIZE_SCALAR(regs
.tbisr
);
2058 SERIALIZE_SCALAR(regs
.tanar
);
2059 SERIALIZE_SCALAR(regs
.tanlpar
);
2060 SERIALIZE_SCALAR(regs
.taner
);
2061 SERIALIZE_SCALAR(regs
.tesr
);
2063 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2064 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2066 SERIALIZE_SCALAR(ioEnable
);
2069 * Serialize the data Fifos
2071 rxFifo
.serialize("rxFifo", cp
);
2072 txFifo
.serialize("txFifo", cp
);
2075 * Serialize the various helper variables
2077 bool txPacketExists
= txPacket
!= nullptr;
2078 SERIALIZE_SCALAR(txPacketExists
);
2079 if (txPacketExists
) {
2080 txPacket
->simLength
= txPacketBufPtr
- txPacket
->data
;
2081 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2082 txPacket
->serialize("txPacket", cp
);
2083 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2084 SERIALIZE_SCALAR(txPktBufPtr
);
2087 bool rxPacketExists
= rxPacket
!= nullptr;
2088 SERIALIZE_SCALAR(rxPacketExists
);
2089 if (rxPacketExists
) {
2090 rxPacket
->serialize("rxPacket", cp
);
2091 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2092 SERIALIZE_SCALAR(rxPktBufPtr
);
2095 SERIALIZE_SCALAR(txXferLen
);
2096 SERIALIZE_SCALAR(rxXferLen
);
2099 * Serialize Cached Descriptors
2101 SERIALIZE_SCALAR(rxDesc64
.link
);
2102 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2103 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2104 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2105 SERIALIZE_SCALAR(txDesc64
.link
);
2106 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2107 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2108 SERIALIZE_SCALAR(txDesc64
.extsts
);
2109 SERIALIZE_SCALAR(rxDesc32
.link
);
2110 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2111 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2112 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2113 SERIALIZE_SCALAR(txDesc32
.link
);
2114 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2115 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2116 SERIALIZE_SCALAR(txDesc32
.extsts
);
2117 SERIALIZE_SCALAR(extstsEnable
);
2120 * Serialize tx state machine
2122 int txState
= this->txState
;
2123 SERIALIZE_SCALAR(txState
);
2124 SERIALIZE_SCALAR(txEnable
);
2125 SERIALIZE_SCALAR(CTDD
);
2126 SERIALIZE_SCALAR(txFragPtr
);
2127 SERIALIZE_SCALAR(txDescCnt
);
2128 int txDmaState
= this->txDmaState
;
2129 SERIALIZE_SCALAR(txDmaState
);
2130 SERIALIZE_SCALAR(txKickTick
);
2133 * Serialize rx state machine
2135 int rxState
= this->rxState
;
2136 SERIALIZE_SCALAR(rxState
);
2137 SERIALIZE_SCALAR(rxEnable
);
2138 SERIALIZE_SCALAR(CRDD
);
2139 SERIALIZE_SCALAR(rxPktBytes
);
2140 SERIALIZE_SCALAR(rxFragPtr
);
2141 SERIALIZE_SCALAR(rxDescCnt
);
2142 int rxDmaState
= this->rxDmaState
;
2143 SERIALIZE_SCALAR(rxDmaState
);
2144 SERIALIZE_SCALAR(rxKickTick
);
2147 * Serialize EEPROM state machine
2149 int eepromState
= this->eepromState
;
2150 SERIALIZE_SCALAR(eepromState
);
2151 SERIALIZE_SCALAR(eepromClk
);
2152 SERIALIZE_SCALAR(eepromBitsToRx
);
2153 SERIALIZE_SCALAR(eepromOpcode
);
2154 SERIALIZE_SCALAR(eepromAddress
);
2155 SERIALIZE_SCALAR(eepromData
);
2158 * If there's a pending transmit, store the time so we can
2159 * reschedule it later
2161 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick() : 0;
2162 SERIALIZE_SCALAR(transmitTick
);
2165 * receive address filter settings
2167 SERIALIZE_SCALAR(rxFilterEnable
);
2168 SERIALIZE_SCALAR(acceptBroadcast
);
2169 SERIALIZE_SCALAR(acceptMulticast
);
2170 SERIALIZE_SCALAR(acceptUnicast
);
2171 SERIALIZE_SCALAR(acceptPerfect
);
2172 SERIALIZE_SCALAR(acceptArp
);
2173 SERIALIZE_SCALAR(multicastHashEnable
);
2176 * Keep track of pending interrupt status.
2178 SERIALIZE_SCALAR(intrTick
);
2179 SERIALIZE_SCALAR(cpuPendingIntr
);
2180 Tick intrEventTick
= 0;
2182 intrEventTick
= intrEvent
->when();
2183 SERIALIZE_SCALAR(intrEventTick
);
2188 NSGigE::unserialize(CheckpointIn
&cp
)
2190 // Unserialize the PciDevice base class
2191 PciDevice::unserialize(cp
);
2193 UNSERIALIZE_SCALAR(regs
.command
);
2194 UNSERIALIZE_SCALAR(regs
.config
);
2195 UNSERIALIZE_SCALAR(regs
.mear
);
2196 UNSERIALIZE_SCALAR(regs
.ptscr
);
2197 UNSERIALIZE_SCALAR(regs
.isr
);
2198 UNSERIALIZE_SCALAR(regs
.imr
);
2199 UNSERIALIZE_SCALAR(regs
.ier
);
2200 UNSERIALIZE_SCALAR(regs
.ihr
);
2201 UNSERIALIZE_SCALAR(regs
.txdp
);
2202 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2203 UNSERIALIZE_SCALAR(regs
.txcfg
);
2204 UNSERIALIZE_SCALAR(regs
.gpior
);
2205 UNSERIALIZE_SCALAR(regs
.rxdp
);
2206 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2207 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2208 UNSERIALIZE_SCALAR(regs
.pqcr
);
2209 UNSERIALIZE_SCALAR(regs
.wcsr
);
2210 UNSERIALIZE_SCALAR(regs
.pcr
);
2211 UNSERIALIZE_SCALAR(regs
.rfcr
);
2212 UNSERIALIZE_SCALAR(regs
.rfdr
);
2213 UNSERIALIZE_SCALAR(regs
.brar
);
2214 UNSERIALIZE_SCALAR(regs
.brdr
);
2215 UNSERIALIZE_SCALAR(regs
.srr
);
2216 UNSERIALIZE_SCALAR(regs
.mibc
);
2217 UNSERIALIZE_SCALAR(regs
.vrcr
);
2218 UNSERIALIZE_SCALAR(regs
.vtcr
);
2219 UNSERIALIZE_SCALAR(regs
.vdr
);
2220 UNSERIALIZE_SCALAR(regs
.ccsr
);
2221 UNSERIALIZE_SCALAR(regs
.tbicr
);
2222 UNSERIALIZE_SCALAR(regs
.tbisr
);
2223 UNSERIALIZE_SCALAR(regs
.tanar
);
2224 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2225 UNSERIALIZE_SCALAR(regs
.taner
);
2226 UNSERIALIZE_SCALAR(regs
.tesr
);
2228 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2229 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2231 UNSERIALIZE_SCALAR(ioEnable
);
2234 * unserialize the data fifos
2236 rxFifo
.unserialize("rxFifo", cp
);
2237 txFifo
.unserialize("txFifo", cp
);
2240 * unserialize the various helper variables
2242 bool txPacketExists
;
2243 UNSERIALIZE_SCALAR(txPacketExists
);
2244 if (txPacketExists
) {
2245 txPacket
= make_shared
<EthPacketData
>(16384);
2246 txPacket
->unserialize("txPacket", cp
);
2247 uint32_t txPktBufPtr
;
2248 UNSERIALIZE_SCALAR(txPktBufPtr
);
2249 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2253 bool rxPacketExists
;
2254 UNSERIALIZE_SCALAR(rxPacketExists
);
2256 if (rxPacketExists
) {
2257 rxPacket
= make_shared
<EthPacketData
>();
2258 rxPacket
->unserialize("rxPacket", cp
);
2259 uint32_t rxPktBufPtr
;
2260 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2261 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2265 UNSERIALIZE_SCALAR(txXferLen
);
2266 UNSERIALIZE_SCALAR(rxXferLen
);
2269 * Unserialize Cached Descriptors
2271 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2272 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2273 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2274 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2275 UNSERIALIZE_SCALAR(txDesc64
.link
);
2276 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2277 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2278 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2279 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2280 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2281 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2282 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2283 UNSERIALIZE_SCALAR(txDesc32
.link
);
2284 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2285 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2286 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2287 UNSERIALIZE_SCALAR(extstsEnable
);
2290 * unserialize tx state machine
2293 UNSERIALIZE_SCALAR(txState
);
2294 this->txState
= (TxState
) txState
;
2295 UNSERIALIZE_SCALAR(txEnable
);
2296 UNSERIALIZE_SCALAR(CTDD
);
2297 UNSERIALIZE_SCALAR(txFragPtr
);
2298 UNSERIALIZE_SCALAR(txDescCnt
);
2300 UNSERIALIZE_SCALAR(txDmaState
);
2301 this->txDmaState
= (DmaState
) txDmaState
;
2302 UNSERIALIZE_SCALAR(txKickTick
);
2304 schedule(txKickEvent
, txKickTick
);
2307 * unserialize rx state machine
2310 UNSERIALIZE_SCALAR(rxState
);
2311 this->rxState
= (RxState
) rxState
;
2312 UNSERIALIZE_SCALAR(rxEnable
);
2313 UNSERIALIZE_SCALAR(CRDD
);
2314 UNSERIALIZE_SCALAR(rxPktBytes
);
2315 UNSERIALIZE_SCALAR(rxFragPtr
);
2316 UNSERIALIZE_SCALAR(rxDescCnt
);
2318 UNSERIALIZE_SCALAR(rxDmaState
);
2319 this->rxDmaState
= (DmaState
) rxDmaState
;
2320 UNSERIALIZE_SCALAR(rxKickTick
);
2322 schedule(rxKickEvent
, rxKickTick
);
2325 * Unserialize EEPROM state machine
2328 UNSERIALIZE_SCALAR(eepromState
);
2329 this->eepromState
= (EEPROMState
) eepromState
;
2330 UNSERIALIZE_SCALAR(eepromClk
);
2331 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2332 UNSERIALIZE_SCALAR(eepromOpcode
);
2333 UNSERIALIZE_SCALAR(eepromAddress
);
2334 UNSERIALIZE_SCALAR(eepromData
);
2337 * If there's a pending transmit, reschedule it now
2340 UNSERIALIZE_SCALAR(transmitTick
);
2342 schedule(txEvent
, curTick() + transmitTick
);
2345 * unserialize receive address filter settings
2347 UNSERIALIZE_SCALAR(rxFilterEnable
);
2348 UNSERIALIZE_SCALAR(acceptBroadcast
);
2349 UNSERIALIZE_SCALAR(acceptMulticast
);
2350 UNSERIALIZE_SCALAR(acceptUnicast
);
2351 UNSERIALIZE_SCALAR(acceptPerfect
);
2352 UNSERIALIZE_SCALAR(acceptArp
);
2353 UNSERIALIZE_SCALAR(multicastHashEnable
);
2356 * Keep track of pending interrupt status.
2358 UNSERIALIZE_SCALAR(intrTick
);
2359 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2361 UNSERIALIZE_SCALAR(intrEventTick
);
2362 if (intrEventTick
) {
2363 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
2365 schedule(intrEvent
, intrEventTick
);
2370 NSGigEParams::create()
2372 return new NSGigE(this);