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
39 #include "base/inet.hh"
40 #include "cpu/thread_context.hh"
41 #include "dev/etherlink.hh"
42 #include "dev/ns_gige.hh"
43 #include "dev/pciconfigall.hh"
44 #include "mem/packet.hh"
45 #include "mem/packet_access.hh"
46 #include "sim/builder.hh"
47 #include "sim/debug.hh"
48 #include "sim/host.hh"
49 #include "sim/stats.hh"
50 #include "sim/system.hh"
52 const char *NsRxStateStrings
[] =
63 const char *NsTxStateStrings
[] =
74 const char *NsDmaState
[] =
85 using namespace TheISA
;
87 ///////////////////////////////////////////////////////////////////////
91 NSGigE::NSGigE(Params
*p
)
92 : PciDev(p
), ioEnable(false),
93 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
94 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
95 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
97 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
98 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
99 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
100 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
101 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
102 eepromOpcode(0), eepromAddress(0), eepromData(0),
103 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
104 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
105 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
106 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
107 rxDmaReadEvent(this), rxDmaWriteEvent(this),
108 txDmaReadEvent(this), txDmaWriteEvent(this),
109 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
110 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
111 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
112 txEvent(this), rxFilterEnable(p
->rx_filter
),
113 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
114 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
115 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
116 intrEvent(0), interface(0)
121 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
123 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
124 memset(&txDesc32
, 0, sizeof(txDesc32
));
125 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
126 memset(&txDesc64
, 0, sizeof(txDesc64
));
136 .name(name() + ".txBytes")
137 .desc("Bytes Transmitted")
142 .name(name() + ".rxBytes")
143 .desc("Bytes Received")
148 .name(name() + ".txPackets")
149 .desc("Number of Packets Transmitted")
154 .name(name() + ".rxPackets")
155 .desc("Number of Packets Received")
160 .name(name() + ".txIpChecksums")
161 .desc("Number of tx IP Checksums done by device")
167 .name(name() + ".rxIpChecksums")
168 .desc("Number of rx IP Checksums done by device")
174 .name(name() + ".txTcpChecksums")
175 .desc("Number of tx TCP Checksums done by device")
181 .name(name() + ".rxTcpChecksums")
182 .desc("Number of rx TCP Checksums done by device")
188 .name(name() + ".txUdpChecksums")
189 .desc("Number of tx UDP Checksums done by device")
195 .name(name() + ".rxUdpChecksums")
196 .desc("Number of rx UDP Checksums done by device")
202 .name(name() + ".descDMAReads")
203 .desc("Number of descriptors the device read w/ DMA")
208 .name(name() + ".descDMAWrites")
209 .desc("Number of descriptors the device wrote w/ DMA")
214 .name(name() + ".descDmaReadBytes")
215 .desc("number of descriptor bytes read w/ DMA")
220 .name(name() + ".descDmaWriteBytes")
221 .desc("number of descriptor bytes write w/ DMA")
226 .name(name() + ".txBandwidth")
227 .desc("Transmit Bandwidth (bits/s)")
233 .name(name() + ".rxBandwidth")
234 .desc("Receive Bandwidth (bits/s)")
240 .name(name() + ".totBandwidth")
241 .desc("Total Bandwidth (bits/s)")
247 .name(name() + ".totPackets")
248 .desc("Total Packets")
254 .name(name() + ".totBytes")
261 .name(name() + ".totPPS")
262 .desc("Total Tranmission Rate (packets/s)")
268 .name(name() + ".txPPS")
269 .desc("Packet Tranmission Rate (packets/s)")
275 .name(name() + ".rxPPS")
276 .desc("Packet Reception Rate (packets/s)")
282 .name(name() + ".postedSwi")
283 .desc("number of software interrupts posted to CPU")
288 .name(name() + ".totalSwi")
289 .desc("total number of Swi written to ISR")
294 .name(name() + ".coalescedSwi")
295 .desc("average number of Swi's coalesced into each post")
300 .name(name() + ".postedRxIdle")
301 .desc("number of rxIdle interrupts posted to CPU")
306 .name(name() + ".totalRxIdle")
307 .desc("total number of RxIdle written to ISR")
312 .name(name() + ".coalescedRxIdle")
313 .desc("average number of RxIdle's coalesced into each post")
318 .name(name() + ".postedRxOk")
319 .desc("number of RxOk interrupts posted to CPU")
324 .name(name() + ".totalRxOk")
325 .desc("total number of RxOk written to ISR")
330 .name(name() + ".coalescedRxOk")
331 .desc("average number of RxOk's coalesced into each post")
336 .name(name() + ".postedRxDesc")
337 .desc("number of RxDesc interrupts posted to CPU")
342 .name(name() + ".totalRxDesc")
343 .desc("total number of RxDesc written to ISR")
348 .name(name() + ".coalescedRxDesc")
349 .desc("average number of RxDesc's coalesced into each post")
354 .name(name() + ".postedTxOk")
355 .desc("number of TxOk interrupts posted to CPU")
360 .name(name() + ".totalTxOk")
361 .desc("total number of TxOk written to ISR")
366 .name(name() + ".coalescedTxOk")
367 .desc("average number of TxOk's coalesced into each post")
372 .name(name() + ".postedTxIdle")
373 .desc("number of TxIdle interrupts posted to CPU")
378 .name(name() + ".totalTxIdle")
379 .desc("total number of TxIdle written to ISR")
384 .name(name() + ".coalescedTxIdle")
385 .desc("average number of TxIdle's coalesced into each post")
390 .name(name() + ".postedTxDesc")
391 .desc("number of TxDesc interrupts posted to CPU")
396 .name(name() + ".totalTxDesc")
397 .desc("total number of TxDesc written to ISR")
402 .name(name() + ".coalescedTxDesc")
403 .desc("average number of TxDesc's coalesced into each post")
408 .name(name() + ".postedRxOrn")
409 .desc("number of RxOrn posted to CPU")
414 .name(name() + ".totalRxOrn")
415 .desc("total number of RxOrn written to ISR")
420 .name(name() + ".coalescedRxOrn")
421 .desc("average number of RxOrn's coalesced into each post")
426 .name(name() + ".coalescedTotal")
427 .desc("average number of interrupts coalesced into each post")
432 .name(name() + ".postedInterrupts")
433 .desc("number of posts to CPU")
438 .name(name() + ".droppedPackets")
439 .desc("number of packets dropped")
443 coalescedSwi
= totalSwi
/ postedInterrupts
;
444 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
445 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
446 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
447 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
448 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
449 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
450 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
452 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
453 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
454 totalRxOrn
) / postedInterrupts
;
456 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
457 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
458 totBandwidth
= txBandwidth
+ rxBandwidth
;
459 totBytes
= txBytes
+ rxBytes
;
460 totPackets
= txPackets
+ rxPackets
;
462 txPacketRate
= txPackets
/ simSeconds
;
463 rxPacketRate
= rxPackets
/ simSeconds
;
468 * This is to write to the PCI general configuration registers
471 NSGigE::writeConfig(PacketPtr pkt
)
473 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
474 if (offset
< PCI_DEVICE_SPECIFIC
)
475 PciDev::writeConfig(pkt
);
477 panic("Device specific PCI config space not implemented!\n");
480 // seems to work fine without all these PCI settings, but i
481 // put in the IO to double check, an assertion will fail if we
482 // need to properly implement it
484 if (config
.data
[offset
] & PCI_CMD_IOSE
)
495 * This reads the device registers, which are detailed in the NS83820
499 NSGigE::read(PacketPtr pkt
)
505 //The mask is to give you only the offset into the device register file
506 Addr daddr
= pkt
->getAddr() & 0xfff;
507 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
508 daddr
, pkt
->getAddr(), pkt
->getSize());
511 // there are some reserved registers, you can see ns_gige_reg.h and
512 // the spec sheet for details
513 if (daddr
> LAST
&& daddr
<= RESERVED
) {
514 panic("Accessing reserved register");
515 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
516 return readConfig(pkt
);
517 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
518 // don't implement all the MIB's. hopefully the kernel
519 // doesn't actually DEPEND upon their values
520 // MIB are just hardware stats keepers
521 pkt
->set
<uint32_t>(0);
522 pkt
->makeAtomicResponse();
524 } else if (daddr
> 0x3FC)
525 panic("Something is messed up!\n");
527 assert(pkt
->getSize() == sizeof(uint32_t));
528 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
534 //these are supposed to be cleared on a read
535 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
552 devIntrClear(ISR_ALL
);
607 // see the spec sheet for how RFCR and RFDR work
608 // basically, you write to RFCR to tell the machine
609 // what you want to do next, then you act upon RFDR,
610 // and the device will be prepared b/c of what you
617 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
619 // Read from perfect match ROM octets
621 reg
= rom
.perfectMatch
[1];
623 reg
+= rom
.perfectMatch
[0];
626 reg
= rom
.perfectMatch
[3] << 8;
627 reg
+= rom
.perfectMatch
[2];
630 reg
= rom
.perfectMatch
[5] << 8;
631 reg
+= rom
.perfectMatch
[4];
634 // Read filter hash table
635 if (rfaddr
>= FHASH_ADDR
&&
636 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
638 // Only word-aligned reads supported
640 panic("unaligned read from filter hash table!");
642 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
643 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
647 panic("reading RFDR for something other than pattern"
648 " matching or hashing! %#x\n", rfaddr
);
658 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
703 if (params()->rx_thread
)
704 reg
|= M5REG_RX_THREAD
;
705 if (params()->tx_thread
)
706 reg
|= M5REG_TX_THREAD
;
712 panic("reading unimplemented register: addr=%#x", daddr
);
715 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
718 pkt
->makeAtomicResponse();
723 NSGigE::write(PacketPtr pkt
)
727 Addr daddr
= pkt
->getAddr() & 0xfff;
728 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
729 daddr
, pkt
->getAddr(), pkt
->getSize());
731 if (daddr
> LAST
&& daddr
<= RESERVED
) {
732 panic("Accessing reserved register");
733 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
734 return writeConfig(pkt
);
735 } else if (daddr
> 0x3FC)
736 panic("Something is messed up!\n");
738 if (pkt
->getSize() == sizeof(uint32_t)) {
739 uint32_t reg
= pkt
->get
<uint32_t>();
742 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
749 } else if (reg
& CR_TXE
) {
752 // the kernel is enabling the transmit machine
753 if (txState
== txIdle
)
759 } else if (reg
& CR_RXE
) {
762 if (rxState
== rxIdle
)
773 devIntrPost(ISR_SWI
);
784 if (reg
& CFGR_LNKSTS
||
787 reg
& CFGR_RESERVED
||
788 reg
& CFGR_T64ADDR
||
789 reg
& CFGR_PCI64_DET
)
791 // First clear all writable bits
792 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
793 CFGR_RESERVED
| CFGR_T64ADDR
|
795 // Now set the appropriate writable bits
796 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
797 CFGR_RESERVED
| CFGR_T64ADDR
|
800 // all these #if 0's are because i don't THINK the kernel needs to
801 // have these implemented. if there is a problem relating to one of
802 // these, you may need to add functionality in.
803 if (reg
& CFGR_TBI_EN
) ;
804 if (reg
& CFGR_MODE_1000
) ;
806 if (reg
& CFGR_AUTO_1000
)
807 panic("CFGR_AUTO_1000 not implemented!\n");
809 if (reg
& CFGR_PINT_DUPSTS
||
810 reg
& CFGR_PINT_LNKSTS
||
811 reg
& CFGR_PINT_SPDSTS
)
814 if (reg
& CFGR_TMRTEST
) ;
815 if (reg
& CFGR_MRM_DIS
) ;
816 if (reg
& CFGR_MWI_DIS
) ;
818 if (reg
& CFGR_T64ADDR
) ;
819 // panic("CFGR_T64ADDR is read only register!\n");
821 if (reg
& CFGR_PCI64_DET
)
822 panic("CFGR_PCI64_DET is read only register!\n");
824 if (reg
& CFGR_DATA64_EN
) ;
825 if (reg
& CFGR_M64ADDR
) ;
826 if (reg
& CFGR_PHY_RST
) ;
827 if (reg
& CFGR_PHY_DIS
) ;
829 if (reg
& CFGR_EXTSTS_EN
)
832 extstsEnable
= false;
834 if (reg
& CFGR_REQALG
) ;
836 if (reg
& CFGR_POW
) ;
837 if (reg
& CFGR_EXD
) ;
838 if (reg
& CFGR_PESEL
) ;
839 if (reg
& CFGR_BROM_DIS
) ;
840 if (reg
& CFGR_EXT_125
) ;
841 if (reg
& CFGR_BEM
) ;
845 // Clear writable bits
846 regs
.mear
&= MEAR_EEDO
;
847 // Set appropriate writable bits
848 regs
.mear
|= reg
& ~MEAR_EEDO
;
850 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
851 // even though it could get it through RFDR
852 if (reg
& MEAR_EESEL
) {
853 // Rising edge of clock
854 if (reg
& MEAR_EECLK
&& !eepromClk
)
858 eepromState
= eepromStart
;
859 regs
.mear
&= ~MEAR_EEDI
;
862 eepromClk
= reg
& MEAR_EECLK
;
864 // since phy is completely faked, MEAR_MD* don't matter
865 if (reg
& MEAR_MDIO
) ;
866 if (reg
& MEAR_MDDIR
) ;
867 if (reg
& MEAR_MDC
) ;
871 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
872 // these control BISTs for various parts of chip - we
873 // don't care or do just fake that the BIST is done
874 if (reg
& PTSCR_RBIST_EN
)
875 regs
.ptscr
|= PTSCR_RBIST_DONE
;
876 if (reg
& PTSCR_EEBIST_EN
)
877 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
878 if (reg
& PTSCR_EELOAD_EN
)
879 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
882 case ISR
: /* writing to the ISR has no effect */
883 panic("ISR is a read only register!\n");
896 /* not going to implement real interrupt holdoff */
900 regs
.txdp
= (reg
& 0xFFFFFFFC);
901 assert(txState
== txIdle
);
912 if (reg
& TX_CFG_CSI
) ;
913 if (reg
& TX_CFG_HBI
) ;
914 if (reg
& TX_CFG_MLB
) ;
915 if (reg
& TX_CFG_ATP
) ;
916 if (reg
& TX_CFG_ECRETRY
) {
918 * this could easily be implemented, but considering
919 * the network is just a fake pipe, wouldn't make
924 if (reg
& TX_CFG_BRST_DIS
) ;
928 /* we handle our own DMA, ignore the kernel's exhortations */
929 if (reg
& TX_CFG_MXDMA
) ;
932 // also, we currently don't care about fill/drain
933 // thresholds though this may change in the future with
934 // more realistic networks or a driver which changes it
935 // according to feedback
940 // Only write writable bits
941 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
942 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
943 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
944 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
945 /* these just control general purpose i/o pins, don't matter */
960 if (reg
& RX_CFG_AEP
) ;
961 if (reg
& RX_CFG_ARP
) ;
962 if (reg
& RX_CFG_STRIPCRC
) ;
963 if (reg
& RX_CFG_RX_RD
) ;
964 if (reg
& RX_CFG_ALP
) ;
965 if (reg
& RX_CFG_AIRL
) ;
967 /* we handle our own DMA, ignore what kernel says about it */
968 if (reg
& RX_CFG_MXDMA
) ;
970 //also, we currently don't care about fill/drain thresholds
971 //though this may change in the future with more realistic
972 //networks or a driver which changes it according to feedback
973 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
978 /* there is no priority queueing used in the linux 2.6 driver */
983 /* not going to implement wake on LAN */
988 /* not going to implement pause control */
995 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
996 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
997 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
998 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
999 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1000 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1001 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1004 if (reg
& RFCR_APAT
)
1005 panic("RFCR_APAT not implemented!\n");
1007 if (reg
& RFCR_UHEN
)
1008 panic("Unicast hash filtering not used by drivers!\n");
1011 panic("RFCR_ULM not implemented!\n");
1016 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1019 rom
.perfectMatch
[0] = (uint8_t)reg
;
1020 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1023 rom
.perfectMatch
[2] = (uint8_t)reg
;
1024 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1027 rom
.perfectMatch
[4] = (uint8_t)reg
;
1028 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1032 if (rfaddr
>= FHASH_ADDR
&&
1033 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1035 // Only word-aligned writes supported
1037 panic("unaligned write to filter hash table!");
1039 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1040 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1041 = (uint8_t)(reg
>> 8);
1044 panic("writing RFDR for something other than pattern matching\
1045 or hashing! %#x\n", rfaddr
);
1053 panic("the driver never uses BRDR, something is wrong!\n");
1056 panic("SRR is read only register!\n");
1059 panic("the driver never uses MIBC, something is wrong!\n");
1070 panic("the driver never uses VDR, something is wrong!\n");
1073 /* not going to implement clockrun stuff */
1079 if (reg
& TBICR_MR_LOOPBACK
)
1080 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1082 if (reg
& TBICR_MR_AN_ENABLE
) {
1083 regs
.tanlpar
= regs
.tanar
;
1084 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1088 if (reg
& TBICR_MR_RESTART_AN
) ;
1094 panic("TBISR is read only register!\n");
1097 // Only write the writable bits
1098 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1099 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1101 // Pause capability unimplemented
1103 if (reg
& TANAR_PS2
) ;
1104 if (reg
& TANAR_PS1
) ;
1110 panic("this should only be written to by the fake phy!\n");
1113 panic("TANER is read only register!\n");
1120 panic("invalid register access daddr=%#x", daddr
);
1123 panic("Invalid Request Size");
1125 pkt
->makeAtomicResponse();
1130 NSGigE::devIntrPost(uint32_t interrupts
)
1132 if (interrupts
& ISR_RESERVE
)
1133 panic("Cannot set a reserved interrupt");
1135 if (interrupts
& ISR_NOIMPL
)
1136 warn("interrupt not implemented %#x\n", interrupts
);
1138 interrupts
&= ISR_IMPL
;
1139 regs
.isr
|= interrupts
;
1141 if (interrupts
& regs
.imr
) {
1142 if (interrupts
& ISR_SWI
) {
1145 if (interrupts
& ISR_RXIDLE
) {
1148 if (interrupts
& ISR_RXOK
) {
1151 if (interrupts
& ISR_RXDESC
) {
1154 if (interrupts
& ISR_TXOK
) {
1157 if (interrupts
& ISR_TXIDLE
) {
1160 if (interrupts
& ISR_TXDESC
) {
1163 if (interrupts
& ISR_RXORN
) {
1168 DPRINTF(EthernetIntr
,
1169 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1170 interrupts
, regs
.isr
, regs
.imr
);
1172 if ((regs
.isr
& regs
.imr
)) {
1173 Tick when
= curTick
;
1174 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1180 /* writing this interrupt counting stats inside this means that this function
1181 is now limited to being used to clear all interrupts upon the kernel
1182 reading isr and servicing. just telling you in case you were thinking
1186 NSGigE::devIntrClear(uint32_t interrupts
)
1188 if (interrupts
& ISR_RESERVE
)
1189 panic("Cannot clear a reserved interrupt");
1191 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1194 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1197 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1200 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1203 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1206 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1209 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1212 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1216 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1219 interrupts
&= ~ISR_NOIMPL
;
1220 regs
.isr
&= ~interrupts
;
1222 DPRINTF(EthernetIntr
,
1223 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1224 interrupts
, regs
.isr
, regs
.imr
);
1226 if (!(regs
.isr
& regs
.imr
))
1231 NSGigE::devIntrChangeMask()
1233 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1234 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1236 if (regs
.isr
& regs
.imr
)
1237 cpuIntrPost(curTick
);
1243 NSGigE::cpuIntrPost(Tick when
)
1245 // If the interrupt you want to post is later than an interrupt
1246 // already scheduled, just let it post in the coming one and don't
1247 // schedule another.
1248 // HOWEVER, must be sure that the scheduled intrTick is in the
1249 // future (this was formerly the source of a bug)
1251 * @todo this warning should be removed and the intrTick code should
1254 assert(when
>= curTick
);
1255 assert(intrTick
>= curTick
|| intrTick
== 0);
1256 if (when
> intrTick
&& intrTick
!= 0) {
1257 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1263 if (intrTick
< curTick
) {
1268 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1272 intrEvent
->squash();
1273 intrEvent
= new IntrEvent(this, intrTick
, true);
1277 NSGigE::cpuInterrupt()
1279 assert(intrTick
== curTick
);
1281 // Whether or not there's a pending interrupt, we don't care about
1286 // Don't send an interrupt if there's already one
1287 if (cpuPendingIntr
) {
1288 DPRINTF(EthernetIntr
,
1289 "would send an interrupt now, but there's already pending\n");
1292 cpuPendingIntr
= true;
1294 DPRINTF(EthernetIntr
, "posting interrupt\n");
1300 NSGigE::cpuIntrClear()
1302 if (!cpuPendingIntr
)
1306 intrEvent
->squash();
1312 cpuPendingIntr
= false;
1314 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1319 NSGigE::cpuIntrPending() const
1320 { return cpuPendingIntr
; }
1326 DPRINTF(Ethernet
, "transmit reset\n");
1331 assert(txDescCnt
== 0);
1334 assert(txDmaState
== dmaIdle
);
1340 DPRINTF(Ethernet
, "receive reset\n");
1343 assert(rxPktBytes
== 0);
1346 assert(rxDescCnt
== 0);
1347 assert(rxDmaState
== dmaIdle
);
1355 memset(®s
, 0, sizeof(regs
));
1356 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1358 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1359 // fill threshold to 32 bytes
1360 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1361 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1362 regs
.mibc
= MIBC_FRZ
;
1363 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1364 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1365 regs
.brar
= 0xffffffff;
1367 extstsEnable
= false;
1368 acceptBroadcast
= false;
1369 acceptMulticast
= false;
1370 acceptUnicast
= false;
1371 acceptPerfect
= false;
1376 NSGigE::doRxDmaRead()
1378 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1379 rxDmaState
= dmaReading
;
1381 if (dmaPending() || getState() != Running
)
1382 rxDmaState
= dmaReadWaiting
;
1384 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1390 NSGigE::rxDmaReadDone()
1392 assert(rxDmaState
== dmaReading
);
1393 rxDmaState
= dmaIdle
;
1395 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1396 rxDmaAddr
, rxDmaLen
);
1397 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1399 // If the transmit state machine has a pending DMA, let it go first
1400 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1407 NSGigE::doRxDmaWrite()
1409 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1410 rxDmaState
= dmaWriting
;
1412 if (dmaPending() || getState() != Running
)
1413 rxDmaState
= dmaWriteWaiting
;
1415 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1420 NSGigE::rxDmaWriteDone()
1422 assert(rxDmaState
== dmaWriting
);
1423 rxDmaState
= dmaIdle
;
1425 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1426 rxDmaAddr
, rxDmaLen
);
1427 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1429 // If the transmit state machine has a pending DMA, let it go first
1430 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1439 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1442 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1443 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1446 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1447 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1451 if (rxKickTick
> curTick
) {
1452 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1458 // Go to the next state machine clock tick.
1459 rxKickTick
= curTick
+ cycles(1);
1462 switch(rxDmaState
) {
1463 case dmaReadWaiting
:
1467 case dmaWriteWaiting
:
1475 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1476 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1478 // see state machine from spec for details
1479 // the way this works is, if you finish work on one state and can
1480 // go directly to another, you do that through jumping to the
1481 // label "next". however, if you have intermediate work, like DMA
1482 // so that you can't go to the next state yet, you go to exit and
1483 // exit the loop. however, when the DMA is done it will trigger
1484 // an event and come back to this loop.
1488 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1493 rxState
= rxDescRefr
;
1495 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1497 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1498 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1499 rxDmaFree
= dmaDescFree
;
1502 descDmaRdBytes
+= rxDmaLen
;
1507 rxState
= rxDescRead
;
1509 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1510 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1511 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1512 rxDmaFree
= dmaDescFree
;
1515 descDmaRdBytes
+= rxDmaLen
;
1523 if (rxDmaState
!= dmaIdle
)
1526 rxState
= rxAdvance
;
1530 if (rxDmaState
!= dmaIdle
)
1533 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1534 regs
.rxdp
& 0x3fffffff);
1535 DPRINTF(EthernetDesc
,
1536 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1537 link
, bufptr
, cmdsts
, extsts
);
1539 if (cmdsts
& CMDSTS_OWN
) {
1540 devIntrPost(ISR_RXIDLE
);
1544 rxState
= rxFifoBlock
;
1546 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1553 * @todo in reality, we should be able to start processing
1554 * the packet as it arrives, and not have to wait for the
1555 * full packet ot be in the receive fifo.
1560 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1562 // If we don't have a packet, grab a new one from the fifo.
1563 rxPacket
= rxFifo
.front();
1564 rxPktBytes
= rxPacket
->length
;
1565 rxPacketBufPtr
= rxPacket
->data
;
1568 if (DTRACE(Ethernet
)) {
1571 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1575 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1576 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1583 // sanity check - i think the driver behaves like this
1584 assert(rxDescCnt
>= rxPktBytes
);
1589 // dont' need the && rxDescCnt > 0 if driver sanity check
1591 if (rxPktBytes
> 0) {
1592 rxState
= rxFragWrite
;
1593 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1595 rxXferLen
= rxPktBytes
;
1597 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1598 rxDmaData
= rxPacketBufPtr
;
1599 rxDmaLen
= rxXferLen
;
1600 rxDmaFree
= dmaDataFree
;
1606 rxState
= rxDescWrite
;
1608 //if (rxPktBytes == 0) { /* packet is done */
1609 assert(rxPktBytes
== 0);
1610 DPRINTF(EthernetSM
, "done with receiving packet\n");
1612 cmdsts
|= CMDSTS_OWN
;
1613 cmdsts
&= ~CMDSTS_MORE
;
1614 cmdsts
|= CMDSTS_OK
;
1615 cmdsts
&= 0xffff0000;
1616 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1620 * all the driver uses these are for its own stats keeping
1621 * which we don't care about, aren't necessary for
1622 * functionality and doing this would just slow us down.
1623 * if they end up using this in a later version for
1624 * functional purposes, just undef
1626 if (rxFilterEnable
) {
1627 cmdsts
&= ~CMDSTS_DEST_MASK
;
1628 const EthAddr
&dst
= rxFifoFront()->dst();
1630 cmdsts
|= CMDSTS_DEST_SELF
;
1631 if (dst
->multicast())
1632 cmdsts
|= CMDSTS_DEST_MULTI
;
1633 if (dst
->broadcast())
1634 cmdsts
|= CMDSTS_DEST_MASK
;
1639 if (extstsEnable
&& ip
) {
1640 extsts
|= EXTSTS_IPPKT
;
1642 if (cksum(ip
) != 0) {
1643 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1644 extsts
|= EXTSTS_IPERR
;
1649 extsts
|= EXTSTS_TCPPKT
;
1651 if (cksum(tcp
) != 0) {
1652 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1653 extsts
|= EXTSTS_TCPERR
;
1657 extsts
|= EXTSTS_UDPPKT
;
1659 if (cksum(udp
) != 0) {
1660 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1661 extsts
|= EXTSTS_UDPERR
;
1668 * the driver seems to always receive into desc buffers
1669 * of size 1514, so you never have a pkt that is split
1670 * into multiple descriptors on the receive side, so
1671 * i don't implement that case, hence the assert above.
1674 DPRINTF(EthernetDesc
,
1675 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1676 regs
.rxdp
& 0x3fffffff);
1677 DPRINTF(EthernetDesc
,
1678 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1679 link
, bufptr
, cmdsts
, extsts
);
1681 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1682 rxDmaData
= &cmdsts
;
1684 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1685 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1687 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1688 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1690 rxDmaFree
= dmaDescFree
;
1693 descDmaWrBytes
+= rxDmaLen
;
1701 if (rxDmaState
!= dmaIdle
)
1704 rxPacketBufPtr
+= rxXferLen
;
1705 rxFragPtr
+= rxXferLen
;
1706 rxPktBytes
-= rxXferLen
;
1708 rxState
= rxFifoBlock
;
1712 if (rxDmaState
!= dmaIdle
)
1715 assert(cmdsts
& CMDSTS_OWN
);
1717 assert(rxPacket
== 0);
1718 devIntrPost(ISR_RXOK
);
1720 if (cmdsts
& CMDSTS_INTR
)
1721 devIntrPost(ISR_RXDESC
);
1724 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1728 rxState
= rxAdvance
;
1733 devIntrPost(ISR_RXIDLE
);
1738 if (rxDmaState
!= dmaIdle
)
1740 rxState
= rxDescRead
;
1744 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1745 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1746 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1747 rxDmaFree
= dmaDescFree
;
1755 panic("Invalid rxState!");
1758 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1759 NsRxStateStrings
[rxState
]);
1764 * @todo do we want to schedule a future kick?
1766 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1767 NsRxStateStrings
[rxState
]);
1769 if (clock
&& !rxKickEvent
.scheduled())
1770 rxKickEvent
.schedule(rxKickTick
);
1776 if (txFifo
.empty()) {
1777 DPRINTF(Ethernet
, "nothing to transmit\n");
1781 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1783 if (interface
->sendPacket(txFifo
.front())) {
1785 if (DTRACE(Ethernet
)) {
1786 IpPtr
ip(txFifo
.front());
1788 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1792 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1793 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1800 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1801 txBytes
+= txFifo
.front()->length
;
1804 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1809 * normally do a writeback of the descriptor here, and ONLY
1810 * after that is done, send this interrupt. but since our
1811 * stuff never actually fails, just do this interrupt here,
1812 * otherwise the code has to stray from this nice format.
1813 * besides, it's functionally the same.
1815 devIntrPost(ISR_TXOK
);
1818 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1819 DPRINTF(Ethernet
, "reschedule transmit\n");
1820 txEvent
.schedule(curTick
+ retryTime
);
1825 NSGigE::doTxDmaRead()
1827 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1828 txDmaState
= dmaReading
;
1830 if (dmaPending() || getState() != Running
)
1831 txDmaState
= dmaReadWaiting
;
1833 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1839 NSGigE::txDmaReadDone()
1841 assert(txDmaState
== dmaReading
);
1842 txDmaState
= dmaIdle
;
1844 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1845 txDmaAddr
, txDmaLen
);
1846 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1848 // If the receive state machine has a pending DMA, let it go first
1849 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1856 NSGigE::doTxDmaWrite()
1858 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1859 txDmaState
= dmaWriting
;
1861 if (dmaPending() || getState() != Running
)
1862 txDmaState
= dmaWriteWaiting
;
1864 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1869 NSGigE::txDmaWriteDone()
1871 assert(txDmaState
== dmaWriting
);
1872 txDmaState
= dmaIdle
;
1874 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1875 txDmaAddr
, txDmaLen
);
1876 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1878 // If the receive state machine has a pending DMA, let it go first
1879 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1888 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1890 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1891 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1894 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1895 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1899 if (txKickTick
> curTick
) {
1900 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1905 // Go to the next state machine clock tick.
1906 txKickTick
= curTick
+ cycles(1);
1909 switch(txDmaState
) {
1910 case dmaReadWaiting
:
1914 case dmaWriteWaiting
:
1922 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1923 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1927 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1932 txState
= txDescRefr
;
1934 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1936 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1937 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1938 txDmaFree
= dmaDescFree
;
1941 descDmaRdBytes
+= txDmaLen
;
1947 txState
= txDescRead
;
1949 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1950 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1951 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1952 txDmaFree
= dmaDescFree
;
1955 descDmaRdBytes
+= txDmaLen
;
1963 if (txDmaState
!= dmaIdle
)
1966 txState
= txAdvance
;
1970 if (txDmaState
!= dmaIdle
)
1973 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1974 regs
.txdp
& 0x3fffffff);
1975 DPRINTF(EthernetDesc
,
1976 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1977 link
, bufptr
, cmdsts
, extsts
);
1979 if (cmdsts
& CMDSTS_OWN
) {
1980 txState
= txFifoBlock
;
1982 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1984 devIntrPost(ISR_TXIDLE
);
1992 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1993 txPacket
= new EthPacketData(16384);
1994 txPacketBufPtr
= txPacket
->data
;
1997 if (txDescCnt
== 0) {
1998 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1999 if (cmdsts
& CMDSTS_MORE
) {
2000 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2001 txState
= txDescWrite
;
2003 cmdsts
&= ~CMDSTS_OWN
;
2005 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2006 txDmaData
= &cmdsts
;
2008 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2009 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2011 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2012 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2014 txDmaFree
= dmaDescFree
;
2019 } else { /* this packet is totally done */
2020 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2021 /* deal with the the packet that just finished */
2022 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2024 if (extsts
& EXTSTS_UDPPKT
) {
2027 udp
->sum(cksum(udp
));
2029 } else if (extsts
& EXTSTS_TCPPKT
) {
2032 tcp
->sum(cksum(tcp
));
2035 if (extsts
& EXTSTS_IPPKT
) {
2042 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2043 // this is just because the receive can't handle a
2044 // packet bigger want to make sure
2045 if (txPacket
->length
> 1514)
2046 panic("transmit packet too large, %s > 1514\n",
2052 txFifo
.push(txPacket
);
2056 * this following section is not tqo spec, but
2057 * functionally shouldn't be any different. normally,
2058 * the chip will wait til the transmit has occurred
2059 * before writing back the descriptor because it has
2060 * to wait to see that it was successfully transmitted
2061 * to decide whether to set CMDSTS_OK or not.
2062 * however, in the simulator since it is always
2063 * successfully transmitted, and writing it exactly to
2064 * spec would complicate the code, we just do it here
2067 cmdsts
&= ~CMDSTS_OWN
;
2068 cmdsts
|= CMDSTS_OK
;
2070 DPRINTF(EthernetDesc
,
2071 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2074 txDmaFree
= dmaDescFree
;
2075 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2076 txDmaData
= &cmdsts
;
2078 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2080 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2082 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2084 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2088 descDmaWrBytes
+= txDmaLen
;
2094 DPRINTF(EthernetSM
, "halting TX state machine\n");
2098 txState
= txAdvance
;
2104 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2105 if (!txFifo
.full()) {
2106 txState
= txFragRead
;
2109 * The number of bytes transferred is either whatever
2110 * is left in the descriptor (txDescCnt), or if there
2111 * is not enough room in the fifo, just whatever room
2112 * is left in the fifo
2114 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2116 txDmaAddr
= txFragPtr
& 0x3fffffff;
2117 txDmaData
= txPacketBufPtr
;
2118 txDmaLen
= txXferLen
;
2119 txDmaFree
= dmaDataFree
;
2124 txState
= txFifoBlock
;
2134 if (txDmaState
!= dmaIdle
)
2137 txPacketBufPtr
+= txXferLen
;
2138 txFragPtr
+= txXferLen
;
2139 txDescCnt
-= txXferLen
;
2140 txFifo
.reserve(txXferLen
);
2142 txState
= txFifoBlock
;
2146 if (txDmaState
!= dmaIdle
)
2149 if (cmdsts
& CMDSTS_INTR
)
2150 devIntrPost(ISR_TXDESC
);
2153 DPRINTF(EthernetSM
, "halting TX state machine\n");
2157 txState
= txAdvance
;
2162 devIntrPost(ISR_TXIDLE
);
2166 if (txDmaState
!= dmaIdle
)
2168 txState
= txDescRead
;
2172 txDmaAddr
= link
& 0x3fffffff;
2173 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2174 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2175 txDmaFree
= dmaDescFree
;
2183 panic("invalid state");
2186 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2187 NsTxStateStrings
[txState
]);
2192 * @todo do we want to schedule a future kick?
2194 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2195 NsTxStateStrings
[txState
]);
2197 if (clock
&& !txKickEvent
.scheduled())
2198 txKickEvent
.schedule(txKickTick
);
2202 * Advance the EEPROM state machine
2203 * Called on rising edge of EEPROM clock bit in MEAR
2206 NSGigE::eepromKick()
2208 switch (eepromState
) {
2212 // Wait for start bit
2213 if (regs
.mear
& MEAR_EEDI
) {
2214 // Set up to get 2 opcode bits
2215 eepromState
= eepromGetOpcode
;
2221 case eepromGetOpcode
:
2223 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2226 // Done getting opcode
2227 if (eepromBitsToRx
== 0) {
2228 if (eepromOpcode
!= EEPROM_READ
)
2229 panic("only EEPROM reads are implemented!");
2231 // Set up to get address
2232 eepromState
= eepromGetAddress
;
2238 case eepromGetAddress
:
2239 eepromAddress
<<= 1;
2240 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2243 // Done getting address
2244 if (eepromBitsToRx
== 0) {
2246 if (eepromAddress
>= EEPROM_SIZE
)
2247 panic("EEPROM read access out of range!");
2249 switch (eepromAddress
) {
2251 case EEPROM_PMATCH2_ADDR
:
2252 eepromData
= rom
.perfectMatch
[5];
2254 eepromData
+= rom
.perfectMatch
[4];
2257 case EEPROM_PMATCH1_ADDR
:
2258 eepromData
= rom
.perfectMatch
[3];
2260 eepromData
+= rom
.perfectMatch
[2];
2263 case EEPROM_PMATCH0_ADDR
:
2264 eepromData
= rom
.perfectMatch
[1];
2266 eepromData
+= rom
.perfectMatch
[0];
2270 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2272 // Set up to read data
2273 eepromState
= eepromRead
;
2274 eepromBitsToRx
= 16;
2276 // Clear data in bit
2277 regs
.mear
&= ~MEAR_EEDI
;
2282 // Clear Data Out bit
2283 regs
.mear
&= ~MEAR_EEDO
;
2284 // Set bit to value of current EEPROM bit
2285 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2291 if (eepromBitsToRx
== 0) {
2292 eepromState
= eepromStart
;
2297 panic("invalid EEPROM state");
2303 NSGigE::transferDone()
2305 if (txFifo
.empty()) {
2306 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2310 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2312 txEvent
.reschedule(curTick
+ cycles(1), true);
2316 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2318 EthPtr eth
= packet
;
2322 const EthAddr
&dst
= eth
->dst();
2323 if (dst
.unicast()) {
2324 // If we're accepting all unicast addresses
2328 // If we make a perfect match
2329 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2332 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2335 } else if (dst
.broadcast()) {
2336 // if we're accepting broadcasts
2337 if (acceptBroadcast
)
2340 } else if (dst
.multicast()) {
2341 // if we're accepting all multicasts
2342 if (acceptMulticast
)
2345 // Multicast hashing faked - all packets accepted
2346 if (multicastHashEnable
)
2351 DPRINTF(Ethernet
, "rxFilter drop\n");
2352 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2359 NSGigE::recvPacket(EthPacketPtr packet
)
2361 rxBytes
+= packet
->length
;
2364 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2368 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2372 if (!rxFilterEnable
) {
2374 "receive packet filtering disabled . . . packet dropped\n");
2378 if (rxFilter(packet
)) {
2379 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2383 if (rxFifo
.avail() < packet
->length
) {
2389 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2392 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2397 devIntrPost(ISR_RXORN
);
2401 rxFifo
.push(packet
);
2411 SimObject::resume();
2413 // During drain we could have left the state machines in a waiting state and
2414 // they wouldn't get out until some other event occured to kick them.
2415 // This way they'll get out immediately
2421 //=====================================================================
2425 NSGigE::serialize(ostream
&os
)
2427 // Serialize the PciDev base class
2428 PciDev::serialize(os
);
2431 * Finalize any DMA events now.
2433 // @todo will mem system save pending dma?
2436 * Serialize the device registers
2438 SERIALIZE_SCALAR(regs
.command
);
2439 SERIALIZE_SCALAR(regs
.config
);
2440 SERIALIZE_SCALAR(regs
.mear
);
2441 SERIALIZE_SCALAR(regs
.ptscr
);
2442 SERIALIZE_SCALAR(regs
.isr
);
2443 SERIALIZE_SCALAR(regs
.imr
);
2444 SERIALIZE_SCALAR(regs
.ier
);
2445 SERIALIZE_SCALAR(regs
.ihr
);
2446 SERIALIZE_SCALAR(regs
.txdp
);
2447 SERIALIZE_SCALAR(regs
.txdp_hi
);
2448 SERIALIZE_SCALAR(regs
.txcfg
);
2449 SERIALIZE_SCALAR(regs
.gpior
);
2450 SERIALIZE_SCALAR(regs
.rxdp
);
2451 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2452 SERIALIZE_SCALAR(regs
.rxcfg
);
2453 SERIALIZE_SCALAR(regs
.pqcr
);
2454 SERIALIZE_SCALAR(regs
.wcsr
);
2455 SERIALIZE_SCALAR(regs
.pcr
);
2456 SERIALIZE_SCALAR(regs
.rfcr
);
2457 SERIALIZE_SCALAR(regs
.rfdr
);
2458 SERIALIZE_SCALAR(regs
.brar
);
2459 SERIALIZE_SCALAR(regs
.brdr
);
2460 SERIALIZE_SCALAR(regs
.srr
);
2461 SERIALIZE_SCALAR(regs
.mibc
);
2462 SERIALIZE_SCALAR(regs
.vrcr
);
2463 SERIALIZE_SCALAR(regs
.vtcr
);
2464 SERIALIZE_SCALAR(regs
.vdr
);
2465 SERIALIZE_SCALAR(regs
.ccsr
);
2466 SERIALIZE_SCALAR(regs
.tbicr
);
2467 SERIALIZE_SCALAR(regs
.tbisr
);
2468 SERIALIZE_SCALAR(regs
.tanar
);
2469 SERIALIZE_SCALAR(regs
.tanlpar
);
2470 SERIALIZE_SCALAR(regs
.taner
);
2471 SERIALIZE_SCALAR(regs
.tesr
);
2473 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2474 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2476 SERIALIZE_SCALAR(ioEnable
);
2479 * Serialize the data Fifos
2481 rxFifo
.serialize("rxFifo", os
);
2482 txFifo
.serialize("txFifo", os
);
2485 * Serialize the various helper variables
2487 bool txPacketExists
= txPacket
;
2488 SERIALIZE_SCALAR(txPacketExists
);
2489 if (txPacketExists
) {
2490 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2491 txPacket
->serialize("txPacket", os
);
2492 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2493 SERIALIZE_SCALAR(txPktBufPtr
);
2496 bool rxPacketExists
= rxPacket
;
2497 SERIALIZE_SCALAR(rxPacketExists
);
2498 if (rxPacketExists
) {
2499 rxPacket
->serialize("rxPacket", os
);
2500 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2501 SERIALIZE_SCALAR(rxPktBufPtr
);
2504 SERIALIZE_SCALAR(txXferLen
);
2505 SERIALIZE_SCALAR(rxXferLen
);
2508 * Serialize Cached Descriptors
2510 SERIALIZE_SCALAR(rxDesc64
.link
);
2511 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2512 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2513 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2514 SERIALIZE_SCALAR(txDesc64
.link
);
2515 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2516 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2517 SERIALIZE_SCALAR(txDesc64
.extsts
);
2518 SERIALIZE_SCALAR(rxDesc32
.link
);
2519 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2520 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2521 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2522 SERIALIZE_SCALAR(txDesc32
.link
);
2523 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2524 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2525 SERIALIZE_SCALAR(txDesc32
.extsts
);
2526 SERIALIZE_SCALAR(extstsEnable
);
2529 * Serialize tx state machine
2531 int txState
= this->txState
;
2532 SERIALIZE_SCALAR(txState
);
2533 SERIALIZE_SCALAR(txEnable
);
2534 SERIALIZE_SCALAR(CTDD
);
2535 SERIALIZE_SCALAR(txFragPtr
);
2536 SERIALIZE_SCALAR(txDescCnt
);
2537 int txDmaState
= this->txDmaState
;
2538 SERIALIZE_SCALAR(txDmaState
);
2539 SERIALIZE_SCALAR(txKickTick
);
2542 * Serialize rx state machine
2544 int rxState
= this->rxState
;
2545 SERIALIZE_SCALAR(rxState
);
2546 SERIALIZE_SCALAR(rxEnable
);
2547 SERIALIZE_SCALAR(CRDD
);
2548 SERIALIZE_SCALAR(rxPktBytes
);
2549 SERIALIZE_SCALAR(rxFragPtr
);
2550 SERIALIZE_SCALAR(rxDescCnt
);
2551 int rxDmaState
= this->rxDmaState
;
2552 SERIALIZE_SCALAR(rxDmaState
);
2553 SERIALIZE_SCALAR(rxKickTick
);
2556 * Serialize EEPROM state machine
2558 int eepromState
= this->eepromState
;
2559 SERIALIZE_SCALAR(eepromState
);
2560 SERIALIZE_SCALAR(eepromClk
);
2561 SERIALIZE_SCALAR(eepromBitsToRx
);
2562 SERIALIZE_SCALAR(eepromOpcode
);
2563 SERIALIZE_SCALAR(eepromAddress
);
2564 SERIALIZE_SCALAR(eepromData
);
2567 * If there's a pending transmit, store the time so we can
2568 * reschedule it later
2570 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2571 SERIALIZE_SCALAR(transmitTick
);
2574 * receive address filter settings
2576 SERIALIZE_SCALAR(rxFilterEnable
);
2577 SERIALIZE_SCALAR(acceptBroadcast
);
2578 SERIALIZE_SCALAR(acceptMulticast
);
2579 SERIALIZE_SCALAR(acceptUnicast
);
2580 SERIALIZE_SCALAR(acceptPerfect
);
2581 SERIALIZE_SCALAR(acceptArp
);
2582 SERIALIZE_SCALAR(multicastHashEnable
);
2585 * Keep track of pending interrupt status.
2587 SERIALIZE_SCALAR(intrTick
);
2588 SERIALIZE_SCALAR(cpuPendingIntr
);
2589 Tick intrEventTick
= 0;
2591 intrEventTick
= intrEvent
->when();
2592 SERIALIZE_SCALAR(intrEventTick
);
2597 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2599 // Unserialize the PciDev base class
2600 PciDev::unserialize(cp
, section
);
2602 UNSERIALIZE_SCALAR(regs
.command
);
2603 UNSERIALIZE_SCALAR(regs
.config
);
2604 UNSERIALIZE_SCALAR(regs
.mear
);
2605 UNSERIALIZE_SCALAR(regs
.ptscr
);
2606 UNSERIALIZE_SCALAR(regs
.isr
);
2607 UNSERIALIZE_SCALAR(regs
.imr
);
2608 UNSERIALIZE_SCALAR(regs
.ier
);
2609 UNSERIALIZE_SCALAR(regs
.ihr
);
2610 UNSERIALIZE_SCALAR(regs
.txdp
);
2611 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2612 UNSERIALIZE_SCALAR(regs
.txcfg
);
2613 UNSERIALIZE_SCALAR(regs
.gpior
);
2614 UNSERIALIZE_SCALAR(regs
.rxdp
);
2615 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2616 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2617 UNSERIALIZE_SCALAR(regs
.pqcr
);
2618 UNSERIALIZE_SCALAR(regs
.wcsr
);
2619 UNSERIALIZE_SCALAR(regs
.pcr
);
2620 UNSERIALIZE_SCALAR(regs
.rfcr
);
2621 UNSERIALIZE_SCALAR(regs
.rfdr
);
2622 UNSERIALIZE_SCALAR(regs
.brar
);
2623 UNSERIALIZE_SCALAR(regs
.brdr
);
2624 UNSERIALIZE_SCALAR(regs
.srr
);
2625 UNSERIALIZE_SCALAR(regs
.mibc
);
2626 UNSERIALIZE_SCALAR(regs
.vrcr
);
2627 UNSERIALIZE_SCALAR(regs
.vtcr
);
2628 UNSERIALIZE_SCALAR(regs
.vdr
);
2629 UNSERIALIZE_SCALAR(regs
.ccsr
);
2630 UNSERIALIZE_SCALAR(regs
.tbicr
);
2631 UNSERIALIZE_SCALAR(regs
.tbisr
);
2632 UNSERIALIZE_SCALAR(regs
.tanar
);
2633 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2634 UNSERIALIZE_SCALAR(regs
.taner
);
2635 UNSERIALIZE_SCALAR(regs
.tesr
);
2637 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2638 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2640 UNSERIALIZE_SCALAR(ioEnable
);
2643 * unserialize the data fifos
2645 rxFifo
.unserialize("rxFifo", cp
, section
);
2646 txFifo
.unserialize("txFifo", cp
, section
);
2649 * unserialize the various helper variables
2651 bool txPacketExists
;
2652 UNSERIALIZE_SCALAR(txPacketExists
);
2653 if (txPacketExists
) {
2654 txPacket
= new EthPacketData(16384);
2655 txPacket
->unserialize("txPacket", cp
, section
);
2656 uint32_t txPktBufPtr
;
2657 UNSERIALIZE_SCALAR(txPktBufPtr
);
2658 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2662 bool rxPacketExists
;
2663 UNSERIALIZE_SCALAR(rxPacketExists
);
2665 if (rxPacketExists
) {
2666 rxPacket
= new EthPacketData(16384);
2667 rxPacket
->unserialize("rxPacket", cp
, section
);
2668 uint32_t rxPktBufPtr
;
2669 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2670 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2674 UNSERIALIZE_SCALAR(txXferLen
);
2675 UNSERIALIZE_SCALAR(rxXferLen
);
2678 * Unserialize Cached Descriptors
2680 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2681 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2682 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2683 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2684 UNSERIALIZE_SCALAR(txDesc64
.link
);
2685 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2686 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2687 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2688 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2689 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2690 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2691 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2692 UNSERIALIZE_SCALAR(txDesc32
.link
);
2693 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2694 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2695 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2696 UNSERIALIZE_SCALAR(extstsEnable
);
2699 * unserialize tx state machine
2702 UNSERIALIZE_SCALAR(txState
);
2703 this->txState
= (TxState
) txState
;
2704 UNSERIALIZE_SCALAR(txEnable
);
2705 UNSERIALIZE_SCALAR(CTDD
);
2706 UNSERIALIZE_SCALAR(txFragPtr
);
2707 UNSERIALIZE_SCALAR(txDescCnt
);
2709 UNSERIALIZE_SCALAR(txDmaState
);
2710 this->txDmaState
= (DmaState
) txDmaState
;
2711 UNSERIALIZE_SCALAR(txKickTick
);
2713 txKickEvent
.schedule(txKickTick
);
2716 * unserialize rx state machine
2719 UNSERIALIZE_SCALAR(rxState
);
2720 this->rxState
= (RxState
) rxState
;
2721 UNSERIALIZE_SCALAR(rxEnable
);
2722 UNSERIALIZE_SCALAR(CRDD
);
2723 UNSERIALIZE_SCALAR(rxPktBytes
);
2724 UNSERIALIZE_SCALAR(rxFragPtr
);
2725 UNSERIALIZE_SCALAR(rxDescCnt
);
2727 UNSERIALIZE_SCALAR(rxDmaState
);
2728 this->rxDmaState
= (DmaState
) rxDmaState
;
2729 UNSERIALIZE_SCALAR(rxKickTick
);
2731 rxKickEvent
.schedule(rxKickTick
);
2734 * Unserialize EEPROM state machine
2737 UNSERIALIZE_SCALAR(eepromState
);
2738 this->eepromState
= (EEPROMState
) eepromState
;
2739 UNSERIALIZE_SCALAR(eepromClk
);
2740 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2741 UNSERIALIZE_SCALAR(eepromOpcode
);
2742 UNSERIALIZE_SCALAR(eepromAddress
);
2743 UNSERIALIZE_SCALAR(eepromData
);
2746 * If there's a pending transmit, reschedule it now
2749 UNSERIALIZE_SCALAR(transmitTick
);
2751 txEvent
.schedule(curTick
+ transmitTick
);
2754 * unserialize receive address filter settings
2756 UNSERIALIZE_SCALAR(rxFilterEnable
);
2757 UNSERIALIZE_SCALAR(acceptBroadcast
);
2758 UNSERIALIZE_SCALAR(acceptMulticast
);
2759 UNSERIALIZE_SCALAR(acceptUnicast
);
2760 UNSERIALIZE_SCALAR(acceptPerfect
);
2761 UNSERIALIZE_SCALAR(acceptArp
);
2762 UNSERIALIZE_SCALAR(multicastHashEnable
);
2765 * Keep track of pending interrupt status.
2767 UNSERIALIZE_SCALAR(intrTick
);
2768 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2770 UNSERIALIZE_SCALAR(intrEventTick
);
2771 if (intrEventTick
) {
2772 intrEvent
= new IntrEvent(this, intrEventTick
, true);
2776 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2778 SimObjectParam
<EtherInt
*> peer
;
2779 SimObjectParam
<NSGigE
*> device
;
2781 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2783 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2785 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2786 INIT_PARAM(device
, "Ethernet device of this interface")
2788 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2790 CREATE_SIM_OBJECT(NSGigEInt
)
2792 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2794 EtherInt
*p
= (EtherInt
*)peer
;
2796 dev_int
->setPeer(p
);
2797 p
->setPeer(dev_int
);
2803 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2806 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2808 SimObjectParam
<System
*> system
;
2809 SimObjectParam
<Platform
*> platform
;
2810 Param
<Tick
> min_backoff_delay
;
2811 Param
<Tick
> max_backoff_delay
;
2812 SimObjectParam
<PciConfigData
*> configdata
;
2813 Param
<uint32_t> pci_bus
;
2814 Param
<uint32_t> pci_dev
;
2815 Param
<uint32_t> pci_func
;
2816 Param
<Tick
> pio_latency
;
2817 Param
<Tick
> config_latency
;
2820 Param
<bool> dma_desc_free
;
2821 Param
<bool> dma_data_free
;
2822 Param
<Tick
> dma_read_delay
;
2823 Param
<Tick
> dma_write_delay
;
2824 Param
<Tick
> dma_read_factor
;
2825 Param
<Tick
> dma_write_factor
;
2826 Param
<bool> dma_no_allocate
;
2827 Param
<Tick
> intr_delay
;
2829 Param
<Tick
> rx_delay
;
2830 Param
<Tick
> tx_delay
;
2831 Param
<uint32_t> rx_fifo_size
;
2832 Param
<uint32_t> tx_fifo_size
;
2834 Param
<bool> rx_filter
;
2835 Param
<string
> hardware_address
;
2836 Param
<bool> rx_thread
;
2837 Param
<bool> tx_thread
;
2840 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2842 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2844 INIT_PARAM(system
, "System pointer"),
2845 INIT_PARAM(platform
, "Platform pointer"),
2846 INIT_PARAM(min_backoff_delay
, "Minimum delay after receving a nack packed"),
2847 INIT_PARAM(max_backoff_delay
, "Maximum delay after receving a nack packed"),
2848 INIT_PARAM(configdata
, "PCI Config data"),
2849 INIT_PARAM(pci_bus
, "PCI bus ID"),
2850 INIT_PARAM(pci_dev
, "PCI device number"),
2851 INIT_PARAM(pci_func
, "PCI function code"),
2852 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency in bus cycles", 1),
2853 INIT_PARAM(config_latency
, "Number of cycles for a config read or write"),
2854 INIT_PARAM(clock
, "State machine cycle time"),
2856 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
2857 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
2858 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
2859 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
2860 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
2861 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
2862 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
2863 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
2865 INIT_PARAM(rx_delay
, "Receive Delay"),
2866 INIT_PARAM(tx_delay
, "Transmit Delay"),
2867 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
2868 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
2870 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
2871 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
2872 INIT_PARAM(rx_thread
, ""),
2873 INIT_PARAM(tx_thread
, ""),
2876 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2879 CREATE_SIM_OBJECT(NSGigE
)
2881 NSGigE::Params
*params
= new NSGigE::Params
;
2883 params
->name
= getInstanceName();
2884 params
->platform
= platform
;
2885 params
->system
= system
;
2886 params
->min_backoff_delay
= min_backoff_delay
;
2887 params
->max_backoff_delay
= max_backoff_delay
;
2888 params
->configData
= configdata
;
2889 params
->busNum
= pci_bus
;
2890 params
->deviceNum
= pci_dev
;
2891 params
->functionNum
= pci_func
;
2892 params
->pio_delay
= pio_latency
;
2893 params
->config_delay
= config_latency
;
2895 params
->clock
= clock
;
2896 params
->dma_desc_free
= dma_desc_free
;
2897 params
->dma_data_free
= dma_data_free
;
2898 params
->dma_read_delay
= dma_read_delay
;
2899 params
->dma_write_delay
= dma_write_delay
;
2900 params
->dma_read_factor
= dma_read_factor
;
2901 params
->dma_write_factor
= dma_write_factor
;
2902 params
->dma_no_allocate
= dma_no_allocate
;
2903 params
->pio_delay
= pio_latency
;
2904 params
->intr_delay
= intr_delay
;
2906 params
->rx_delay
= rx_delay
;
2907 params
->tx_delay
= tx_delay
;
2908 params
->rx_fifo_size
= rx_fifo_size
;
2909 params
->tx_fifo_size
= tx_fifo_size
;
2911 params
->rx_filter
= rx_filter
;
2912 params
->eaddr
= hardware_address
;
2913 params
->rx_thread
= rx_thread
;
2914 params
->tx_thread
= tx_thread
;
2917 return new NSGigE(params
);
2920 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)