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.
28 * Authors: Nathan Binkert
33 * Device module for modelling the National Semiconductor
34 * DP83820 ethernet controller. Does not support priority queueing
37 #include "dev/net/ns_gige.hh"
43 #include "base/debug.hh"
44 #include "base/inet.hh"
45 #include "base/types.hh"
46 #include "debug/EthernetAll.hh"
47 #include "dev/net/etherlink.hh"
48 #include "mem/packet.hh"
49 #include "mem/packet_access.hh"
50 #include "params/NSGigE.hh"
51 #include "sim/system.hh"
53 // clang complains about std::set being overloaded with Packet::set if
54 // we open up the entire namespace std
55 using std::make_shared
;
60 const char *NsRxStateStrings
[] =
71 const char *NsTxStateStrings
[] =
82 const char *NsDmaState
[] =
93 ///////////////////////////////////////////////////////////////////////
97 NSGigE::NSGigE(Params
*p
)
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
),
119 rxKickEvent([this]{ rxKick(); }, name()),
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)
131 interface
= new NSGigEInt(name() + ".int0", this);
134 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
136 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
137 memset(&txDesc32
, 0, sizeof(txDesc32
));
138 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
139 memset(&txDesc64
, 0, sizeof(txDesc64
));
148 * This is to write to the PCI general configuration registers
151 NSGigE::writeConfig(PacketPtr pkt
)
153 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
154 if (offset
< PCI_DEVICE_SPECIFIC
)
155 PciDevice::writeConfig(pkt
);
157 panic("Device specific PCI config space not implemented!\n");
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
164 if (config
.data
[offset
] & PCI_CMD_IOSE
)
175 NSGigE::getPort(const std::string
&if_name
, PortID idx
)
177 if (if_name
== "interface")
179 return EtherDevBase::getPort(if_name
, idx
);
183 * This reads the device registers, which are detailed in the NS83820
187 NSGigE::read(PacketPtr pkt
)
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());
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();
210 } else if (daddr
> 0x3FC)
211 panic("Something is messed up!\n");
213 assert(pkt
->getSize() == sizeof(uint32_t));
214 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
220 //these are supposed to be cleared on a read
221 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
238 devIntrClear(ISR_ALL
);
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
303 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
305 // Read from perfect match ROM octets
307 reg
= rom
.perfectMatch
[1];
309 reg
+= rom
.perfectMatch
[0];
312 reg
= rom
.perfectMatch
[3] << 8;
313 reg
+= rom
.perfectMatch
[2];
316 reg
= rom
.perfectMatch
[5] << 8;
317 reg
+= rom
.perfectMatch
[4];
320 // Read filter hash table
321 if (rfaddr
>= FHASH_ADDR
&&
322 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
324 // Only word-aligned reads supported
326 panic("unaligned read from filter hash table!");
328 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
329 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
333 panic("reading RFDR for something other than pattern"
334 " matching or hashing! %#x\n", rfaddr
);
344 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
389 if (params()->rx_thread
)
390 reg
|= M5REG_RX_THREAD
;
391 if (params()->tx_thread
)
392 reg
|= M5REG_TX_THREAD
;
398 panic("reading unimplemented register: addr=%#x", daddr
);
401 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
404 pkt
->makeAtomicResponse();
409 NSGigE::write(PacketPtr pkt
)
413 Addr daddr
= pkt
->getAddr() & 0xfff;
414 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
415 daddr
, pkt
->getAddr(), pkt
->getSize());
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");
424 if (pkt
->getSize() == sizeof(uint32_t)) {
425 uint32_t reg
= pkt
->getLE
<uint32_t>();
428 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
435 } else if (reg
& CR_TXE
) {
438 // the kernel is enabling the transmit machine
439 if (txState
== txIdle
)
445 } else if (reg
& CR_RXE
) {
448 if (rxState
== rxIdle
)
459 devIntrPost(ISR_SWI
);
470 if (reg
& CFGR_LNKSTS
||
473 reg
& CFGR_RESERVED
||
474 reg
& CFGR_T64ADDR
||
475 reg
& CFGR_PCI64_DET
) {
476 // First clear all writable bits
477 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
478 CFGR_RESERVED
| CFGR_T64ADDR
|
480 // Now set the appropriate writable bits
481 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
482 CFGR_RESERVED
| CFGR_T64ADDR
|
486 if (reg
& CFGR_AUTO_1000
)
487 panic("CFGR_AUTO_1000 not implemented!\n");
489 if (reg
& CFGR_PCI64_DET
)
490 panic("CFGR_PCI64_DET is read only register!\n");
492 if (reg
& CFGR_EXTSTS_EN
)
495 extstsEnable
= false;
499 // Clear writable bits
500 regs
.mear
&= MEAR_EEDO
;
501 // Set appropriate writable bits
502 regs
.mear
|= reg
& ~MEAR_EEDO
;
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
)
512 eepromState
= eepromStart
;
513 regs
.mear
&= ~MEAR_EEDI
;
516 eepromClk
= reg
& MEAR_EECLK
;
518 // since phy is completely faked, MEAR_MD* don't matter
522 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
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
)
526 regs
.ptscr
|= PTSCR_RBIST_DONE
;
527 if (reg
& PTSCR_EEBIST_EN
)
528 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
529 if (reg
& PTSCR_EELOAD_EN
)
530 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
533 case ISR
: /* writing to the ISR has no effect */
534 panic("ISR is a read only register!\n");
547 /* not going to implement real interrupt holdoff */
551 regs
.txdp
= (reg
& 0xFFFFFFFC);
552 assert(txState
== txIdle
);
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
571 // Only write writable bits
572 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
573 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
574 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
575 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
576 /* these just control general purpose i/o pins, don't matter */
593 /* there is no priority queueing used in the linux 2.6 driver */
598 /* not going to implement wake on LAN */
603 /* not going to implement pause control */
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;
619 panic("Unicast hash filtering not used by drivers!\n");
622 panic("RFCR_ULM not implemented!\n");
627 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
630 rom
.perfectMatch
[0] = (uint8_t)reg
;
631 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
634 rom
.perfectMatch
[2] = (uint8_t)reg
;
635 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
638 rom
.perfectMatch
[4] = (uint8_t)reg
;
639 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
643 if (rfaddr
>= FHASH_ADDR
&&
644 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
646 // Only word-aligned writes supported
648 panic("unaligned write to filter hash table!");
650 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
651 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
652 = (uint8_t)(reg
>> 8);
655 panic("writing RFDR for something other than pattern matching "
656 "or hashing! %#x\n", rfaddr
);
665 panic("the driver never uses BRDR, something is wrong!\n");
668 panic("SRR is read only register!\n");
671 panic("the driver never uses MIBC, something is wrong!\n");
682 panic("the driver never uses VDR, something is wrong!\n");
685 /* not going to implement clockrun stuff */
691 if (reg
& TBICR_MR_LOOPBACK
)
692 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
694 if (reg
& TBICR_MR_AN_ENABLE
) {
695 regs
.tanlpar
= regs
.tanar
;
696 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
702 panic("TBISR is read only register!\n");
705 // Only write the writable bits
706 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
707 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
709 // Pause capability unimplemented
713 panic("this should only be written to by the fake phy!\n");
716 panic("TANER is read only register!\n");
723 panic("invalid register access daddr=%#x", daddr
);
726 panic("Invalid Request Size");
728 pkt
->makeAtomicResponse();
733 NSGigE::devIntrPost(uint32_t interrupts
)
735 if (interrupts
& ISR_RESERVE
)
736 panic("Cannot set a reserved interrupt");
738 if (interrupts
& ISR_NOIMPL
)
739 warn("interrupt not implemented %#x\n", interrupts
);
741 interrupts
&= ISR_IMPL
;
742 regs
.isr
|= interrupts
;
744 if (interrupts
& regs
.imr
) {
745 if (interrupts
& ISR_SWI
) {
748 if (interrupts
& ISR_RXIDLE
) {
751 if (interrupts
& ISR_RXOK
) {
754 if (interrupts
& ISR_RXDESC
) {
757 if (interrupts
& ISR_TXOK
) {
760 if (interrupts
& ISR_TXIDLE
) {
763 if (interrupts
& ISR_TXDESC
) {
766 if (interrupts
& ISR_RXORN
) {
771 DPRINTF(EthernetIntr
,
772 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
773 interrupts
, regs
.isr
, regs
.imr
);
775 if ((regs
.isr
& regs
.imr
)) {
776 Tick when
= curTick();
777 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
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
790 NSGigE::devIntrClear(uint32_t interrupts
)
792 if (interrupts
& ISR_RESERVE
)
793 panic("Cannot clear a reserved interrupt");
795 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
798 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
801 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
804 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
807 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
810 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
813 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
816 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
820 interrupts
&= ~ISR_NOIMPL
;
821 regs
.isr
&= ~interrupts
;
823 DPRINTF(EthernetIntr
,
824 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
825 interrupts
, regs
.isr
, regs
.imr
);
827 if (!(regs
.isr
& regs
.imr
))
832 NSGigE::devIntrChangeMask()
834 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
835 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
837 if (regs
.isr
& regs
.imr
)
838 cpuIntrPost(curTick());
844 NSGigE::cpuIntrPost(Tick when
)
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
849 // HOWEVER, must be sure that the scheduled intrTick is in the
850 // future (this was formerly the source of a bug)
852 * @todo this warning should be removed and the intrTick code should
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",
864 if (intrTick
< curTick()) {
865 intrTick
= curTick();
868 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
874 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
876 schedule(intrEvent
, intrTick
);
880 NSGigE::cpuInterrupt()
882 assert(intrTick
== curTick());
884 // Whether or not there's a pending interrupt, we don't care about
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");
895 cpuPendingIntr
= true;
897 DPRINTF(EthernetIntr
, "posting interrupt\n");
903 NSGigE::cpuIntrClear()
915 cpuPendingIntr
= false;
917 DPRINTF(EthernetIntr
, "clearing interrupt\n");
922 NSGigE::cpuIntrPending() const
923 { return cpuPendingIntr
; }
929 DPRINTF(Ethernet
, "transmit reset\n");
934 assert(txDescCnt
== 0);
937 assert(txDmaState
== dmaIdle
);
943 DPRINTF(Ethernet
, "receive reset\n");
946 assert(rxPktBytes
== 0);
949 assert(rxDescCnt
== 0);
950 assert(rxDmaState
== dmaIdle
);
958 memset(®s
, 0, sizeof(regs
));
959 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
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
965 regs
.mibc
= MIBC_FRZ
;
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;
970 extstsEnable
= false;
971 acceptBroadcast
= false;
972 acceptMulticast
= false;
973 acceptUnicast
= false;
974 acceptPerfect
= false;
979 NSGigE::doRxDmaRead()
981 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
982 rxDmaState
= dmaReading
;
984 if (dmaPending() || drainState() != DrainState::Running
)
985 rxDmaState
= dmaReadWaiting
;
987 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
993 NSGigE::rxDmaReadDone()
995 assert(rxDmaState
== dmaReading
);
996 rxDmaState
= dmaIdle
;
998 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
999 rxDmaAddr
, rxDmaLen
);
1000 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1002 // If the transmit state machine has a pending DMA, let it go first
1003 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1010 NSGigE::doRxDmaWrite()
1012 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1013 rxDmaState
= dmaWriting
;
1015 if (dmaPending() || drainState() != DrainState::Running
)
1016 rxDmaState
= dmaWriteWaiting
;
1018 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1023 NSGigE::rxDmaWriteDone()
1025 assert(rxDmaState
== dmaWriting
);
1026 rxDmaState
= dmaIdle
;
1028 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1029 rxDmaAddr
, rxDmaLen
);
1030 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1032 // If the transmit state machine has a pending DMA, let it go first
1033 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1042 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1045 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1046 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1049 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1050 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1053 if (rxKickTick
> curTick()) {
1054 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1060 // Go to the next state machine clock tick.
1061 rxKickTick
= clockEdge(Cycles(1));
1063 switch(rxDmaState
) {
1064 case dmaReadWaiting
:
1068 case dmaWriteWaiting
:
1076 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1077 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
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.
1089 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1094 rxState
= rxDescRefr
;
1096 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1098 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1099 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1100 rxDmaFree
= dmaDescFree
;
1103 descDmaRdBytes
+= rxDmaLen
;
1108 rxState
= rxDescRead
;
1110 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1111 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1112 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1113 rxDmaFree
= dmaDescFree
;
1116 descDmaRdBytes
+= rxDmaLen
;
1124 if (rxDmaState
!= dmaIdle
)
1127 rxState
= rxAdvance
;
1131 if (rxDmaState
!= dmaIdle
)
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
);
1140 if (cmdsts
& CMDSTS_OWN
) {
1141 devIntrPost(ISR_RXIDLE
);
1145 rxState
= rxFifoBlock
;
1147 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1154 * @todo in reality, we should be able to start processing
1155 * the packet as it arrives, and not have to wait for the
1156 * full packet ot be in the receive fifo.
1161 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
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
;
1169 if (DTRACE(Ethernet
)) {
1172 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1176 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1177 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1184 // sanity check - i think the driver behaves like this
1185 assert(rxDescCnt
>= rxPktBytes
);
1190 // dont' need the && rxDescCnt > 0 if driver sanity check
1192 if (rxPktBytes
> 0) {
1193 rxState
= rxFragWrite
;
1194 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1196 rxXferLen
= rxPktBytes
;
1198 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1199 rxDmaData
= rxPacketBufPtr
;
1200 rxDmaLen
= rxXferLen
;
1201 rxDmaFree
= dmaDataFree
;
1207 rxState
= rxDescWrite
;
1209 //if (rxPktBytes == 0) { /* packet is done */
1210 assert(rxPktBytes
== 0);
1211 DPRINTF(EthernetSM
, "done with receiving packet\n");
1213 cmdsts
|= CMDSTS_OWN
;
1214 cmdsts
&= ~CMDSTS_MORE
;
1215 cmdsts
|= CMDSTS_OK
;
1216 cmdsts
&= 0xffff0000;
1217 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
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
;
1230 extsts
|= EXTSTS_TCPPKT
;
1232 if (cksum(tcp
) != 0) {
1233 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1234 extsts
|= EXTSTS_TCPERR
;
1238 extsts
|= EXTSTS_UDPPKT
;
1240 if (cksum(udp
) != 0) {
1241 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1242 extsts
|= EXTSTS_UDPERR
;
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.
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
);
1262 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1263 rxDmaData
= &cmdsts
;
1265 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1266 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1268 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1269 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1271 rxDmaFree
= dmaDescFree
;
1274 descDmaWrBytes
+= rxDmaLen
;
1282 if (rxDmaState
!= dmaIdle
)
1285 rxPacketBufPtr
+= rxXferLen
;
1286 rxFragPtr
+= rxXferLen
;
1287 rxPktBytes
-= rxXferLen
;
1289 rxState
= rxFifoBlock
;
1293 if (rxDmaState
!= dmaIdle
)
1296 assert(cmdsts
& CMDSTS_OWN
);
1298 assert(rxPacket
== 0);
1299 devIntrPost(ISR_RXOK
);
1301 if (cmdsts
& CMDSTS_INTR
)
1302 devIntrPost(ISR_RXDESC
);
1305 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1309 rxState
= rxAdvance
;
1314 devIntrPost(ISR_RXIDLE
);
1319 if (rxDmaState
!= dmaIdle
)
1321 rxState
= rxDescRead
;
1325 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1326 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1327 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1328 rxDmaFree
= dmaDescFree
;
1336 panic("Invalid rxState!");
1339 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1340 NsRxStateStrings
[rxState
]);
1345 * @todo do we want to schedule a future kick?
1347 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1348 NsRxStateStrings
[rxState
]);
1350 if (!rxKickEvent
.scheduled())
1351 schedule(rxKickEvent
, rxKickTick
);
1357 if (txFifo
.empty()) {
1358 DPRINTF(Ethernet
, "nothing to transmit\n");
1362 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1364 if (interface
->sendPacket(txFifo
.front())) {
1366 if (DTRACE(Ethernet
)) {
1367 IpPtr
ip(txFifo
.front());
1369 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1373 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1374 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1381 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1382 txBytes
+= txFifo
.front()->length
;
1385 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
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.
1396 devIntrPost(ISR_TXOK
);
1399 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1400 DPRINTF(Ethernet
, "reschedule transmit\n");
1401 schedule(txEvent
, curTick() + retryTime
);
1406 NSGigE::doTxDmaRead()
1408 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1409 txDmaState
= dmaReading
;
1411 if (dmaPending() || drainState() != DrainState::Running
)
1412 txDmaState
= dmaReadWaiting
;
1414 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1420 NSGigE::txDmaReadDone()
1422 assert(txDmaState
== dmaReading
);
1423 txDmaState
= dmaIdle
;
1425 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1426 txDmaAddr
, txDmaLen
);
1427 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1429 // If the receive state machine has a pending DMA, let it go first
1430 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1437 NSGigE::doTxDmaWrite()
1439 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1440 txDmaState
= dmaWriting
;
1442 if (dmaPending() || drainState() != DrainState::Running
)
1443 txDmaState
= dmaWriteWaiting
;
1445 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1450 NSGigE::txDmaWriteDone()
1452 assert(txDmaState
== dmaWriting
);
1453 txDmaState
= dmaIdle
;
1455 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1456 txDmaAddr
, txDmaLen
);
1457 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1459 // If the receive state machine has a pending DMA, let it go first
1460 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1469 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1471 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1472 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1475 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1476 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1479 if (txKickTick
> curTick()) {
1480 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1485 // Go to the next state machine clock tick.
1486 txKickTick
= clockEdge(Cycles(1));
1488 switch(txDmaState
) {
1489 case dmaReadWaiting
:
1493 case dmaWriteWaiting
:
1501 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1502 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1506 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1511 txState
= txDescRefr
;
1513 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1515 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1516 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1517 txDmaFree
= dmaDescFree
;
1520 descDmaRdBytes
+= txDmaLen
;
1526 txState
= txDescRead
;
1528 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1529 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1530 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1531 txDmaFree
= dmaDescFree
;
1534 descDmaRdBytes
+= txDmaLen
;
1542 if (txDmaState
!= dmaIdle
)
1545 txState
= txAdvance
;
1549 if (txDmaState
!= dmaIdle
)
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
);
1558 if (cmdsts
& CMDSTS_OWN
) {
1559 txState
= txFifoBlock
;
1561 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1563 devIntrPost(ISR_TXIDLE
);
1571 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1572 txPacket
= make_shared
<EthPacketData
>(16384);
1573 txPacketBufPtr
= txPacket
->data
;
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");
1580 txState
= txDescWrite
;
1582 cmdsts
&= ~CMDSTS_OWN
;
1584 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1585 txDmaData
= &cmdsts
;
1587 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1588 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1590 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1591 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1593 txDmaFree
= dmaDescFree
;
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
) {
1603 if (extsts
& EXTSTS_UDPPKT
) {
1607 udp
->sum(cksum(udp
));
1610 Debug::breakpoint();
1611 warn_once("UDPPKT set, but not UDP!\n");
1613 } else if (extsts
& EXTSTS_TCPPKT
) {
1617 tcp
->sum(cksum(tcp
));
1620 warn_once("TCPPKT set, but not UDP!\n");
1623 if (extsts
& EXTSTS_IPPKT
) {
1629 warn_once("IPPKT set, but not UDP!\n");
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",
1645 txFifo
.push(txPacket
);
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
1660 cmdsts
&= ~CMDSTS_OWN
;
1661 cmdsts
|= CMDSTS_OK
;
1663 DPRINTF(EthernetDesc
,
1664 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1667 txDmaFree
= dmaDescFree
;
1668 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1669 txDmaData
= &cmdsts
;
1671 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1673 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1675 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1677 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1681 descDmaWrBytes
+= txDmaLen
;
1687 DPRINTF(EthernetSM
, "halting TX state machine\n");
1691 txState
= txAdvance
;
1697 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1698 if (!txFifo
.full()) {
1699 txState
= txFragRead
;
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
1707 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1709 txDmaAddr
= txFragPtr
& 0x3fffffff;
1710 txDmaData
= txPacketBufPtr
;
1711 txDmaLen
= txXferLen
;
1712 txDmaFree
= dmaDataFree
;
1717 txState
= txFifoBlock
;
1727 if (txDmaState
!= dmaIdle
)
1730 txPacketBufPtr
+= txXferLen
;
1731 txFragPtr
+= txXferLen
;
1732 txDescCnt
-= txXferLen
;
1733 txFifo
.reserve(txXferLen
);
1735 txState
= txFifoBlock
;
1739 if (txDmaState
!= dmaIdle
)
1742 if (cmdsts
& CMDSTS_INTR
)
1743 devIntrPost(ISR_TXDESC
);
1746 DPRINTF(EthernetSM
, "halting TX state machine\n");
1750 txState
= txAdvance
;
1755 devIntrPost(ISR_TXIDLE
);
1759 if (txDmaState
!= dmaIdle
)
1761 txState
= txDescRead
;
1765 txDmaAddr
= link
& 0x3fffffff;
1766 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1767 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1768 txDmaFree
= dmaDescFree
;
1776 panic("invalid state");
1779 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1780 NsTxStateStrings
[txState
]);
1785 * @todo do we want to schedule a future kick?
1787 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1788 NsTxStateStrings
[txState
]);
1790 if (!txKickEvent
.scheduled())
1791 schedule(txKickEvent
, txKickTick
);
1795 * Advance the EEPROM state machine
1796 * Called on rising edge of EEPROM clock bit in MEAR
1799 NSGigE::eepromKick()
1801 switch (eepromState
) {
1805 // Wait for start bit
1806 if (regs
.mear
& MEAR_EEDI
) {
1807 // Set up to get 2 opcode bits
1808 eepromState
= eepromGetOpcode
;
1814 case eepromGetOpcode
:
1816 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1819 // Done getting opcode
1820 if (eepromBitsToRx
== 0) {
1821 if (eepromOpcode
!= EEPROM_READ
)
1822 panic("only EEPROM reads are implemented!");
1824 // Set up to get address
1825 eepromState
= eepromGetAddress
;
1831 case eepromGetAddress
:
1832 eepromAddress
<<= 1;
1833 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1836 // Done getting address
1837 if (eepromBitsToRx
== 0) {
1839 if (eepromAddress
>= EEPROM_SIZE
)
1840 panic("EEPROM read access out of range!");
1842 switch (eepromAddress
) {
1844 case EEPROM_PMATCH2_ADDR
:
1845 eepromData
= rom
.perfectMatch
[5];
1847 eepromData
+= rom
.perfectMatch
[4];
1850 case EEPROM_PMATCH1_ADDR
:
1851 eepromData
= rom
.perfectMatch
[3];
1853 eepromData
+= rom
.perfectMatch
[2];
1856 case EEPROM_PMATCH0_ADDR
:
1857 eepromData
= rom
.perfectMatch
[1];
1859 eepromData
+= rom
.perfectMatch
[0];
1863 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1865 // Set up to read data
1866 eepromState
= eepromRead
;
1867 eepromBitsToRx
= 16;
1869 // Clear data in bit
1870 regs
.mear
&= ~MEAR_EEDI
;
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;
1884 if (eepromBitsToRx
== 0) {
1885 eepromState
= eepromStart
;
1890 panic("invalid EEPROM state");
1896 NSGigE::transferDone()
1898 if (txFifo
.empty()) {
1899 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
1903 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
1905 reschedule(txEvent
, clockEdge(Cycles(1)), true);
1909 NSGigE::rxFilter(const EthPacketPtr
&packet
)
1911 EthPtr eth
= packet
;
1915 const EthAddr
&dst
= eth
->dst();
1916 if (dst
.unicast()) {
1917 // If we're accepting all unicast addresses
1921 // If we make a perfect match
1922 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
1925 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
1928 } else if (dst
.broadcast()) {
1929 // if we're accepting broadcasts
1930 if (acceptBroadcast
)
1933 } else if (dst
.multicast()) {
1934 // if we're accepting all multicasts
1935 if (acceptMulticast
)
1938 // Multicast hashing faked - all packets accepted
1939 if (multicastHashEnable
)
1944 DPRINTF(Ethernet
, "rxFilter drop\n");
1945 DDUMP(EthernetData
, packet
->data
, packet
->length
);
1952 NSGigE::recvPacket(EthPacketPtr packet
)
1954 rxBytes
+= packet
->length
;
1957 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
1961 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
1965 if (!rxFilterEnable
) {
1967 "receive packet filtering disabled . . . packet dropped\n");
1971 if (rxFilter(packet
)) {
1972 DPRINTF(Ethernet
, "packet filtered...dropped\n");
1976 if (rxFifo
.avail() < packet
->length
) {
1982 "packet won't fit in receive buffer...pkt ID %d dropped\n",
1985 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
1990 devIntrPost(ISR_RXORN
);
1994 rxFifo
.push(packet
);
2002 NSGigE::drainResume()
2004 Drainable::drainResume();
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
2014 //=====================================================================
2018 NSGigE::serialize(CheckpointOut
&cp
) const
2020 // Serialize the PciDevice base class
2021 PciDevice::serialize(cp
);
2024 * Finalize any DMA events now.
2026 // @todo will mem system save pending dma?
2029 * Serialize the device registers
2031 SERIALIZE_SCALAR(regs
.command
);
2032 SERIALIZE_SCALAR(regs
.config
);
2033 SERIALIZE_SCALAR(regs
.mear
);
2034 SERIALIZE_SCALAR(regs
.ptscr
);
2035 SERIALIZE_SCALAR(regs
.isr
);
2036 SERIALIZE_SCALAR(regs
.imr
);
2037 SERIALIZE_SCALAR(regs
.ier
);
2038 SERIALIZE_SCALAR(regs
.ihr
);
2039 SERIALIZE_SCALAR(regs
.txdp
);
2040 SERIALIZE_SCALAR(regs
.txdp_hi
);
2041 SERIALIZE_SCALAR(regs
.txcfg
);
2042 SERIALIZE_SCALAR(regs
.gpior
);
2043 SERIALIZE_SCALAR(regs
.rxdp
);
2044 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2045 SERIALIZE_SCALAR(regs
.rxcfg
);
2046 SERIALIZE_SCALAR(regs
.pqcr
);
2047 SERIALIZE_SCALAR(regs
.wcsr
);
2048 SERIALIZE_SCALAR(regs
.pcr
);
2049 SERIALIZE_SCALAR(regs
.rfcr
);
2050 SERIALIZE_SCALAR(regs
.rfdr
);
2051 SERIALIZE_SCALAR(regs
.brar
);
2052 SERIALIZE_SCALAR(regs
.brdr
);
2053 SERIALIZE_SCALAR(regs
.srr
);
2054 SERIALIZE_SCALAR(regs
.mibc
);
2055 SERIALIZE_SCALAR(regs
.vrcr
);
2056 SERIALIZE_SCALAR(regs
.vtcr
);
2057 SERIALIZE_SCALAR(regs
.vdr
);
2058 SERIALIZE_SCALAR(regs
.ccsr
);
2059 SERIALIZE_SCALAR(regs
.tbicr
);
2060 SERIALIZE_SCALAR(regs
.tbisr
);
2061 SERIALIZE_SCALAR(regs
.tanar
);
2062 SERIALIZE_SCALAR(regs
.tanlpar
);
2063 SERIALIZE_SCALAR(regs
.taner
);
2064 SERIALIZE_SCALAR(regs
.tesr
);
2066 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2067 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2069 SERIALIZE_SCALAR(ioEnable
);
2072 * Serialize the data Fifos
2074 rxFifo
.serialize("rxFifo", cp
);
2075 txFifo
.serialize("txFifo", cp
);
2078 * Serialize the various helper variables
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
);
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
);
2098 SERIALIZE_SCALAR(txXferLen
);
2099 SERIALIZE_SCALAR(rxXferLen
);
2102 * Serialize Cached Descriptors
2104 SERIALIZE_SCALAR(rxDesc64
.link
);
2105 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2106 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2107 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2108 SERIALIZE_SCALAR(txDesc64
.link
);
2109 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2110 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2111 SERIALIZE_SCALAR(txDesc64
.extsts
);
2112 SERIALIZE_SCALAR(rxDesc32
.link
);
2113 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2114 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2115 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2116 SERIALIZE_SCALAR(txDesc32
.link
);
2117 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2118 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2119 SERIALIZE_SCALAR(txDesc32
.extsts
);
2120 SERIALIZE_SCALAR(extstsEnable
);
2123 * Serialize tx state machine
2125 int txState
= this->txState
;
2126 SERIALIZE_SCALAR(txState
);
2127 SERIALIZE_SCALAR(txEnable
);
2128 SERIALIZE_SCALAR(CTDD
);
2129 SERIALIZE_SCALAR(txFragPtr
);
2130 SERIALIZE_SCALAR(txDescCnt
);
2131 int txDmaState
= this->txDmaState
;
2132 SERIALIZE_SCALAR(txDmaState
);
2133 SERIALIZE_SCALAR(txKickTick
);
2136 * Serialize rx state machine
2138 int rxState
= this->rxState
;
2139 SERIALIZE_SCALAR(rxState
);
2140 SERIALIZE_SCALAR(rxEnable
);
2141 SERIALIZE_SCALAR(CRDD
);
2142 SERIALIZE_SCALAR(rxPktBytes
);
2143 SERIALIZE_SCALAR(rxFragPtr
);
2144 SERIALIZE_SCALAR(rxDescCnt
);
2145 int rxDmaState
= this->rxDmaState
;
2146 SERIALIZE_SCALAR(rxDmaState
);
2147 SERIALIZE_SCALAR(rxKickTick
);
2150 * Serialize EEPROM state machine
2152 int eepromState
= this->eepromState
;
2153 SERIALIZE_SCALAR(eepromState
);
2154 SERIALIZE_SCALAR(eepromClk
);
2155 SERIALIZE_SCALAR(eepromBitsToRx
);
2156 SERIALIZE_SCALAR(eepromOpcode
);
2157 SERIALIZE_SCALAR(eepromAddress
);
2158 SERIALIZE_SCALAR(eepromData
);
2161 * If there's a pending transmit, store the time so we can
2162 * reschedule it later
2164 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick() : 0;
2165 SERIALIZE_SCALAR(transmitTick
);
2168 * receive address filter settings
2170 SERIALIZE_SCALAR(rxFilterEnable
);
2171 SERIALIZE_SCALAR(acceptBroadcast
);
2172 SERIALIZE_SCALAR(acceptMulticast
);
2173 SERIALIZE_SCALAR(acceptUnicast
);
2174 SERIALIZE_SCALAR(acceptPerfect
);
2175 SERIALIZE_SCALAR(acceptArp
);
2176 SERIALIZE_SCALAR(multicastHashEnable
);
2179 * Keep track of pending interrupt status.
2181 SERIALIZE_SCALAR(intrTick
);
2182 SERIALIZE_SCALAR(cpuPendingIntr
);
2183 Tick intrEventTick
= 0;
2185 intrEventTick
= intrEvent
->when();
2186 SERIALIZE_SCALAR(intrEventTick
);
2191 NSGigE::unserialize(CheckpointIn
&cp
)
2193 // Unserialize the PciDevice base class
2194 PciDevice::unserialize(cp
);
2196 UNSERIALIZE_SCALAR(regs
.command
);
2197 UNSERIALIZE_SCALAR(regs
.config
);
2198 UNSERIALIZE_SCALAR(regs
.mear
);
2199 UNSERIALIZE_SCALAR(regs
.ptscr
);
2200 UNSERIALIZE_SCALAR(regs
.isr
);
2201 UNSERIALIZE_SCALAR(regs
.imr
);
2202 UNSERIALIZE_SCALAR(regs
.ier
);
2203 UNSERIALIZE_SCALAR(regs
.ihr
);
2204 UNSERIALIZE_SCALAR(regs
.txdp
);
2205 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2206 UNSERIALIZE_SCALAR(regs
.txcfg
);
2207 UNSERIALIZE_SCALAR(regs
.gpior
);
2208 UNSERIALIZE_SCALAR(regs
.rxdp
);
2209 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2210 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2211 UNSERIALIZE_SCALAR(regs
.pqcr
);
2212 UNSERIALIZE_SCALAR(regs
.wcsr
);
2213 UNSERIALIZE_SCALAR(regs
.pcr
);
2214 UNSERIALIZE_SCALAR(regs
.rfcr
);
2215 UNSERIALIZE_SCALAR(regs
.rfdr
);
2216 UNSERIALIZE_SCALAR(regs
.brar
);
2217 UNSERIALIZE_SCALAR(regs
.brdr
);
2218 UNSERIALIZE_SCALAR(regs
.srr
);
2219 UNSERIALIZE_SCALAR(regs
.mibc
);
2220 UNSERIALIZE_SCALAR(regs
.vrcr
);
2221 UNSERIALIZE_SCALAR(regs
.vtcr
);
2222 UNSERIALIZE_SCALAR(regs
.vdr
);
2223 UNSERIALIZE_SCALAR(regs
.ccsr
);
2224 UNSERIALIZE_SCALAR(regs
.tbicr
);
2225 UNSERIALIZE_SCALAR(regs
.tbisr
);
2226 UNSERIALIZE_SCALAR(regs
.tanar
);
2227 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2228 UNSERIALIZE_SCALAR(regs
.taner
);
2229 UNSERIALIZE_SCALAR(regs
.tesr
);
2231 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2232 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2234 UNSERIALIZE_SCALAR(ioEnable
);
2237 * unserialize the data fifos
2239 rxFifo
.unserialize("rxFifo", cp
);
2240 txFifo
.unserialize("txFifo", cp
);
2243 * unserialize the various helper variables
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
;
2256 bool rxPacketExists
;
2257 UNSERIALIZE_SCALAR(rxPacketExists
);
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
;
2268 UNSERIALIZE_SCALAR(txXferLen
);
2269 UNSERIALIZE_SCALAR(rxXferLen
);
2272 * Unserialize Cached Descriptors
2274 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2275 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2276 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2277 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2278 UNSERIALIZE_SCALAR(txDesc64
.link
);
2279 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2280 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2281 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2282 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2283 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2284 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2285 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2286 UNSERIALIZE_SCALAR(txDesc32
.link
);
2287 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2288 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2289 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2290 UNSERIALIZE_SCALAR(extstsEnable
);
2293 * unserialize tx state machine
2296 UNSERIALIZE_SCALAR(txState
);
2297 this->txState
= (TxState
) txState
;
2298 UNSERIALIZE_SCALAR(txEnable
);
2299 UNSERIALIZE_SCALAR(CTDD
);
2300 UNSERIALIZE_SCALAR(txFragPtr
);
2301 UNSERIALIZE_SCALAR(txDescCnt
);
2303 UNSERIALIZE_SCALAR(txDmaState
);
2304 this->txDmaState
= (DmaState
) txDmaState
;
2305 UNSERIALIZE_SCALAR(txKickTick
);
2307 schedule(txKickEvent
, txKickTick
);
2310 * unserialize rx state machine
2313 UNSERIALIZE_SCALAR(rxState
);
2314 this->rxState
= (RxState
) rxState
;
2315 UNSERIALIZE_SCALAR(rxEnable
);
2316 UNSERIALIZE_SCALAR(CRDD
);
2317 UNSERIALIZE_SCALAR(rxPktBytes
);
2318 UNSERIALIZE_SCALAR(rxFragPtr
);
2319 UNSERIALIZE_SCALAR(rxDescCnt
);
2321 UNSERIALIZE_SCALAR(rxDmaState
);
2322 this->rxDmaState
= (DmaState
) rxDmaState
;
2323 UNSERIALIZE_SCALAR(rxKickTick
);
2325 schedule(rxKickEvent
, rxKickTick
);
2328 * Unserialize EEPROM state machine
2331 UNSERIALIZE_SCALAR(eepromState
);
2332 this->eepromState
= (EEPROMState
) eepromState
;
2333 UNSERIALIZE_SCALAR(eepromClk
);
2334 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2335 UNSERIALIZE_SCALAR(eepromOpcode
);
2336 UNSERIALIZE_SCALAR(eepromAddress
);
2337 UNSERIALIZE_SCALAR(eepromData
);
2340 * If there's a pending transmit, reschedule it now
2343 UNSERIALIZE_SCALAR(transmitTick
);
2345 schedule(txEvent
, curTick() + transmitTick
);
2348 * unserialize receive address filter settings
2350 UNSERIALIZE_SCALAR(rxFilterEnable
);
2351 UNSERIALIZE_SCALAR(acceptBroadcast
);
2352 UNSERIALIZE_SCALAR(acceptMulticast
);
2353 UNSERIALIZE_SCALAR(acceptUnicast
);
2354 UNSERIALIZE_SCALAR(acceptPerfect
);
2355 UNSERIALIZE_SCALAR(acceptArp
);
2356 UNSERIALIZE_SCALAR(multicastHashEnable
);
2359 * Keep track of pending interrupt status.
2361 UNSERIALIZE_SCALAR(intrTick
);
2362 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2364 UNSERIALIZE_SCALAR(intrEventTick
);
2365 if (intrEventTick
) {
2366 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
2368 schedule(intrEvent
, intrEventTick
);
2373 NSGigEParams::create()
2375 return new NSGigE(this);