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.
32 * Device module for modelling the National Semiconductor
33 * DP83820 ethernet controller. Does not support priority queueing
38 #include "arch/alpha/ev5.hh"
39 #include "base/inet.hh"
40 #include "cpu/exec_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 "sim/builder.hh"
46 #include "sim/debug.hh"
47 #include "sim/host.hh"
48 #include "sim/stats.hh"
49 #include "sim/system.hh"
51 const char *NsRxStateStrings
[] =
62 const char *NsTxStateStrings
[] =
73 const char *NsDmaState
[] =
84 using namespace TheISA
;
86 ///////////////////////////////////////////////////////////////////////
90 NSGigE::NSGigE(Params
*p
)
91 : PciDev(p
), ioEnable(false),
92 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
93 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
94 txXferLen(0), rxXferLen(0), clock(p
->clock
),
95 txState(txIdle
), txEnable(false), CTDD(false),
96 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
97 rxEnable(false), CRDD(false), rxPktBytes(0),
98 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
99 eepromState(eepromStart
), rxDmaReadEvent(this), rxDmaWriteEvent(this),
100 txDmaReadEvent(this), txDmaWriteEvent(this),
101 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
102 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
103 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
104 txEvent(this), rxFilterEnable(p
->rx_filter
), acceptBroadcast(false),
105 acceptMulticast(false), acceptUnicast(false),
106 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
107 intrTick(0), cpuPendingIntr(false),
108 intrEvent(0), interface(0)
111 intrDelay
= p
->intr_delay
;
112 dmaReadDelay
= p
->dma_read_delay
;
113 dmaWriteDelay
= p
->dma_write_delay
;
114 dmaReadFactor
= p
->dma_read_factor
;
115 dmaWriteFactor
= p
->dma_write_factor
;
118 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
120 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
121 memset(&txDesc32
, 0, sizeof(txDesc32
));
122 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
123 memset(&txDesc64
, 0, sizeof(txDesc64
));
133 .name(name() + ".txBytes")
134 .desc("Bytes Transmitted")
139 .name(name() + ".rxBytes")
140 .desc("Bytes Received")
145 .name(name() + ".txPackets")
146 .desc("Number of Packets Transmitted")
151 .name(name() + ".rxPackets")
152 .desc("Number of Packets Received")
157 .name(name() + ".txIpChecksums")
158 .desc("Number of tx IP Checksums done by device")
164 .name(name() + ".rxIpChecksums")
165 .desc("Number of rx IP Checksums done by device")
171 .name(name() + ".txTcpChecksums")
172 .desc("Number of tx TCP Checksums done by device")
178 .name(name() + ".rxTcpChecksums")
179 .desc("Number of rx TCP Checksums done by device")
185 .name(name() + ".txUdpChecksums")
186 .desc("Number of tx UDP Checksums done by device")
192 .name(name() + ".rxUdpChecksums")
193 .desc("Number of rx UDP Checksums done by device")
199 .name(name() + ".descDMAReads")
200 .desc("Number of descriptors the device read w/ DMA")
205 .name(name() + ".descDMAWrites")
206 .desc("Number of descriptors the device wrote w/ DMA")
211 .name(name() + ".descDmaReadBytes")
212 .desc("number of descriptor bytes read w/ DMA")
217 .name(name() + ".descDmaWriteBytes")
218 .desc("number of descriptor bytes write w/ DMA")
223 .name(name() + ".txBandwidth")
224 .desc("Transmit Bandwidth (bits/s)")
230 .name(name() + ".rxBandwidth")
231 .desc("Receive Bandwidth (bits/s)")
237 .name(name() + ".totBandwidth")
238 .desc("Total Bandwidth (bits/s)")
244 .name(name() + ".totPackets")
245 .desc("Total Packets")
251 .name(name() + ".totBytes")
258 .name(name() + ".totPPS")
259 .desc("Total Tranmission Rate (packets/s)")
265 .name(name() + ".txPPS")
266 .desc("Packet Tranmission Rate (packets/s)")
272 .name(name() + ".rxPPS")
273 .desc("Packet Reception Rate (packets/s)")
279 .name(name() + ".postedSwi")
280 .desc("number of software interrupts posted to CPU")
285 .name(name() + ".totalSwi")
286 .desc("total number of Swi written to ISR")
291 .name(name() + ".coalescedSwi")
292 .desc("average number of Swi's coalesced into each post")
297 .name(name() + ".postedRxIdle")
298 .desc("number of rxIdle interrupts posted to CPU")
303 .name(name() + ".totalRxIdle")
304 .desc("total number of RxIdle written to ISR")
309 .name(name() + ".coalescedRxIdle")
310 .desc("average number of RxIdle's coalesced into each post")
315 .name(name() + ".postedRxOk")
316 .desc("number of RxOk interrupts posted to CPU")
321 .name(name() + ".totalRxOk")
322 .desc("total number of RxOk written to ISR")
327 .name(name() + ".coalescedRxOk")
328 .desc("average number of RxOk's coalesced into each post")
333 .name(name() + ".postedRxDesc")
334 .desc("number of RxDesc interrupts posted to CPU")
339 .name(name() + ".totalRxDesc")
340 .desc("total number of RxDesc written to ISR")
345 .name(name() + ".coalescedRxDesc")
346 .desc("average number of RxDesc's coalesced into each post")
351 .name(name() + ".postedTxOk")
352 .desc("number of TxOk interrupts posted to CPU")
357 .name(name() + ".totalTxOk")
358 .desc("total number of TxOk written to ISR")
363 .name(name() + ".coalescedTxOk")
364 .desc("average number of TxOk's coalesced into each post")
369 .name(name() + ".postedTxIdle")
370 .desc("number of TxIdle interrupts posted to CPU")
375 .name(name() + ".totalTxIdle")
376 .desc("total number of TxIdle written to ISR")
381 .name(name() + ".coalescedTxIdle")
382 .desc("average number of TxIdle's coalesced into each post")
387 .name(name() + ".postedTxDesc")
388 .desc("number of TxDesc interrupts posted to CPU")
393 .name(name() + ".totalTxDesc")
394 .desc("total number of TxDesc written to ISR")
399 .name(name() + ".coalescedTxDesc")
400 .desc("average number of TxDesc's coalesced into each post")
405 .name(name() + ".postedRxOrn")
406 .desc("number of RxOrn posted to CPU")
411 .name(name() + ".totalRxOrn")
412 .desc("total number of RxOrn written to ISR")
417 .name(name() + ".coalescedRxOrn")
418 .desc("average number of RxOrn's coalesced into each post")
423 .name(name() + ".coalescedTotal")
424 .desc("average number of interrupts coalesced into each post")
429 .name(name() + ".postedInterrupts")
430 .desc("number of posts to CPU")
435 .name(name() + ".droppedPackets")
436 .desc("number of packets dropped")
440 coalescedSwi
= totalSwi
/ postedInterrupts
;
441 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
442 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
443 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
444 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
445 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
446 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
447 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
449 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
450 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
451 totalRxOrn
) / postedInterrupts
;
453 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
454 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
455 totBandwidth
= txBandwidth
+ rxBandwidth
;
456 totBytes
= txBytes
+ rxBytes
;
457 totPackets
= txPackets
+ rxPackets
;
459 txPacketRate
= txPackets
/ simSeconds
;
460 rxPacketRate
= rxPackets
/ simSeconds
;
465 * This is to write to the PCI general configuration registers
468 NSGigE::writeConfig(int offset
, const uint16_t data
)
470 if (offset
< PCI_DEVICE_SPECIFIC
)
471 PciDev::writeConfig(offset
, data
);
473 panic("Device specific PCI config space not implemented!\n");
476 // seems to work fine without all these PCI settings, but i
477 // put in the IO to double check, an assertion will fail if we
478 // need to properly implement it
480 if (config
.data
[offset
] & PCI_CMD_IOSE
)
489 * This reads the device registers, which are detailed in the NS83820
493 NSGigE::read(Packet
*pkt
)
499 //The mask is to give you only the offset into the device register file
500 Addr daddr
= pkt
->getAddr() & 0xfff;
501 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
502 daddr
, pkt
->getAddr(), pkt
->getSize());
505 // there are some reserved registers, you can see ns_gige_reg.h and
506 // the spec sheet for details
507 if (daddr
> LAST
&& daddr
<= RESERVED
) {
508 panic("Accessing reserved register");
509 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
510 if (pkt
->getSize() == sizeof(uint8_t))
511 readConfig(daddr
& 0xff, pkt
->getPtr
<uint8_t>());
512 if (pkt
->getSize() == sizeof(uint16_t))
513 readConfig(daddr
& 0xff, pkt
->getPtr
<uint16_t>());
514 if (pkt
->getSize() == sizeof(uint32_t))
515 readConfig(daddr
& 0xff, pkt
->getPtr
<uint32_t>());
516 pkt
->result
= Packet::Success
;
518 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
519 // don't implement all the MIB's. hopefully the kernel
520 // doesn't actually DEPEND upon their values
521 // MIB are just hardware stats keepers
522 pkt
->set
<uint32_t>(0);
523 pkt
->result
= Packet::Success
;
525 } else if (daddr
> 0x3FC)
526 panic("Something is messed up!\n");
528 assert(pkt
->getSize() == sizeof(uint32_t));
529 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
535 //these are supposed to be cleared on a read
536 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
553 devIntrClear(ISR_ALL
);
608 // see the spec sheet for how RFCR and RFDR work
609 // basically, you write to RFCR to tell the machine
610 // what you want to do next, then you act upon RFDR,
611 // and the device will be prepared b/c of what you
618 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
620 // Read from perfect match ROM octets
622 reg
= rom
.perfectMatch
[1];
624 reg
+= rom
.perfectMatch
[0];
627 reg
= rom
.perfectMatch
[3] << 8;
628 reg
+= rom
.perfectMatch
[2];
631 reg
= rom
.perfectMatch
[5] << 8;
632 reg
+= rom
.perfectMatch
[4];
635 // Read filter hash table
636 if (rfaddr
>= FHASH_ADDR
&&
637 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
639 // Only word-aligned reads supported
641 panic("unaligned read from filter hash table!");
643 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
644 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
648 panic("reading RFDR for something other than pattern"
649 " matching or hashing! %#x\n", rfaddr
);
659 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
704 if (params()->rx_thread
)
705 reg
|= M5REG_RX_THREAD
;
706 if (params()->tx_thread
)
707 reg
|= M5REG_TX_THREAD
;
713 panic("reading unimplemented register: addr=%#x", daddr
);
716 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
719 pkt
->result
= Packet::Success
;
724 NSGigE::write(Packet
*pkt
)
728 Addr daddr
= pkt
->getAddr() & 0xfff;
729 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
730 daddr
, pkt
->getAddr(), pkt
->getSize());
732 if (daddr
> LAST
&& daddr
<= RESERVED
) {
733 panic("Accessing reserved register");
734 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
735 if (pkt
->getSize() == sizeof(uint8_t))
736 writeConfig(daddr
& 0xff, pkt
->get
<uint8_t>());
737 if (pkt
->getSize() == sizeof(uint16_t))
738 writeConfig(daddr
& 0xff, pkt
->get
<uint16_t>());
739 if (pkt
->getSize() == sizeof(uint32_t))
740 writeConfig(daddr
& 0xff, pkt
->get
<uint32_t>());
741 pkt
->result
= Packet::Success
;
743 } else if (daddr
> 0x3FC)
744 panic("Something is messed up!\n");
746 if (pkt
->getSize() == sizeof(uint32_t)) {
747 uint32_t reg
= pkt
->get
<uint32_t>();
750 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
757 } else if (reg
& CR_TXE
) {
760 // the kernel is enabling the transmit machine
761 if (txState
== txIdle
)
767 } else if (reg
& CR_RXE
) {
770 if (rxState
== rxIdle
)
781 devIntrPost(ISR_SWI
);
792 if (reg
& CFGR_LNKSTS
||
795 reg
& CFGR_RESERVED
||
796 reg
& CFGR_T64ADDR
||
797 reg
& CFGR_PCI64_DET
)
799 // First clear all writable bits
800 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
801 CFGR_RESERVED
| CFGR_T64ADDR
|
803 // Now set the appropriate writable bits
804 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
805 CFGR_RESERVED
| CFGR_T64ADDR
|
808 // all these #if 0's are because i don't THINK the kernel needs to
809 // have these implemented. if there is a problem relating to one of
810 // these, you may need to add functionality in.
811 if (reg
& CFGR_TBI_EN
) ;
812 if (reg
& CFGR_MODE_1000
) ;
814 if (reg
& CFGR_AUTO_1000
)
815 panic("CFGR_AUTO_1000 not implemented!\n");
817 if (reg
& CFGR_PINT_DUPSTS
||
818 reg
& CFGR_PINT_LNKSTS
||
819 reg
& CFGR_PINT_SPDSTS
)
822 if (reg
& CFGR_TMRTEST
) ;
823 if (reg
& CFGR_MRM_DIS
) ;
824 if (reg
& CFGR_MWI_DIS
) ;
826 if (reg
& CFGR_T64ADDR
) ;
827 // panic("CFGR_T64ADDR is read only register!\n");
829 if (reg
& CFGR_PCI64_DET
)
830 panic("CFGR_PCI64_DET is read only register!\n");
832 if (reg
& CFGR_DATA64_EN
) ;
833 if (reg
& CFGR_M64ADDR
) ;
834 if (reg
& CFGR_PHY_RST
) ;
835 if (reg
& CFGR_PHY_DIS
) ;
837 if (reg
& CFGR_EXTSTS_EN
)
840 extstsEnable
= false;
842 if (reg
& CFGR_REQALG
) ;
844 if (reg
& CFGR_POW
) ;
845 if (reg
& CFGR_EXD
) ;
846 if (reg
& CFGR_PESEL
) ;
847 if (reg
& CFGR_BROM_DIS
) ;
848 if (reg
& CFGR_EXT_125
) ;
849 if (reg
& CFGR_BEM
) ;
853 // Clear writable bits
854 regs
.mear
&= MEAR_EEDO
;
855 // Set appropriate writable bits
856 regs
.mear
|= reg
& ~MEAR_EEDO
;
858 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
859 // even though it could get it through RFDR
860 if (reg
& MEAR_EESEL
) {
861 // Rising edge of clock
862 if (reg
& MEAR_EECLK
&& !eepromClk
)
866 eepromState
= eepromStart
;
867 regs
.mear
&= ~MEAR_EEDI
;
870 eepromClk
= reg
& MEAR_EECLK
;
872 // since phy is completely faked, MEAR_MD* don't matter
873 if (reg
& MEAR_MDIO
) ;
874 if (reg
& MEAR_MDDIR
) ;
875 if (reg
& MEAR_MDC
) ;
879 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
880 // these control BISTs for various parts of chip - we
881 // don't care or do just fake that the BIST is done
882 if (reg
& PTSCR_RBIST_EN
)
883 regs
.ptscr
|= PTSCR_RBIST_DONE
;
884 if (reg
& PTSCR_EEBIST_EN
)
885 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
886 if (reg
& PTSCR_EELOAD_EN
)
887 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
890 case ISR
: /* writing to the ISR has no effect */
891 panic("ISR is a read only register!\n");
904 /* not going to implement real interrupt holdoff */
908 regs
.txdp
= (reg
& 0xFFFFFFFC);
909 assert(txState
== txIdle
);
920 if (reg
& TX_CFG_CSI
) ;
921 if (reg
& TX_CFG_HBI
) ;
922 if (reg
& TX_CFG_MLB
) ;
923 if (reg
& TX_CFG_ATP
) ;
924 if (reg
& TX_CFG_ECRETRY
) {
926 * this could easily be implemented, but considering
927 * the network is just a fake pipe, wouldn't make
932 if (reg
& TX_CFG_BRST_DIS
) ;
936 /* we handle our own DMA, ignore the kernel's exhortations */
937 if (reg
& TX_CFG_MXDMA
) ;
940 // also, we currently don't care about fill/drain
941 // thresholds though this may change in the future with
942 // more realistic networks or a driver which changes it
943 // according to feedback
948 // Only write writable bits
949 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
950 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
951 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
952 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
953 /* these just control general purpose i/o pins, don't matter */
968 if (reg
& RX_CFG_AEP
) ;
969 if (reg
& RX_CFG_ARP
) ;
970 if (reg
& RX_CFG_STRIPCRC
) ;
971 if (reg
& RX_CFG_RX_RD
) ;
972 if (reg
& RX_CFG_ALP
) ;
973 if (reg
& RX_CFG_AIRL
) ;
975 /* we handle our own DMA, ignore what kernel says about it */
976 if (reg
& RX_CFG_MXDMA
) ;
978 //also, we currently don't care about fill/drain thresholds
979 //though this may change in the future with more realistic
980 //networks or a driver which changes it according to feedback
981 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
986 /* there is no priority queueing used in the linux 2.6 driver */
991 /* not going to implement wake on LAN */
996 /* not going to implement pause control */
1003 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1004 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1005 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1006 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1007 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1008 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1009 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1012 if (reg
& RFCR_APAT
)
1013 panic("RFCR_APAT not implemented!\n");
1015 if (reg
& RFCR_UHEN
)
1016 panic("Unicast hash filtering not used by drivers!\n");
1019 panic("RFCR_ULM not implemented!\n");
1024 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1027 rom
.perfectMatch
[0] = (uint8_t)reg
;
1028 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1031 rom
.perfectMatch
[2] = (uint8_t)reg
;
1032 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1035 rom
.perfectMatch
[4] = (uint8_t)reg
;
1036 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1040 if (rfaddr
>= FHASH_ADDR
&&
1041 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1043 // Only word-aligned writes supported
1045 panic("unaligned write to filter hash table!");
1047 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1048 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1049 = (uint8_t)(reg
>> 8);
1052 panic("writing RFDR for something other than pattern matching\
1053 or hashing! %#x\n", rfaddr
);
1061 panic("the driver never uses BRDR, something is wrong!\n");
1064 panic("SRR is read only register!\n");
1067 panic("the driver never uses MIBC, something is wrong!\n");
1078 panic("the driver never uses VDR, something is wrong!\n");
1081 /* not going to implement clockrun stuff */
1087 if (reg
& TBICR_MR_LOOPBACK
)
1088 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1090 if (reg
& TBICR_MR_AN_ENABLE
) {
1091 regs
.tanlpar
= regs
.tanar
;
1092 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1096 if (reg
& TBICR_MR_RESTART_AN
) ;
1102 panic("TBISR is read only register!\n");
1105 // Only write the writable bits
1106 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1107 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1109 // Pause capability unimplemented
1111 if (reg
& TANAR_PS2
) ;
1112 if (reg
& TANAR_PS1
) ;
1118 panic("this should only be written to by the fake phy!\n");
1121 panic("TANER is read only register!\n");
1128 panic("invalid register access daddr=%#x", daddr
);
1131 panic("Invalid Request Size");
1133 pkt
->result
= Packet::Success
;
1138 NSGigE::devIntrPost(uint32_t interrupts
)
1140 if (interrupts
& ISR_RESERVE
)
1141 panic("Cannot set a reserved interrupt");
1143 if (interrupts
& ISR_NOIMPL
)
1144 warn("interrupt not implemented %#x\n", interrupts
);
1146 interrupts
&= ISR_IMPL
;
1147 regs
.isr
|= interrupts
;
1149 if (interrupts
& regs
.imr
) {
1150 if (interrupts
& ISR_SWI
) {
1153 if (interrupts
& ISR_RXIDLE
) {
1156 if (interrupts
& ISR_RXOK
) {
1159 if (interrupts
& ISR_RXDESC
) {
1162 if (interrupts
& ISR_TXOK
) {
1165 if (interrupts
& ISR_TXIDLE
) {
1168 if (interrupts
& ISR_TXDESC
) {
1171 if (interrupts
& ISR_RXORN
) {
1176 DPRINTF(EthernetIntr
,
1177 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1178 interrupts
, regs
.isr
, regs
.imr
);
1180 if ((regs
.isr
& regs
.imr
)) {
1181 Tick when
= curTick
;
1182 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1188 /* writing this interrupt counting stats inside this means that this function
1189 is now limited to being used to clear all interrupts upon the kernel
1190 reading isr and servicing. just telling you in case you were thinking
1194 NSGigE::devIntrClear(uint32_t interrupts
)
1196 if (interrupts
& ISR_RESERVE
)
1197 panic("Cannot clear a reserved interrupt");
1199 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1202 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1205 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1208 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1211 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1214 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1217 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1220 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1224 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1227 interrupts
&= ~ISR_NOIMPL
;
1228 regs
.isr
&= ~interrupts
;
1230 DPRINTF(EthernetIntr
,
1231 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1232 interrupts
, regs
.isr
, regs
.imr
);
1234 if (!(regs
.isr
& regs
.imr
))
1239 NSGigE::devIntrChangeMask()
1241 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1242 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1244 if (regs
.isr
& regs
.imr
)
1245 cpuIntrPost(curTick
);
1251 NSGigE::cpuIntrPost(Tick when
)
1253 // If the interrupt you want to post is later than an interrupt
1254 // already scheduled, just let it post in the coming one and don't
1255 // schedule another.
1256 // HOWEVER, must be sure that the scheduled intrTick is in the
1257 // future (this was formerly the source of a bug)
1259 * @todo this warning should be removed and the intrTick code should
1262 assert(when
>= curTick
);
1263 assert(intrTick
>= curTick
|| intrTick
== 0);
1264 if (when
> intrTick
&& intrTick
!= 0) {
1265 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1271 if (intrTick
< curTick
) {
1276 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1280 intrEvent
->squash();
1281 intrEvent
= new IntrEvent(this, true);
1282 intrEvent
->schedule(intrTick
);
1286 NSGigE::cpuInterrupt()
1288 assert(intrTick
== curTick
);
1290 // Whether or not there's a pending interrupt, we don't care about
1295 // Don't send an interrupt if there's already one
1296 if (cpuPendingIntr
) {
1297 DPRINTF(EthernetIntr
,
1298 "would send an interrupt now, but there's already pending\n");
1301 cpuPendingIntr
= true;
1303 DPRINTF(EthernetIntr
, "posting interrupt\n");
1309 NSGigE::cpuIntrClear()
1311 if (!cpuPendingIntr
)
1315 intrEvent
->squash();
1321 cpuPendingIntr
= false;
1323 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1328 NSGigE::cpuIntrPending() const
1329 { return cpuPendingIntr
; }
1335 DPRINTF(Ethernet
, "transmit reset\n");
1340 assert(txDescCnt
== 0);
1343 assert(txDmaState
== dmaIdle
);
1349 DPRINTF(Ethernet
, "receive reset\n");
1352 assert(rxPktBytes
== 0);
1355 assert(rxDescCnt
== 0);
1356 assert(rxDmaState
== dmaIdle
);
1364 memset(®s
, 0, sizeof(regs
));
1365 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1367 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1368 // fill threshold to 32 bytes
1369 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1370 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1371 regs
.mibc
= MIBC_FRZ
;
1372 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1373 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1374 regs
.brar
= 0xffffffff;
1376 extstsEnable
= false;
1377 acceptBroadcast
= false;
1378 acceptMulticast
= false;
1379 acceptUnicast
= false;
1380 acceptPerfect
= false;
1385 NSGigE::doRxDmaRead()
1387 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1388 rxDmaState
= dmaReading
;
1391 rxDmaState
= dmaReadWaiting
;
1393 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1399 NSGigE::rxDmaReadDone()
1401 assert(rxDmaState
== dmaReading
);
1402 rxDmaState
= dmaIdle
;
1404 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1405 rxDmaAddr
, rxDmaLen
);
1406 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1408 // If the transmit state machine has a pending DMA, let it go first
1409 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1416 NSGigE::doRxDmaWrite()
1418 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1419 rxDmaState
= dmaWriting
;
1422 rxDmaState
= dmaWriteWaiting
;
1424 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1429 NSGigE::rxDmaWriteDone()
1431 assert(rxDmaState
== dmaWriting
);
1432 rxDmaState
= dmaIdle
;
1434 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1435 rxDmaAddr
, rxDmaLen
);
1436 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1438 // If the transmit state machine has a pending DMA, let it go first
1439 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1448 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1451 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1452 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1455 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1456 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1460 if (rxKickTick
> curTick
) {
1461 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1467 // Go to the next state machine clock tick.
1468 rxKickTick
= curTick
+ cycles(1);
1471 switch(rxDmaState
) {
1472 case dmaReadWaiting
:
1476 case dmaWriteWaiting
:
1484 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1485 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1487 // see state machine from spec for details
1488 // the way this works is, if you finish work on one state and can
1489 // go directly to another, you do that through jumping to the
1490 // label "next". however, if you have intermediate work, like DMA
1491 // so that you can't go to the next state yet, you go to exit and
1492 // exit the loop. however, when the DMA is done it will trigger
1493 // an event and come back to this loop.
1497 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1502 rxState
= rxDescRefr
;
1504 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1506 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1507 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1508 rxDmaFree
= dmaDescFree
;
1511 descDmaRdBytes
+= rxDmaLen
;
1516 rxState
= rxDescRead
;
1518 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1519 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1520 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1521 rxDmaFree
= dmaDescFree
;
1524 descDmaRdBytes
+= rxDmaLen
;
1532 if (rxDmaState
!= dmaIdle
)
1535 rxState
= rxAdvance
;
1539 if (rxDmaState
!= dmaIdle
)
1542 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1543 regs
.rxdp
& 0x3fffffff);
1544 DPRINTF(EthernetDesc
,
1545 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1546 link
, bufptr
, cmdsts
, extsts
);
1548 if (cmdsts
& CMDSTS_OWN
) {
1549 devIntrPost(ISR_RXIDLE
);
1553 rxState
= rxFifoBlock
;
1555 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1562 * @todo in reality, we should be able to start processing
1563 * the packet as it arrives, and not have to wait for the
1564 * full packet ot be in the receive fifo.
1569 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1571 // If we don't have a packet, grab a new one from the fifo.
1572 rxPacket
= rxFifo
.front();
1573 rxPktBytes
= rxPacket
->length
;
1574 rxPacketBufPtr
= rxPacket
->data
;
1577 if (DTRACE(Ethernet
)) {
1580 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1584 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1585 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1592 // sanity check - i think the driver behaves like this
1593 assert(rxDescCnt
>= rxPktBytes
);
1598 // dont' need the && rxDescCnt > 0 if driver sanity check
1600 if (rxPktBytes
> 0) {
1601 rxState
= rxFragWrite
;
1602 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1604 rxXferLen
= rxPktBytes
;
1606 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1607 rxDmaData
= rxPacketBufPtr
;
1608 rxDmaLen
= rxXferLen
;
1609 rxDmaFree
= dmaDataFree
;
1615 rxState
= rxDescWrite
;
1617 //if (rxPktBytes == 0) { /* packet is done */
1618 assert(rxPktBytes
== 0);
1619 DPRINTF(EthernetSM
, "done with receiving packet\n");
1621 cmdsts
|= CMDSTS_OWN
;
1622 cmdsts
&= ~CMDSTS_MORE
;
1623 cmdsts
|= CMDSTS_OK
;
1624 cmdsts
&= 0xffff0000;
1625 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1629 * all the driver uses these are for its own stats keeping
1630 * which we don't care about, aren't necessary for
1631 * functionality and doing this would just slow us down.
1632 * if they end up using this in a later version for
1633 * functional purposes, just undef
1635 if (rxFilterEnable
) {
1636 cmdsts
&= ~CMDSTS_DEST_MASK
;
1637 const EthAddr
&dst
= rxFifoFront()->dst();
1639 cmdsts
|= CMDSTS_DEST_SELF
;
1640 if (dst
->multicast())
1641 cmdsts
|= CMDSTS_DEST_MULTI
;
1642 if (dst
->broadcast())
1643 cmdsts
|= CMDSTS_DEST_MASK
;
1648 if (extstsEnable
&& ip
) {
1649 extsts
|= EXTSTS_IPPKT
;
1651 if (cksum(ip
) != 0) {
1652 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1653 extsts
|= EXTSTS_IPERR
;
1658 extsts
|= EXTSTS_TCPPKT
;
1660 if (cksum(tcp
) != 0) {
1661 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1662 extsts
|= EXTSTS_TCPERR
;
1666 extsts
|= EXTSTS_UDPPKT
;
1668 if (cksum(udp
) != 0) {
1669 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1670 extsts
|= EXTSTS_UDPERR
;
1677 * the driver seems to always receive into desc buffers
1678 * of size 1514, so you never have a pkt that is split
1679 * into multiple descriptors on the receive side, so
1680 * i don't implement that case, hence the assert above.
1683 DPRINTF(EthernetDesc
,
1684 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1685 regs
.rxdp
& 0x3fffffff);
1686 DPRINTF(EthernetDesc
,
1687 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1688 link
, bufptr
, cmdsts
, extsts
);
1690 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1691 rxDmaData
= &cmdsts
;
1693 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1694 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1696 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1697 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1699 rxDmaFree
= dmaDescFree
;
1702 descDmaWrBytes
+= rxDmaLen
;
1710 if (rxDmaState
!= dmaIdle
)
1713 rxPacketBufPtr
+= rxXferLen
;
1714 rxFragPtr
+= rxXferLen
;
1715 rxPktBytes
-= rxXferLen
;
1717 rxState
= rxFifoBlock
;
1721 if (rxDmaState
!= dmaIdle
)
1724 assert(cmdsts
& CMDSTS_OWN
);
1726 assert(rxPacket
== 0);
1727 devIntrPost(ISR_RXOK
);
1729 if (cmdsts
& CMDSTS_INTR
)
1730 devIntrPost(ISR_RXDESC
);
1733 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1737 rxState
= rxAdvance
;
1742 devIntrPost(ISR_RXIDLE
);
1747 if (rxDmaState
!= dmaIdle
)
1749 rxState
= rxDescRead
;
1753 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1754 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1755 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1756 rxDmaFree
= dmaDescFree
;
1764 panic("Invalid rxState!");
1767 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1768 NsRxStateStrings
[rxState
]);
1773 * @todo do we want to schedule a future kick?
1775 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1776 NsRxStateStrings
[rxState
]);
1778 if (clock
&& !rxKickEvent
.scheduled())
1779 rxKickEvent
.schedule(rxKickTick
);
1785 if (txFifo
.empty()) {
1786 DPRINTF(Ethernet
, "nothing to transmit\n");
1790 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1792 if (interface
->sendPacket(txFifo
.front())) {
1794 if (DTRACE(Ethernet
)) {
1795 IpPtr
ip(txFifo
.front());
1797 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1801 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1802 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1809 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1810 txBytes
+= txFifo
.front()->length
;
1813 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1818 * normally do a writeback of the descriptor here, and ONLY
1819 * after that is done, send this interrupt. but since our
1820 * stuff never actually fails, just do this interrupt here,
1821 * otherwise the code has to stray from this nice format.
1822 * besides, it's functionally the same.
1824 devIntrPost(ISR_TXOK
);
1827 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1828 DPRINTF(Ethernet
, "reschedule transmit\n");
1829 txEvent
.schedule(curTick
+ retryTime
);
1834 NSGigE::doTxDmaRead()
1836 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1837 txDmaState
= dmaReading
;
1840 txDmaState
= dmaReadWaiting
;
1842 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1848 NSGigE::txDmaReadDone()
1850 assert(txDmaState
== dmaReading
);
1851 txDmaState
= dmaIdle
;
1853 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1854 txDmaAddr
, txDmaLen
);
1855 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1857 // If the receive state machine has a pending DMA, let it go first
1858 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1865 NSGigE::doTxDmaWrite()
1867 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1868 txDmaState
= dmaWriting
;
1871 txDmaState
= dmaWriteWaiting
;
1873 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1878 NSGigE::txDmaWriteDone()
1880 assert(txDmaState
== dmaWriting
);
1881 txDmaState
= dmaIdle
;
1883 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1884 txDmaAddr
, txDmaLen
);
1885 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1887 // If the receive state machine has a pending DMA, let it go first
1888 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1897 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1899 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1900 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1903 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1904 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1908 if (txKickTick
> curTick
) {
1909 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1914 // Go to the next state machine clock tick.
1915 txKickTick
= curTick
+ cycles(1);
1918 switch(txDmaState
) {
1919 case dmaReadWaiting
:
1923 case dmaWriteWaiting
:
1931 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1932 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1936 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1941 txState
= txDescRefr
;
1943 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1945 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1946 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1947 txDmaFree
= dmaDescFree
;
1950 descDmaRdBytes
+= txDmaLen
;
1956 txState
= txDescRead
;
1958 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1959 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1960 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1961 txDmaFree
= dmaDescFree
;
1964 descDmaRdBytes
+= txDmaLen
;
1972 if (txDmaState
!= dmaIdle
)
1975 txState
= txAdvance
;
1979 if (txDmaState
!= dmaIdle
)
1982 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1983 regs
.txdp
& 0x3fffffff);
1984 DPRINTF(EthernetDesc
,
1985 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1986 link
, bufptr
, cmdsts
, extsts
);
1988 if (cmdsts
& CMDSTS_OWN
) {
1989 txState
= txFifoBlock
;
1991 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1993 devIntrPost(ISR_TXIDLE
);
2001 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2002 txPacket
= new EthPacketData(16384);
2003 txPacketBufPtr
= txPacket
->data
;
2006 if (txDescCnt
== 0) {
2007 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2008 if (cmdsts
& CMDSTS_MORE
) {
2009 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2010 txState
= txDescWrite
;
2012 cmdsts
&= ~CMDSTS_OWN
;
2014 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2015 txDmaData
= &cmdsts
;
2017 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2018 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2020 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2021 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2023 txDmaFree
= dmaDescFree
;
2028 } else { /* this packet is totally done */
2029 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2030 /* deal with the the packet that just finished */
2031 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2033 if (extsts
& EXTSTS_UDPPKT
) {
2036 udp
->sum(cksum(udp
));
2038 } else if (extsts
& EXTSTS_TCPPKT
) {
2041 tcp
->sum(cksum(tcp
));
2044 if (extsts
& EXTSTS_IPPKT
) {
2051 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2052 // this is just because the receive can't handle a
2053 // packet bigger want to make sure
2054 if (txPacket
->length
> 1514)
2055 panic("transmit packet too large, %s > 1514\n",
2061 txFifo
.push(txPacket
);
2065 * this following section is not tqo spec, but
2066 * functionally shouldn't be any different. normally,
2067 * the chip will wait til the transmit has occurred
2068 * before writing back the descriptor because it has
2069 * to wait to see that it was successfully transmitted
2070 * to decide whether to set CMDSTS_OK or not.
2071 * however, in the simulator since it is always
2072 * successfully transmitted, and writing it exactly to
2073 * spec would complicate the code, we just do it here
2076 cmdsts
&= ~CMDSTS_OWN
;
2077 cmdsts
|= CMDSTS_OK
;
2079 DPRINTF(EthernetDesc
,
2080 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2083 txDmaFree
= dmaDescFree
;
2084 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2085 txDmaData
= &cmdsts
;
2087 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2089 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2091 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2093 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2097 descDmaWrBytes
+= txDmaLen
;
2103 DPRINTF(EthernetSM
, "halting TX state machine\n");
2107 txState
= txAdvance
;
2113 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2114 if (!txFifo
.full()) {
2115 txState
= txFragRead
;
2118 * The number of bytes transferred is either whatever
2119 * is left in the descriptor (txDescCnt), or if there
2120 * is not enough room in the fifo, just whatever room
2121 * is left in the fifo
2123 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2125 txDmaAddr
= txFragPtr
& 0x3fffffff;
2126 txDmaData
= txPacketBufPtr
;
2127 txDmaLen
= txXferLen
;
2128 txDmaFree
= dmaDataFree
;
2133 txState
= txFifoBlock
;
2143 if (txDmaState
!= dmaIdle
)
2146 txPacketBufPtr
+= txXferLen
;
2147 txFragPtr
+= txXferLen
;
2148 txDescCnt
-= txXferLen
;
2149 txFifo
.reserve(txXferLen
);
2151 txState
= txFifoBlock
;
2155 if (txDmaState
!= dmaIdle
)
2158 if (cmdsts
& CMDSTS_INTR
)
2159 devIntrPost(ISR_TXDESC
);
2162 DPRINTF(EthernetSM
, "halting TX state machine\n");
2166 txState
= txAdvance
;
2171 devIntrPost(ISR_TXIDLE
);
2175 if (txDmaState
!= dmaIdle
)
2177 txState
= txDescRead
;
2181 txDmaAddr
= link
& 0x3fffffff;
2182 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2183 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2184 txDmaFree
= dmaDescFree
;
2192 panic("invalid state");
2195 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2196 NsTxStateStrings
[txState
]);
2201 * @todo do we want to schedule a future kick?
2203 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2204 NsTxStateStrings
[txState
]);
2206 if (clock
&& !txKickEvent
.scheduled())
2207 txKickEvent
.schedule(txKickTick
);
2211 * Advance the EEPROM state machine
2212 * Called on rising edge of EEPROM clock bit in MEAR
2215 NSGigE::eepromKick()
2217 switch (eepromState
) {
2221 // Wait for start bit
2222 if (regs
.mear
& MEAR_EEDI
) {
2223 // Set up to get 2 opcode bits
2224 eepromState
= eepromGetOpcode
;
2230 case eepromGetOpcode
:
2232 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2235 // Done getting opcode
2236 if (eepromBitsToRx
== 0) {
2237 if (eepromOpcode
!= EEPROM_READ
)
2238 panic("only EEPROM reads are implemented!");
2240 // Set up to get address
2241 eepromState
= eepromGetAddress
;
2247 case eepromGetAddress
:
2248 eepromAddress
<<= 1;
2249 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2252 // Done getting address
2253 if (eepromBitsToRx
== 0) {
2255 if (eepromAddress
>= EEPROM_SIZE
)
2256 panic("EEPROM read access out of range!");
2258 switch (eepromAddress
) {
2260 case EEPROM_PMATCH2_ADDR
:
2261 eepromData
= rom
.perfectMatch
[5];
2263 eepromData
+= rom
.perfectMatch
[4];
2266 case EEPROM_PMATCH1_ADDR
:
2267 eepromData
= rom
.perfectMatch
[3];
2269 eepromData
+= rom
.perfectMatch
[2];
2272 case EEPROM_PMATCH0_ADDR
:
2273 eepromData
= rom
.perfectMatch
[1];
2275 eepromData
+= rom
.perfectMatch
[0];
2279 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2281 // Set up to read data
2282 eepromState
= eepromRead
;
2283 eepromBitsToRx
= 16;
2285 // Clear data in bit
2286 regs
.mear
&= ~MEAR_EEDI
;
2291 // Clear Data Out bit
2292 regs
.mear
&= ~MEAR_EEDO
;
2293 // Set bit to value of current EEPROM bit
2294 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2300 if (eepromBitsToRx
== 0) {
2301 eepromState
= eepromStart
;
2306 panic("invalid EEPROM state");
2312 NSGigE::transferDone()
2314 if (txFifo
.empty()) {
2315 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2319 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2321 if (txEvent
.scheduled())
2322 txEvent
.reschedule(curTick
+ cycles(1));
2324 txEvent
.schedule(curTick
+ cycles(1));
2328 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2330 EthPtr eth
= packet
;
2334 const EthAddr
&dst
= eth
->dst();
2335 if (dst
.unicast()) {
2336 // If we're accepting all unicast addresses
2340 // If we make a perfect match
2341 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2344 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2347 } else if (dst
.broadcast()) {
2348 // if we're accepting broadcasts
2349 if (acceptBroadcast
)
2352 } else if (dst
.multicast()) {
2353 // if we're accepting all multicasts
2354 if (acceptMulticast
)
2357 // Multicast hashing faked - all packets accepted
2358 if (multicastHashEnable
)
2363 DPRINTF(Ethernet
, "rxFilter drop\n");
2364 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2371 NSGigE::recvPacket(EthPacketPtr packet
)
2373 rxBytes
+= packet
->length
;
2376 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2380 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2384 if (!rxFilterEnable
) {
2386 "receive packet filtering disabled . . . packet dropped\n");
2390 if (rxFilter(packet
)) {
2391 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2395 if (rxFifo
.avail() < packet
->length
) {
2401 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2404 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2409 devIntrPost(ISR_RXORN
);
2413 rxFifo
.push(packet
);
2419 //=====================================================================
2423 NSGigE::serialize(ostream
&os
)
2425 // Serialize the PciDev base class
2426 PciDev::serialize(os
);
2429 * Finalize any DMA events now.
2431 // @todo will mem system save pending dma?
2434 * Serialize the device registers
2436 SERIALIZE_SCALAR(regs
.command
);
2437 SERIALIZE_SCALAR(regs
.config
);
2438 SERIALIZE_SCALAR(regs
.mear
);
2439 SERIALIZE_SCALAR(regs
.ptscr
);
2440 SERIALIZE_SCALAR(regs
.isr
);
2441 SERIALIZE_SCALAR(regs
.imr
);
2442 SERIALIZE_SCALAR(regs
.ier
);
2443 SERIALIZE_SCALAR(regs
.ihr
);
2444 SERIALIZE_SCALAR(regs
.txdp
);
2445 SERIALIZE_SCALAR(regs
.txdp_hi
);
2446 SERIALIZE_SCALAR(regs
.txcfg
);
2447 SERIALIZE_SCALAR(regs
.gpior
);
2448 SERIALIZE_SCALAR(regs
.rxdp
);
2449 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2450 SERIALIZE_SCALAR(regs
.rxcfg
);
2451 SERIALIZE_SCALAR(regs
.pqcr
);
2452 SERIALIZE_SCALAR(regs
.wcsr
);
2453 SERIALIZE_SCALAR(regs
.pcr
);
2454 SERIALIZE_SCALAR(regs
.rfcr
);
2455 SERIALIZE_SCALAR(regs
.rfdr
);
2456 SERIALIZE_SCALAR(regs
.brar
);
2457 SERIALIZE_SCALAR(regs
.brdr
);
2458 SERIALIZE_SCALAR(regs
.srr
);
2459 SERIALIZE_SCALAR(regs
.mibc
);
2460 SERIALIZE_SCALAR(regs
.vrcr
);
2461 SERIALIZE_SCALAR(regs
.vtcr
);
2462 SERIALIZE_SCALAR(regs
.vdr
);
2463 SERIALIZE_SCALAR(regs
.ccsr
);
2464 SERIALIZE_SCALAR(regs
.tbicr
);
2465 SERIALIZE_SCALAR(regs
.tbisr
);
2466 SERIALIZE_SCALAR(regs
.tanar
);
2467 SERIALIZE_SCALAR(regs
.tanlpar
);
2468 SERIALIZE_SCALAR(regs
.taner
);
2469 SERIALIZE_SCALAR(regs
.tesr
);
2471 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2472 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2474 SERIALIZE_SCALAR(ioEnable
);
2477 * Serialize the data Fifos
2479 rxFifo
.serialize("rxFifo", os
);
2480 txFifo
.serialize("txFifo", os
);
2483 * Serialize the various helper variables
2485 bool txPacketExists
= txPacket
;
2486 SERIALIZE_SCALAR(txPacketExists
);
2487 if (txPacketExists
) {
2488 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2489 txPacket
->serialize("txPacket", os
);
2490 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2491 SERIALIZE_SCALAR(txPktBufPtr
);
2494 bool rxPacketExists
= rxPacket
;
2495 SERIALIZE_SCALAR(rxPacketExists
);
2496 if (rxPacketExists
) {
2497 rxPacket
->serialize("rxPacket", os
);
2498 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2499 SERIALIZE_SCALAR(rxPktBufPtr
);
2502 SERIALIZE_SCALAR(txXferLen
);
2503 SERIALIZE_SCALAR(rxXferLen
);
2506 * Serialize Cached Descriptors
2508 SERIALIZE_SCALAR(rxDesc64
.link
);
2509 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2510 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2511 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2512 SERIALIZE_SCALAR(txDesc64
.link
);
2513 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2514 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2515 SERIALIZE_SCALAR(txDesc64
.extsts
);
2516 SERIALIZE_SCALAR(rxDesc32
.link
);
2517 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2518 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2519 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2520 SERIALIZE_SCALAR(txDesc32
.link
);
2521 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2522 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2523 SERIALIZE_SCALAR(txDesc32
.extsts
);
2524 SERIALIZE_SCALAR(extstsEnable
);
2527 * Serialize tx state machine
2529 int txState
= this->txState
;
2530 SERIALIZE_SCALAR(txState
);
2531 SERIALIZE_SCALAR(txEnable
);
2532 SERIALIZE_SCALAR(CTDD
);
2533 SERIALIZE_SCALAR(txFragPtr
);
2534 SERIALIZE_SCALAR(txDescCnt
);
2535 int txDmaState
= this->txDmaState
;
2536 SERIALIZE_SCALAR(txDmaState
);
2537 SERIALIZE_SCALAR(txKickTick
);
2540 * Serialize rx state machine
2542 int rxState
= this->rxState
;
2543 SERIALIZE_SCALAR(rxState
);
2544 SERIALIZE_SCALAR(rxEnable
);
2545 SERIALIZE_SCALAR(CRDD
);
2546 SERIALIZE_SCALAR(rxPktBytes
);
2547 SERIALIZE_SCALAR(rxFragPtr
);
2548 SERIALIZE_SCALAR(rxDescCnt
);
2549 int rxDmaState
= this->rxDmaState
;
2550 SERIALIZE_SCALAR(rxDmaState
);
2551 SERIALIZE_SCALAR(rxKickTick
);
2554 * Serialize EEPROM state machine
2556 int eepromState
= this->eepromState
;
2557 SERIALIZE_SCALAR(eepromState
);
2558 SERIALIZE_SCALAR(eepromClk
);
2559 SERIALIZE_SCALAR(eepromBitsToRx
);
2560 SERIALIZE_SCALAR(eepromOpcode
);
2561 SERIALIZE_SCALAR(eepromAddress
);
2562 SERIALIZE_SCALAR(eepromData
);
2565 * If there's a pending transmit, store the time so we can
2566 * reschedule it later
2568 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2569 SERIALIZE_SCALAR(transmitTick
);
2572 * receive address filter settings
2574 SERIALIZE_SCALAR(rxFilterEnable
);
2575 SERIALIZE_SCALAR(acceptBroadcast
);
2576 SERIALIZE_SCALAR(acceptMulticast
);
2577 SERIALIZE_SCALAR(acceptUnicast
);
2578 SERIALIZE_SCALAR(acceptPerfect
);
2579 SERIALIZE_SCALAR(acceptArp
);
2580 SERIALIZE_SCALAR(multicastHashEnable
);
2583 * Keep track of pending interrupt status.
2585 SERIALIZE_SCALAR(intrTick
);
2586 SERIALIZE_SCALAR(cpuPendingIntr
);
2587 Tick intrEventTick
= 0;
2589 intrEventTick
= intrEvent
->when();
2590 SERIALIZE_SCALAR(intrEventTick
);
2595 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2597 // Unserialize the PciDev base class
2598 PciDev::unserialize(cp
, section
);
2600 UNSERIALIZE_SCALAR(regs
.command
);
2601 UNSERIALIZE_SCALAR(regs
.config
);
2602 UNSERIALIZE_SCALAR(regs
.mear
);
2603 UNSERIALIZE_SCALAR(regs
.ptscr
);
2604 UNSERIALIZE_SCALAR(regs
.isr
);
2605 UNSERIALIZE_SCALAR(regs
.imr
);
2606 UNSERIALIZE_SCALAR(regs
.ier
);
2607 UNSERIALIZE_SCALAR(regs
.ihr
);
2608 UNSERIALIZE_SCALAR(regs
.txdp
);
2609 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2610 UNSERIALIZE_SCALAR(regs
.txcfg
);
2611 UNSERIALIZE_SCALAR(regs
.gpior
);
2612 UNSERIALIZE_SCALAR(regs
.rxdp
);
2613 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2614 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2615 UNSERIALIZE_SCALAR(regs
.pqcr
);
2616 UNSERIALIZE_SCALAR(regs
.wcsr
);
2617 UNSERIALIZE_SCALAR(regs
.pcr
);
2618 UNSERIALIZE_SCALAR(regs
.rfcr
);
2619 UNSERIALIZE_SCALAR(regs
.rfdr
);
2620 UNSERIALIZE_SCALAR(regs
.brar
);
2621 UNSERIALIZE_SCALAR(regs
.brdr
);
2622 UNSERIALIZE_SCALAR(regs
.srr
);
2623 UNSERIALIZE_SCALAR(regs
.mibc
);
2624 UNSERIALIZE_SCALAR(regs
.vrcr
);
2625 UNSERIALIZE_SCALAR(regs
.vtcr
);
2626 UNSERIALIZE_SCALAR(regs
.vdr
);
2627 UNSERIALIZE_SCALAR(regs
.ccsr
);
2628 UNSERIALIZE_SCALAR(regs
.tbicr
);
2629 UNSERIALIZE_SCALAR(regs
.tbisr
);
2630 UNSERIALIZE_SCALAR(regs
.tanar
);
2631 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2632 UNSERIALIZE_SCALAR(regs
.taner
);
2633 UNSERIALIZE_SCALAR(regs
.tesr
);
2635 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2636 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2638 UNSERIALIZE_SCALAR(ioEnable
);
2641 * unserialize the data fifos
2643 rxFifo
.unserialize("rxFifo", cp
, section
);
2644 txFifo
.unserialize("txFifo", cp
, section
);
2647 * unserialize the various helper variables
2649 bool txPacketExists
;
2650 UNSERIALIZE_SCALAR(txPacketExists
);
2651 if (txPacketExists
) {
2652 txPacket
= new EthPacketData(16384);
2653 txPacket
->unserialize("txPacket", cp
, section
);
2654 uint32_t txPktBufPtr
;
2655 UNSERIALIZE_SCALAR(txPktBufPtr
);
2656 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2660 bool rxPacketExists
;
2661 UNSERIALIZE_SCALAR(rxPacketExists
);
2663 if (rxPacketExists
) {
2664 rxPacket
= new EthPacketData(16384);
2665 rxPacket
->unserialize("rxPacket", cp
, section
);
2666 uint32_t rxPktBufPtr
;
2667 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2668 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2672 UNSERIALIZE_SCALAR(txXferLen
);
2673 UNSERIALIZE_SCALAR(rxXferLen
);
2676 * Unserialize Cached Descriptors
2678 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2679 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2680 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2681 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2682 UNSERIALIZE_SCALAR(txDesc64
.link
);
2683 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2684 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2685 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2686 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2687 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2688 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2689 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2690 UNSERIALIZE_SCALAR(txDesc32
.link
);
2691 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2692 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2693 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2694 UNSERIALIZE_SCALAR(extstsEnable
);
2697 * unserialize tx state machine
2700 UNSERIALIZE_SCALAR(txState
);
2701 this->txState
= (TxState
) txState
;
2702 UNSERIALIZE_SCALAR(txEnable
);
2703 UNSERIALIZE_SCALAR(CTDD
);
2704 UNSERIALIZE_SCALAR(txFragPtr
);
2705 UNSERIALIZE_SCALAR(txDescCnt
);
2707 UNSERIALIZE_SCALAR(txDmaState
);
2708 this->txDmaState
= (DmaState
) txDmaState
;
2709 UNSERIALIZE_SCALAR(txKickTick
);
2711 txKickEvent
.schedule(txKickTick
);
2714 * unserialize rx state machine
2717 UNSERIALIZE_SCALAR(rxState
);
2718 this->rxState
= (RxState
) rxState
;
2719 UNSERIALIZE_SCALAR(rxEnable
);
2720 UNSERIALIZE_SCALAR(CRDD
);
2721 UNSERIALIZE_SCALAR(rxPktBytes
);
2722 UNSERIALIZE_SCALAR(rxFragPtr
);
2723 UNSERIALIZE_SCALAR(rxDescCnt
);
2725 UNSERIALIZE_SCALAR(rxDmaState
);
2726 this->rxDmaState
= (DmaState
) rxDmaState
;
2727 UNSERIALIZE_SCALAR(rxKickTick
);
2729 rxKickEvent
.schedule(rxKickTick
);
2732 * Unserialize EEPROM state machine
2735 UNSERIALIZE_SCALAR(eepromState
);
2736 this->eepromState
= (EEPROMState
) eepromState
;
2737 UNSERIALIZE_SCALAR(eepromClk
);
2738 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2739 UNSERIALIZE_SCALAR(eepromOpcode
);
2740 UNSERIALIZE_SCALAR(eepromAddress
);
2741 UNSERIALIZE_SCALAR(eepromData
);
2744 * If there's a pending transmit, reschedule it now
2747 UNSERIALIZE_SCALAR(transmitTick
);
2749 txEvent
.schedule(curTick
+ transmitTick
);
2752 * unserialize receive address filter settings
2754 UNSERIALIZE_SCALAR(rxFilterEnable
);
2755 UNSERIALIZE_SCALAR(acceptBroadcast
);
2756 UNSERIALIZE_SCALAR(acceptMulticast
);
2757 UNSERIALIZE_SCALAR(acceptUnicast
);
2758 UNSERIALIZE_SCALAR(acceptPerfect
);
2759 UNSERIALIZE_SCALAR(acceptArp
);
2760 UNSERIALIZE_SCALAR(multicastHashEnable
);
2763 * Keep track of pending interrupt status.
2765 UNSERIALIZE_SCALAR(intrTick
);
2766 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2768 UNSERIALIZE_SCALAR(intrEventTick
);
2769 if (intrEventTick
) {
2770 intrEvent
= new IntrEvent(this, true);
2771 intrEvent
->schedule(intrEventTick
);
2775 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2777 SimObjectParam
<EtherInt
*> peer
;
2778 SimObjectParam
<NSGigE
*> device
;
2780 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2782 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2784 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2785 INIT_PARAM(device
, "Ethernet device of this interface")
2787 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2789 CREATE_SIM_OBJECT(NSGigEInt
)
2791 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2793 EtherInt
*p
= (EtherInt
*)peer
;
2795 dev_int
->setPeer(p
);
2796 p
->setPeer(dev_int
);
2802 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2805 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2807 SimObjectParam
<System
*> system
;
2808 SimObjectParam
<Platform
*> platform
;
2809 SimObjectParam
<PciConfigAll
*> configspace
;
2810 SimObjectParam
<PciConfigData
*> configdata
;
2811 Param
<uint32_t> pci_bus
;
2812 Param
<uint32_t> pci_dev
;
2813 Param
<uint32_t> pci_func
;
2814 Param
<Tick
> pio_latency
;
2817 Param
<bool> dma_desc_free
;
2818 Param
<bool> dma_data_free
;
2819 Param
<Tick
> dma_read_delay
;
2820 Param
<Tick
> dma_write_delay
;
2821 Param
<Tick
> dma_read_factor
;
2822 Param
<Tick
> dma_write_factor
;
2823 Param
<bool> dma_no_allocate
;
2824 Param
<Tick
> intr_delay
;
2826 Param
<Tick
> rx_delay
;
2827 Param
<Tick
> tx_delay
;
2828 Param
<uint32_t> rx_fifo_size
;
2829 Param
<uint32_t> tx_fifo_size
;
2831 Param
<bool> rx_filter
;
2832 Param
<string
> hardware_address
;
2833 Param
<bool> rx_thread
;
2834 Param
<bool> tx_thread
;
2837 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2839 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2841 INIT_PARAM(system
, "System pointer"),
2842 INIT_PARAM(platform
, "Platform pointer"),
2843 INIT_PARAM(configspace
, "PCI Configspace"),
2844 INIT_PARAM(configdata
, "PCI Config data"),
2845 INIT_PARAM(pci_bus
, "PCI bus ID"),
2846 INIT_PARAM(pci_dev
, "PCI device number"),
2847 INIT_PARAM(pci_func
, "PCI function code"),
2848 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency in bus cycles", 1),
2849 INIT_PARAM(clock
, "State machine cycle time"),
2851 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
2852 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
2853 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
2854 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
2855 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
2856 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
2857 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
2858 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
2860 INIT_PARAM(rx_delay
, "Receive Delay"),
2861 INIT_PARAM(tx_delay
, "Transmit Delay"),
2862 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
2863 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
2865 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
2866 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
2867 INIT_PARAM(rx_thread
, ""),
2868 INIT_PARAM(tx_thread
, ""),
2871 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2874 CREATE_SIM_OBJECT(NSGigE
)
2876 NSGigE::Params
*params
= new NSGigE::Params
;
2878 params
->name
= getInstanceName();
2879 params
->platform
= platform
;
2880 params
->system
= system
;
2881 params
->configSpace
= configspace
;
2882 params
->configData
= configdata
;
2883 params
->busNum
= pci_bus
;
2884 params
->deviceNum
= pci_dev
;
2885 params
->functionNum
= pci_func
;
2886 params
->pio_delay
= pio_latency
;
2888 params
->clock
= clock
;
2889 params
->dma_desc_free
= dma_desc_free
;
2890 params
->dma_data_free
= dma_data_free
;
2891 params
->dma_read_delay
= dma_read_delay
;
2892 params
->dma_write_delay
= dma_write_delay
;
2893 params
->dma_read_factor
= dma_read_factor
;
2894 params
->dma_write_factor
= dma_write_factor
;
2895 params
->dma_no_allocate
= dma_no_allocate
;
2896 params
->pio_delay
= pio_latency
;
2897 params
->intr_delay
= intr_delay
;
2899 params
->rx_delay
= rx_delay
;
2900 params
->tx_delay
= tx_delay
;
2901 params
->rx_fifo_size
= rx_fifo_size
;
2902 params
->tx_fifo_size
= tx_fifo_size
;
2904 params
->rx_filter
= rx_filter
;
2905 params
->eaddr
= hardware_address
;
2906 params
->rx_thread
= rx_thread
;
2907 params
->tx_thread
= tx_thread
;
2910 return new NSGigE(params
);
2913 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)