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 intrDelay
= p
->intr_delay
;
135 dmaReadDelay
= p
->dma_read_delay
;
136 dmaWriteDelay
= p
->dma_write_delay
;
137 dmaReadFactor
= p
->dma_read_factor
;
138 dmaWriteFactor
= p
->dma_write_factor
;
141 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
143 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
144 memset(&txDesc32
, 0, sizeof(txDesc32
));
145 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
146 memset(&txDesc64
, 0, sizeof(txDesc64
));
156 .name(name() + ".txBytes")
157 .desc("Bytes Transmitted")
162 .name(name() + ".rxBytes")
163 .desc("Bytes Received")
168 .name(name() + ".txPackets")
169 .desc("Number of Packets Transmitted")
174 .name(name() + ".rxPackets")
175 .desc("Number of Packets Received")
180 .name(name() + ".txIpChecksums")
181 .desc("Number of tx IP Checksums done by device")
187 .name(name() + ".rxIpChecksums")
188 .desc("Number of rx IP Checksums done by device")
194 .name(name() + ".txTcpChecksums")
195 .desc("Number of tx TCP Checksums done by device")
201 .name(name() + ".rxTcpChecksums")
202 .desc("Number of rx TCP Checksums done by device")
208 .name(name() + ".txUdpChecksums")
209 .desc("Number of tx UDP Checksums done by device")
215 .name(name() + ".rxUdpChecksums")
216 .desc("Number of rx UDP Checksums done by device")
222 .name(name() + ".descDMAReads")
223 .desc("Number of descriptors the device read w/ DMA")
228 .name(name() + ".descDMAWrites")
229 .desc("Number of descriptors the device wrote w/ DMA")
234 .name(name() + ".descDmaReadBytes")
235 .desc("number of descriptor bytes read w/ DMA")
240 .name(name() + ".descDmaWriteBytes")
241 .desc("number of descriptor bytes write w/ DMA")
246 .name(name() + ".txBandwidth")
247 .desc("Transmit Bandwidth (bits/s)")
253 .name(name() + ".rxBandwidth")
254 .desc("Receive Bandwidth (bits/s)")
260 .name(name() + ".totBandwidth")
261 .desc("Total Bandwidth (bits/s)")
267 .name(name() + ".totPackets")
268 .desc("Total Packets")
274 .name(name() + ".totBytes")
281 .name(name() + ".totPPS")
282 .desc("Total Tranmission Rate (packets/s)")
288 .name(name() + ".txPPS")
289 .desc("Packet Tranmission Rate (packets/s)")
295 .name(name() + ".rxPPS")
296 .desc("Packet Reception Rate (packets/s)")
302 .name(name() + ".postedSwi")
303 .desc("number of software interrupts posted to CPU")
308 .name(name() + ".totalSwi")
309 .desc("total number of Swi written to ISR")
314 .name(name() + ".coalescedSwi")
315 .desc("average number of Swi's coalesced into each post")
320 .name(name() + ".postedRxIdle")
321 .desc("number of rxIdle interrupts posted to CPU")
326 .name(name() + ".totalRxIdle")
327 .desc("total number of RxIdle written to ISR")
332 .name(name() + ".coalescedRxIdle")
333 .desc("average number of RxIdle's coalesced into each post")
338 .name(name() + ".postedRxOk")
339 .desc("number of RxOk interrupts posted to CPU")
344 .name(name() + ".totalRxOk")
345 .desc("total number of RxOk written to ISR")
350 .name(name() + ".coalescedRxOk")
351 .desc("average number of RxOk's coalesced into each post")
356 .name(name() + ".postedRxDesc")
357 .desc("number of RxDesc interrupts posted to CPU")
362 .name(name() + ".totalRxDesc")
363 .desc("total number of RxDesc written to ISR")
368 .name(name() + ".coalescedRxDesc")
369 .desc("average number of RxDesc's coalesced into each post")
374 .name(name() + ".postedTxOk")
375 .desc("number of TxOk interrupts posted to CPU")
380 .name(name() + ".totalTxOk")
381 .desc("total number of TxOk written to ISR")
386 .name(name() + ".coalescedTxOk")
387 .desc("average number of TxOk's coalesced into each post")
392 .name(name() + ".postedTxIdle")
393 .desc("number of TxIdle interrupts posted to CPU")
398 .name(name() + ".totalTxIdle")
399 .desc("total number of TxIdle written to ISR")
404 .name(name() + ".coalescedTxIdle")
405 .desc("average number of TxIdle's coalesced into each post")
410 .name(name() + ".postedTxDesc")
411 .desc("number of TxDesc interrupts posted to CPU")
416 .name(name() + ".totalTxDesc")
417 .desc("total number of TxDesc written to ISR")
422 .name(name() + ".coalescedTxDesc")
423 .desc("average number of TxDesc's coalesced into each post")
428 .name(name() + ".postedRxOrn")
429 .desc("number of RxOrn posted to CPU")
434 .name(name() + ".totalRxOrn")
435 .desc("total number of RxOrn written to ISR")
440 .name(name() + ".coalescedRxOrn")
441 .desc("average number of RxOrn's coalesced into each post")
446 .name(name() + ".coalescedTotal")
447 .desc("average number of interrupts coalesced into each post")
452 .name(name() + ".postedInterrupts")
453 .desc("number of posts to CPU")
458 .name(name() + ".droppedPackets")
459 .desc("number of packets dropped")
463 coalescedSwi
= totalSwi
/ postedInterrupts
;
464 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
465 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
466 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
467 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
468 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
469 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
470 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
472 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
473 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
474 totalRxOrn
) / postedInterrupts
;
476 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
477 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
478 totBandwidth
= txBandwidth
+ rxBandwidth
;
479 totBytes
= txBytes
+ rxBytes
;
480 totPackets
= txPackets
+ rxPackets
;
482 txPacketRate
= txPackets
/ simSeconds
;
483 rxPacketRate
= rxPackets
/ simSeconds
;
487 * This is to read the PCI general configuration registers
490 NSGigE::readConfig(int offset
, int size
, uint8_t *data
)
492 if (offset
< PCI_DEVICE_SPECIFIC
)
493 PciDev::readConfig(offset
, size
, data
);
495 panic("Device specific PCI config space not implemented!\n");
499 * This is to write to the PCI general configuration registers
502 NSGigE::writeConfig(int offset
, int size
, const uint8_t* data
)
504 if (offset
< PCI_DEVICE_SPECIFIC
)
505 PciDev::writeConfig(offset
, size
, data
);
507 panic("Device specific PCI config space not implemented!\n");
509 // Need to catch writes to BARs to update the PIO interface
511 // seems to work fine without all these PCI settings, but i
512 // put in the IO to double check, an assertion will fail if we
513 // need to properly implement it
515 if (config
.data
[offset
] & PCI_CMD_IOSE
)
521 if (config
.data
[offset
] & PCI_CMD_BME
) {
528 if (config
.data
[offset
] & PCI_CMD_MSE
) {
537 case PCI0_BASE_ADDR0
:
538 if (BARAddrs
[0] != 0) {
540 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
542 BARAddrs
[0] &= EV5::PAddrUncachedMask
;
545 case PCI0_BASE_ADDR1
:
546 if (BARAddrs
[1] != 0) {
548 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
550 BARAddrs
[1] &= EV5::PAddrUncachedMask
;
557 * This reads the device registers, which are detailed in the NS83820
561 NSGigE::read(MemReqPtr
&req
, uint8_t *data
)
565 //The mask is to give you only the offset into the device register file
566 Addr daddr
= req
->paddr
& 0xfff;
567 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x va=%#x size=%d\n",
568 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
571 // there are some reserved registers, you can see ns_gige_reg.h and
572 // the spec sheet for details
573 if (daddr
> LAST
&& daddr
<= RESERVED
) {
574 panic("Accessing reserved register");
575 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
576 readConfig(daddr
& 0xff, req
->size
, data
);
578 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
579 // don't implement all the MIB's. hopefully the kernel
580 // doesn't actually DEPEND upon their values
581 // MIB are just hardware stats keepers
582 uint32_t ®
= *(uint32_t *) data
;
585 } else if (daddr
> 0x3FC)
586 panic("Something is messed up!\n");
589 case sizeof(uint32_t):
591 uint32_t ®
= *(uint32_t *)data
;
597 //these are supposed to be cleared on a read
598 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
615 devIntrClear(ISR_ALL
);
670 // see the spec sheet for how RFCR and RFDR work
671 // basically, you write to RFCR to tell the machine
672 // what you want to do next, then you act upon RFDR,
673 // and the device will be prepared b/c of what you
680 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
682 // Read from perfect match ROM octets
684 reg
= rom
.perfectMatch
[1];
686 reg
+= rom
.perfectMatch
[0];
689 reg
= rom
.perfectMatch
[3] << 8;
690 reg
+= rom
.perfectMatch
[2];
693 reg
= rom
.perfectMatch
[5] << 8;
694 reg
+= rom
.perfectMatch
[4];
697 // Read filter hash table
698 if (rfaddr
>= FHASH_ADDR
&&
699 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
701 // Only word-aligned reads supported
703 panic("unaligned read from filter hash table!");
705 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
706 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
710 panic("reading RFDR for something other than pattern"
711 " matching or hashing! %#x\n", rfaddr
);
721 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
766 if (params()->rx_thread
)
767 reg
|= M5REG_RX_THREAD
;
768 if (params()->tx_thread
)
769 reg
|= M5REG_TX_THREAD
;
773 panic("reading unimplemented register: addr=%#x", daddr
);
776 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
782 panic("accessing register with invalid size: addr=%#x, size=%d",
790 NSGigE::write(MemReqPtr
&req
, const uint8_t *data
)
794 Addr daddr
= req
->paddr
& 0xfff;
795 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x va=%#x size=%d\n",
796 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
798 if (daddr
> LAST
&& daddr
<= RESERVED
) {
799 panic("Accessing reserved register");
800 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
801 writeConfig(daddr
& 0xff, req
->size
, data
);
803 } else if (daddr
> 0x3FC)
804 panic("Something is messed up!\n");
806 if (req
->size
== sizeof(uint32_t)) {
807 uint32_t reg
= *(uint32_t *)data
;
810 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
817 } else if (reg
& CR_TXE
) {
820 // the kernel is enabling the transmit machine
821 if (txState
== txIdle
)
827 } else if (reg
& CR_RXE
) {
830 if (rxState
== rxIdle
)
841 devIntrPost(ISR_SWI
);
852 if (reg
& CFGR_LNKSTS
||
855 reg
& CFGR_RESERVED
||
856 reg
& CFGR_T64ADDR
||
857 reg
& CFGR_PCI64_DET
)
859 // First clear all writable bits
860 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
861 CFGR_RESERVED
| CFGR_T64ADDR
|
863 // Now set the appropriate writable bits
864 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
865 CFGR_RESERVED
| CFGR_T64ADDR
|
868 // all these #if 0's are because i don't THINK the kernel needs to
869 // have these implemented. if there is a problem relating to one of
870 // these, you may need to add functionality in.
871 if (reg
& CFGR_TBI_EN
) ;
872 if (reg
& CFGR_MODE_1000
) ;
874 if (reg
& CFGR_AUTO_1000
)
875 panic("CFGR_AUTO_1000 not implemented!\n");
877 if (reg
& CFGR_PINT_DUPSTS
||
878 reg
& CFGR_PINT_LNKSTS
||
879 reg
& CFGR_PINT_SPDSTS
)
882 if (reg
& CFGR_TMRTEST
) ;
883 if (reg
& CFGR_MRM_DIS
) ;
884 if (reg
& CFGR_MWI_DIS
) ;
886 if (reg
& CFGR_T64ADDR
) ;
887 // panic("CFGR_T64ADDR is read only register!\n");
889 if (reg
& CFGR_PCI64_DET
)
890 panic("CFGR_PCI64_DET is read only register!\n");
892 if (reg
& CFGR_DATA64_EN
) ;
893 if (reg
& CFGR_M64ADDR
) ;
894 if (reg
& CFGR_PHY_RST
) ;
895 if (reg
& CFGR_PHY_DIS
) ;
897 if (reg
& CFGR_EXTSTS_EN
)
900 extstsEnable
= false;
902 if (reg
& CFGR_REQALG
) ;
904 if (reg
& CFGR_POW
) ;
905 if (reg
& CFGR_EXD
) ;
906 if (reg
& CFGR_PESEL
) ;
907 if (reg
& CFGR_BROM_DIS
) ;
908 if (reg
& CFGR_EXT_125
) ;
909 if (reg
& CFGR_BEM
) ;
913 // Clear writable bits
914 regs
.mear
&= MEAR_EEDO
;
915 // Set appropriate writable bits
916 regs
.mear
|= reg
& ~MEAR_EEDO
;
918 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
919 // even though it could get it through RFDR
920 if (reg
& MEAR_EESEL
) {
921 // Rising edge of clock
922 if (reg
& MEAR_EECLK
&& !eepromClk
)
926 eepromState
= eepromStart
;
927 regs
.mear
&= ~MEAR_EEDI
;
930 eepromClk
= reg
& MEAR_EECLK
;
932 // since phy is completely faked, MEAR_MD* don't matter
933 if (reg
& MEAR_MDIO
) ;
934 if (reg
& MEAR_MDDIR
) ;
935 if (reg
& MEAR_MDC
) ;
939 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
940 // these control BISTs for various parts of chip - we
941 // don't care or do just fake that the BIST is done
942 if (reg
& PTSCR_RBIST_EN
)
943 regs
.ptscr
|= PTSCR_RBIST_DONE
;
944 if (reg
& PTSCR_EEBIST_EN
)
945 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
946 if (reg
& PTSCR_EELOAD_EN
)
947 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
950 case ISR
: /* writing to the ISR has no effect */
951 panic("ISR is a read only register!\n");
964 /* not going to implement real interrupt holdoff */
968 regs
.txdp
= (reg
& 0xFFFFFFFC);
969 assert(txState
== txIdle
);
980 if (reg
& TX_CFG_CSI
) ;
981 if (reg
& TX_CFG_HBI
) ;
982 if (reg
& TX_CFG_MLB
) ;
983 if (reg
& TX_CFG_ATP
) ;
984 if (reg
& TX_CFG_ECRETRY
) {
986 * this could easily be implemented, but considering
987 * the network is just a fake pipe, wouldn't make
992 if (reg
& TX_CFG_BRST_DIS
) ;
996 /* we handle our own DMA, ignore the kernel's exhortations */
997 if (reg
& TX_CFG_MXDMA
) ;
1000 // also, we currently don't care about fill/drain
1001 // thresholds though this may change in the future with
1002 // more realistic networks or a driver which changes it
1003 // according to feedback
1008 // Only write writable bits
1009 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1010 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1011 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1012 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1013 /* these just control general purpose i/o pins, don't matter */
1028 if (reg
& RX_CFG_AEP
) ;
1029 if (reg
& RX_CFG_ARP
) ;
1030 if (reg
& RX_CFG_STRIPCRC
) ;
1031 if (reg
& RX_CFG_RX_RD
) ;
1032 if (reg
& RX_CFG_ALP
) ;
1033 if (reg
& RX_CFG_AIRL
) ;
1035 /* we handle our own DMA, ignore what kernel says about it */
1036 if (reg
& RX_CFG_MXDMA
) ;
1038 //also, we currently don't care about fill/drain thresholds
1039 //though this may change in the future with more realistic
1040 //networks or a driver which changes it according to feedback
1041 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1046 /* there is no priority queueing used in the linux 2.6 driver */
1051 /* not going to implement wake on LAN */
1056 /* not going to implement pause control */
1063 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1064 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1065 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1066 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1067 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1068 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1069 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1072 if (reg
& RFCR_APAT
)
1073 panic("RFCR_APAT not implemented!\n");
1075 if (reg
& RFCR_UHEN
)
1076 panic("Unicast hash filtering not used by drivers!\n");
1079 panic("RFCR_ULM not implemented!\n");
1084 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1087 rom
.perfectMatch
[0] = (uint8_t)reg
;
1088 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1091 rom
.perfectMatch
[2] = (uint8_t)reg
;
1092 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1095 rom
.perfectMatch
[4] = (uint8_t)reg
;
1096 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1100 if (rfaddr
>= FHASH_ADDR
&&
1101 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1103 // Only word-aligned writes supported
1105 panic("unaligned write to filter hash table!");
1107 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1108 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1109 = (uint8_t)(reg
>> 8);
1112 panic("writing RFDR for something other than pattern matching\
1113 or hashing! %#x\n", rfaddr
);
1121 panic("the driver never uses BRDR, something is wrong!\n");
1124 panic("SRR is read only register!\n");
1127 panic("the driver never uses MIBC, something is wrong!\n");
1138 panic("the driver never uses VDR, something is wrong!\n");
1141 /* not going to implement clockrun stuff */
1147 if (reg
& TBICR_MR_LOOPBACK
)
1148 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1150 if (reg
& TBICR_MR_AN_ENABLE
) {
1151 regs
.tanlpar
= regs
.tanar
;
1152 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1156 if (reg
& TBICR_MR_RESTART_AN
) ;
1162 panic("TBISR is read only register!\n");
1165 // Only write the writable bits
1166 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1167 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1169 // Pause capability unimplemented
1171 if (reg
& TANAR_PS2
) ;
1172 if (reg
& TANAR_PS1
) ;
1178 panic("this should only be written to by the fake phy!\n");
1181 panic("TANER is read only register!\n");
1188 panic("invalid register access daddr=%#x", daddr
);
1191 panic("Invalid Request Size");
1198 NSGigE::devIntrPost(uint32_t interrupts
)
1200 if (interrupts
& ISR_RESERVE
)
1201 panic("Cannot set a reserved interrupt");
1203 if (interrupts
& ISR_NOIMPL
)
1204 warn("interrupt not implemented %#x\n", interrupts
);
1206 interrupts
&= ISR_IMPL
;
1207 regs
.isr
|= interrupts
;
1209 if (interrupts
& regs
.imr
) {
1210 if (interrupts
& ISR_SWI
) {
1213 if (interrupts
& ISR_RXIDLE
) {
1216 if (interrupts
& ISR_RXOK
) {
1219 if (interrupts
& ISR_RXDESC
) {
1222 if (interrupts
& ISR_TXOK
) {
1225 if (interrupts
& ISR_TXIDLE
) {
1228 if (interrupts
& ISR_TXDESC
) {
1231 if (interrupts
& ISR_RXORN
) {
1236 DPRINTF(EthernetIntr
,
1237 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1238 interrupts
, regs
.isr
, regs
.imr
);
1240 if ((regs
.isr
& regs
.imr
)) {
1241 Tick when
= curTick
;
1242 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1248 /* writing this interrupt counting stats inside this means that this function
1249 is now limited to being used to clear all interrupts upon the kernel
1250 reading isr and servicing. just telling you in case you were thinking
1254 NSGigE::devIntrClear(uint32_t interrupts
)
1256 if (interrupts
& ISR_RESERVE
)
1257 panic("Cannot clear a reserved interrupt");
1259 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1262 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1265 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1268 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1271 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1274 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1277 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1280 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1284 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1287 interrupts
&= ~ISR_NOIMPL
;
1288 regs
.isr
&= ~interrupts
;
1290 DPRINTF(EthernetIntr
,
1291 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1292 interrupts
, regs
.isr
, regs
.imr
);
1294 if (!(regs
.isr
& regs
.imr
))
1299 NSGigE::devIntrChangeMask()
1301 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1302 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1304 if (regs
.isr
& regs
.imr
)
1305 cpuIntrPost(curTick
);
1311 NSGigE::cpuIntrPost(Tick when
)
1313 // If the interrupt you want to post is later than an interrupt
1314 // already scheduled, just let it post in the coming one and don't
1315 // schedule another.
1316 // HOWEVER, must be sure that the scheduled intrTick is in the
1317 // future (this was formerly the source of a bug)
1319 * @todo this warning should be removed and the intrTick code should
1322 assert(when
>= curTick
);
1323 assert(intrTick
>= curTick
|| intrTick
== 0);
1324 if (when
> intrTick
&& intrTick
!= 0) {
1325 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1331 if (intrTick
< curTick
) {
1336 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1340 intrEvent
->squash();
1341 intrEvent
= new IntrEvent(this, true);
1342 intrEvent
->schedule(intrTick
);
1346 NSGigE::cpuInterrupt()
1348 assert(intrTick
== curTick
);
1350 // Whether or not there's a pending interrupt, we don't care about
1355 // Don't send an interrupt if there's already one
1356 if (cpuPendingIntr
) {
1357 DPRINTF(EthernetIntr
,
1358 "would send an interrupt now, but there's already pending\n");
1361 cpuPendingIntr
= true;
1363 DPRINTF(EthernetIntr
, "posting interrupt\n");
1369 NSGigE::cpuIntrClear()
1371 if (!cpuPendingIntr
)
1375 intrEvent
->squash();
1381 cpuPendingIntr
= false;
1383 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1388 NSGigE::cpuIntrPending() const
1389 { return cpuPendingIntr
; }
1395 DPRINTF(Ethernet
, "transmit reset\n");
1400 assert(txDescCnt
== 0);
1403 assert(txDmaState
== dmaIdle
);
1409 DPRINTF(Ethernet
, "receive reset\n");
1412 assert(rxPktBytes
== 0);
1415 assert(rxDescCnt
== 0);
1416 assert(rxDmaState
== dmaIdle
);
1424 memset(®s
, 0, sizeof(regs
));
1425 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1427 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1428 // fill threshold to 32 bytes
1429 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1430 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1431 regs
.mibc
= MIBC_FRZ
;
1432 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1433 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1434 regs
.brar
= 0xffffffff;
1436 extstsEnable
= false;
1437 acceptBroadcast
= false;
1438 acceptMulticast
= false;
1439 acceptUnicast
= false;
1440 acceptPerfect
= false;
1445 NSGigE::rxDmaReadCopy()
1447 assert(rxDmaState
== dmaReading
);
1449 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1450 rxDmaState
= dmaIdle
;
1452 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1453 rxDmaAddr
, rxDmaLen
);
1454 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1458 NSGigE::doRxDmaRead()
1460 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1461 rxDmaState
= dmaReading
;
1463 if (dmaInterface
&& !rxDmaFree
) {
1464 if (dmaInterface
->busy())
1465 rxDmaState
= dmaReadWaiting
;
1467 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1468 &rxDmaReadEvent
, true);
1472 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1477 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1478 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1479 rxDmaReadEvent
.schedule(start
);
1484 NSGigE::rxDmaReadDone()
1486 assert(rxDmaState
== dmaReading
);
1489 // If the transmit state machine has a pending DMA, let it go first
1490 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1497 NSGigE::rxDmaWriteCopy()
1499 assert(rxDmaState
== dmaWriting
);
1501 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1502 rxDmaState
= dmaIdle
;
1504 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1505 rxDmaAddr
, rxDmaLen
);
1506 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1510 NSGigE::doRxDmaWrite()
1512 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1513 rxDmaState
= dmaWriting
;
1515 if (dmaInterface
&& !rxDmaFree
) {
1516 if (dmaInterface
->busy())
1517 rxDmaState
= dmaWriteWaiting
;
1519 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1520 &rxDmaWriteEvent
, true);
1524 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1529 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1530 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1531 rxDmaWriteEvent
.schedule(start
);
1536 NSGigE::rxDmaWriteDone()
1538 assert(rxDmaState
== dmaWriting
);
1541 // If the transmit state machine has a pending DMA, let it go first
1542 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1551 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1554 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1555 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1558 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1559 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1563 if (rxKickTick
> curTick
) {
1564 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1570 // Go to the next state machine clock tick.
1571 rxKickTick
= curTick
+ cycles(1);
1574 switch(rxDmaState
) {
1575 case dmaReadWaiting
:
1579 case dmaWriteWaiting
:
1587 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1588 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1590 // see state machine from spec for details
1591 // the way this works is, if you finish work on one state and can
1592 // go directly to another, you do that through jumping to the
1593 // label "next". however, if you have intermediate work, like DMA
1594 // so that you can't go to the next state yet, you go to exit and
1595 // exit the loop. however, when the DMA is done it will trigger
1596 // an event and come back to this loop.
1600 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1605 rxState
= rxDescRefr
;
1607 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1609 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1610 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1611 rxDmaFree
= dmaDescFree
;
1614 descDmaRdBytes
+= rxDmaLen
;
1619 rxState
= rxDescRead
;
1621 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1622 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1623 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1624 rxDmaFree
= dmaDescFree
;
1627 descDmaRdBytes
+= rxDmaLen
;
1635 if (rxDmaState
!= dmaIdle
)
1638 rxState
= rxAdvance
;
1642 if (rxDmaState
!= dmaIdle
)
1645 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1646 regs
.rxdp
& 0x3fffffff);
1647 DPRINTF(EthernetDesc
,
1648 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1649 link
, bufptr
, cmdsts
, extsts
);
1651 if (cmdsts
& CMDSTS_OWN
) {
1652 devIntrPost(ISR_RXIDLE
);
1656 rxState
= rxFifoBlock
;
1658 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1665 * @todo in reality, we should be able to start processing
1666 * the packet as it arrives, and not have to wait for the
1667 * full packet ot be in the receive fifo.
1672 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1674 // If we don't have a packet, grab a new one from the fifo.
1675 rxPacket
= rxFifo
.front();
1676 rxPktBytes
= rxPacket
->length
;
1677 rxPacketBufPtr
= rxPacket
->data
;
1680 if (DTRACE(Ethernet
)) {
1683 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1687 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1688 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1695 // sanity check - i think the driver behaves like this
1696 assert(rxDescCnt
>= rxPktBytes
);
1701 // dont' need the && rxDescCnt > 0 if driver sanity check
1703 if (rxPktBytes
> 0) {
1704 rxState
= rxFragWrite
;
1705 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1707 rxXferLen
= rxPktBytes
;
1709 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1710 rxDmaData
= rxPacketBufPtr
;
1711 rxDmaLen
= rxXferLen
;
1712 rxDmaFree
= dmaDataFree
;
1718 rxState
= rxDescWrite
;
1720 //if (rxPktBytes == 0) { /* packet is done */
1721 assert(rxPktBytes
== 0);
1722 DPRINTF(EthernetSM
, "done with receiving packet\n");
1724 cmdsts
|= CMDSTS_OWN
;
1725 cmdsts
&= ~CMDSTS_MORE
;
1726 cmdsts
|= CMDSTS_OK
;
1727 cmdsts
&= 0xffff0000;
1728 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1732 * all the driver uses these are for its own stats keeping
1733 * which we don't care about, aren't necessary for
1734 * functionality and doing this would just slow us down.
1735 * if they end up using this in a later version for
1736 * functional purposes, just undef
1738 if (rxFilterEnable
) {
1739 cmdsts
&= ~CMDSTS_DEST_MASK
;
1740 const EthAddr
&dst
= rxFifoFront()->dst();
1742 cmdsts
|= CMDSTS_DEST_SELF
;
1743 if (dst
->multicast())
1744 cmdsts
|= CMDSTS_DEST_MULTI
;
1745 if (dst
->broadcast())
1746 cmdsts
|= CMDSTS_DEST_MASK
;
1751 if (extstsEnable
&& ip
) {
1752 extsts
|= EXTSTS_IPPKT
;
1754 if (cksum(ip
) != 0) {
1755 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1756 extsts
|= EXTSTS_IPERR
;
1761 extsts
|= EXTSTS_TCPPKT
;
1763 if (cksum(tcp
) != 0) {
1764 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1765 extsts
|= EXTSTS_TCPERR
;
1769 extsts
|= EXTSTS_UDPPKT
;
1771 if (cksum(udp
) != 0) {
1772 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1773 extsts
|= EXTSTS_UDPERR
;
1780 * the driver seems to always receive into desc buffers
1781 * of size 1514, so you never have a pkt that is split
1782 * into multiple descriptors on the receive side, so
1783 * i don't implement that case, hence the assert above.
1786 DPRINTF(EthernetDesc
,
1787 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1788 regs
.rxdp
& 0x3fffffff);
1789 DPRINTF(EthernetDesc
,
1790 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1791 link
, bufptr
, cmdsts
, extsts
);
1793 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1794 rxDmaData
= &cmdsts
;
1796 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1797 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1799 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1800 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1802 rxDmaFree
= dmaDescFree
;
1805 descDmaWrBytes
+= rxDmaLen
;
1813 if (rxDmaState
!= dmaIdle
)
1816 rxPacketBufPtr
+= rxXferLen
;
1817 rxFragPtr
+= rxXferLen
;
1818 rxPktBytes
-= rxXferLen
;
1820 rxState
= rxFifoBlock
;
1824 if (rxDmaState
!= dmaIdle
)
1827 assert(cmdsts
& CMDSTS_OWN
);
1829 assert(rxPacket
== 0);
1830 devIntrPost(ISR_RXOK
);
1832 if (cmdsts
& CMDSTS_INTR
)
1833 devIntrPost(ISR_RXDESC
);
1836 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1840 rxState
= rxAdvance
;
1845 devIntrPost(ISR_RXIDLE
);
1850 if (rxDmaState
!= dmaIdle
)
1852 rxState
= rxDescRead
;
1856 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1857 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1858 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1859 rxDmaFree
= dmaDescFree
;
1867 panic("Invalid rxState!");
1870 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1871 NsRxStateStrings
[rxState
]);
1876 * @todo do we want to schedule a future kick?
1878 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1879 NsRxStateStrings
[rxState
]);
1881 if (clock
&& !rxKickEvent
.scheduled())
1882 rxKickEvent
.schedule(rxKickTick
);
1888 if (txFifo
.empty()) {
1889 DPRINTF(Ethernet
, "nothing to transmit\n");
1893 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1895 if (interface
->sendPacket(txFifo
.front())) {
1897 if (DTRACE(Ethernet
)) {
1898 IpPtr
ip(txFifo
.front());
1900 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1904 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1905 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1912 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1913 txBytes
+= txFifo
.front()->length
;
1916 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1921 * normally do a writeback of the descriptor here, and ONLY
1922 * after that is done, send this interrupt. but since our
1923 * stuff never actually fails, just do this interrupt here,
1924 * otherwise the code has to stray from this nice format.
1925 * besides, it's functionally the same.
1927 devIntrPost(ISR_TXOK
);
1930 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1931 DPRINTF(Ethernet
, "reschedule transmit\n");
1932 txEvent
.schedule(curTick
+ retryTime
);
1937 NSGigE::txDmaReadCopy()
1939 assert(txDmaState
== dmaReading
);
1941 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1942 txDmaState
= dmaIdle
;
1944 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1945 txDmaAddr
, txDmaLen
);
1946 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1950 NSGigE::doTxDmaRead()
1952 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1953 txDmaState
= dmaReading
;
1955 if (dmaInterface
&& !txDmaFree
) {
1956 if (dmaInterface
->busy())
1957 txDmaState
= dmaReadWaiting
;
1959 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1960 &txDmaReadEvent
, true);
1964 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1969 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1970 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1971 txDmaReadEvent
.schedule(start
);
1976 NSGigE::txDmaReadDone()
1978 assert(txDmaState
== dmaReading
);
1981 // If the receive state machine has a pending DMA, let it go first
1982 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1989 NSGigE::txDmaWriteCopy()
1991 assert(txDmaState
== dmaWriting
);
1993 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
1994 txDmaState
= dmaIdle
;
1996 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1997 txDmaAddr
, txDmaLen
);
1998 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
2002 NSGigE::doTxDmaWrite()
2004 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
2005 txDmaState
= dmaWriting
;
2007 if (dmaInterface
&& !txDmaFree
) {
2008 if (dmaInterface
->busy())
2009 txDmaState
= dmaWriteWaiting
;
2011 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2012 &txDmaWriteEvent
, true);
2016 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2021 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2022 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2023 txDmaWriteEvent
.schedule(start
);
2028 NSGigE::txDmaWriteDone()
2030 assert(txDmaState
== dmaWriting
);
2033 // If the receive state machine has a pending DMA, let it go first
2034 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2043 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
2045 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
2046 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
2049 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
2050 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
2054 if (txKickTick
> curTick
) {
2055 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2060 // Go to the next state machine clock tick.
2061 txKickTick
= curTick
+ cycles(1);
2064 switch(txDmaState
) {
2065 case dmaReadWaiting
:
2069 case dmaWriteWaiting
:
2077 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
2078 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
2082 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2087 txState
= txDescRefr
;
2089 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2091 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
2092 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
2093 txDmaFree
= dmaDescFree
;
2096 descDmaRdBytes
+= txDmaLen
;
2102 txState
= txDescRead
;
2104 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2105 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2106 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2107 txDmaFree
= dmaDescFree
;
2110 descDmaRdBytes
+= txDmaLen
;
2118 if (txDmaState
!= dmaIdle
)
2121 txState
= txAdvance
;
2125 if (txDmaState
!= dmaIdle
)
2128 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
2129 regs
.txdp
& 0x3fffffff);
2130 DPRINTF(EthernetDesc
,
2131 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
2132 link
, bufptr
, cmdsts
, extsts
);
2134 if (cmdsts
& CMDSTS_OWN
) {
2135 txState
= txFifoBlock
;
2137 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
2139 devIntrPost(ISR_TXIDLE
);
2147 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2148 txPacket
= new PacketData(16384);
2149 txPacketBufPtr
= txPacket
->data
;
2152 if (txDescCnt
== 0) {
2153 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2154 if (cmdsts
& CMDSTS_MORE
) {
2155 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2156 txState
= txDescWrite
;
2158 cmdsts
&= ~CMDSTS_OWN
;
2160 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2161 txDmaData
= &cmdsts
;
2163 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2164 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2166 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2167 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2169 txDmaFree
= dmaDescFree
;
2174 } else { /* this packet is totally done */
2175 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2176 /* deal with the the packet that just finished */
2177 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2179 if (extsts
& EXTSTS_UDPPKT
) {
2182 udp
->sum(cksum(udp
));
2184 } else if (extsts
& EXTSTS_TCPPKT
) {
2187 tcp
->sum(cksum(tcp
));
2190 if (extsts
& EXTSTS_IPPKT
) {
2197 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2198 // this is just because the receive can't handle a
2199 // packet bigger want to make sure
2200 if (txPacket
->length
> 1514)
2201 panic("transmit packet too large, %s > 1514\n",
2207 txFifo
.push(txPacket
);
2211 * this following section is not tqo spec, but
2212 * functionally shouldn't be any different. normally,
2213 * the chip will wait til the transmit has occurred
2214 * before writing back the descriptor because it has
2215 * to wait to see that it was successfully transmitted
2216 * to decide whether to set CMDSTS_OK or not.
2217 * however, in the simulator since it is always
2218 * successfully transmitted, and writing it exactly to
2219 * spec would complicate the code, we just do it here
2222 cmdsts
&= ~CMDSTS_OWN
;
2223 cmdsts
|= CMDSTS_OK
;
2225 DPRINTF(EthernetDesc
,
2226 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2229 txDmaFree
= dmaDescFree
;
2230 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2231 txDmaData
= &cmdsts
;
2233 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2235 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2237 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2239 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2243 descDmaWrBytes
+= txDmaLen
;
2249 DPRINTF(EthernetSM
, "halting TX state machine\n");
2253 txState
= txAdvance
;
2259 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2260 if (!txFifo
.full()) {
2261 txState
= txFragRead
;
2264 * The number of bytes transferred is either whatever
2265 * is left in the descriptor (txDescCnt), or if there
2266 * is not enough room in the fifo, just whatever room
2267 * is left in the fifo
2269 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2271 txDmaAddr
= txFragPtr
& 0x3fffffff;
2272 txDmaData
= txPacketBufPtr
;
2273 txDmaLen
= txXferLen
;
2274 txDmaFree
= dmaDataFree
;
2279 txState
= txFifoBlock
;
2289 if (txDmaState
!= dmaIdle
)
2292 txPacketBufPtr
+= txXferLen
;
2293 txFragPtr
+= txXferLen
;
2294 txDescCnt
-= txXferLen
;
2295 txFifo
.reserve(txXferLen
);
2297 txState
= txFifoBlock
;
2301 if (txDmaState
!= dmaIdle
)
2304 if (cmdsts
& CMDSTS_INTR
)
2305 devIntrPost(ISR_TXDESC
);
2308 DPRINTF(EthernetSM
, "halting TX state machine\n");
2312 txState
= txAdvance
;
2317 devIntrPost(ISR_TXIDLE
);
2321 if (txDmaState
!= dmaIdle
)
2323 txState
= txDescRead
;
2327 txDmaAddr
= link
& 0x3fffffff;
2328 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2329 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2330 txDmaFree
= dmaDescFree
;
2338 panic("invalid state");
2341 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2342 NsTxStateStrings
[txState
]);
2347 * @todo do we want to schedule a future kick?
2349 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2350 NsTxStateStrings
[txState
]);
2352 if (clock
&& !txKickEvent
.scheduled())
2353 txKickEvent
.schedule(txKickTick
);
2357 * Advance the EEPROM state machine
2358 * Called on rising edge of EEPROM clock bit in MEAR
2361 NSGigE::eepromKick()
2363 switch (eepromState
) {
2367 // Wait for start bit
2368 if (regs
.mear
& MEAR_EEDI
) {
2369 // Set up to get 2 opcode bits
2370 eepromState
= eepromGetOpcode
;
2376 case eepromGetOpcode
:
2378 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2381 // Done getting opcode
2382 if (eepromBitsToRx
== 0) {
2383 if (eepromOpcode
!= EEPROM_READ
)
2384 panic("only EEPROM reads are implemented!");
2386 // Set up to get address
2387 eepromState
= eepromGetAddress
;
2393 case eepromGetAddress
:
2394 eepromAddress
<<= 1;
2395 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2398 // Done getting address
2399 if (eepromBitsToRx
== 0) {
2401 if (eepromAddress
>= EEPROM_SIZE
)
2402 panic("EEPROM read access out of range!");
2404 switch (eepromAddress
) {
2406 case EEPROM_PMATCH2_ADDR
:
2407 eepromData
= rom
.perfectMatch
[5];
2409 eepromData
+= rom
.perfectMatch
[4];
2412 case EEPROM_PMATCH1_ADDR
:
2413 eepromData
= rom
.perfectMatch
[3];
2415 eepromData
+= rom
.perfectMatch
[2];
2418 case EEPROM_PMATCH0_ADDR
:
2419 eepromData
= rom
.perfectMatch
[1];
2421 eepromData
+= rom
.perfectMatch
[0];
2425 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2427 // Set up to read data
2428 eepromState
= eepromRead
;
2429 eepromBitsToRx
= 16;
2431 // Clear data in bit
2432 regs
.mear
&= ~MEAR_EEDI
;
2437 // Clear Data Out bit
2438 regs
.mear
&= ~MEAR_EEDO
;
2439 // Set bit to value of current EEPROM bit
2440 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2446 if (eepromBitsToRx
== 0) {
2447 eepromState
= eepromStart
;
2452 panic("invalid EEPROM state");
2458 NSGigE::transferDone()
2460 if (txFifo
.empty()) {
2461 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2465 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2467 if (txEvent
.scheduled())
2468 txEvent
.reschedule(curTick
+ cycles(1));
2470 txEvent
.schedule(curTick
+ cycles(1));
2474 NSGigE::rxFilter(const PacketPtr
&packet
)
2476 EthPtr eth
= packet
;
2480 const EthAddr
&dst
= eth
->dst();
2481 if (dst
.unicast()) {
2482 // If we're accepting all unicast addresses
2486 // If we make a perfect match
2487 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2490 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2493 } else if (dst
.broadcast()) {
2494 // if we're accepting broadcasts
2495 if (acceptBroadcast
)
2498 } else if (dst
.multicast()) {
2499 // if we're accepting all multicasts
2500 if (acceptMulticast
)
2503 // Multicast hashing faked - all packets accepted
2504 if (multicastHashEnable
)
2509 DPRINTF(Ethernet
, "rxFilter drop\n");
2510 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2517 NSGigE::recvPacket(PacketPtr packet
)
2519 rxBytes
+= packet
->length
;
2522 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2526 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2530 if (!rxFilterEnable
) {
2532 "receive packet filtering disabled . . . packet dropped\n");
2536 if (rxFilter(packet
)) {
2537 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2541 if (rxFifo
.avail() < packet
->length
) {
2547 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2550 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2555 devIntrPost(ISR_RXORN
);
2559 rxFifo
.push(packet
);
2565 //=====================================================================
2569 NSGigE::serialize(ostream
&os
)
2571 // Serialize the PciDev base class
2572 PciDev::serialize(os
);
2575 * Finalize any DMA events now.
2577 if (rxDmaReadEvent
.scheduled())
2579 if (rxDmaWriteEvent
.scheduled())
2581 if (txDmaReadEvent
.scheduled())
2583 if (txDmaWriteEvent
.scheduled())
2587 * Serialize the device registers
2589 SERIALIZE_SCALAR(regs
.command
);
2590 SERIALIZE_SCALAR(regs
.config
);
2591 SERIALIZE_SCALAR(regs
.mear
);
2592 SERIALIZE_SCALAR(regs
.ptscr
);
2593 SERIALIZE_SCALAR(regs
.isr
);
2594 SERIALIZE_SCALAR(regs
.imr
);
2595 SERIALIZE_SCALAR(regs
.ier
);
2596 SERIALIZE_SCALAR(regs
.ihr
);
2597 SERIALIZE_SCALAR(regs
.txdp
);
2598 SERIALIZE_SCALAR(regs
.txdp_hi
);
2599 SERIALIZE_SCALAR(regs
.txcfg
);
2600 SERIALIZE_SCALAR(regs
.gpior
);
2601 SERIALIZE_SCALAR(regs
.rxdp
);
2602 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2603 SERIALIZE_SCALAR(regs
.rxcfg
);
2604 SERIALIZE_SCALAR(regs
.pqcr
);
2605 SERIALIZE_SCALAR(regs
.wcsr
);
2606 SERIALIZE_SCALAR(regs
.pcr
);
2607 SERIALIZE_SCALAR(regs
.rfcr
);
2608 SERIALIZE_SCALAR(regs
.rfdr
);
2609 SERIALIZE_SCALAR(regs
.brar
);
2610 SERIALIZE_SCALAR(regs
.brdr
);
2611 SERIALIZE_SCALAR(regs
.srr
);
2612 SERIALIZE_SCALAR(regs
.mibc
);
2613 SERIALIZE_SCALAR(regs
.vrcr
);
2614 SERIALIZE_SCALAR(regs
.vtcr
);
2615 SERIALIZE_SCALAR(regs
.vdr
);
2616 SERIALIZE_SCALAR(regs
.ccsr
);
2617 SERIALIZE_SCALAR(regs
.tbicr
);
2618 SERIALIZE_SCALAR(regs
.tbisr
);
2619 SERIALIZE_SCALAR(regs
.tanar
);
2620 SERIALIZE_SCALAR(regs
.tanlpar
);
2621 SERIALIZE_SCALAR(regs
.taner
);
2622 SERIALIZE_SCALAR(regs
.tesr
);
2624 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2625 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2627 SERIALIZE_SCALAR(ioEnable
);
2630 * Serialize the data Fifos
2632 rxFifo
.serialize("rxFifo", os
);
2633 txFifo
.serialize("txFifo", os
);
2636 * Serialize the various helper variables
2638 bool txPacketExists
= txPacket
;
2639 SERIALIZE_SCALAR(txPacketExists
);
2640 if (txPacketExists
) {
2641 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2642 txPacket
->serialize("txPacket", os
);
2643 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2644 SERIALIZE_SCALAR(txPktBufPtr
);
2647 bool rxPacketExists
= rxPacket
;
2648 SERIALIZE_SCALAR(rxPacketExists
);
2649 if (rxPacketExists
) {
2650 rxPacket
->serialize("rxPacket", os
);
2651 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2652 SERIALIZE_SCALAR(rxPktBufPtr
);
2655 SERIALIZE_SCALAR(txXferLen
);
2656 SERIALIZE_SCALAR(rxXferLen
);
2659 * Serialize Cached Descriptors
2661 SERIALIZE_SCALAR(rxDesc64
.link
);
2662 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2663 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2664 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2665 SERIALIZE_SCALAR(txDesc64
.link
);
2666 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2667 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2668 SERIALIZE_SCALAR(txDesc64
.extsts
);
2669 SERIALIZE_SCALAR(rxDesc32
.link
);
2670 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2671 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2672 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2673 SERIALIZE_SCALAR(txDesc32
.link
);
2674 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2675 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2676 SERIALIZE_SCALAR(txDesc32
.extsts
);
2677 SERIALIZE_SCALAR(extstsEnable
);
2680 * Serialize tx state machine
2682 int txState
= this->txState
;
2683 SERIALIZE_SCALAR(txState
);
2684 SERIALIZE_SCALAR(txEnable
);
2685 SERIALIZE_SCALAR(CTDD
);
2686 SERIALIZE_SCALAR(txFragPtr
);
2687 SERIALIZE_SCALAR(txDescCnt
);
2688 int txDmaState
= this->txDmaState
;
2689 SERIALIZE_SCALAR(txDmaState
);
2690 SERIALIZE_SCALAR(txKickTick
);
2693 * Serialize rx state machine
2695 int rxState
= this->rxState
;
2696 SERIALIZE_SCALAR(rxState
);
2697 SERIALIZE_SCALAR(rxEnable
);
2698 SERIALIZE_SCALAR(CRDD
);
2699 SERIALIZE_SCALAR(rxPktBytes
);
2700 SERIALIZE_SCALAR(rxFragPtr
);
2701 SERIALIZE_SCALAR(rxDescCnt
);
2702 int rxDmaState
= this->rxDmaState
;
2703 SERIALIZE_SCALAR(rxDmaState
);
2704 SERIALIZE_SCALAR(rxKickTick
);
2707 * Serialize EEPROM state machine
2709 int eepromState
= this->eepromState
;
2710 SERIALIZE_SCALAR(eepromState
);
2711 SERIALIZE_SCALAR(eepromClk
);
2712 SERIALIZE_SCALAR(eepromBitsToRx
);
2713 SERIALIZE_SCALAR(eepromOpcode
);
2714 SERIALIZE_SCALAR(eepromAddress
);
2715 SERIALIZE_SCALAR(eepromData
);
2718 * If there's a pending transmit, store the time so we can
2719 * reschedule it later
2721 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2722 SERIALIZE_SCALAR(transmitTick
);
2725 * receive address filter settings
2727 SERIALIZE_SCALAR(rxFilterEnable
);
2728 SERIALIZE_SCALAR(acceptBroadcast
);
2729 SERIALIZE_SCALAR(acceptMulticast
);
2730 SERIALIZE_SCALAR(acceptUnicast
);
2731 SERIALIZE_SCALAR(acceptPerfect
);
2732 SERIALIZE_SCALAR(acceptArp
);
2733 SERIALIZE_SCALAR(multicastHashEnable
);
2736 * Keep track of pending interrupt status.
2738 SERIALIZE_SCALAR(intrTick
);
2739 SERIALIZE_SCALAR(cpuPendingIntr
);
2740 Tick intrEventTick
= 0;
2742 intrEventTick
= intrEvent
->when();
2743 SERIALIZE_SCALAR(intrEventTick
);
2748 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2750 // Unserialize the PciDev base class
2751 PciDev::unserialize(cp
, section
);
2753 UNSERIALIZE_SCALAR(regs
.command
);
2754 UNSERIALIZE_SCALAR(regs
.config
);
2755 UNSERIALIZE_SCALAR(regs
.mear
);
2756 UNSERIALIZE_SCALAR(regs
.ptscr
);
2757 UNSERIALIZE_SCALAR(regs
.isr
);
2758 UNSERIALIZE_SCALAR(regs
.imr
);
2759 UNSERIALIZE_SCALAR(regs
.ier
);
2760 UNSERIALIZE_SCALAR(regs
.ihr
);
2761 UNSERIALIZE_SCALAR(regs
.txdp
);
2762 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2763 UNSERIALIZE_SCALAR(regs
.txcfg
);
2764 UNSERIALIZE_SCALAR(regs
.gpior
);
2765 UNSERIALIZE_SCALAR(regs
.rxdp
);
2766 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2767 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2768 UNSERIALIZE_SCALAR(regs
.pqcr
);
2769 UNSERIALIZE_SCALAR(regs
.wcsr
);
2770 UNSERIALIZE_SCALAR(regs
.pcr
);
2771 UNSERIALIZE_SCALAR(regs
.rfcr
);
2772 UNSERIALIZE_SCALAR(regs
.rfdr
);
2773 UNSERIALIZE_SCALAR(regs
.brar
);
2774 UNSERIALIZE_SCALAR(regs
.brdr
);
2775 UNSERIALIZE_SCALAR(regs
.srr
);
2776 UNSERIALIZE_SCALAR(regs
.mibc
);
2777 UNSERIALIZE_SCALAR(regs
.vrcr
);
2778 UNSERIALIZE_SCALAR(regs
.vtcr
);
2779 UNSERIALIZE_SCALAR(regs
.vdr
);
2780 UNSERIALIZE_SCALAR(regs
.ccsr
);
2781 UNSERIALIZE_SCALAR(regs
.tbicr
);
2782 UNSERIALIZE_SCALAR(regs
.tbisr
);
2783 UNSERIALIZE_SCALAR(regs
.tanar
);
2784 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2785 UNSERIALIZE_SCALAR(regs
.taner
);
2786 UNSERIALIZE_SCALAR(regs
.tesr
);
2788 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2789 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2791 UNSERIALIZE_SCALAR(ioEnable
);
2794 * unserialize the data fifos
2796 rxFifo
.unserialize("rxFifo", cp
, section
);
2797 txFifo
.unserialize("txFifo", cp
, section
);
2800 * unserialize the various helper variables
2802 bool txPacketExists
;
2803 UNSERIALIZE_SCALAR(txPacketExists
);
2804 if (txPacketExists
) {
2805 txPacket
= new PacketData(16384);
2806 txPacket
->unserialize("txPacket", cp
, section
);
2807 uint32_t txPktBufPtr
;
2808 UNSERIALIZE_SCALAR(txPktBufPtr
);
2809 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2813 bool rxPacketExists
;
2814 UNSERIALIZE_SCALAR(rxPacketExists
);
2816 if (rxPacketExists
) {
2817 rxPacket
= new PacketData(16384);
2818 rxPacket
->unserialize("rxPacket", cp
, section
);
2819 uint32_t rxPktBufPtr
;
2820 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2821 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2825 UNSERIALIZE_SCALAR(txXferLen
);
2826 UNSERIALIZE_SCALAR(rxXferLen
);
2829 * Unserialize Cached Descriptors
2831 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2832 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2833 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2834 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2835 UNSERIALIZE_SCALAR(txDesc64
.link
);
2836 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2837 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2838 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2839 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2840 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2841 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2842 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2843 UNSERIALIZE_SCALAR(txDesc32
.link
);
2844 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2845 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2846 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2847 UNSERIALIZE_SCALAR(extstsEnable
);
2850 * unserialize tx state machine
2853 UNSERIALIZE_SCALAR(txState
);
2854 this->txState
= (TxState
) txState
;
2855 UNSERIALIZE_SCALAR(txEnable
);
2856 UNSERIALIZE_SCALAR(CTDD
);
2857 UNSERIALIZE_SCALAR(txFragPtr
);
2858 UNSERIALIZE_SCALAR(txDescCnt
);
2860 UNSERIALIZE_SCALAR(txDmaState
);
2861 this->txDmaState
= (DmaState
) txDmaState
;
2862 UNSERIALIZE_SCALAR(txKickTick
);
2864 txKickEvent
.schedule(txKickTick
);
2867 * unserialize rx state machine
2870 UNSERIALIZE_SCALAR(rxState
);
2871 this->rxState
= (RxState
) rxState
;
2872 UNSERIALIZE_SCALAR(rxEnable
);
2873 UNSERIALIZE_SCALAR(CRDD
);
2874 UNSERIALIZE_SCALAR(rxPktBytes
);
2875 UNSERIALIZE_SCALAR(rxFragPtr
);
2876 UNSERIALIZE_SCALAR(rxDescCnt
);
2878 UNSERIALIZE_SCALAR(rxDmaState
);
2879 this->rxDmaState
= (DmaState
) rxDmaState
;
2880 UNSERIALIZE_SCALAR(rxKickTick
);
2882 rxKickEvent
.schedule(rxKickTick
);
2885 * Unserialize EEPROM state machine
2888 UNSERIALIZE_SCALAR(eepromState
);
2889 this->eepromState
= (EEPROMState
) eepromState
;
2890 UNSERIALIZE_SCALAR(eepromClk
);
2891 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2892 UNSERIALIZE_SCALAR(eepromOpcode
);
2893 UNSERIALIZE_SCALAR(eepromAddress
);
2894 UNSERIALIZE_SCALAR(eepromData
);
2897 * If there's a pending transmit, reschedule it now
2900 UNSERIALIZE_SCALAR(transmitTick
);
2902 txEvent
.schedule(curTick
+ transmitTick
);
2905 * unserialize receive address filter settings
2907 UNSERIALIZE_SCALAR(rxFilterEnable
);
2908 UNSERIALIZE_SCALAR(acceptBroadcast
);
2909 UNSERIALIZE_SCALAR(acceptMulticast
);
2910 UNSERIALIZE_SCALAR(acceptUnicast
);
2911 UNSERIALIZE_SCALAR(acceptPerfect
);
2912 UNSERIALIZE_SCALAR(acceptArp
);
2913 UNSERIALIZE_SCALAR(multicastHashEnable
);
2916 * Keep track of pending interrupt status.
2918 UNSERIALIZE_SCALAR(intrTick
);
2919 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2921 UNSERIALIZE_SCALAR(intrEventTick
);
2922 if (intrEventTick
) {
2923 intrEvent
= new IntrEvent(this, true);
2924 intrEvent
->schedule(intrEventTick
);
2928 * re-add addrRanges to bus bridges
2931 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2932 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2937 NSGigE::cacheAccess(MemReqPtr
&req
)
2939 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2940 req
->paddr
, req
->paddr
& 0xfff);
2942 return curTick
+ pioLatency
;
2945 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2947 SimObjectParam
<EtherInt
*> peer
;
2948 SimObjectParam
<NSGigE
*> device
;
2950 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2952 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2954 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2955 INIT_PARAM(device
, "Ethernet device of this interface")
2957 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2959 CREATE_SIM_OBJECT(NSGigEInt
)
2961 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2963 EtherInt
*p
= (EtherInt
*)peer
;
2965 dev_int
->setPeer(p
);
2966 p
->setPeer(dev_int
);
2972 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2975 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2980 SimObjectParam
<MemoryController
*> mmu
;
2981 SimObjectParam
<PhysicalMemory
*> physmem
;
2982 SimObjectParam
<PciConfigAll
*> configspace
;
2983 SimObjectParam
<PciConfigData
*> configdata
;
2984 SimObjectParam
<Platform
*> platform
;
2985 Param
<uint32_t> pci_bus
;
2986 Param
<uint32_t> pci_dev
;
2987 Param
<uint32_t> pci_func
;
2989 SimObjectParam
<HierParams
*> hier
;
2990 SimObjectParam
<Bus
*> pio_bus
;
2991 SimObjectParam
<Bus
*> dma_bus
;
2992 SimObjectParam
<Bus
*> payload_bus
;
2993 Param
<bool> dma_desc_free
;
2994 Param
<bool> dma_data_free
;
2995 Param
<Tick
> dma_read_delay
;
2996 Param
<Tick
> dma_write_delay
;
2997 Param
<Tick
> dma_read_factor
;
2998 Param
<Tick
> dma_write_factor
;
2999 Param
<bool> dma_no_allocate
;
3000 Param
<Tick
> pio_latency
;
3001 Param
<Tick
> intr_delay
;
3003 Param
<Tick
> rx_delay
;
3004 Param
<Tick
> tx_delay
;
3005 Param
<uint32_t> rx_fifo_size
;
3006 Param
<uint32_t> tx_fifo_size
;
3008 Param
<bool> rx_filter
;
3009 Param
<string
> hardware_address
;
3010 Param
<bool> rx_thread
;
3011 Param
<bool> tx_thread
;
3013 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3015 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3017 INIT_PARAM(clock
, "State machine processor frequency"),
3019 INIT_PARAM(addr
, "Device Address"),
3020 INIT_PARAM(mmu
, "Memory Controller"),
3021 INIT_PARAM(physmem
, "Physical Memory"),
3022 INIT_PARAM(configspace
, "PCI Configspace"),
3023 INIT_PARAM(configdata
, "PCI Config data"),
3024 INIT_PARAM(platform
, "Platform"),
3025 INIT_PARAM(pci_bus
, "PCI bus"),
3026 INIT_PARAM(pci_dev
, "PCI device number"),
3027 INIT_PARAM(pci_func
, "PCI function code"),
3029 INIT_PARAM(hier
, "Hierarchy global variables"),
3030 INIT_PARAM(pio_bus
, ""),
3031 INIT_PARAM(dma_bus
, ""),
3032 INIT_PARAM(payload_bus
, "The IO Bus to attach to for payload"),
3033 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
3034 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
3035 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
3036 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
3037 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
3038 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
3039 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
3040 INIT_PARAM(pio_latency
, "Programmed IO latency in bus cycles"),
3041 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
3043 INIT_PARAM(rx_delay
, "Receive Delay"),
3044 INIT_PARAM(tx_delay
, "Transmit Delay"),
3045 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
3046 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
3048 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
3049 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
3050 INIT_PARAM(rx_thread
, ""),
3051 INIT_PARAM(tx_thread
, "")
3053 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3056 CREATE_SIM_OBJECT(NSGigE
)
3058 NSGigE::Params
*params
= new NSGigE::Params
;
3060 params
->name
= getInstanceName();
3062 params
->clock
= clock
;
3065 params
->pmem
= physmem
;
3066 params
->configSpace
= configspace
;
3067 params
->configData
= configdata
;
3068 params
->plat
= platform
;
3069 params
->busNum
= pci_bus
;
3070 params
->deviceNum
= pci_dev
;
3071 params
->functionNum
= pci_func
;
3073 params
->hier
= hier
;
3074 params
->pio_bus
= pio_bus
;
3075 params
->header_bus
= dma_bus
;
3076 params
->payload_bus
= payload_bus
;
3077 params
->dma_desc_free
= dma_desc_free
;
3078 params
->dma_data_free
= dma_data_free
;
3079 params
->dma_read_delay
= dma_read_delay
;
3080 params
->dma_write_delay
= dma_write_delay
;
3081 params
->dma_read_factor
= dma_read_factor
;
3082 params
->dma_write_factor
= dma_write_factor
;
3083 params
->dma_no_allocate
= dma_no_allocate
;
3084 params
->pio_latency
= pio_latency
;
3085 params
->intr_delay
= intr_delay
;
3087 params
->rx_delay
= rx_delay
;
3088 params
->tx_delay
= tx_delay
;
3089 params
->rx_fifo_size
= rx_fifo_size
;
3090 params
->tx_fifo_size
= tx_fifo_size
;
3092 params
->rx_filter
= rx_filter
;
3093 params
->eaddr
= hardware_address
;
3094 params
->rx_thread
= rx_thread
;
3095 params
->tx_thread
= tx_thread
;
3097 return new NSGigE(params
);
3100 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)