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 "arch/alpha/ev5.hh"
38 #include "base/inet.hh"
39 #include "cpu/exec_context.hh"
40 #include "dev/etherlink.hh"
41 #include "dev/ns_gige.hh"
42 #include "dev/pciconfigall.hh"
43 #include "mem/bus/bus.hh"
44 #include "mem/bus/dma_interface.hh"
45 #include "mem/bus/pio_interface.hh"
46 #include "mem/bus/pio_interface_impl.hh"
47 #include "mem/functional/memory_control.hh"
48 #include "mem/functional/physical.hh"
49 #include "sim/builder.hh"
50 #include "sim/debug.hh"
51 #include "sim/host.hh"
52 #include "sim/stats.hh"
53 #include "arch/vtophys.hh"
55 const char *NsRxStateStrings
[] =
66 const char *NsTxStateStrings
[] =
77 const char *NsDmaState
[] =
88 using namespace TheISA
;
90 ///////////////////////////////////////////////////////////////////////
94 NSGigE::NSGigE(Params
*p
)
95 : PciDev(p
), ioEnable(false),
96 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
97 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
98 txXferLen(0), rxXferLen(0), clock(p
->clock
),
99 txState(txIdle
), txEnable(false), CTDD(false),
100 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
101 rxEnable(false), CRDD(false), rxPktBytes(0),
102 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
103 eepromState(eepromStart
), rxDmaReadEvent(this), rxDmaWriteEvent(this),
104 txDmaReadEvent(this), txDmaWriteEvent(this),
105 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
106 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
107 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
108 txEvent(this), rxFilterEnable(p
->rx_filter
), acceptBroadcast(false),
109 acceptMulticast(false), acceptUnicast(false),
110 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
111 physmem(p
->pmem
), intrTick(0), cpuPendingIntr(false),
112 intrEvent(0), interface(0)
115 pioInterface
= newPioInterface(name() + ".pio", p
->hier
,
117 &NSGigE::cacheAccess
);
118 pioLatency
= p
->pio_latency
* p
->pio_bus
->clockRate
;
123 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
128 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
132 } else if (p
->payload_bus
)
133 panic("Must define a header bus if defining a payload bus");
135 intrDelay
= p
->intr_delay
;
136 dmaReadDelay
= p
->dma_read_delay
;
137 dmaWriteDelay
= p
->dma_write_delay
;
138 dmaReadFactor
= p
->dma_read_factor
;
139 dmaWriteFactor
= p
->dma_write_factor
;
142 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
144 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
145 memset(&txDesc32
, 0, sizeof(txDesc32
));
146 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
147 memset(&txDesc64
, 0, sizeof(txDesc64
));
157 .name(name() + ".txBytes")
158 .desc("Bytes Transmitted")
163 .name(name() + ".rxBytes")
164 .desc("Bytes Received")
169 .name(name() + ".txPackets")
170 .desc("Number of Packets Transmitted")
175 .name(name() + ".rxPackets")
176 .desc("Number of Packets Received")
181 .name(name() + ".txIpChecksums")
182 .desc("Number of tx IP Checksums done by device")
188 .name(name() + ".rxIpChecksums")
189 .desc("Number of rx IP Checksums done by device")
195 .name(name() + ".txTcpChecksums")
196 .desc("Number of tx TCP Checksums done by device")
202 .name(name() + ".rxTcpChecksums")
203 .desc("Number of rx TCP Checksums done by device")
209 .name(name() + ".txUdpChecksums")
210 .desc("Number of tx UDP Checksums done by device")
216 .name(name() + ".rxUdpChecksums")
217 .desc("Number of rx UDP Checksums done by device")
223 .name(name() + ".descDMAReads")
224 .desc("Number of descriptors the device read w/ DMA")
229 .name(name() + ".descDMAWrites")
230 .desc("Number of descriptors the device wrote w/ DMA")
235 .name(name() + ".descDmaReadBytes")
236 .desc("number of descriptor bytes read w/ DMA")
241 .name(name() + ".descDmaWriteBytes")
242 .desc("number of descriptor bytes write w/ DMA")
247 .name(name() + ".txBandwidth")
248 .desc("Transmit Bandwidth (bits/s)")
254 .name(name() + ".rxBandwidth")
255 .desc("Receive Bandwidth (bits/s)")
261 .name(name() + ".totBandwidth")
262 .desc("Total Bandwidth (bits/s)")
268 .name(name() + ".totPackets")
269 .desc("Total Packets")
275 .name(name() + ".totBytes")
282 .name(name() + ".totPPS")
283 .desc("Total Tranmission Rate (packets/s)")
289 .name(name() + ".txPPS")
290 .desc("Packet Tranmission Rate (packets/s)")
296 .name(name() + ".rxPPS")
297 .desc("Packet Reception Rate (packets/s)")
303 .name(name() + ".postedSwi")
304 .desc("number of software interrupts posted to CPU")
309 .name(name() + ".totalSwi")
310 .desc("total number of Swi written to ISR")
315 .name(name() + ".coalescedSwi")
316 .desc("average number of Swi's coalesced into each post")
321 .name(name() + ".postedRxIdle")
322 .desc("number of rxIdle interrupts posted to CPU")
327 .name(name() + ".totalRxIdle")
328 .desc("total number of RxIdle written to ISR")
333 .name(name() + ".coalescedRxIdle")
334 .desc("average number of RxIdle's coalesced into each post")
339 .name(name() + ".postedRxOk")
340 .desc("number of RxOk interrupts posted to CPU")
345 .name(name() + ".totalRxOk")
346 .desc("total number of RxOk written to ISR")
351 .name(name() + ".coalescedRxOk")
352 .desc("average number of RxOk's coalesced into each post")
357 .name(name() + ".postedRxDesc")
358 .desc("number of RxDesc interrupts posted to CPU")
363 .name(name() + ".totalRxDesc")
364 .desc("total number of RxDesc written to ISR")
369 .name(name() + ".coalescedRxDesc")
370 .desc("average number of RxDesc's coalesced into each post")
375 .name(name() + ".postedTxOk")
376 .desc("number of TxOk interrupts posted to CPU")
381 .name(name() + ".totalTxOk")
382 .desc("total number of TxOk written to ISR")
387 .name(name() + ".coalescedTxOk")
388 .desc("average number of TxOk's coalesced into each post")
393 .name(name() + ".postedTxIdle")
394 .desc("number of TxIdle interrupts posted to CPU")
399 .name(name() + ".totalTxIdle")
400 .desc("total number of TxIdle written to ISR")
405 .name(name() + ".coalescedTxIdle")
406 .desc("average number of TxIdle's coalesced into each post")
411 .name(name() + ".postedTxDesc")
412 .desc("number of TxDesc interrupts posted to CPU")
417 .name(name() + ".totalTxDesc")
418 .desc("total number of TxDesc written to ISR")
423 .name(name() + ".coalescedTxDesc")
424 .desc("average number of TxDesc's coalesced into each post")
429 .name(name() + ".postedRxOrn")
430 .desc("number of RxOrn posted to CPU")
435 .name(name() + ".totalRxOrn")
436 .desc("total number of RxOrn written to ISR")
441 .name(name() + ".coalescedRxOrn")
442 .desc("average number of RxOrn's coalesced into each post")
447 .name(name() + ".coalescedTotal")
448 .desc("average number of interrupts coalesced into each post")
453 .name(name() + ".postedInterrupts")
454 .desc("number of posts to CPU")
459 .name(name() + ".droppedPackets")
460 .desc("number of packets dropped")
464 coalescedSwi
= totalSwi
/ postedInterrupts
;
465 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
466 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
467 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
468 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
469 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
470 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
471 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
473 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
474 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
475 totalRxOrn
) / postedInterrupts
;
477 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
478 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
479 totBandwidth
= txBandwidth
+ rxBandwidth
;
480 totBytes
= txBytes
+ rxBytes
;
481 totPackets
= txPackets
+ rxPackets
;
483 txPacketRate
= txPackets
/ simSeconds
;
484 rxPacketRate
= rxPackets
/ simSeconds
;
488 * This is to read the PCI general configuration registers
491 NSGigE::readConfig(int offset
, int size
, uint8_t *data
)
493 if (offset
< PCI_DEVICE_SPECIFIC
)
494 PciDev::readConfig(offset
, size
, data
);
496 panic("Device specific PCI config space not implemented!\n");
500 * This is to write to the PCI general configuration registers
503 NSGigE::writeConfig(int offset
, int size
, const uint8_t* data
)
505 if (offset
< PCI_DEVICE_SPECIFIC
)
506 PciDev::writeConfig(offset
, size
, data
);
508 panic("Device specific PCI config space not implemented!\n");
510 // Need to catch writes to BARs to update the PIO interface
512 // seems to work fine without all these PCI settings, but i
513 // put in the IO to double check, an assertion will fail if we
514 // need to properly implement it
516 if (config
.data
[offset
] & PCI_CMD_IOSE
)
522 if (config
.data
[offset
] & PCI_CMD_BME
) {
529 if (config
.data
[offset
] & PCI_CMD_MSE
) {
538 case PCI0_BASE_ADDR0
:
539 if (BARAddrs
[0] != 0) {
541 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
543 BARAddrs
[0] &= EV5::PAddrUncachedMask
;
546 case PCI0_BASE_ADDR1
:
547 if (BARAddrs
[1] != 0) {
549 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
551 BARAddrs
[1] &= EV5::PAddrUncachedMask
;
558 * This reads the device registers, which are detailed in the NS83820
562 NSGigE::read(MemReqPtr
&req
, uint8_t *data
)
566 //The mask is to give you only the offset into the device register file
567 Addr daddr
= req
->paddr
& 0xfff;
568 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x va=%#x size=%d\n",
569 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
572 // there are some reserved registers, you can see ns_gige_reg.h and
573 // the spec sheet for details
574 if (daddr
> LAST
&& daddr
<= RESERVED
) {
575 panic("Accessing reserved register");
576 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
577 readConfig(daddr
& 0xff, req
->size
, data
);
579 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
580 // don't implement all the MIB's. hopefully the kernel
581 // doesn't actually DEPEND upon their values
582 // MIB are just hardware stats keepers
583 uint32_t ®
= *(uint32_t *) data
;
586 } else if (daddr
> 0x3FC)
587 panic("Something is messed up!\n");
590 case sizeof(uint32_t):
592 uint32_t ®
= *(uint32_t *)data
;
598 //these are supposed to be cleared on a read
599 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
616 devIntrClear(ISR_ALL
);
671 // see the spec sheet for how RFCR and RFDR work
672 // basically, you write to RFCR to tell the machine
673 // what you want to do next, then you act upon RFDR,
674 // and the device will be prepared b/c of what you
681 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
683 // Read from perfect match ROM octets
685 reg
= rom
.perfectMatch
[1];
687 reg
+= rom
.perfectMatch
[0];
690 reg
= rom
.perfectMatch
[3] << 8;
691 reg
+= rom
.perfectMatch
[2];
694 reg
= rom
.perfectMatch
[5] << 8;
695 reg
+= rom
.perfectMatch
[4];
698 // Read filter hash table
699 if (rfaddr
>= FHASH_ADDR
&&
700 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
702 // Only word-aligned reads supported
704 panic("unaligned read from filter hash table!");
706 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
707 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
711 panic("reading RFDR for something other than pattern"
712 " matching or hashing! %#x\n", rfaddr
);
722 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
767 if (params()->rx_thread
)
768 reg
|= M5REG_RX_THREAD
;
769 if (params()->tx_thread
)
770 reg
|= M5REG_TX_THREAD
;
776 panic("reading unimplemented register: addr=%#x", daddr
);
779 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
785 panic("accessing register with invalid size: addr=%#x, size=%d",
793 NSGigE::write(MemReqPtr
&req
, const uint8_t *data
)
797 Addr daddr
= req
->paddr
& 0xfff;
798 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x va=%#x size=%d\n",
799 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
801 if (daddr
> LAST
&& daddr
<= RESERVED
) {
802 panic("Accessing reserved register");
803 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
804 writeConfig(daddr
& 0xff, req
->size
, data
);
806 } else if (daddr
> 0x3FC)
807 panic("Something is messed up!\n");
809 if (req
->size
== sizeof(uint32_t)) {
810 uint32_t reg
= *(uint32_t *)data
;
813 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
820 } else if (reg
& CR_TXE
) {
823 // the kernel is enabling the transmit machine
824 if (txState
== txIdle
)
830 } else if (reg
& CR_RXE
) {
833 if (rxState
== rxIdle
)
844 devIntrPost(ISR_SWI
);
855 if (reg
& CFGR_LNKSTS
||
858 reg
& CFGR_RESERVED
||
859 reg
& CFGR_T64ADDR
||
860 reg
& CFGR_PCI64_DET
)
862 // First clear all writable bits
863 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
864 CFGR_RESERVED
| CFGR_T64ADDR
|
866 // Now set the appropriate writable bits
867 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
868 CFGR_RESERVED
| CFGR_T64ADDR
|
871 // all these #if 0's are because i don't THINK the kernel needs to
872 // have these implemented. if there is a problem relating to one of
873 // these, you may need to add functionality in.
874 if (reg
& CFGR_TBI_EN
) ;
875 if (reg
& CFGR_MODE_1000
) ;
877 if (reg
& CFGR_AUTO_1000
)
878 panic("CFGR_AUTO_1000 not implemented!\n");
880 if (reg
& CFGR_PINT_DUPSTS
||
881 reg
& CFGR_PINT_LNKSTS
||
882 reg
& CFGR_PINT_SPDSTS
)
885 if (reg
& CFGR_TMRTEST
) ;
886 if (reg
& CFGR_MRM_DIS
) ;
887 if (reg
& CFGR_MWI_DIS
) ;
889 if (reg
& CFGR_T64ADDR
) ;
890 // panic("CFGR_T64ADDR is read only register!\n");
892 if (reg
& CFGR_PCI64_DET
)
893 panic("CFGR_PCI64_DET is read only register!\n");
895 if (reg
& CFGR_DATA64_EN
) ;
896 if (reg
& CFGR_M64ADDR
) ;
897 if (reg
& CFGR_PHY_RST
) ;
898 if (reg
& CFGR_PHY_DIS
) ;
900 if (reg
& CFGR_EXTSTS_EN
)
903 extstsEnable
= false;
905 if (reg
& CFGR_REQALG
) ;
907 if (reg
& CFGR_POW
) ;
908 if (reg
& CFGR_EXD
) ;
909 if (reg
& CFGR_PESEL
) ;
910 if (reg
& CFGR_BROM_DIS
) ;
911 if (reg
& CFGR_EXT_125
) ;
912 if (reg
& CFGR_BEM
) ;
916 // Clear writable bits
917 regs
.mear
&= MEAR_EEDO
;
918 // Set appropriate writable bits
919 regs
.mear
|= reg
& ~MEAR_EEDO
;
921 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
922 // even though it could get it through RFDR
923 if (reg
& MEAR_EESEL
) {
924 // Rising edge of clock
925 if (reg
& MEAR_EECLK
&& !eepromClk
)
929 eepromState
= eepromStart
;
930 regs
.mear
&= ~MEAR_EEDI
;
933 eepromClk
= reg
& MEAR_EECLK
;
935 // since phy is completely faked, MEAR_MD* don't matter
936 if (reg
& MEAR_MDIO
) ;
937 if (reg
& MEAR_MDDIR
) ;
938 if (reg
& MEAR_MDC
) ;
942 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
943 // these control BISTs for various parts of chip - we
944 // don't care or do just fake that the BIST is done
945 if (reg
& PTSCR_RBIST_EN
)
946 regs
.ptscr
|= PTSCR_RBIST_DONE
;
947 if (reg
& PTSCR_EEBIST_EN
)
948 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
949 if (reg
& PTSCR_EELOAD_EN
)
950 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
953 case ISR
: /* writing to the ISR has no effect */
954 panic("ISR is a read only register!\n");
967 /* not going to implement real interrupt holdoff */
971 regs
.txdp
= (reg
& 0xFFFFFFFC);
972 assert(txState
== txIdle
);
983 if (reg
& TX_CFG_CSI
) ;
984 if (reg
& TX_CFG_HBI
) ;
985 if (reg
& TX_CFG_MLB
) ;
986 if (reg
& TX_CFG_ATP
) ;
987 if (reg
& TX_CFG_ECRETRY
) {
989 * this could easily be implemented, but considering
990 * the network is just a fake pipe, wouldn't make
995 if (reg
& TX_CFG_BRST_DIS
) ;
999 /* we handle our own DMA, ignore the kernel's exhortations */
1000 if (reg
& TX_CFG_MXDMA
) ;
1003 // also, we currently don't care about fill/drain
1004 // thresholds though this may change in the future with
1005 // more realistic networks or a driver which changes it
1006 // according to feedback
1011 // Only write writable bits
1012 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1013 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1014 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1015 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1016 /* these just control general purpose i/o pins, don't matter */
1031 if (reg
& RX_CFG_AEP
) ;
1032 if (reg
& RX_CFG_ARP
) ;
1033 if (reg
& RX_CFG_STRIPCRC
) ;
1034 if (reg
& RX_CFG_RX_RD
) ;
1035 if (reg
& RX_CFG_ALP
) ;
1036 if (reg
& RX_CFG_AIRL
) ;
1038 /* we handle our own DMA, ignore what kernel says about it */
1039 if (reg
& RX_CFG_MXDMA
) ;
1041 //also, we currently don't care about fill/drain thresholds
1042 //though this may change in the future with more realistic
1043 //networks or a driver which changes it according to feedback
1044 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1049 /* there is no priority queueing used in the linux 2.6 driver */
1054 /* not going to implement wake on LAN */
1059 /* not going to implement pause control */
1066 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1067 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1068 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1069 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1070 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1071 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1072 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1075 if (reg
& RFCR_APAT
)
1076 panic("RFCR_APAT not implemented!\n");
1078 if (reg
& RFCR_UHEN
)
1079 panic("Unicast hash filtering not used by drivers!\n");
1082 panic("RFCR_ULM not implemented!\n");
1087 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1090 rom
.perfectMatch
[0] = (uint8_t)reg
;
1091 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1094 rom
.perfectMatch
[2] = (uint8_t)reg
;
1095 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1098 rom
.perfectMatch
[4] = (uint8_t)reg
;
1099 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1103 if (rfaddr
>= FHASH_ADDR
&&
1104 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1106 // Only word-aligned writes supported
1108 panic("unaligned write to filter hash table!");
1110 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1111 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1112 = (uint8_t)(reg
>> 8);
1115 panic("writing RFDR for something other than pattern matching\
1116 or hashing! %#x\n", rfaddr
);
1124 panic("the driver never uses BRDR, something is wrong!\n");
1127 panic("SRR is read only register!\n");
1130 panic("the driver never uses MIBC, something is wrong!\n");
1141 panic("the driver never uses VDR, something is wrong!\n");
1144 /* not going to implement clockrun stuff */
1150 if (reg
& TBICR_MR_LOOPBACK
)
1151 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1153 if (reg
& TBICR_MR_AN_ENABLE
) {
1154 regs
.tanlpar
= regs
.tanar
;
1155 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1159 if (reg
& TBICR_MR_RESTART_AN
) ;
1165 panic("TBISR is read only register!\n");
1168 // Only write the writable bits
1169 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1170 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1172 // Pause capability unimplemented
1174 if (reg
& TANAR_PS2
) ;
1175 if (reg
& TANAR_PS1
) ;
1181 panic("this should only be written to by the fake phy!\n");
1184 panic("TANER is read only register!\n");
1191 panic("invalid register access daddr=%#x", daddr
);
1194 panic("Invalid Request Size");
1201 NSGigE::devIntrPost(uint32_t interrupts
)
1203 if (interrupts
& ISR_RESERVE
)
1204 panic("Cannot set a reserved interrupt");
1206 if (interrupts
& ISR_NOIMPL
)
1207 warn("interrupt not implemented %#x\n", interrupts
);
1209 interrupts
&= ISR_IMPL
;
1210 regs
.isr
|= interrupts
;
1212 if (interrupts
& regs
.imr
) {
1213 if (interrupts
& ISR_SWI
) {
1216 if (interrupts
& ISR_RXIDLE
) {
1219 if (interrupts
& ISR_RXOK
) {
1222 if (interrupts
& ISR_RXDESC
) {
1225 if (interrupts
& ISR_TXOK
) {
1228 if (interrupts
& ISR_TXIDLE
) {
1231 if (interrupts
& ISR_TXDESC
) {
1234 if (interrupts
& ISR_RXORN
) {
1239 DPRINTF(EthernetIntr
,
1240 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1241 interrupts
, regs
.isr
, regs
.imr
);
1243 if ((regs
.isr
& regs
.imr
)) {
1244 Tick when
= curTick
;
1245 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1251 /* writing this interrupt counting stats inside this means that this function
1252 is now limited to being used to clear all interrupts upon the kernel
1253 reading isr and servicing. just telling you in case you were thinking
1257 NSGigE::devIntrClear(uint32_t interrupts
)
1259 if (interrupts
& ISR_RESERVE
)
1260 panic("Cannot clear a reserved interrupt");
1262 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1265 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1268 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1271 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1274 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1277 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1280 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1283 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1287 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1290 interrupts
&= ~ISR_NOIMPL
;
1291 regs
.isr
&= ~interrupts
;
1293 DPRINTF(EthernetIntr
,
1294 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1295 interrupts
, regs
.isr
, regs
.imr
);
1297 if (!(regs
.isr
& regs
.imr
))
1302 NSGigE::devIntrChangeMask()
1304 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1305 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1307 if (regs
.isr
& regs
.imr
)
1308 cpuIntrPost(curTick
);
1314 NSGigE::cpuIntrPost(Tick when
)
1316 // If the interrupt you want to post is later than an interrupt
1317 // already scheduled, just let it post in the coming one and don't
1318 // schedule another.
1319 // HOWEVER, must be sure that the scheduled intrTick is in the
1320 // future (this was formerly the source of a bug)
1322 * @todo this warning should be removed and the intrTick code should
1325 assert(when
>= curTick
);
1326 assert(intrTick
>= curTick
|| intrTick
== 0);
1327 if (when
> intrTick
&& intrTick
!= 0) {
1328 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1334 if (intrTick
< curTick
) {
1339 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1343 intrEvent
->squash();
1344 intrEvent
= new IntrEvent(this, true);
1345 intrEvent
->schedule(intrTick
);
1349 NSGigE::cpuInterrupt()
1351 assert(intrTick
== curTick
);
1353 // Whether or not there's a pending interrupt, we don't care about
1358 // Don't send an interrupt if there's already one
1359 if (cpuPendingIntr
) {
1360 DPRINTF(EthernetIntr
,
1361 "would send an interrupt now, but there's already pending\n");
1364 cpuPendingIntr
= true;
1366 DPRINTF(EthernetIntr
, "posting interrupt\n");
1372 NSGigE::cpuIntrClear()
1374 if (!cpuPendingIntr
)
1378 intrEvent
->squash();
1384 cpuPendingIntr
= false;
1386 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1391 NSGigE::cpuIntrPending() const
1392 { return cpuPendingIntr
; }
1398 DPRINTF(Ethernet
, "transmit reset\n");
1403 assert(txDescCnt
== 0);
1406 assert(txDmaState
== dmaIdle
);
1412 DPRINTF(Ethernet
, "receive reset\n");
1415 assert(rxPktBytes
== 0);
1418 assert(rxDescCnt
== 0);
1419 assert(rxDmaState
== dmaIdle
);
1427 memset(®s
, 0, sizeof(regs
));
1428 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1430 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1431 // fill threshold to 32 bytes
1432 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1433 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1434 regs
.mibc
= MIBC_FRZ
;
1435 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1436 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1437 regs
.brar
= 0xffffffff;
1439 extstsEnable
= false;
1440 acceptBroadcast
= false;
1441 acceptMulticast
= false;
1442 acceptUnicast
= false;
1443 acceptPerfect
= false;
1448 NSGigE::rxDmaReadCopy()
1450 assert(rxDmaState
== dmaReading
);
1452 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1453 rxDmaState
= dmaIdle
;
1455 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1456 rxDmaAddr
, rxDmaLen
);
1457 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1461 NSGigE::doRxDmaRead()
1463 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1464 rxDmaState
= dmaReading
;
1466 if (dmaInterface
&& !rxDmaFree
) {
1467 if (dmaInterface
->busy())
1468 rxDmaState
= dmaReadWaiting
;
1470 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1471 &rxDmaReadEvent
, true);
1475 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1480 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1481 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1482 rxDmaReadEvent
.schedule(start
);
1487 NSGigE::rxDmaReadDone()
1489 assert(rxDmaState
== dmaReading
);
1492 // If the transmit state machine has a pending DMA, let it go first
1493 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1500 NSGigE::rxDmaWriteCopy()
1502 assert(rxDmaState
== dmaWriting
);
1504 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1505 rxDmaState
= dmaIdle
;
1507 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1508 rxDmaAddr
, rxDmaLen
);
1509 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1513 NSGigE::doRxDmaWrite()
1515 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1516 rxDmaState
= dmaWriting
;
1518 if (dmaInterface
&& !rxDmaFree
) {
1519 if (dmaInterface
->busy())
1520 rxDmaState
= dmaWriteWaiting
;
1522 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1523 &rxDmaWriteEvent
, true);
1527 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1532 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1533 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1534 rxDmaWriteEvent
.schedule(start
);
1539 NSGigE::rxDmaWriteDone()
1541 assert(rxDmaState
== dmaWriting
);
1544 // If the transmit state machine has a pending DMA, let it go first
1545 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1554 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1557 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1558 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1561 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1562 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1566 if (rxKickTick
> curTick
) {
1567 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1573 // Go to the next state machine clock tick.
1574 rxKickTick
= curTick
+ cycles(1);
1577 switch(rxDmaState
) {
1578 case dmaReadWaiting
:
1582 case dmaWriteWaiting
:
1590 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1591 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1593 // see state machine from spec for details
1594 // the way this works is, if you finish work on one state and can
1595 // go directly to another, you do that through jumping to the
1596 // label "next". however, if you have intermediate work, like DMA
1597 // so that you can't go to the next state yet, you go to exit and
1598 // exit the loop. however, when the DMA is done it will trigger
1599 // an event and come back to this loop.
1603 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1608 rxState
= rxDescRefr
;
1610 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1612 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1613 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1614 rxDmaFree
= dmaDescFree
;
1617 descDmaRdBytes
+= rxDmaLen
;
1622 rxState
= rxDescRead
;
1624 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1625 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1626 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1627 rxDmaFree
= dmaDescFree
;
1630 descDmaRdBytes
+= rxDmaLen
;
1638 if (rxDmaState
!= dmaIdle
)
1641 rxState
= rxAdvance
;
1645 if (rxDmaState
!= dmaIdle
)
1648 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1649 regs
.rxdp
& 0x3fffffff);
1650 DPRINTF(EthernetDesc
,
1651 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1652 link
, bufptr
, cmdsts
, extsts
);
1654 if (cmdsts
& CMDSTS_OWN
) {
1655 devIntrPost(ISR_RXIDLE
);
1659 rxState
= rxFifoBlock
;
1661 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1668 * @todo in reality, we should be able to start processing
1669 * the packet as it arrives, and not have to wait for the
1670 * full packet ot be in the receive fifo.
1675 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1677 // If we don't have a packet, grab a new one from the fifo.
1678 rxPacket
= rxFifo
.front();
1679 rxPktBytes
= rxPacket
->length
;
1680 rxPacketBufPtr
= rxPacket
->data
;
1683 if (DTRACE(Ethernet
)) {
1686 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1690 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1691 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1698 // sanity check - i think the driver behaves like this
1699 assert(rxDescCnt
>= rxPktBytes
);
1704 // dont' need the && rxDescCnt > 0 if driver sanity check
1706 if (rxPktBytes
> 0) {
1707 rxState
= rxFragWrite
;
1708 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1710 rxXferLen
= rxPktBytes
;
1712 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1713 rxDmaData
= rxPacketBufPtr
;
1714 rxDmaLen
= rxXferLen
;
1715 rxDmaFree
= dmaDataFree
;
1721 rxState
= rxDescWrite
;
1723 //if (rxPktBytes == 0) { /* packet is done */
1724 assert(rxPktBytes
== 0);
1725 DPRINTF(EthernetSM
, "done with receiving packet\n");
1727 cmdsts
|= CMDSTS_OWN
;
1728 cmdsts
&= ~CMDSTS_MORE
;
1729 cmdsts
|= CMDSTS_OK
;
1730 cmdsts
&= 0xffff0000;
1731 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1735 * all the driver uses these are for its own stats keeping
1736 * which we don't care about, aren't necessary for
1737 * functionality and doing this would just slow us down.
1738 * if they end up using this in a later version for
1739 * functional purposes, just undef
1741 if (rxFilterEnable
) {
1742 cmdsts
&= ~CMDSTS_DEST_MASK
;
1743 const EthAddr
&dst
= rxFifoFront()->dst();
1745 cmdsts
|= CMDSTS_DEST_SELF
;
1746 if (dst
->multicast())
1747 cmdsts
|= CMDSTS_DEST_MULTI
;
1748 if (dst
->broadcast())
1749 cmdsts
|= CMDSTS_DEST_MASK
;
1754 if (extstsEnable
&& ip
) {
1755 extsts
|= EXTSTS_IPPKT
;
1757 if (cksum(ip
) != 0) {
1758 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1759 extsts
|= EXTSTS_IPERR
;
1764 extsts
|= EXTSTS_TCPPKT
;
1766 if (cksum(tcp
) != 0) {
1767 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1768 extsts
|= EXTSTS_TCPERR
;
1772 extsts
|= EXTSTS_UDPPKT
;
1774 if (cksum(udp
) != 0) {
1775 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1776 extsts
|= EXTSTS_UDPERR
;
1783 * the driver seems to always receive into desc buffers
1784 * of size 1514, so you never have a pkt that is split
1785 * into multiple descriptors on the receive side, so
1786 * i don't implement that case, hence the assert above.
1789 DPRINTF(EthernetDesc
,
1790 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1791 regs
.rxdp
& 0x3fffffff);
1792 DPRINTF(EthernetDesc
,
1793 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1794 link
, bufptr
, cmdsts
, extsts
);
1796 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1797 rxDmaData
= &cmdsts
;
1799 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1800 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1802 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1803 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1805 rxDmaFree
= dmaDescFree
;
1808 descDmaWrBytes
+= rxDmaLen
;
1816 if (rxDmaState
!= dmaIdle
)
1819 rxPacketBufPtr
+= rxXferLen
;
1820 rxFragPtr
+= rxXferLen
;
1821 rxPktBytes
-= rxXferLen
;
1823 rxState
= rxFifoBlock
;
1827 if (rxDmaState
!= dmaIdle
)
1830 assert(cmdsts
& CMDSTS_OWN
);
1832 assert(rxPacket
== 0);
1833 devIntrPost(ISR_RXOK
);
1835 if (cmdsts
& CMDSTS_INTR
)
1836 devIntrPost(ISR_RXDESC
);
1839 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1843 rxState
= rxAdvance
;
1848 devIntrPost(ISR_RXIDLE
);
1853 if (rxDmaState
!= dmaIdle
)
1855 rxState
= rxDescRead
;
1859 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1860 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1861 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1862 rxDmaFree
= dmaDescFree
;
1870 panic("Invalid rxState!");
1873 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1874 NsRxStateStrings
[rxState
]);
1879 * @todo do we want to schedule a future kick?
1881 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1882 NsRxStateStrings
[rxState
]);
1884 if (clock
&& !rxKickEvent
.scheduled())
1885 rxKickEvent
.schedule(rxKickTick
);
1891 if (txFifo
.empty()) {
1892 DPRINTF(Ethernet
, "nothing to transmit\n");
1896 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1898 if (interface
->sendPacket(txFifo
.front())) {
1900 if (DTRACE(Ethernet
)) {
1901 IpPtr
ip(txFifo
.front());
1903 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1907 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1908 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1915 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1916 txBytes
+= txFifo
.front()->length
;
1919 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1924 * normally do a writeback of the descriptor here, and ONLY
1925 * after that is done, send this interrupt. but since our
1926 * stuff never actually fails, just do this interrupt here,
1927 * otherwise the code has to stray from this nice format.
1928 * besides, it's functionally the same.
1930 devIntrPost(ISR_TXOK
);
1933 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1934 DPRINTF(Ethernet
, "reschedule transmit\n");
1935 txEvent
.schedule(curTick
+ retryTime
);
1940 NSGigE::txDmaReadCopy()
1942 assert(txDmaState
== dmaReading
);
1944 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1945 txDmaState
= dmaIdle
;
1947 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1948 txDmaAddr
, txDmaLen
);
1949 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1953 NSGigE::doTxDmaRead()
1955 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1956 txDmaState
= dmaReading
;
1958 if (dmaInterface
&& !txDmaFree
) {
1959 if (dmaInterface
->busy())
1960 txDmaState
= dmaReadWaiting
;
1962 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1963 &txDmaReadEvent
, true);
1967 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1972 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1973 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1974 txDmaReadEvent
.schedule(start
);
1979 NSGigE::txDmaReadDone()
1981 assert(txDmaState
== dmaReading
);
1984 // If the receive state machine has a pending DMA, let it go first
1985 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1992 NSGigE::txDmaWriteCopy()
1994 assert(txDmaState
== dmaWriting
);
1996 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
1997 txDmaState
= dmaIdle
;
1999 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
2000 txDmaAddr
, txDmaLen
);
2001 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
2005 NSGigE::doTxDmaWrite()
2007 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
2008 txDmaState
= dmaWriting
;
2010 if (dmaInterface
&& !txDmaFree
) {
2011 if (dmaInterface
->busy())
2012 txDmaState
= dmaWriteWaiting
;
2014 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2015 &txDmaWriteEvent
, true);
2019 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2024 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2025 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2026 txDmaWriteEvent
.schedule(start
);
2031 NSGigE::txDmaWriteDone()
2033 assert(txDmaState
== dmaWriting
);
2036 // If the receive state machine has a pending DMA, let it go first
2037 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2046 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
2048 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
2049 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
2052 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
2053 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
2057 if (txKickTick
> curTick
) {
2058 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2063 // Go to the next state machine clock tick.
2064 txKickTick
= curTick
+ cycles(1);
2067 switch(txDmaState
) {
2068 case dmaReadWaiting
:
2072 case dmaWriteWaiting
:
2080 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
2081 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
2085 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2090 txState
= txDescRefr
;
2092 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2094 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
2095 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
2096 txDmaFree
= dmaDescFree
;
2099 descDmaRdBytes
+= txDmaLen
;
2105 txState
= txDescRead
;
2107 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2108 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2109 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2110 txDmaFree
= dmaDescFree
;
2113 descDmaRdBytes
+= txDmaLen
;
2121 if (txDmaState
!= dmaIdle
)
2124 txState
= txAdvance
;
2128 if (txDmaState
!= dmaIdle
)
2131 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
2132 regs
.txdp
& 0x3fffffff);
2133 DPRINTF(EthernetDesc
,
2134 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
2135 link
, bufptr
, cmdsts
, extsts
);
2137 if (cmdsts
& CMDSTS_OWN
) {
2138 txState
= txFifoBlock
;
2140 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
2142 devIntrPost(ISR_TXIDLE
);
2150 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2151 txPacket
= new PacketData(16384);
2152 txPacketBufPtr
= txPacket
->data
;
2155 if (txDescCnt
== 0) {
2156 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2157 if (cmdsts
& CMDSTS_MORE
) {
2158 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2159 txState
= txDescWrite
;
2161 cmdsts
&= ~CMDSTS_OWN
;
2163 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2164 txDmaData
= &cmdsts
;
2166 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2167 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2169 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2170 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2172 txDmaFree
= dmaDescFree
;
2177 } else { /* this packet is totally done */
2178 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2179 /* deal with the the packet that just finished */
2180 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2182 if (extsts
& EXTSTS_UDPPKT
) {
2185 udp
->sum(cksum(udp
));
2187 } else if (extsts
& EXTSTS_TCPPKT
) {
2190 tcp
->sum(cksum(tcp
));
2193 if (extsts
& EXTSTS_IPPKT
) {
2200 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2201 // this is just because the receive can't handle a
2202 // packet bigger want to make sure
2203 if (txPacket
->length
> 1514)
2204 panic("transmit packet too large, %s > 1514\n",
2210 txFifo
.push(txPacket
);
2214 * this following section is not tqo spec, but
2215 * functionally shouldn't be any different. normally,
2216 * the chip will wait til the transmit has occurred
2217 * before writing back the descriptor because it has
2218 * to wait to see that it was successfully transmitted
2219 * to decide whether to set CMDSTS_OK or not.
2220 * however, in the simulator since it is always
2221 * successfully transmitted, and writing it exactly to
2222 * spec would complicate the code, we just do it here
2225 cmdsts
&= ~CMDSTS_OWN
;
2226 cmdsts
|= CMDSTS_OK
;
2228 DPRINTF(EthernetDesc
,
2229 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2232 txDmaFree
= dmaDescFree
;
2233 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2234 txDmaData
= &cmdsts
;
2236 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2238 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2240 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2242 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2246 descDmaWrBytes
+= txDmaLen
;
2252 DPRINTF(EthernetSM
, "halting TX state machine\n");
2256 txState
= txAdvance
;
2262 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2263 if (!txFifo
.full()) {
2264 txState
= txFragRead
;
2267 * The number of bytes transferred is either whatever
2268 * is left in the descriptor (txDescCnt), or if there
2269 * is not enough room in the fifo, just whatever room
2270 * is left in the fifo
2272 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2274 txDmaAddr
= txFragPtr
& 0x3fffffff;
2275 txDmaData
= txPacketBufPtr
;
2276 txDmaLen
= txXferLen
;
2277 txDmaFree
= dmaDataFree
;
2282 txState
= txFifoBlock
;
2292 if (txDmaState
!= dmaIdle
)
2295 txPacketBufPtr
+= txXferLen
;
2296 txFragPtr
+= txXferLen
;
2297 txDescCnt
-= txXferLen
;
2298 txFifo
.reserve(txXferLen
);
2300 txState
= txFifoBlock
;
2304 if (txDmaState
!= dmaIdle
)
2307 if (cmdsts
& CMDSTS_INTR
)
2308 devIntrPost(ISR_TXDESC
);
2311 DPRINTF(EthernetSM
, "halting TX state machine\n");
2315 txState
= txAdvance
;
2320 devIntrPost(ISR_TXIDLE
);
2324 if (txDmaState
!= dmaIdle
)
2326 txState
= txDescRead
;
2330 txDmaAddr
= link
& 0x3fffffff;
2331 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2332 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2333 txDmaFree
= dmaDescFree
;
2341 panic("invalid state");
2344 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2345 NsTxStateStrings
[txState
]);
2350 * @todo do we want to schedule a future kick?
2352 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2353 NsTxStateStrings
[txState
]);
2355 if (clock
&& !txKickEvent
.scheduled())
2356 txKickEvent
.schedule(txKickTick
);
2360 * Advance the EEPROM state machine
2361 * Called on rising edge of EEPROM clock bit in MEAR
2364 NSGigE::eepromKick()
2366 switch (eepromState
) {
2370 // Wait for start bit
2371 if (regs
.mear
& MEAR_EEDI
) {
2372 // Set up to get 2 opcode bits
2373 eepromState
= eepromGetOpcode
;
2379 case eepromGetOpcode
:
2381 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2384 // Done getting opcode
2385 if (eepromBitsToRx
== 0) {
2386 if (eepromOpcode
!= EEPROM_READ
)
2387 panic("only EEPROM reads are implemented!");
2389 // Set up to get address
2390 eepromState
= eepromGetAddress
;
2396 case eepromGetAddress
:
2397 eepromAddress
<<= 1;
2398 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2401 // Done getting address
2402 if (eepromBitsToRx
== 0) {
2404 if (eepromAddress
>= EEPROM_SIZE
)
2405 panic("EEPROM read access out of range!");
2407 switch (eepromAddress
) {
2409 case EEPROM_PMATCH2_ADDR
:
2410 eepromData
= rom
.perfectMatch
[5];
2412 eepromData
+= rom
.perfectMatch
[4];
2415 case EEPROM_PMATCH1_ADDR
:
2416 eepromData
= rom
.perfectMatch
[3];
2418 eepromData
+= rom
.perfectMatch
[2];
2421 case EEPROM_PMATCH0_ADDR
:
2422 eepromData
= rom
.perfectMatch
[1];
2424 eepromData
+= rom
.perfectMatch
[0];
2428 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2430 // Set up to read data
2431 eepromState
= eepromRead
;
2432 eepromBitsToRx
= 16;
2434 // Clear data in bit
2435 regs
.mear
&= ~MEAR_EEDI
;
2440 // Clear Data Out bit
2441 regs
.mear
&= ~MEAR_EEDO
;
2442 // Set bit to value of current EEPROM bit
2443 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2449 if (eepromBitsToRx
== 0) {
2450 eepromState
= eepromStart
;
2455 panic("invalid EEPROM state");
2461 NSGigE::transferDone()
2463 if (txFifo
.empty()) {
2464 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2468 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2470 if (txEvent
.scheduled())
2471 txEvent
.reschedule(curTick
+ cycles(1));
2473 txEvent
.schedule(curTick
+ cycles(1));
2477 NSGigE::rxFilter(const PacketPtr
&packet
)
2479 EthPtr eth
= packet
;
2483 const EthAddr
&dst
= eth
->dst();
2484 if (dst
.unicast()) {
2485 // If we're accepting all unicast addresses
2489 // If we make a perfect match
2490 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2493 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2496 } else if (dst
.broadcast()) {
2497 // if we're accepting broadcasts
2498 if (acceptBroadcast
)
2501 } else if (dst
.multicast()) {
2502 // if we're accepting all multicasts
2503 if (acceptMulticast
)
2506 // Multicast hashing faked - all packets accepted
2507 if (multicastHashEnable
)
2512 DPRINTF(Ethernet
, "rxFilter drop\n");
2513 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2520 NSGigE::recvPacket(PacketPtr packet
)
2522 rxBytes
+= packet
->length
;
2525 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2529 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2533 if (!rxFilterEnable
) {
2535 "receive packet filtering disabled . . . packet dropped\n");
2539 if (rxFilter(packet
)) {
2540 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2544 if (rxFifo
.avail() < packet
->length
) {
2550 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2553 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2558 devIntrPost(ISR_RXORN
);
2562 rxFifo
.push(packet
);
2568 //=====================================================================
2572 NSGigE::serialize(ostream
&os
)
2574 // Serialize the PciDev base class
2575 PciDev::serialize(os
);
2578 * Finalize any DMA events now.
2580 if (rxDmaReadEvent
.scheduled())
2582 if (rxDmaWriteEvent
.scheduled())
2584 if (txDmaReadEvent
.scheduled())
2586 if (txDmaWriteEvent
.scheduled())
2590 * Serialize the device registers
2592 SERIALIZE_SCALAR(regs
.command
);
2593 SERIALIZE_SCALAR(regs
.config
);
2594 SERIALIZE_SCALAR(regs
.mear
);
2595 SERIALIZE_SCALAR(regs
.ptscr
);
2596 SERIALIZE_SCALAR(regs
.isr
);
2597 SERIALIZE_SCALAR(regs
.imr
);
2598 SERIALIZE_SCALAR(regs
.ier
);
2599 SERIALIZE_SCALAR(regs
.ihr
);
2600 SERIALIZE_SCALAR(regs
.txdp
);
2601 SERIALIZE_SCALAR(regs
.txdp_hi
);
2602 SERIALIZE_SCALAR(regs
.txcfg
);
2603 SERIALIZE_SCALAR(regs
.gpior
);
2604 SERIALIZE_SCALAR(regs
.rxdp
);
2605 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2606 SERIALIZE_SCALAR(regs
.rxcfg
);
2607 SERIALIZE_SCALAR(regs
.pqcr
);
2608 SERIALIZE_SCALAR(regs
.wcsr
);
2609 SERIALIZE_SCALAR(regs
.pcr
);
2610 SERIALIZE_SCALAR(regs
.rfcr
);
2611 SERIALIZE_SCALAR(regs
.rfdr
);
2612 SERIALIZE_SCALAR(regs
.brar
);
2613 SERIALIZE_SCALAR(regs
.brdr
);
2614 SERIALIZE_SCALAR(regs
.srr
);
2615 SERIALIZE_SCALAR(regs
.mibc
);
2616 SERIALIZE_SCALAR(regs
.vrcr
);
2617 SERIALIZE_SCALAR(regs
.vtcr
);
2618 SERIALIZE_SCALAR(regs
.vdr
);
2619 SERIALIZE_SCALAR(regs
.ccsr
);
2620 SERIALIZE_SCALAR(regs
.tbicr
);
2621 SERIALIZE_SCALAR(regs
.tbisr
);
2622 SERIALIZE_SCALAR(regs
.tanar
);
2623 SERIALIZE_SCALAR(regs
.tanlpar
);
2624 SERIALIZE_SCALAR(regs
.taner
);
2625 SERIALIZE_SCALAR(regs
.tesr
);
2627 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2628 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2630 SERIALIZE_SCALAR(ioEnable
);
2633 * Serialize the data Fifos
2635 rxFifo
.serialize("rxFifo", os
);
2636 txFifo
.serialize("txFifo", os
);
2639 * Serialize the various helper variables
2641 bool txPacketExists
= txPacket
;
2642 SERIALIZE_SCALAR(txPacketExists
);
2643 if (txPacketExists
) {
2644 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2645 txPacket
->serialize("txPacket", os
);
2646 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2647 SERIALIZE_SCALAR(txPktBufPtr
);
2650 bool rxPacketExists
= rxPacket
;
2651 SERIALIZE_SCALAR(rxPacketExists
);
2652 if (rxPacketExists
) {
2653 rxPacket
->serialize("rxPacket", os
);
2654 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2655 SERIALIZE_SCALAR(rxPktBufPtr
);
2658 SERIALIZE_SCALAR(txXferLen
);
2659 SERIALIZE_SCALAR(rxXferLen
);
2662 * Serialize Cached Descriptors
2664 SERIALIZE_SCALAR(rxDesc64
.link
);
2665 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2666 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2667 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2668 SERIALIZE_SCALAR(txDesc64
.link
);
2669 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2670 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2671 SERIALIZE_SCALAR(txDesc64
.extsts
);
2672 SERIALIZE_SCALAR(rxDesc32
.link
);
2673 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2674 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2675 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2676 SERIALIZE_SCALAR(txDesc32
.link
);
2677 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2678 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2679 SERIALIZE_SCALAR(txDesc32
.extsts
);
2680 SERIALIZE_SCALAR(extstsEnable
);
2683 * Serialize tx state machine
2685 int txState
= this->txState
;
2686 SERIALIZE_SCALAR(txState
);
2687 SERIALIZE_SCALAR(txEnable
);
2688 SERIALIZE_SCALAR(CTDD
);
2689 SERIALIZE_SCALAR(txFragPtr
);
2690 SERIALIZE_SCALAR(txDescCnt
);
2691 int txDmaState
= this->txDmaState
;
2692 SERIALIZE_SCALAR(txDmaState
);
2693 SERIALIZE_SCALAR(txKickTick
);
2696 * Serialize rx state machine
2698 int rxState
= this->rxState
;
2699 SERIALIZE_SCALAR(rxState
);
2700 SERIALIZE_SCALAR(rxEnable
);
2701 SERIALIZE_SCALAR(CRDD
);
2702 SERIALIZE_SCALAR(rxPktBytes
);
2703 SERIALIZE_SCALAR(rxFragPtr
);
2704 SERIALIZE_SCALAR(rxDescCnt
);
2705 int rxDmaState
= this->rxDmaState
;
2706 SERIALIZE_SCALAR(rxDmaState
);
2707 SERIALIZE_SCALAR(rxKickTick
);
2710 * Serialize EEPROM state machine
2712 int eepromState
= this->eepromState
;
2713 SERIALIZE_SCALAR(eepromState
);
2714 SERIALIZE_SCALAR(eepromClk
);
2715 SERIALIZE_SCALAR(eepromBitsToRx
);
2716 SERIALIZE_SCALAR(eepromOpcode
);
2717 SERIALIZE_SCALAR(eepromAddress
);
2718 SERIALIZE_SCALAR(eepromData
);
2721 * If there's a pending transmit, store the time so we can
2722 * reschedule it later
2724 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2725 SERIALIZE_SCALAR(transmitTick
);
2728 * receive address filter settings
2730 SERIALIZE_SCALAR(rxFilterEnable
);
2731 SERIALIZE_SCALAR(acceptBroadcast
);
2732 SERIALIZE_SCALAR(acceptMulticast
);
2733 SERIALIZE_SCALAR(acceptUnicast
);
2734 SERIALIZE_SCALAR(acceptPerfect
);
2735 SERIALIZE_SCALAR(acceptArp
);
2736 SERIALIZE_SCALAR(multicastHashEnable
);
2739 * Keep track of pending interrupt status.
2741 SERIALIZE_SCALAR(intrTick
);
2742 SERIALIZE_SCALAR(cpuPendingIntr
);
2743 Tick intrEventTick
= 0;
2745 intrEventTick
= intrEvent
->when();
2746 SERIALIZE_SCALAR(intrEventTick
);
2751 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2753 // Unserialize the PciDev base class
2754 PciDev::unserialize(cp
, section
);
2756 UNSERIALIZE_SCALAR(regs
.command
);
2757 UNSERIALIZE_SCALAR(regs
.config
);
2758 UNSERIALIZE_SCALAR(regs
.mear
);
2759 UNSERIALIZE_SCALAR(regs
.ptscr
);
2760 UNSERIALIZE_SCALAR(regs
.isr
);
2761 UNSERIALIZE_SCALAR(regs
.imr
);
2762 UNSERIALIZE_SCALAR(regs
.ier
);
2763 UNSERIALIZE_SCALAR(regs
.ihr
);
2764 UNSERIALIZE_SCALAR(regs
.txdp
);
2765 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2766 UNSERIALIZE_SCALAR(regs
.txcfg
);
2767 UNSERIALIZE_SCALAR(regs
.gpior
);
2768 UNSERIALIZE_SCALAR(regs
.rxdp
);
2769 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2770 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2771 UNSERIALIZE_SCALAR(regs
.pqcr
);
2772 UNSERIALIZE_SCALAR(regs
.wcsr
);
2773 UNSERIALIZE_SCALAR(regs
.pcr
);
2774 UNSERIALIZE_SCALAR(regs
.rfcr
);
2775 UNSERIALIZE_SCALAR(regs
.rfdr
);
2776 UNSERIALIZE_SCALAR(regs
.brar
);
2777 UNSERIALIZE_SCALAR(regs
.brdr
);
2778 UNSERIALIZE_SCALAR(regs
.srr
);
2779 UNSERIALIZE_SCALAR(regs
.mibc
);
2780 UNSERIALIZE_SCALAR(regs
.vrcr
);
2781 UNSERIALIZE_SCALAR(regs
.vtcr
);
2782 UNSERIALIZE_SCALAR(regs
.vdr
);
2783 UNSERIALIZE_SCALAR(regs
.ccsr
);
2784 UNSERIALIZE_SCALAR(regs
.tbicr
);
2785 UNSERIALIZE_SCALAR(regs
.tbisr
);
2786 UNSERIALIZE_SCALAR(regs
.tanar
);
2787 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2788 UNSERIALIZE_SCALAR(regs
.taner
);
2789 UNSERIALIZE_SCALAR(regs
.tesr
);
2791 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2792 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2794 UNSERIALIZE_SCALAR(ioEnable
);
2797 * unserialize the data fifos
2799 rxFifo
.unserialize("rxFifo", cp
, section
);
2800 txFifo
.unserialize("txFifo", cp
, section
);
2803 * unserialize the various helper variables
2805 bool txPacketExists
;
2806 UNSERIALIZE_SCALAR(txPacketExists
);
2807 if (txPacketExists
) {
2808 txPacket
= new PacketData(16384);
2809 txPacket
->unserialize("txPacket", cp
, section
);
2810 uint32_t txPktBufPtr
;
2811 UNSERIALIZE_SCALAR(txPktBufPtr
);
2812 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2816 bool rxPacketExists
;
2817 UNSERIALIZE_SCALAR(rxPacketExists
);
2819 if (rxPacketExists
) {
2820 rxPacket
= new PacketData(16384);
2821 rxPacket
->unserialize("rxPacket", cp
, section
);
2822 uint32_t rxPktBufPtr
;
2823 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2824 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2828 UNSERIALIZE_SCALAR(txXferLen
);
2829 UNSERIALIZE_SCALAR(rxXferLen
);
2832 * Unserialize Cached Descriptors
2834 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2835 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2836 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2837 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2838 UNSERIALIZE_SCALAR(txDesc64
.link
);
2839 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2840 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2841 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2842 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2843 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2844 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2845 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2846 UNSERIALIZE_SCALAR(txDesc32
.link
);
2847 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2848 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2849 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2850 UNSERIALIZE_SCALAR(extstsEnable
);
2853 * unserialize tx state machine
2856 UNSERIALIZE_SCALAR(txState
);
2857 this->txState
= (TxState
) txState
;
2858 UNSERIALIZE_SCALAR(txEnable
);
2859 UNSERIALIZE_SCALAR(CTDD
);
2860 UNSERIALIZE_SCALAR(txFragPtr
);
2861 UNSERIALIZE_SCALAR(txDescCnt
);
2863 UNSERIALIZE_SCALAR(txDmaState
);
2864 this->txDmaState
= (DmaState
) txDmaState
;
2865 UNSERIALIZE_SCALAR(txKickTick
);
2867 txKickEvent
.schedule(txKickTick
);
2870 * unserialize rx state machine
2873 UNSERIALIZE_SCALAR(rxState
);
2874 this->rxState
= (RxState
) rxState
;
2875 UNSERIALIZE_SCALAR(rxEnable
);
2876 UNSERIALIZE_SCALAR(CRDD
);
2877 UNSERIALIZE_SCALAR(rxPktBytes
);
2878 UNSERIALIZE_SCALAR(rxFragPtr
);
2879 UNSERIALIZE_SCALAR(rxDescCnt
);
2881 UNSERIALIZE_SCALAR(rxDmaState
);
2882 this->rxDmaState
= (DmaState
) rxDmaState
;
2883 UNSERIALIZE_SCALAR(rxKickTick
);
2885 rxKickEvent
.schedule(rxKickTick
);
2888 * Unserialize EEPROM state machine
2891 UNSERIALIZE_SCALAR(eepromState
);
2892 this->eepromState
= (EEPROMState
) eepromState
;
2893 UNSERIALIZE_SCALAR(eepromClk
);
2894 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2895 UNSERIALIZE_SCALAR(eepromOpcode
);
2896 UNSERIALIZE_SCALAR(eepromAddress
);
2897 UNSERIALIZE_SCALAR(eepromData
);
2900 * If there's a pending transmit, reschedule it now
2903 UNSERIALIZE_SCALAR(transmitTick
);
2905 txEvent
.schedule(curTick
+ transmitTick
);
2908 * unserialize receive address filter settings
2910 UNSERIALIZE_SCALAR(rxFilterEnable
);
2911 UNSERIALIZE_SCALAR(acceptBroadcast
);
2912 UNSERIALIZE_SCALAR(acceptMulticast
);
2913 UNSERIALIZE_SCALAR(acceptUnicast
);
2914 UNSERIALIZE_SCALAR(acceptPerfect
);
2915 UNSERIALIZE_SCALAR(acceptArp
);
2916 UNSERIALIZE_SCALAR(multicastHashEnable
);
2919 * Keep track of pending interrupt status.
2921 UNSERIALIZE_SCALAR(intrTick
);
2922 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2924 UNSERIALIZE_SCALAR(intrEventTick
);
2925 if (intrEventTick
) {
2926 intrEvent
= new IntrEvent(this, true);
2927 intrEvent
->schedule(intrEventTick
);
2931 * re-add addrRanges to bus bridges
2934 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2935 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2940 NSGigE::cacheAccess(MemReqPtr
&req
)
2942 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2943 req
->paddr
, req
->paddr
& 0xfff);
2945 return curTick
+ pioLatency
;
2948 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2950 SimObjectParam
<EtherInt
*> peer
;
2951 SimObjectParam
<NSGigE
*> device
;
2953 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2955 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2957 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2958 INIT_PARAM(device
, "Ethernet device of this interface")
2960 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2962 CREATE_SIM_OBJECT(NSGigEInt
)
2964 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2966 EtherInt
*p
= (EtherInt
*)peer
;
2968 dev_int
->setPeer(p
);
2969 p
->setPeer(dev_int
);
2975 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2978 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2983 SimObjectParam
<MemoryController
*> mmu
;
2984 SimObjectParam
<PhysicalMemory
*> physmem
;
2985 SimObjectParam
<PciConfigAll
*> configspace
;
2986 SimObjectParam
<PciConfigData
*> configdata
;
2987 SimObjectParam
<Platform
*> platform
;
2988 Param
<uint32_t> pci_bus
;
2989 Param
<uint32_t> pci_dev
;
2990 Param
<uint32_t> pci_func
;
2992 SimObjectParam
<HierParams
*> hier
;
2993 SimObjectParam
<Bus
*> pio_bus
;
2994 SimObjectParam
<Bus
*> dma_bus
;
2995 SimObjectParam
<Bus
*> payload_bus
;
2996 Param
<bool> dma_desc_free
;
2997 Param
<bool> dma_data_free
;
2998 Param
<Tick
> dma_read_delay
;
2999 Param
<Tick
> dma_write_delay
;
3000 Param
<Tick
> dma_read_factor
;
3001 Param
<Tick
> dma_write_factor
;
3002 Param
<bool> dma_no_allocate
;
3003 Param
<Tick
> pio_latency
;
3004 Param
<Tick
> intr_delay
;
3006 Param
<Tick
> rx_delay
;
3007 Param
<Tick
> tx_delay
;
3008 Param
<uint32_t> rx_fifo_size
;
3009 Param
<uint32_t> tx_fifo_size
;
3011 Param
<bool> rx_filter
;
3012 Param
<string
> hardware_address
;
3013 Param
<bool> rx_thread
;
3014 Param
<bool> tx_thread
;
3017 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3019 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3021 INIT_PARAM(clock
, "State machine processor frequency"),
3023 INIT_PARAM(addr
, "Device Address"),
3024 INIT_PARAM(mmu
, "Memory Controller"),
3025 INIT_PARAM(physmem
, "Physical Memory"),
3026 INIT_PARAM(configspace
, "PCI Configspace"),
3027 INIT_PARAM(configdata
, "PCI Config data"),
3028 INIT_PARAM(platform
, "Platform"),
3029 INIT_PARAM(pci_bus
, "PCI bus"),
3030 INIT_PARAM(pci_dev
, "PCI device number"),
3031 INIT_PARAM(pci_func
, "PCI function code"),
3033 INIT_PARAM(hier
, "Hierarchy global variables"),
3034 INIT_PARAM(pio_bus
, ""),
3035 INIT_PARAM(dma_bus
, ""),
3036 INIT_PARAM(payload_bus
, "The IO Bus to attach to for payload"),
3037 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
3038 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
3039 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
3040 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
3041 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
3042 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
3043 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
3044 INIT_PARAM(pio_latency
, "Programmed IO latency in bus cycles"),
3045 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
3047 INIT_PARAM(rx_delay
, "Receive Delay"),
3048 INIT_PARAM(tx_delay
, "Transmit Delay"),
3049 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
3050 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
3052 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
3053 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
3054 INIT_PARAM(rx_thread
, ""),
3055 INIT_PARAM(tx_thread
, ""),
3058 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3061 CREATE_SIM_OBJECT(NSGigE
)
3063 NSGigE::Params
*params
= new NSGigE::Params
;
3065 params
->name
= getInstanceName();
3067 params
->clock
= clock
;
3070 params
->pmem
= physmem
;
3071 params
->configSpace
= configspace
;
3072 params
->configData
= configdata
;
3073 params
->plat
= platform
;
3074 params
->busNum
= pci_bus
;
3075 params
->deviceNum
= pci_dev
;
3076 params
->functionNum
= pci_func
;
3078 params
->hier
= hier
;
3079 params
->pio_bus
= pio_bus
;
3080 params
->header_bus
= dma_bus
;
3081 params
->payload_bus
= payload_bus
;
3082 params
->dma_desc_free
= dma_desc_free
;
3083 params
->dma_data_free
= dma_data_free
;
3084 params
->dma_read_delay
= dma_read_delay
;
3085 params
->dma_write_delay
= dma_write_delay
;
3086 params
->dma_read_factor
= dma_read_factor
;
3087 params
->dma_write_factor
= dma_write_factor
;
3088 params
->dma_no_allocate
= dma_no_allocate
;
3089 params
->pio_latency
= pio_latency
;
3090 params
->intr_delay
= intr_delay
;
3092 params
->rx_delay
= rx_delay
;
3093 params
->tx_delay
= tx_delay
;
3094 params
->rx_fifo_size
= rx_fifo_size
;
3095 params
->tx_fifo_size
= tx_fifo_size
;
3097 params
->rx_filter
= rx_filter
;
3098 params
->eaddr
= hardware_address
;
3099 params
->rx_thread
= rx_thread
;
3100 params
->tx_thread
= tx_thread
;
3103 return new NSGigE(params
);
3106 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)