2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Device module for modelling the National Semiconductor
31 * DP83820 ethernet controller. Does not support priority queueing
37 #include "base/inet.hh"
38 #include "cpu/exec_context.hh"
39 #include "dev/etherlink.hh"
40 #include "dev/ns_gige.hh"
41 #include "dev/pciconfigall.hh"
42 #include "mem/bus/bus.hh"
43 #include "mem/bus/dma_interface.hh"
44 #include "mem/bus/pio_interface.hh"
45 #include "mem/bus/pio_interface_impl.hh"
46 #include "mem/functional/memory_control.hh"
47 #include "mem/functional/physical.hh"
48 #include "sim/builder.hh"
49 #include "sim/debug.hh"
50 #include "sim/host.hh"
51 #include "sim/stats.hh"
52 #include "targetarch/vtophys.hh"
54 const char *NsRxStateStrings
[] =
65 const char *NsTxStateStrings
[] =
76 const char *NsDmaState
[] =
87 using namespace TheISA
;
89 ///////////////////////////////////////////////////////////////////////
93 NSGigE::NSGigE(Params
*p
)
94 : PciDev(p
), ioEnable(false),
95 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
96 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
97 txXferLen(0), rxXferLen(0), clock(p
->clock
),
98 txState(txIdle
), txEnable(false), CTDD(false),
99 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
100 rxEnable(false), CRDD(false), rxPktBytes(0),
101 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
102 eepromState(eepromStart
), rxDmaReadEvent(this), rxDmaWriteEvent(this),
103 txDmaReadEvent(this), txDmaWriteEvent(this),
104 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
105 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
106 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
107 txEvent(this), rxFilterEnable(p
->rx_filter
), acceptBroadcast(false),
108 acceptMulticast(false), acceptUnicast(false),
109 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
110 physmem(p
->pmem
), intrTick(0), cpuPendingIntr(false),
111 intrEvent(0), interface(0)
114 pioInterface
= newPioInterface(name() + ".pio", p
->hier
,
116 &NSGigE::cacheAccess
);
117 pioLatency
= p
->pio_latency
* p
->pio_bus
->clockRate
;
122 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
127 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
131 } else if (p
->payload_bus
)
132 panic("Must define a header bus if defining a payload bus");
134 pioDelayWrite
= p
->pio_delay_write
&& pioInterface
;
136 intrDelay
= p
->intr_delay
;
137 dmaReadDelay
= p
->dma_read_delay
;
138 dmaWriteDelay
= p
->dma_write_delay
;
139 dmaReadFactor
= p
->dma_read_factor
;
140 dmaWriteFactor
= p
->dma_write_factor
;
143 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
145 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
146 memset(&txDesc32
, 0, sizeof(txDesc32
));
147 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
148 memset(&txDesc64
, 0, sizeof(txDesc64
));
158 .name(name() + ".txBytes")
159 .desc("Bytes Transmitted")
164 .name(name() + ".rxBytes")
165 .desc("Bytes Received")
170 .name(name() + ".txPackets")
171 .desc("Number of Packets Transmitted")
176 .name(name() + ".rxPackets")
177 .desc("Number of Packets Received")
182 .name(name() + ".txIpChecksums")
183 .desc("Number of tx IP Checksums done by device")
189 .name(name() + ".rxIpChecksums")
190 .desc("Number of rx IP Checksums done by device")
196 .name(name() + ".txTcpChecksums")
197 .desc("Number of tx TCP Checksums done by device")
203 .name(name() + ".rxTcpChecksums")
204 .desc("Number of rx TCP Checksums done by device")
210 .name(name() + ".txUdpChecksums")
211 .desc("Number of tx UDP Checksums done by device")
217 .name(name() + ".rxUdpChecksums")
218 .desc("Number of rx UDP Checksums done by device")
224 .name(name() + ".descDMAReads")
225 .desc("Number of descriptors the device read w/ DMA")
230 .name(name() + ".descDMAWrites")
231 .desc("Number of descriptors the device wrote w/ DMA")
236 .name(name() + ".descDmaReadBytes")
237 .desc("number of descriptor bytes read w/ DMA")
242 .name(name() + ".descDmaWriteBytes")
243 .desc("number of descriptor bytes write w/ DMA")
248 .name(name() + ".txBandwidth")
249 .desc("Transmit Bandwidth (bits/s)")
255 .name(name() + ".rxBandwidth")
256 .desc("Receive Bandwidth (bits/s)")
262 .name(name() + ".totBandwidth")
263 .desc("Total Bandwidth (bits/s)")
269 .name(name() + ".totPackets")
270 .desc("Total Packets")
276 .name(name() + ".totBytes")
283 .name(name() + ".totPPS")
284 .desc("Total Tranmission Rate (packets/s)")
290 .name(name() + ".txPPS")
291 .desc("Packet Tranmission Rate (packets/s)")
297 .name(name() + ".rxPPS")
298 .desc("Packet Reception Rate (packets/s)")
304 .name(name() + ".postedSwi")
305 .desc("number of software interrupts posted to CPU")
310 .name(name() + ".totalSwi")
311 .desc("total number of Swi written to ISR")
316 .name(name() + ".coalescedSwi")
317 .desc("average number of Swi's coalesced into each post")
322 .name(name() + ".postedRxIdle")
323 .desc("number of rxIdle interrupts posted to CPU")
328 .name(name() + ".totalRxIdle")
329 .desc("total number of RxIdle written to ISR")
334 .name(name() + ".coalescedRxIdle")
335 .desc("average number of RxIdle's coalesced into each post")
340 .name(name() + ".postedRxOk")
341 .desc("number of RxOk interrupts posted to CPU")
346 .name(name() + ".totalRxOk")
347 .desc("total number of RxOk written to ISR")
352 .name(name() + ".coalescedRxOk")
353 .desc("average number of RxOk's coalesced into each post")
358 .name(name() + ".postedRxDesc")
359 .desc("number of RxDesc interrupts posted to CPU")
364 .name(name() + ".totalRxDesc")
365 .desc("total number of RxDesc written to ISR")
370 .name(name() + ".coalescedRxDesc")
371 .desc("average number of RxDesc's coalesced into each post")
376 .name(name() + ".postedTxOk")
377 .desc("number of TxOk interrupts posted to CPU")
382 .name(name() + ".totalTxOk")
383 .desc("total number of TxOk written to ISR")
388 .name(name() + ".coalescedTxOk")
389 .desc("average number of TxOk's coalesced into each post")
394 .name(name() + ".postedTxIdle")
395 .desc("number of TxIdle interrupts posted to CPU")
400 .name(name() + ".totalTxIdle")
401 .desc("total number of TxIdle written to ISR")
406 .name(name() + ".coalescedTxIdle")
407 .desc("average number of TxIdle's coalesced into each post")
412 .name(name() + ".postedTxDesc")
413 .desc("number of TxDesc interrupts posted to CPU")
418 .name(name() + ".totalTxDesc")
419 .desc("total number of TxDesc written to ISR")
424 .name(name() + ".coalescedTxDesc")
425 .desc("average number of TxDesc's coalesced into each post")
430 .name(name() + ".postedRxOrn")
431 .desc("number of RxOrn posted to CPU")
436 .name(name() + ".totalRxOrn")
437 .desc("total number of RxOrn written to ISR")
442 .name(name() + ".coalescedRxOrn")
443 .desc("average number of RxOrn's coalesced into each post")
448 .name(name() + ".coalescedTotal")
449 .desc("average number of interrupts coalesced into each post")
454 .name(name() + ".postedInterrupts")
455 .desc("number of posts to CPU")
460 .name(name() + ".droppedPackets")
461 .desc("number of packets dropped")
465 coalescedSwi
= totalSwi
/ postedInterrupts
;
466 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
467 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
468 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
469 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
470 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
471 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
472 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
474 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
475 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
476 totalRxOrn
) / postedInterrupts
;
478 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
479 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
480 totBandwidth
= txBandwidth
+ rxBandwidth
;
481 totBytes
= txBytes
+ rxBytes
;
482 totPackets
= txPackets
+ rxPackets
;
484 txPacketRate
= txPackets
/ simSeconds
;
485 rxPacketRate
= rxPackets
/ simSeconds
;
489 * This is to read the PCI general configuration registers
492 NSGigE::readConfig(int offset
, int size
, uint8_t *data
)
494 if (offset
< PCI_DEVICE_SPECIFIC
)
495 PciDev::readConfig(offset
, size
, data
);
497 panic("Device specific PCI config space not implemented!\n");
501 * This is to write to the PCI general configuration registers
504 NSGigE::writeConfig(int offset
, int size
, const uint8_t* data
)
506 if (offset
< PCI_DEVICE_SPECIFIC
)
507 PciDev::writeConfig(offset
, size
, data
);
509 panic("Device specific PCI config space not implemented!\n");
511 // Need to catch writes to BARs to update the PIO interface
513 // seems to work fine without all these PCI settings, but i
514 // put in the IO to double check, an assertion will fail if we
515 // need to properly implement it
517 if (config
.data
[offset
] & PCI_CMD_IOSE
)
523 if (config
.data
[offset
] & PCI_CMD_BME
) {
530 if (config
.data
[offset
] & PCI_CMD_MSE
) {
539 case PCI0_BASE_ADDR0
:
540 if (BARAddrs
[0] != 0) {
542 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
544 BARAddrs
[0] &= EV5::PAddrUncachedMask
;
547 case PCI0_BASE_ADDR1
:
548 if (BARAddrs
[1] != 0) {
550 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
552 BARAddrs
[1] &= EV5::PAddrUncachedMask
;
559 * This reads the device registers, which are detailed in the NS83820
563 NSGigE::read(MemReqPtr
&req
, uint8_t *data
)
567 //The mask is to give you only the offset into the device register file
568 Addr daddr
= req
->paddr
& 0xfff;
569 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x va=%#x size=%d\n",
570 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
573 // there are some reserved registers, you can see ns_gige_reg.h and
574 // the spec sheet for details
575 if (daddr
> LAST
&& daddr
<= RESERVED
) {
576 panic("Accessing reserved register");
577 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
578 readConfig(daddr
& 0xff, req
->size
, data
);
580 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
581 // don't implement all the MIB's. hopefully the kernel
582 // doesn't actually DEPEND upon their values
583 // MIB are just hardware stats keepers
584 uint32_t ®
= *(uint32_t *) data
;
587 } else if (daddr
> 0x3FC)
588 panic("Something is messed up!\n");
591 case sizeof(uint32_t):
593 uint32_t ®
= *(uint32_t *)data
;
599 //these are supposed to be cleared on a read
600 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
617 devIntrClear(ISR_ALL
);
672 // see the spec sheet for how RFCR and RFDR work
673 // basically, you write to RFCR to tell the machine
674 // what you want to do next, then you act upon RFDR,
675 // and the device will be prepared b/c of what you
682 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
684 // Read from perfect match ROM octets
686 reg
= rom
.perfectMatch
[1];
688 reg
+= rom
.perfectMatch
[0];
691 reg
= rom
.perfectMatch
[3] << 8;
692 reg
+= rom
.perfectMatch
[2];
695 reg
= rom
.perfectMatch
[5] << 8;
696 reg
+= rom
.perfectMatch
[4];
699 // Read filter hash table
700 if (rfaddr
>= FHASH_ADDR
&&
701 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
703 // Only word-aligned reads supported
705 panic("unaligned read from filter hash table!");
707 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
708 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
712 panic("reading RFDR for something other than pattern"
713 " matching or hashing! %#x\n", rfaddr
);
723 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
768 if (params()->rx_thread
)
769 reg
|= M5REG_RX_THREAD
;
770 if (params()->tx_thread
)
771 reg
|= M5REG_TX_THREAD
;
775 panic("reading unimplemented register: addr=%#x", daddr
);
778 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
784 panic("accessing register with invalid size: addr=%#x, size=%d",
792 NSGigE::write(MemReqPtr
&req
, const uint8_t *data
)
796 Addr daddr
= req
->paddr
& 0xfff;
797 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x va=%#x size=%d\n",
798 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
800 if (daddr
> LAST
&& daddr
<= RESERVED
) {
801 panic("Accessing reserved register");
802 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
803 writeConfig(daddr
& 0xff, req
->size
, data
);
805 } else if (daddr
> 0x3FC)
806 panic("Something is messed up!\n");
809 int cpu
= (req
->xc
->regs
.ipr
[TheISA::IPR_PALtemp16
] >> 8) & 0xff;
810 if (cpu
>= writeQueue
.size())
811 writeQueue
.resize(cpu
+ 1);
812 writeQueue
[cpu
].push_back(RegWriteData(daddr
, *(uint32_t *)data
));
815 if (req
->size
== sizeof(uint32_t)) {
816 uint32_t reg
= *(uint32_t *)data
;
819 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
826 } else if (reg
& CR_TXE
) {
827 if (!pioDelayWrite
) {
830 // the kernel is enabling the transmit machine
831 if (txState
== txIdle
)
838 } else if (reg
& CR_RXE
) {
839 if (!pioDelayWrite
) {
842 if (rxState
== rxIdle
)
854 devIntrPost(ISR_SWI
);
865 if (reg
& CFGR_LNKSTS
||
868 reg
& CFGR_RESERVED
||
869 reg
& CFGR_T64ADDR
||
870 reg
& CFGR_PCI64_DET
)
872 // First clear all writable bits
873 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
874 CFGR_RESERVED
| CFGR_T64ADDR
|
876 // Now set the appropriate writable bits
877 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
878 CFGR_RESERVED
| CFGR_T64ADDR
|
881 // all these #if 0's are because i don't THINK the kernel needs to
882 // have these implemented. if there is a problem relating to one of
883 // these, you may need to add functionality in.
884 if (reg
& CFGR_TBI_EN
) ;
885 if (reg
& CFGR_MODE_1000
) ;
887 if (reg
& CFGR_AUTO_1000
)
888 panic("CFGR_AUTO_1000 not implemented!\n");
890 if (reg
& CFGR_PINT_DUPSTS
||
891 reg
& CFGR_PINT_LNKSTS
||
892 reg
& CFGR_PINT_SPDSTS
)
895 if (reg
& CFGR_TMRTEST
) ;
896 if (reg
& CFGR_MRM_DIS
) ;
897 if (reg
& CFGR_MWI_DIS
) ;
899 if (reg
& CFGR_T64ADDR
) ;
900 // panic("CFGR_T64ADDR is read only register!\n");
902 if (reg
& CFGR_PCI64_DET
)
903 panic("CFGR_PCI64_DET is read only register!\n");
905 if (reg
& CFGR_DATA64_EN
) ;
906 if (reg
& CFGR_M64ADDR
) ;
907 if (reg
& CFGR_PHY_RST
) ;
908 if (reg
& CFGR_PHY_DIS
) ;
910 if (reg
& CFGR_EXTSTS_EN
)
913 extstsEnable
= false;
915 if (reg
& CFGR_REQALG
) ;
917 if (reg
& CFGR_POW
) ;
918 if (reg
& CFGR_EXD
) ;
919 if (reg
& CFGR_PESEL
) ;
920 if (reg
& CFGR_BROM_DIS
) ;
921 if (reg
& CFGR_EXT_125
) ;
922 if (reg
& CFGR_BEM
) ;
926 // Clear writable bits
927 regs
.mear
&= MEAR_EEDO
;
928 // Set appropriate writable bits
929 regs
.mear
|= reg
& ~MEAR_EEDO
;
931 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
932 // even though it could get it through RFDR
933 if (reg
& MEAR_EESEL
) {
934 // Rising edge of clock
935 if (reg
& MEAR_EECLK
&& !eepromClk
)
939 eepromState
= eepromStart
;
940 regs
.mear
&= ~MEAR_EEDI
;
943 eepromClk
= reg
& MEAR_EECLK
;
945 // since phy is completely faked, MEAR_MD* don't matter
946 if (reg
& MEAR_MDIO
) ;
947 if (reg
& MEAR_MDDIR
) ;
948 if (reg
& MEAR_MDC
) ;
952 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
953 // these control BISTs for various parts of chip - we
954 // don't care or do just fake that the BIST is done
955 if (reg
& PTSCR_RBIST_EN
)
956 regs
.ptscr
|= PTSCR_RBIST_DONE
;
957 if (reg
& PTSCR_EEBIST_EN
)
958 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
959 if (reg
& PTSCR_EELOAD_EN
)
960 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
963 case ISR
: /* writing to the ISR has no effect */
964 panic("ISR is a read only register!\n");
977 /* not going to implement real interrupt holdoff */
981 regs
.txdp
= (reg
& 0xFFFFFFFC);
982 assert(txState
== txIdle
);
993 if (reg
& TX_CFG_CSI
) ;
994 if (reg
& TX_CFG_HBI
) ;
995 if (reg
& TX_CFG_MLB
) ;
996 if (reg
& TX_CFG_ATP
) ;
997 if (reg
& TX_CFG_ECRETRY
) {
999 * this could easily be implemented, but considering
1000 * the network is just a fake pipe, wouldn't make
1005 if (reg
& TX_CFG_BRST_DIS
) ;
1009 /* we handle our own DMA, ignore the kernel's exhortations */
1010 if (reg
& TX_CFG_MXDMA
) ;
1013 // also, we currently don't care about fill/drain
1014 // thresholds though this may change in the future with
1015 // more realistic networks or a driver which changes it
1016 // according to feedback
1021 // Only write writable bits
1022 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1023 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1024 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1025 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1026 /* these just control general purpose i/o pins, don't matter */
1041 if (reg
& RX_CFG_AEP
) ;
1042 if (reg
& RX_CFG_ARP
) ;
1043 if (reg
& RX_CFG_STRIPCRC
) ;
1044 if (reg
& RX_CFG_RX_RD
) ;
1045 if (reg
& RX_CFG_ALP
) ;
1046 if (reg
& RX_CFG_AIRL
) ;
1048 /* we handle our own DMA, ignore what kernel says about it */
1049 if (reg
& RX_CFG_MXDMA
) ;
1051 //also, we currently don't care about fill/drain thresholds
1052 //though this may change in the future with more realistic
1053 //networks or a driver which changes it according to feedback
1054 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1059 /* there is no priority queueing used in the linux 2.6 driver */
1064 /* not going to implement wake on LAN */
1069 /* not going to implement pause control */
1076 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1077 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1078 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1079 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1080 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1081 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1082 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1085 if (reg
& RFCR_APAT
)
1086 panic("RFCR_APAT not implemented!\n");
1088 if (reg
& RFCR_UHEN
)
1089 panic("Unicast hash filtering not used by drivers!\n");
1092 panic("RFCR_ULM not implemented!\n");
1097 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1100 rom
.perfectMatch
[0] = (uint8_t)reg
;
1101 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1104 rom
.perfectMatch
[2] = (uint8_t)reg
;
1105 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1108 rom
.perfectMatch
[4] = (uint8_t)reg
;
1109 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1113 if (rfaddr
>= FHASH_ADDR
&&
1114 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1116 // Only word-aligned writes supported
1118 panic("unaligned write to filter hash table!");
1120 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1121 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1122 = (uint8_t)(reg
>> 8);
1125 panic("writing RFDR for something other than pattern matching\
1126 or hashing! %#x\n", rfaddr
);
1134 panic("the driver never uses BRDR, something is wrong!\n");
1137 panic("SRR is read only register!\n");
1140 panic("the driver never uses MIBC, something is wrong!\n");
1151 panic("the driver never uses VDR, something is wrong!\n");
1154 /* not going to implement clockrun stuff */
1160 if (reg
& TBICR_MR_LOOPBACK
)
1161 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1163 if (reg
& TBICR_MR_AN_ENABLE
) {
1164 regs
.tanlpar
= regs
.tanar
;
1165 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1169 if (reg
& TBICR_MR_RESTART_AN
) ;
1175 panic("TBISR is read only register!\n");
1178 // Only write the writable bits
1179 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1180 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1182 // Pause capability unimplemented
1184 if (reg
& TANAR_PS2
) ;
1185 if (reg
& TANAR_PS1
) ;
1191 panic("this should only be written to by the fake phy!\n");
1194 panic("TANER is read only register!\n");
1201 panic("invalid register access daddr=%#x", daddr
);
1204 panic("Invalid Request Size");
1211 NSGigE::devIntrPost(uint32_t interrupts
)
1213 if (interrupts
& ISR_RESERVE
)
1214 panic("Cannot set a reserved interrupt");
1216 if (interrupts
& ISR_NOIMPL
)
1217 warn("interrupt not implemented %#x\n", interrupts
);
1219 interrupts
&= ISR_IMPL
;
1220 regs
.isr
|= interrupts
;
1222 if (interrupts
& regs
.imr
) {
1223 if (interrupts
& ISR_SWI
) {
1226 if (interrupts
& ISR_RXIDLE
) {
1229 if (interrupts
& ISR_RXOK
) {
1232 if (interrupts
& ISR_RXDESC
) {
1235 if (interrupts
& ISR_TXOK
) {
1238 if (interrupts
& ISR_TXIDLE
) {
1241 if (interrupts
& ISR_TXDESC
) {
1244 if (interrupts
& ISR_RXORN
) {
1249 DPRINTF(EthernetIntr
,
1250 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1251 interrupts
, regs
.isr
, regs
.imr
);
1253 if ((regs
.isr
& regs
.imr
)) {
1254 Tick when
= curTick
;
1255 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1261 /* writing this interrupt counting stats inside this means that this function
1262 is now limited to being used to clear all interrupts upon the kernel
1263 reading isr and servicing. just telling you in case you were thinking
1267 NSGigE::devIntrClear(uint32_t interrupts
)
1269 if (interrupts
& ISR_RESERVE
)
1270 panic("Cannot clear a reserved interrupt");
1272 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1275 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1278 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1281 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1284 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1287 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1290 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1293 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1297 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1300 interrupts
&= ~ISR_NOIMPL
;
1301 regs
.isr
&= ~interrupts
;
1303 DPRINTF(EthernetIntr
,
1304 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1305 interrupts
, regs
.isr
, regs
.imr
);
1307 if (!(regs
.isr
& regs
.imr
))
1312 NSGigE::devIntrChangeMask()
1314 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1315 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1317 if (regs
.isr
& regs
.imr
)
1318 cpuIntrPost(curTick
);
1324 NSGigE::cpuIntrPost(Tick when
)
1326 // If the interrupt you want to post is later than an interrupt
1327 // already scheduled, just let it post in the coming one and don't
1328 // schedule another.
1329 // HOWEVER, must be sure that the scheduled intrTick is in the
1330 // future (this was formerly the source of a bug)
1332 * @todo this warning should be removed and the intrTick code should
1335 assert(when
>= curTick
);
1336 assert(intrTick
>= curTick
|| intrTick
== 0);
1337 if (when
> intrTick
&& intrTick
!= 0) {
1338 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1344 if (intrTick
< curTick
) {
1349 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1353 intrEvent
->squash();
1354 intrEvent
= new IntrEvent(this, true);
1355 intrEvent
->schedule(intrTick
);
1359 NSGigE::cpuInterrupt()
1361 assert(intrTick
== curTick
);
1363 // Whether or not there's a pending interrupt, we don't care about
1368 // Don't send an interrupt if there's already one
1369 if (cpuPendingIntr
) {
1370 DPRINTF(EthernetIntr
,
1371 "would send an interrupt now, but there's already pending\n");
1374 cpuPendingIntr
= true;
1376 DPRINTF(EthernetIntr
, "posting interrupt\n");
1382 NSGigE::cpuIntrClear()
1384 if (!cpuPendingIntr
)
1388 intrEvent
->squash();
1394 cpuPendingIntr
= false;
1396 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1401 NSGigE::cpuIntrPending() const
1402 { return cpuPendingIntr
; }
1408 DPRINTF(Ethernet
, "transmit reset\n");
1413 assert(txDescCnt
== 0);
1416 assert(txDmaState
== dmaIdle
);
1422 DPRINTF(Ethernet
, "receive reset\n");
1425 assert(rxPktBytes
== 0);
1428 assert(rxDescCnt
== 0);
1429 assert(rxDmaState
== dmaIdle
);
1437 memset(®s
, 0, sizeof(regs
));
1438 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1440 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1441 // fill threshold to 32 bytes
1442 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1443 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1444 regs
.mibc
= MIBC_FRZ
;
1445 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1446 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1447 regs
.brar
= 0xffffffff;
1449 extstsEnable
= false;
1450 acceptBroadcast
= false;
1451 acceptMulticast
= false;
1452 acceptUnicast
= false;
1453 acceptPerfect
= false;
1458 NSGigE::rxDmaReadCopy()
1460 assert(rxDmaState
== dmaReading
);
1462 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1463 rxDmaState
= dmaIdle
;
1465 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1466 rxDmaAddr
, rxDmaLen
);
1467 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1471 NSGigE::doRxDmaRead()
1473 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1474 rxDmaState
= dmaReading
;
1476 if (dmaInterface
&& !rxDmaFree
) {
1477 if (dmaInterface
->busy())
1478 rxDmaState
= dmaReadWaiting
;
1480 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1481 &rxDmaReadEvent
, true);
1485 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1490 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1491 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1492 rxDmaReadEvent
.schedule(start
);
1497 NSGigE::rxDmaReadDone()
1499 assert(rxDmaState
== dmaReading
);
1502 // If the transmit state machine has a pending DMA, let it go first
1503 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1510 NSGigE::rxDmaWriteCopy()
1512 assert(rxDmaState
== dmaWriting
);
1514 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1515 rxDmaState
= dmaIdle
;
1517 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1518 rxDmaAddr
, rxDmaLen
);
1519 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1523 NSGigE::doRxDmaWrite()
1525 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1526 rxDmaState
= dmaWriting
;
1528 if (dmaInterface
&& !rxDmaFree
) {
1529 if (dmaInterface
->busy())
1530 rxDmaState
= dmaWriteWaiting
;
1532 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1533 &rxDmaWriteEvent
, true);
1537 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1542 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1543 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1544 rxDmaWriteEvent
.schedule(start
);
1549 NSGigE::rxDmaWriteDone()
1551 assert(rxDmaState
== dmaWriting
);
1554 // If the transmit state machine has a pending DMA, let it go first
1555 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1564 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1567 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1568 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1571 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1572 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1576 if (rxKickTick
> curTick
) {
1577 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1583 // Go to the next state machine clock tick.
1584 rxKickTick
= curTick
+ cycles(1);
1587 switch(rxDmaState
) {
1588 case dmaReadWaiting
:
1592 case dmaWriteWaiting
:
1600 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1601 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1603 // see state machine from spec for details
1604 // the way this works is, if you finish work on one state and can
1605 // go directly to another, you do that through jumping to the
1606 // label "next". however, if you have intermediate work, like DMA
1607 // so that you can't go to the next state yet, you go to exit and
1608 // exit the loop. however, when the DMA is done it will trigger
1609 // an event and come back to this loop.
1613 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1618 rxState
= rxDescRefr
;
1620 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1622 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1623 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1624 rxDmaFree
= dmaDescFree
;
1627 descDmaRdBytes
+= rxDmaLen
;
1632 rxState
= rxDescRead
;
1634 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1635 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1636 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1637 rxDmaFree
= dmaDescFree
;
1640 descDmaRdBytes
+= rxDmaLen
;
1648 if (rxDmaState
!= dmaIdle
)
1651 rxState
= rxAdvance
;
1655 if (rxDmaState
!= dmaIdle
)
1658 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1659 regs
.rxdp
& 0x3fffffff);
1660 DPRINTF(EthernetDesc
,
1661 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1662 link
, bufptr
, cmdsts
, extsts
);
1664 if (cmdsts
& CMDSTS_OWN
) {
1665 devIntrPost(ISR_RXIDLE
);
1669 rxState
= rxFifoBlock
;
1671 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1678 * @todo in reality, we should be able to start processing
1679 * the packet as it arrives, and not have to wait for the
1680 * full packet ot be in the receive fifo.
1685 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1687 // If we don't have a packet, grab a new one from the fifo.
1688 rxPacket
= rxFifo
.front();
1689 rxPktBytes
= rxPacket
->length
;
1690 rxPacketBufPtr
= rxPacket
->data
;
1693 if (DTRACE(Ethernet
)) {
1696 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1700 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1701 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1708 // sanity check - i think the driver behaves like this
1709 assert(rxDescCnt
>= rxPktBytes
);
1714 // dont' need the && rxDescCnt > 0 if driver sanity check
1716 if (rxPktBytes
> 0) {
1717 rxState
= rxFragWrite
;
1718 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1720 rxXferLen
= rxPktBytes
;
1722 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1723 rxDmaData
= rxPacketBufPtr
;
1724 rxDmaLen
= rxXferLen
;
1725 rxDmaFree
= dmaDataFree
;
1731 rxState
= rxDescWrite
;
1733 //if (rxPktBytes == 0) { /* packet is done */
1734 assert(rxPktBytes
== 0);
1735 DPRINTF(EthernetSM
, "done with receiving packet\n");
1737 cmdsts
|= CMDSTS_OWN
;
1738 cmdsts
&= ~CMDSTS_MORE
;
1739 cmdsts
|= CMDSTS_OK
;
1740 cmdsts
&= 0xffff0000;
1741 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1745 * all the driver uses these are for its own stats keeping
1746 * which we don't care about, aren't necessary for
1747 * functionality and doing this would just slow us down.
1748 * if they end up using this in a later version for
1749 * functional purposes, just undef
1751 if (rxFilterEnable
) {
1752 cmdsts
&= ~CMDSTS_DEST_MASK
;
1753 const EthAddr
&dst
= rxFifoFront()->dst();
1755 cmdsts
|= CMDSTS_DEST_SELF
;
1756 if (dst
->multicast())
1757 cmdsts
|= CMDSTS_DEST_MULTI
;
1758 if (dst
->broadcast())
1759 cmdsts
|= CMDSTS_DEST_MASK
;
1764 if (extstsEnable
&& ip
) {
1765 extsts
|= EXTSTS_IPPKT
;
1767 if (cksum(ip
) != 0) {
1768 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1769 extsts
|= EXTSTS_IPERR
;
1774 extsts
|= EXTSTS_TCPPKT
;
1776 if (cksum(tcp
) != 0) {
1777 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1778 extsts
|= EXTSTS_TCPERR
;
1782 extsts
|= EXTSTS_UDPPKT
;
1784 if (cksum(udp
) != 0) {
1785 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1786 extsts
|= EXTSTS_UDPERR
;
1793 * the driver seems to always receive into desc buffers
1794 * of size 1514, so you never have a pkt that is split
1795 * into multiple descriptors on the receive side, so
1796 * i don't implement that case, hence the assert above.
1799 DPRINTF(EthernetDesc
,
1800 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1801 regs
.rxdp
& 0x3fffffff);
1802 DPRINTF(EthernetDesc
,
1803 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1804 link
, bufptr
, cmdsts
, extsts
);
1806 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1807 rxDmaData
= &cmdsts
;
1809 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1810 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1812 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1813 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1815 rxDmaFree
= dmaDescFree
;
1818 descDmaWrBytes
+= rxDmaLen
;
1826 if (rxDmaState
!= dmaIdle
)
1829 rxPacketBufPtr
+= rxXferLen
;
1830 rxFragPtr
+= rxXferLen
;
1831 rxPktBytes
-= rxXferLen
;
1833 rxState
= rxFifoBlock
;
1837 if (rxDmaState
!= dmaIdle
)
1840 assert(cmdsts
& CMDSTS_OWN
);
1842 assert(rxPacket
== 0);
1843 devIntrPost(ISR_RXOK
);
1845 if (cmdsts
& CMDSTS_INTR
)
1846 devIntrPost(ISR_RXDESC
);
1849 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1853 rxState
= rxAdvance
;
1858 devIntrPost(ISR_RXIDLE
);
1863 if (rxDmaState
!= dmaIdle
)
1865 rxState
= rxDescRead
;
1869 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1870 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1871 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1872 rxDmaFree
= dmaDescFree
;
1880 panic("Invalid rxState!");
1883 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1884 NsRxStateStrings
[rxState
]);
1889 * @todo do we want to schedule a future kick?
1891 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1892 NsRxStateStrings
[rxState
]);
1894 if (clock
&& !rxKickEvent
.scheduled())
1895 rxKickEvent
.schedule(rxKickTick
);
1901 if (txFifo
.empty()) {
1902 DPRINTF(Ethernet
, "nothing to transmit\n");
1906 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1908 if (interface
->sendPacket(txFifo
.front())) {
1910 if (DTRACE(Ethernet
)) {
1911 IpPtr
ip(txFifo
.front());
1913 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1917 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1918 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1925 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1926 txBytes
+= txFifo
.front()->length
;
1929 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1934 * normally do a writeback of the descriptor here, and ONLY
1935 * after that is done, send this interrupt. but since our
1936 * stuff never actually fails, just do this interrupt here,
1937 * otherwise the code has to stray from this nice format.
1938 * besides, it's functionally the same.
1940 devIntrPost(ISR_TXOK
);
1943 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1944 DPRINTF(Ethernet
, "reschedule transmit\n");
1945 txEvent
.schedule(curTick
+ retryTime
);
1950 NSGigE::txDmaReadCopy()
1952 assert(txDmaState
== dmaReading
);
1954 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1955 txDmaState
= dmaIdle
;
1957 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1958 txDmaAddr
, txDmaLen
);
1959 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1963 NSGigE::doTxDmaRead()
1965 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1966 txDmaState
= dmaReading
;
1968 if (dmaInterface
&& !txDmaFree
) {
1969 if (dmaInterface
->busy())
1970 txDmaState
= dmaReadWaiting
;
1972 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1973 &txDmaReadEvent
, true);
1977 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1982 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1983 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1984 txDmaReadEvent
.schedule(start
);
1989 NSGigE::txDmaReadDone()
1991 assert(txDmaState
== dmaReading
);
1994 // If the receive state machine has a pending DMA, let it go first
1995 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2002 NSGigE::txDmaWriteCopy()
2004 assert(txDmaState
== dmaWriting
);
2006 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
2007 txDmaState
= dmaIdle
;
2009 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
2010 txDmaAddr
, txDmaLen
);
2011 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
2015 NSGigE::doTxDmaWrite()
2017 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
2018 txDmaState
= dmaWriting
;
2020 if (dmaInterface
&& !txDmaFree
) {
2021 if (dmaInterface
->busy())
2022 txDmaState
= dmaWriteWaiting
;
2024 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2025 &txDmaWriteEvent
, true);
2029 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2034 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2035 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2036 txDmaWriteEvent
.schedule(start
);
2041 NSGigE::txDmaWriteDone()
2043 assert(txDmaState
== dmaWriting
);
2046 // If the receive state machine has a pending DMA, let it go first
2047 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2056 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
2058 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
2059 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
2062 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
2063 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
2067 if (txKickTick
> curTick
) {
2068 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2073 // Go to the next state machine clock tick.
2074 txKickTick
= curTick
+ cycles(1);
2077 switch(txDmaState
) {
2078 case dmaReadWaiting
:
2082 case dmaWriteWaiting
:
2090 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
2091 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
2095 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2100 txState
= txDescRefr
;
2102 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2104 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
2105 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
2106 txDmaFree
= dmaDescFree
;
2109 descDmaRdBytes
+= txDmaLen
;
2115 txState
= txDescRead
;
2117 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2118 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2119 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2120 txDmaFree
= dmaDescFree
;
2123 descDmaRdBytes
+= txDmaLen
;
2131 if (txDmaState
!= dmaIdle
)
2134 txState
= txAdvance
;
2138 if (txDmaState
!= dmaIdle
)
2141 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
2142 regs
.txdp
& 0x3fffffff);
2143 DPRINTF(EthernetDesc
,
2144 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
2145 link
, bufptr
, cmdsts
, extsts
);
2147 if (cmdsts
& CMDSTS_OWN
) {
2148 txState
= txFifoBlock
;
2150 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
2152 devIntrPost(ISR_TXIDLE
);
2160 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2161 txPacket
= new PacketData(16384);
2162 txPacketBufPtr
= txPacket
->data
;
2165 if (txDescCnt
== 0) {
2166 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2167 if (cmdsts
& CMDSTS_MORE
) {
2168 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2169 txState
= txDescWrite
;
2171 cmdsts
&= ~CMDSTS_OWN
;
2173 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2174 txDmaData
= &cmdsts
;
2176 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2177 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2179 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2180 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2182 txDmaFree
= dmaDescFree
;
2187 } else { /* this packet is totally done */
2188 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2189 /* deal with the the packet that just finished */
2190 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2192 if (extsts
& EXTSTS_UDPPKT
) {
2195 udp
->sum(cksum(udp
));
2197 } else if (extsts
& EXTSTS_TCPPKT
) {
2200 tcp
->sum(cksum(tcp
));
2203 if (extsts
& EXTSTS_IPPKT
) {
2210 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2211 // this is just because the receive can't handle a
2212 // packet bigger want to make sure
2213 if (txPacket
->length
> 1514)
2214 panic("transmit packet too large, %s > 1514\n",
2220 txFifo
.push(txPacket
);
2224 * this following section is not tqo spec, but
2225 * functionally shouldn't be any different. normally,
2226 * the chip will wait til the transmit has occurred
2227 * before writing back the descriptor because it has
2228 * to wait to see that it was successfully transmitted
2229 * to decide whether to set CMDSTS_OK or not.
2230 * however, in the simulator since it is always
2231 * successfully transmitted, and writing it exactly to
2232 * spec would complicate the code, we just do it here
2235 cmdsts
&= ~CMDSTS_OWN
;
2236 cmdsts
|= CMDSTS_OK
;
2238 DPRINTF(EthernetDesc
,
2239 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2242 txDmaFree
= dmaDescFree
;
2243 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2244 txDmaData
= &cmdsts
;
2246 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2248 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2250 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2252 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2256 descDmaWrBytes
+= txDmaLen
;
2262 DPRINTF(EthernetSM
, "halting TX state machine\n");
2266 txState
= txAdvance
;
2272 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2273 if (!txFifo
.full()) {
2274 txState
= txFragRead
;
2277 * The number of bytes transferred is either whatever
2278 * is left in the descriptor (txDescCnt), or if there
2279 * is not enough room in the fifo, just whatever room
2280 * is left in the fifo
2282 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2284 txDmaAddr
= txFragPtr
& 0x3fffffff;
2285 txDmaData
= txPacketBufPtr
;
2286 txDmaLen
= txXferLen
;
2287 txDmaFree
= dmaDataFree
;
2292 txState
= txFifoBlock
;
2302 if (txDmaState
!= dmaIdle
)
2305 txPacketBufPtr
+= txXferLen
;
2306 txFragPtr
+= txXferLen
;
2307 txDescCnt
-= txXferLen
;
2308 txFifo
.reserve(txXferLen
);
2310 txState
= txFifoBlock
;
2314 if (txDmaState
!= dmaIdle
)
2317 if (cmdsts
& CMDSTS_INTR
)
2318 devIntrPost(ISR_TXDESC
);
2321 DPRINTF(EthernetSM
, "halting TX state machine\n");
2325 txState
= txAdvance
;
2330 devIntrPost(ISR_TXIDLE
);
2334 if (txDmaState
!= dmaIdle
)
2336 txState
= txDescRead
;
2340 txDmaAddr
= link
& 0x3fffffff;
2341 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2342 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2343 txDmaFree
= dmaDescFree
;
2351 panic("invalid state");
2354 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2355 NsTxStateStrings
[txState
]);
2360 * @todo do we want to schedule a future kick?
2362 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2363 NsTxStateStrings
[txState
]);
2365 if (clock
&& !txKickEvent
.scheduled())
2366 txKickEvent
.schedule(txKickTick
);
2370 * Advance the EEPROM state machine
2371 * Called on rising edge of EEPROM clock bit in MEAR
2374 NSGigE::eepromKick()
2376 switch (eepromState
) {
2380 // Wait for start bit
2381 if (regs
.mear
& MEAR_EEDI
) {
2382 // Set up to get 2 opcode bits
2383 eepromState
= eepromGetOpcode
;
2389 case eepromGetOpcode
:
2391 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2394 // Done getting opcode
2395 if (eepromBitsToRx
== 0) {
2396 if (eepromOpcode
!= EEPROM_READ
)
2397 panic("only EEPROM reads are implemented!");
2399 // Set up to get address
2400 eepromState
= eepromGetAddress
;
2406 case eepromGetAddress
:
2407 eepromAddress
<<= 1;
2408 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2411 // Done getting address
2412 if (eepromBitsToRx
== 0) {
2414 if (eepromAddress
>= EEPROM_SIZE
)
2415 panic("EEPROM read access out of range!");
2417 switch (eepromAddress
) {
2419 case EEPROM_PMATCH2_ADDR
:
2420 eepromData
= rom
.perfectMatch
[5];
2422 eepromData
+= rom
.perfectMatch
[4];
2425 case EEPROM_PMATCH1_ADDR
:
2426 eepromData
= rom
.perfectMatch
[3];
2428 eepromData
+= rom
.perfectMatch
[2];
2431 case EEPROM_PMATCH0_ADDR
:
2432 eepromData
= rom
.perfectMatch
[1];
2434 eepromData
+= rom
.perfectMatch
[0];
2438 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2440 // Set up to read data
2441 eepromState
= eepromRead
;
2442 eepromBitsToRx
= 16;
2444 // Clear data in bit
2445 regs
.mear
&= ~MEAR_EEDI
;
2450 // Clear Data Out bit
2451 regs
.mear
&= ~MEAR_EEDO
;
2452 // Set bit to value of current EEPROM bit
2453 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2459 if (eepromBitsToRx
== 0) {
2460 eepromState
= eepromStart
;
2465 panic("invalid EEPROM state");
2471 NSGigE::transferDone()
2473 if (txFifo
.empty()) {
2474 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2478 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2480 if (txEvent
.scheduled())
2481 txEvent
.reschedule(curTick
+ cycles(1));
2483 txEvent
.schedule(curTick
+ cycles(1));
2487 NSGigE::rxFilter(const PacketPtr
&packet
)
2489 EthPtr eth
= packet
;
2493 const EthAddr
&dst
= eth
->dst();
2494 if (dst
.unicast()) {
2495 // If we're accepting all unicast addresses
2499 // If we make a perfect match
2500 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2503 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2506 } else if (dst
.broadcast()) {
2507 // if we're accepting broadcasts
2508 if (acceptBroadcast
)
2511 } else if (dst
.multicast()) {
2512 // if we're accepting all multicasts
2513 if (acceptMulticast
)
2516 // Multicast hashing faked - all packets accepted
2517 if (multicastHashEnable
)
2522 DPRINTF(Ethernet
, "rxFilter drop\n");
2523 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2530 NSGigE::recvPacket(PacketPtr packet
)
2532 rxBytes
+= packet
->length
;
2535 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2539 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2543 if (!rxFilterEnable
) {
2545 "receive packet filtering disabled . . . packet dropped\n");
2549 if (rxFilter(packet
)) {
2550 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2554 if (rxFifo
.avail() < packet
->length
) {
2560 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2563 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2568 devIntrPost(ISR_RXORN
);
2572 rxFifo
.push(packet
);
2578 //=====================================================================
2582 NSGigE::serialize(ostream
&os
)
2584 // Serialize the PciDev base class
2585 PciDev::serialize(os
);
2588 * Finalize any DMA events now.
2590 if (rxDmaReadEvent
.scheduled())
2592 if (rxDmaWriteEvent
.scheduled())
2594 if (txDmaReadEvent
.scheduled())
2596 if (txDmaWriteEvent
.scheduled())
2600 * Serialize the device registers
2602 SERIALIZE_SCALAR(regs
.command
);
2603 SERIALIZE_SCALAR(regs
.config
);
2604 SERIALIZE_SCALAR(regs
.mear
);
2605 SERIALIZE_SCALAR(regs
.ptscr
);
2606 SERIALIZE_SCALAR(regs
.isr
);
2607 SERIALIZE_SCALAR(regs
.imr
);
2608 SERIALIZE_SCALAR(regs
.ier
);
2609 SERIALIZE_SCALAR(regs
.ihr
);
2610 SERIALIZE_SCALAR(regs
.txdp
);
2611 SERIALIZE_SCALAR(regs
.txdp_hi
);
2612 SERIALIZE_SCALAR(regs
.txcfg
);
2613 SERIALIZE_SCALAR(regs
.gpior
);
2614 SERIALIZE_SCALAR(regs
.rxdp
);
2615 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2616 SERIALIZE_SCALAR(regs
.rxcfg
);
2617 SERIALIZE_SCALAR(regs
.pqcr
);
2618 SERIALIZE_SCALAR(regs
.wcsr
);
2619 SERIALIZE_SCALAR(regs
.pcr
);
2620 SERIALIZE_SCALAR(regs
.rfcr
);
2621 SERIALIZE_SCALAR(regs
.rfdr
);
2622 SERIALIZE_SCALAR(regs
.brar
);
2623 SERIALIZE_SCALAR(regs
.brdr
);
2624 SERIALIZE_SCALAR(regs
.srr
);
2625 SERIALIZE_SCALAR(regs
.mibc
);
2626 SERIALIZE_SCALAR(regs
.vrcr
);
2627 SERIALIZE_SCALAR(regs
.vtcr
);
2628 SERIALIZE_SCALAR(regs
.vdr
);
2629 SERIALIZE_SCALAR(regs
.ccsr
);
2630 SERIALIZE_SCALAR(regs
.tbicr
);
2631 SERIALIZE_SCALAR(regs
.tbisr
);
2632 SERIALIZE_SCALAR(regs
.tanar
);
2633 SERIALIZE_SCALAR(regs
.tanlpar
);
2634 SERIALIZE_SCALAR(regs
.taner
);
2635 SERIALIZE_SCALAR(regs
.tesr
);
2637 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2638 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2640 SERIALIZE_SCALAR(ioEnable
);
2643 * Serialize the data Fifos
2645 rxFifo
.serialize("rxFifo", os
);
2646 txFifo
.serialize("txFifo", os
);
2649 * Serialize the various helper variables
2651 bool txPacketExists
= txPacket
;
2652 SERIALIZE_SCALAR(txPacketExists
);
2653 if (txPacketExists
) {
2654 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2655 txPacket
->serialize("txPacket", os
);
2656 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2657 SERIALIZE_SCALAR(txPktBufPtr
);
2660 bool rxPacketExists
= rxPacket
;
2661 SERIALIZE_SCALAR(rxPacketExists
);
2662 if (rxPacketExists
) {
2663 rxPacket
->serialize("rxPacket", os
);
2664 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2665 SERIALIZE_SCALAR(rxPktBufPtr
);
2668 SERIALIZE_SCALAR(txXferLen
);
2669 SERIALIZE_SCALAR(rxXferLen
);
2672 * Serialize Cached Descriptors
2674 SERIALIZE_SCALAR(rxDesc64
.link
);
2675 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2676 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2677 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2678 SERIALIZE_SCALAR(txDesc64
.link
);
2679 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2680 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2681 SERIALIZE_SCALAR(txDesc64
.extsts
);
2682 SERIALIZE_SCALAR(rxDesc32
.link
);
2683 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2684 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2685 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2686 SERIALIZE_SCALAR(txDesc32
.link
);
2687 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2688 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2689 SERIALIZE_SCALAR(txDesc32
.extsts
);
2690 SERIALIZE_SCALAR(extstsEnable
);
2693 * Serialize tx state machine
2695 int txState
= this->txState
;
2696 SERIALIZE_SCALAR(txState
);
2697 SERIALIZE_SCALAR(txEnable
);
2698 SERIALIZE_SCALAR(CTDD
);
2699 SERIALIZE_SCALAR(txFragPtr
);
2700 SERIALIZE_SCALAR(txDescCnt
);
2701 int txDmaState
= this->txDmaState
;
2702 SERIALIZE_SCALAR(txDmaState
);
2703 SERIALIZE_SCALAR(txKickTick
);
2706 * Serialize rx state machine
2708 int rxState
= this->rxState
;
2709 SERIALIZE_SCALAR(rxState
);
2710 SERIALIZE_SCALAR(rxEnable
);
2711 SERIALIZE_SCALAR(CRDD
);
2712 SERIALIZE_SCALAR(rxPktBytes
);
2713 SERIALIZE_SCALAR(rxFragPtr
);
2714 SERIALIZE_SCALAR(rxDescCnt
);
2715 int rxDmaState
= this->rxDmaState
;
2716 SERIALIZE_SCALAR(rxDmaState
);
2717 SERIALIZE_SCALAR(rxKickTick
);
2720 * Serialize EEPROM state machine
2722 int eepromState
= this->eepromState
;
2723 SERIALIZE_SCALAR(eepromState
);
2724 SERIALIZE_SCALAR(eepromClk
);
2725 SERIALIZE_SCALAR(eepromBitsToRx
);
2726 SERIALIZE_SCALAR(eepromOpcode
);
2727 SERIALIZE_SCALAR(eepromAddress
);
2728 SERIALIZE_SCALAR(eepromData
);
2731 * If there's a pending transmit, store the time so we can
2732 * reschedule it later
2734 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2735 SERIALIZE_SCALAR(transmitTick
);
2738 * receive address filter settings
2740 SERIALIZE_SCALAR(rxFilterEnable
);
2741 SERIALIZE_SCALAR(acceptBroadcast
);
2742 SERIALIZE_SCALAR(acceptMulticast
);
2743 SERIALIZE_SCALAR(acceptUnicast
);
2744 SERIALIZE_SCALAR(acceptPerfect
);
2745 SERIALIZE_SCALAR(acceptArp
);
2746 SERIALIZE_SCALAR(multicastHashEnable
);
2749 * Keep track of pending interrupt status.
2751 SERIALIZE_SCALAR(intrTick
);
2752 SERIALIZE_SCALAR(cpuPendingIntr
);
2753 Tick intrEventTick
= 0;
2755 intrEventTick
= intrEvent
->when();
2756 SERIALIZE_SCALAR(intrEventTick
);
2761 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2763 // Unserialize the PciDev base class
2764 PciDev::unserialize(cp
, section
);
2766 UNSERIALIZE_SCALAR(regs
.command
);
2767 UNSERIALIZE_SCALAR(regs
.config
);
2768 UNSERIALIZE_SCALAR(regs
.mear
);
2769 UNSERIALIZE_SCALAR(regs
.ptscr
);
2770 UNSERIALIZE_SCALAR(regs
.isr
);
2771 UNSERIALIZE_SCALAR(regs
.imr
);
2772 UNSERIALIZE_SCALAR(regs
.ier
);
2773 UNSERIALIZE_SCALAR(regs
.ihr
);
2774 UNSERIALIZE_SCALAR(regs
.txdp
);
2775 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2776 UNSERIALIZE_SCALAR(regs
.txcfg
);
2777 UNSERIALIZE_SCALAR(regs
.gpior
);
2778 UNSERIALIZE_SCALAR(regs
.rxdp
);
2779 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2780 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2781 UNSERIALIZE_SCALAR(regs
.pqcr
);
2782 UNSERIALIZE_SCALAR(regs
.wcsr
);
2783 UNSERIALIZE_SCALAR(regs
.pcr
);
2784 UNSERIALIZE_SCALAR(regs
.rfcr
);
2785 UNSERIALIZE_SCALAR(regs
.rfdr
);
2786 UNSERIALIZE_SCALAR(regs
.brar
);
2787 UNSERIALIZE_SCALAR(regs
.brdr
);
2788 UNSERIALIZE_SCALAR(regs
.srr
);
2789 UNSERIALIZE_SCALAR(regs
.mibc
);
2790 UNSERIALIZE_SCALAR(regs
.vrcr
);
2791 UNSERIALIZE_SCALAR(regs
.vtcr
);
2792 UNSERIALIZE_SCALAR(regs
.vdr
);
2793 UNSERIALIZE_SCALAR(regs
.ccsr
);
2794 UNSERIALIZE_SCALAR(regs
.tbicr
);
2795 UNSERIALIZE_SCALAR(regs
.tbisr
);
2796 UNSERIALIZE_SCALAR(regs
.tanar
);
2797 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2798 UNSERIALIZE_SCALAR(regs
.taner
);
2799 UNSERIALIZE_SCALAR(regs
.tesr
);
2801 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2802 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2804 UNSERIALIZE_SCALAR(ioEnable
);
2807 * unserialize the data fifos
2809 rxFifo
.unserialize("rxFifo", cp
, section
);
2810 txFifo
.unserialize("txFifo", cp
, section
);
2813 * unserialize the various helper variables
2815 bool txPacketExists
;
2816 UNSERIALIZE_SCALAR(txPacketExists
);
2817 if (txPacketExists
) {
2818 txPacket
= new PacketData(16384);
2819 txPacket
->unserialize("txPacket", cp
, section
);
2820 uint32_t txPktBufPtr
;
2821 UNSERIALIZE_SCALAR(txPktBufPtr
);
2822 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2826 bool rxPacketExists
;
2827 UNSERIALIZE_SCALAR(rxPacketExists
);
2829 if (rxPacketExists
) {
2830 rxPacket
= new PacketData(16384);
2831 rxPacket
->unserialize("rxPacket", cp
, section
);
2832 uint32_t rxPktBufPtr
;
2833 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2834 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2838 UNSERIALIZE_SCALAR(txXferLen
);
2839 UNSERIALIZE_SCALAR(rxXferLen
);
2842 * Unserialize Cached Descriptors
2844 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2845 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2846 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2847 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2848 UNSERIALIZE_SCALAR(txDesc64
.link
);
2849 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2850 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2851 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2852 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2853 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2854 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2855 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2856 UNSERIALIZE_SCALAR(txDesc32
.link
);
2857 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2858 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2859 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2860 UNSERIALIZE_SCALAR(extstsEnable
);
2863 * unserialize tx state machine
2866 UNSERIALIZE_SCALAR(txState
);
2867 this->txState
= (TxState
) txState
;
2868 UNSERIALIZE_SCALAR(txEnable
);
2869 UNSERIALIZE_SCALAR(CTDD
);
2870 UNSERIALIZE_SCALAR(txFragPtr
);
2871 UNSERIALIZE_SCALAR(txDescCnt
);
2873 UNSERIALIZE_SCALAR(txDmaState
);
2874 this->txDmaState
= (DmaState
) txDmaState
;
2875 UNSERIALIZE_SCALAR(txKickTick
);
2877 txKickEvent
.schedule(txKickTick
);
2880 * unserialize rx state machine
2883 UNSERIALIZE_SCALAR(rxState
);
2884 this->rxState
= (RxState
) rxState
;
2885 UNSERIALIZE_SCALAR(rxEnable
);
2886 UNSERIALIZE_SCALAR(CRDD
);
2887 UNSERIALIZE_SCALAR(rxPktBytes
);
2888 UNSERIALIZE_SCALAR(rxFragPtr
);
2889 UNSERIALIZE_SCALAR(rxDescCnt
);
2891 UNSERIALIZE_SCALAR(rxDmaState
);
2892 this->rxDmaState
= (DmaState
) rxDmaState
;
2893 UNSERIALIZE_SCALAR(rxKickTick
);
2895 rxKickEvent
.schedule(rxKickTick
);
2898 * Unserialize EEPROM state machine
2901 UNSERIALIZE_SCALAR(eepromState
);
2902 this->eepromState
= (EEPROMState
) eepromState
;
2903 UNSERIALIZE_SCALAR(eepromClk
);
2904 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2905 UNSERIALIZE_SCALAR(eepromOpcode
);
2906 UNSERIALIZE_SCALAR(eepromAddress
);
2907 UNSERIALIZE_SCALAR(eepromData
);
2910 * If there's a pending transmit, reschedule it now
2913 UNSERIALIZE_SCALAR(transmitTick
);
2915 txEvent
.schedule(curTick
+ transmitTick
);
2918 * unserialize receive address filter settings
2920 UNSERIALIZE_SCALAR(rxFilterEnable
);
2921 UNSERIALIZE_SCALAR(acceptBroadcast
);
2922 UNSERIALIZE_SCALAR(acceptMulticast
);
2923 UNSERIALIZE_SCALAR(acceptUnicast
);
2924 UNSERIALIZE_SCALAR(acceptPerfect
);
2925 UNSERIALIZE_SCALAR(acceptArp
);
2926 UNSERIALIZE_SCALAR(multicastHashEnable
);
2929 * Keep track of pending interrupt status.
2931 UNSERIALIZE_SCALAR(intrTick
);
2932 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2934 UNSERIALIZE_SCALAR(intrEventTick
);
2935 if (intrEventTick
) {
2936 intrEvent
= new IntrEvent(this, true);
2937 intrEvent
->schedule(intrEventTick
);
2941 * re-add addrRanges to bus bridges
2944 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2945 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2950 NSGigE::cacheAccess(MemReqPtr
&req
)
2952 Addr daddr
= req
->paddr
& 0xfff;
2953 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2956 if (!pioDelayWrite
|| !req
->cmd
.isWrite())
2957 return curTick
+ pioLatency
;
2959 int cpu
= (req
->xc
->regs
.ipr
[TheISA::IPR_PALtemp16
] >> 8) & 0xff;
2960 std::list
<RegWriteData
> &wq
= writeQueue
[cpu
];
2962 panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu
, daddr
);
2964 const RegWriteData
&data
= wq
.front();
2965 if (data
.daddr
!= daddr
)
2966 panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x",
2967 cpu
, data
.daddr
, daddr
);
2970 if ((data
.value
& (CR_TXD
| CR_TXE
)) == CR_TXE
) {
2972 if (txState
== txIdle
)
2976 if ((data
.value
& (CR_RXD
| CR_RXE
)) == CR_RXE
) {
2978 if (rxState
== rxIdle
)
2984 return curTick
+ pioLatency
;
2987 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2989 SimObjectParam
<EtherInt
*> peer
;
2990 SimObjectParam
<NSGigE
*> device
;
2992 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2994 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2996 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2997 INIT_PARAM(device
, "Ethernet device of this interface")
2999 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
3001 CREATE_SIM_OBJECT(NSGigEInt
)
3003 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
3005 EtherInt
*p
= (EtherInt
*)peer
;
3007 dev_int
->setPeer(p
);
3008 p
->setPeer(dev_int
);
3014 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
3017 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3022 SimObjectParam
<MemoryController
*> mmu
;
3023 SimObjectParam
<PhysicalMemory
*> physmem
;
3024 SimObjectParam
<PciConfigAll
*> configspace
;
3025 SimObjectParam
<PciConfigData
*> configdata
;
3026 SimObjectParam
<Platform
*> platform
;
3027 Param
<uint32_t> pci_bus
;
3028 Param
<uint32_t> pci_dev
;
3029 Param
<uint32_t> pci_func
;
3031 SimObjectParam
<HierParams
*> hier
;
3032 SimObjectParam
<Bus
*> pio_bus
;
3033 SimObjectParam
<Bus
*> dma_bus
;
3034 SimObjectParam
<Bus
*> payload_bus
;
3035 Param
<bool> dma_desc_free
;
3036 Param
<bool> dma_data_free
;
3037 Param
<Tick
> dma_read_delay
;
3038 Param
<Tick
> dma_write_delay
;
3039 Param
<Tick
> dma_read_factor
;
3040 Param
<Tick
> dma_write_factor
;
3041 Param
<bool> dma_no_allocate
;
3042 Param
<Tick
> pio_latency
;
3043 Param
<bool> pio_delay_write
;
3044 Param
<Tick
> intr_delay
;
3046 Param
<Tick
> rx_delay
;
3047 Param
<Tick
> tx_delay
;
3048 Param
<uint32_t> rx_fifo_size
;
3049 Param
<uint32_t> tx_fifo_size
;
3051 Param
<bool> rx_filter
;
3052 Param
<string
> hardware_address
;
3053 Param
<bool> rx_thread
;
3054 Param
<bool> tx_thread
;
3056 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3058 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3060 INIT_PARAM(clock
, "State machine processor frequency"),
3062 INIT_PARAM(addr
, "Device Address"),
3063 INIT_PARAM(mmu
, "Memory Controller"),
3064 INIT_PARAM(physmem
, "Physical Memory"),
3065 INIT_PARAM(configspace
, "PCI Configspace"),
3066 INIT_PARAM(configdata
, "PCI Config data"),
3067 INIT_PARAM(platform
, "Platform"),
3068 INIT_PARAM(pci_bus
, "PCI bus"),
3069 INIT_PARAM(pci_dev
, "PCI device number"),
3070 INIT_PARAM(pci_func
, "PCI function code"),
3072 INIT_PARAM(hier
, "Hierarchy global variables"),
3073 INIT_PARAM(pio_bus
, ""),
3074 INIT_PARAM(dma_bus
, ""),
3075 INIT_PARAM(payload_bus
, "The IO Bus to attach to for payload"),
3076 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
3077 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
3078 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
3079 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
3080 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
3081 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
3082 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
3083 INIT_PARAM(pio_latency
, "Programmed IO latency in bus cycles"),
3084 INIT_PARAM(pio_delay_write
, ""),
3085 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
3087 INIT_PARAM(rx_delay
, "Receive Delay"),
3088 INIT_PARAM(tx_delay
, "Transmit Delay"),
3089 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
3090 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
3092 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
3093 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
3094 INIT_PARAM(rx_thread
, ""),
3095 INIT_PARAM(tx_thread
, "")
3097 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3100 CREATE_SIM_OBJECT(NSGigE
)
3102 NSGigE::Params
*params
= new NSGigE::Params
;
3104 params
->name
= getInstanceName();
3106 params
->clock
= clock
;
3109 params
->pmem
= physmem
;
3110 params
->configSpace
= configspace
;
3111 params
->configData
= configdata
;
3112 params
->plat
= platform
;
3113 params
->busNum
= pci_bus
;
3114 params
->deviceNum
= pci_dev
;
3115 params
->functionNum
= pci_func
;
3117 params
->hier
= hier
;
3118 params
->pio_bus
= pio_bus
;
3119 params
->header_bus
= dma_bus
;
3120 params
->payload_bus
= payload_bus
;
3121 params
->dma_desc_free
= dma_desc_free
;
3122 params
->dma_data_free
= dma_data_free
;
3123 params
->dma_read_delay
= dma_read_delay
;
3124 params
->dma_write_delay
= dma_write_delay
;
3125 params
->dma_read_factor
= dma_read_factor
;
3126 params
->dma_write_factor
= dma_write_factor
;
3127 params
->dma_no_allocate
= dma_no_allocate
;
3128 params
->pio_latency
= pio_latency
;
3129 params
->pio_delay_write
= pio_delay_write
;
3130 params
->intr_delay
= intr_delay
;
3132 params
->rx_delay
= rx_delay
;
3133 params
->tx_delay
= tx_delay
;
3134 params
->rx_fifo_size
= rx_fifo_size
;
3135 params
->tx_fifo_size
= tx_fifo_size
;
3137 params
->rx_filter
= rx_filter
;
3138 params
->eaddr
= hardware_address
;
3139 params
->rx_thread
= rx_thread
;
3140 params
->tx_thread
= tx_thread
;
3142 return new NSGigE(params
);
3145 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)