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
[] =
88 ///////////////////////////////////////////////////////////////////////
92 NSGigE::NSGigE(Params
*p
)
93 : PciDev(p
), ioEnable(false),
94 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
95 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
96 txXferLen(0), rxXferLen(0), clock(p
->clock
),
97 txState(txIdle
), txEnable(false), CTDD(false),
98 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
99 rxEnable(false), CRDD(false), rxPktBytes(0),
100 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
101 eepromState(eepromStart
), rxDmaReadEvent(this), rxDmaWriteEvent(this),
102 txDmaReadEvent(this), txDmaWriteEvent(this),
103 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
104 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
105 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
106 txEvent(this), rxFilterEnable(p
->rx_filter
), acceptBroadcast(false),
107 acceptMulticast(false), acceptUnicast(false),
108 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
109 physmem(p
->pmem
), intrTick(0), cpuPendingIntr(false),
110 intrEvent(0), interface(0)
113 pioInterface
= newPioInterface(name() + ".pio", p
->hier
,
115 &NSGigE::cacheAccess
);
117 pioLatency
= p
->pio_latency
* p
->header_bus
->clockRate
;
120 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
125 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
129 } else if (p
->payload_bus
) {
130 pioInterface
= newPioInterface(name() + ".pio2", p
->hier
,
131 p
->payload_bus
, this,
132 &NSGigE::cacheAccess
);
134 pioLatency
= p
->pio_latency
* p
->payload_bus
->clockRate
;
136 dmaInterface
= new DMAInterface
<Bus
>(name() + ".dma",
143 intrDelay
= p
->intr_delay
;
144 dmaReadDelay
= p
->dma_read_delay
;
145 dmaWriteDelay
= p
->dma_write_delay
;
146 dmaReadFactor
= p
->dma_read_factor
;
147 dmaWriteFactor
= p
->dma_write_factor
;
150 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
160 .name(name() + ".txBytes")
161 .desc("Bytes Transmitted")
166 .name(name() + ".rxBytes")
167 .desc("Bytes Received")
172 .name(name() + ".txPackets")
173 .desc("Number of Packets Transmitted")
178 .name(name() + ".rxPackets")
179 .desc("Number of Packets Received")
184 .name(name() + ".txIpChecksums")
185 .desc("Number of tx IP Checksums done by device")
191 .name(name() + ".rxIpChecksums")
192 .desc("Number of rx IP Checksums done by device")
198 .name(name() + ".txTcpChecksums")
199 .desc("Number of tx TCP Checksums done by device")
205 .name(name() + ".rxTcpChecksums")
206 .desc("Number of rx TCP Checksums done by device")
212 .name(name() + ".txUdpChecksums")
213 .desc("Number of tx UDP Checksums done by device")
219 .name(name() + ".rxUdpChecksums")
220 .desc("Number of rx UDP Checksums done by device")
226 .name(name() + ".descDMAReads")
227 .desc("Number of descriptors the device read w/ DMA")
232 .name(name() + ".descDMAWrites")
233 .desc("Number of descriptors the device wrote w/ DMA")
238 .name(name() + ".descDmaReadBytes")
239 .desc("number of descriptor bytes read w/ DMA")
244 .name(name() + ".descDmaWriteBytes")
245 .desc("number of descriptor bytes write w/ DMA")
250 .name(name() + ".txBandwidth")
251 .desc("Transmit Bandwidth (bits/s)")
257 .name(name() + ".rxBandwidth")
258 .desc("Receive Bandwidth (bits/s)")
264 .name(name() + ".totBandwidth")
265 .desc("Total Bandwidth (bits/s)")
271 .name(name() + ".totPackets")
272 .desc("Total Packets")
278 .name(name() + ".totBytes")
285 .name(name() + ".totPPS")
286 .desc("Total Tranmission Rate (packets/s)")
292 .name(name() + ".txPPS")
293 .desc("Packet Tranmission Rate (packets/s)")
299 .name(name() + ".rxPPS")
300 .desc("Packet Reception Rate (packets/s)")
306 .name(name() + ".postedSwi")
307 .desc("number of software interrupts posted to CPU")
312 .name(name() + ".totalSwi")
313 .desc("number of total Swi written to ISR")
318 .name(name() + ".coalescedSwi")
319 .desc("average number of Swi's coalesced into each post")
324 .name(name() + ".postedRxIdle")
325 .desc("number of rxIdle interrupts posted to CPU")
330 .name(name() + ".totalRxIdle")
331 .desc("number of total RxIdle written to ISR")
336 .name(name() + ".coalescedRxIdle")
337 .desc("average number of RxIdle's coalesced into each post")
342 .name(name() + ".postedRxOk")
343 .desc("number of RxOk interrupts posted to CPU")
348 .name(name() + ".totalRxOk")
349 .desc("number of total RxOk written to ISR")
354 .name(name() + ".coalescedRxOk")
355 .desc("average number of RxOk's coalesced into each post")
360 .name(name() + ".postedRxDesc")
361 .desc("number of RxDesc interrupts posted to CPU")
366 .name(name() + ".totalRxDesc")
367 .desc("number of total RxDesc written to ISR")
372 .name(name() + ".coalescedRxDesc")
373 .desc("average number of RxDesc's coalesced into each post")
378 .name(name() + ".postedTxOk")
379 .desc("number of TxOk interrupts posted to CPU")
384 .name(name() + ".totalTxOk")
385 .desc("number of total TxOk written to ISR")
390 .name(name() + ".coalescedTxOk")
391 .desc("average number of TxOk's coalesced into each post")
396 .name(name() + ".postedTxIdle")
397 .desc("number of TxIdle interrupts posted to CPU")
402 .name(name() + ".totalTxIdle")
403 .desc("number of total TxIdle written to ISR")
408 .name(name() + ".coalescedTxIdle")
409 .desc("average number of TxIdle's coalesced into each post")
414 .name(name() + ".postedTxDesc")
415 .desc("number of TxDesc interrupts posted to CPU")
420 .name(name() + ".totalTxDesc")
421 .desc("number of total TxDesc written to ISR")
426 .name(name() + ".coalescedTxDesc")
427 .desc("average number of TxDesc's coalesced into each post")
432 .name(name() + ".postedRxOrn")
433 .desc("number of RxOrn posted to CPU")
438 .name(name() + ".totalRxOrn")
439 .desc("number of total RxOrn written to ISR")
444 .name(name() + ".coalescedRxOrn")
445 .desc("average number of RxOrn's coalesced into each post")
450 .name(name() + ".coalescedTotal")
451 .desc("average number of interrupts coalesced into each post")
456 .name(name() + ".postedInterrupts")
457 .desc("number of posts to CPU")
462 .name(name() + ".droppedPackets")
463 .desc("number of packets dropped")
467 coalescedSwi
= totalSwi
/ postedInterrupts
;
468 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
469 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
470 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
471 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
472 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
473 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
474 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
476 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
477 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
478 totalRxOrn
) / postedInterrupts
;
480 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
481 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
482 totBandwidth
= txBandwidth
+ rxBandwidth
;
483 totBytes
= txBytes
+ rxBytes
;
484 totPackets
= txPackets
+ rxPackets
;
486 txPacketRate
= txPackets
/ simSeconds
;
487 rxPacketRate
= rxPackets
/ simSeconds
;
491 * This is to read the PCI general configuration registers
494 NSGigE::readConfig(int offset
, int size
, uint8_t *data
)
496 if (offset
< PCI_DEVICE_SPECIFIC
)
497 PciDev::readConfig(offset
, size
, data
);
499 panic("Device specific PCI config space not implemented!\n");
503 * This is to write to the PCI general configuration registers
506 NSGigE::writeConfig(int offset
, int size
, const uint8_t* data
)
508 if (offset
< PCI_DEVICE_SPECIFIC
)
509 PciDev::writeConfig(offset
, size
, data
);
511 panic("Device specific PCI config space not implemented!\n");
513 // Need to catch writes to BARs to update the PIO interface
515 // seems to work fine without all these PCI settings, but i
516 // put in the IO to double check, an assertion will fail if we
517 // need to properly implement it
519 if (config
.data
[offset
] & PCI_CMD_IOSE
)
525 if (config
.data
[offset
] & PCI_CMD_BME
) {
532 if (config
.data
[offset
] & PCI_CMD_MSE
) {
541 case PCI0_BASE_ADDR0
:
542 if (BARAddrs
[0] != 0) {
544 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
546 BARAddrs
[0] &= EV5::PAddrUncachedMask
;
549 case PCI0_BASE_ADDR1
:
550 if (BARAddrs
[1] != 0) {
552 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
554 BARAddrs
[1] &= EV5::PAddrUncachedMask
;
561 * This reads the device registers, which are detailed in the NS83820
565 NSGigE::read(MemReqPtr
&req
, uint8_t *data
)
569 //The mask is to give you only the offset into the device register file
570 Addr daddr
= req
->paddr
& 0xfff;
571 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x va=%#x size=%d\n",
572 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
575 // there are some reserved registers, you can see ns_gige_reg.h and
576 // the spec sheet for details
577 if (daddr
> LAST
&& daddr
<= RESERVED
) {
578 panic("Accessing reserved register");
579 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
580 readConfig(daddr
& 0xff, req
->size
, data
);
582 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
583 // don't implement all the MIB's. hopefully the kernel
584 // doesn't actually DEPEND upon their values
585 // MIB are just hardware stats keepers
586 uint32_t ®
= *(uint32_t *) data
;
589 } else if (daddr
> 0x3FC)
590 panic("Something is messed up!\n");
593 case sizeof(uint32_t):
595 uint32_t ®
= *(uint32_t *)data
;
601 //these are supposed to be cleared on a read
602 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
619 devIntrClear(ISR_ALL
);
674 // see the spec sheet for how RFCR and RFDR work
675 // basically, you write to RFCR to tell the machine
676 // what you want to do next, then you act upon RFDR,
677 // and the device will be prepared b/c of what you
684 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
686 // Read from perfect match ROM octets
688 reg
= rom
.perfectMatch
[1];
690 reg
+= rom
.perfectMatch
[0];
693 reg
= rom
.perfectMatch
[3] << 8;
694 reg
+= rom
.perfectMatch
[2];
697 reg
= rom
.perfectMatch
[5] << 8;
698 reg
+= rom
.perfectMatch
[4];
701 // Read filter hash table
702 if (rfaddr
>= FHASH_ADDR
&&
703 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
705 // Only word-aligned reads supported
707 panic("unaligned read from filter hash table!");
709 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
710 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
714 panic("reading RFDR for something other than pattern"
715 " matching or hashing! %#x\n", rfaddr
);
725 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
769 reg
= params()->m5reg
;
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.
872 if (reg
& CFGR_TBI_EN
) ;
873 if (reg
& CFGR_MODE_1000
) ;
876 if (reg
& CFGR_AUTO_1000
)
877 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
) ;
901 if (reg
& CFGR_EXTSTS_EN
)
904 extstsEnable
= false;
907 if (reg
& CFGR_REQALG
) ;
909 if (reg
& CFGR_POW
) ;
910 if (reg
& CFGR_EXD
) ;
911 if (reg
& CFGR_PESEL
) ;
912 if (reg
& CFGR_BROM_DIS
) ;
913 if (reg
& CFGR_EXT_125
) ;
914 if (reg
& CFGR_BEM
) ;
919 // Clear writable bits
920 regs
.mear
&= MEAR_EEDO
;
921 // Set appropriate writable bits
922 regs
.mear
|= reg
& ~MEAR_EEDO
;
924 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
925 // even though it could get it through RFDR
926 if (reg
& MEAR_EESEL
) {
927 // Rising edge of clock
928 if (reg
& MEAR_EECLK
&& !eepromClk
)
932 eepromState
= eepromStart
;
933 regs
.mear
&= ~MEAR_EEDI
;
936 eepromClk
= reg
& MEAR_EECLK
;
938 // since phy is completely faked, MEAR_MD* don't matter
940 if (reg
& MEAR_MDIO
) ;
941 if (reg
& MEAR_MDDIR
) ;
942 if (reg
& MEAR_MDC
) ;
947 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
948 // these control BISTs for various parts of chip - we
949 // don't care or do just fake that the BIST is done
950 if (reg
& PTSCR_RBIST_EN
)
951 regs
.ptscr
|= PTSCR_RBIST_DONE
;
952 if (reg
& PTSCR_EEBIST_EN
)
953 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
954 if (reg
& PTSCR_EELOAD_EN
)
955 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
958 case ISR
: /* writing to the ISR has no effect */
959 panic("ISR is a read only register!\n");
972 /* not going to implement real interrupt holdoff */
976 regs
.txdp
= (reg
& 0xFFFFFFFC);
977 assert(txState
== txIdle
);
988 if (reg
& TX_CFG_CSI
) ;
989 if (reg
& TX_CFG_HBI
) ;
990 if (reg
& TX_CFG_MLB
) ;
991 if (reg
& TX_CFG_ATP
) ;
992 if (reg
& TX_CFG_ECRETRY
) {
994 * this could easily be implemented, but considering
995 * the network is just a fake pipe, wouldn't make
1000 if (reg
& TX_CFG_BRST_DIS
) ;
1004 /* we handle our own DMA, ignore the kernel's exhortations */
1005 if (reg
& TX_CFG_MXDMA
) ;
1008 // also, we currently don't care about fill/drain
1009 // thresholds though this may change in the future with
1010 // more realistic networks or a driver which changes it
1011 // according to feedback
1016 // Only write writable bits
1017 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1018 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1019 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1020 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1021 /* these just control general purpose i/o pins, don't matter */
1036 if (reg
& RX_CFG_AEP
) ;
1037 if (reg
& RX_CFG_ARP
) ;
1038 if (reg
& RX_CFG_STRIPCRC
) ;
1039 if (reg
& RX_CFG_RX_RD
) ;
1040 if (reg
& RX_CFG_ALP
) ;
1041 if (reg
& RX_CFG_AIRL
) ;
1043 /* we handle our own DMA, ignore what kernel says about it */
1044 if (reg
& RX_CFG_MXDMA
) ;
1046 //also, we currently don't care about fill/drain thresholds
1047 //though this may change in the future with more realistic
1048 //networks or a driver which changes it according to feedback
1049 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1054 /* there is no priority queueing used in the linux 2.6 driver */
1059 /* not going to implement wake on LAN */
1064 /* not going to implement pause control */
1071 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1072 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1073 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1074 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1075 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1076 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1077 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1080 if (reg
& RFCR_APAT
)
1081 panic("RFCR_APAT not implemented!\n");
1083 if (reg
& RFCR_UHEN
)
1084 panic("Unicast hash filtering not used by drivers!\n");
1087 panic("RFCR_ULM not implemented!\n");
1092 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1095 rom
.perfectMatch
[0] = (uint8_t)reg
;
1096 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1099 rom
.perfectMatch
[2] = (uint8_t)reg
;
1100 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1103 rom
.perfectMatch
[4] = (uint8_t)reg
;
1104 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1108 if (rfaddr
>= FHASH_ADDR
&&
1109 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1111 // Only word-aligned writes supported
1113 panic("unaligned write to filter hash table!");
1115 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1116 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1117 = (uint8_t)(reg
>> 8);
1120 panic("writing RFDR for something other than pattern matching\
1121 or hashing! %#x\n", rfaddr
);
1129 panic("the driver never uses BRDR, something is wrong!\n");
1132 panic("SRR is read only register!\n");
1135 panic("the driver never uses MIBC, something is wrong!\n");
1146 panic("the driver never uses VDR, something is wrong!\n");
1149 /* not going to implement clockrun stuff */
1155 if (reg
& TBICR_MR_LOOPBACK
)
1156 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1158 if (reg
& TBICR_MR_AN_ENABLE
) {
1159 regs
.tanlpar
= regs
.tanar
;
1160 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1164 if (reg
& TBICR_MR_RESTART_AN
) ;
1170 panic("TBISR is read only register!\n");
1173 // Only write the writable bits
1174 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1175 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1177 // Pause capability unimplemented
1179 if (reg
& TANAR_PS2
) ;
1180 if (reg
& TANAR_PS1
) ;
1186 panic("this should only be written to by the fake phy!\n");
1189 panic("TANER is read only register!\n");
1196 panic("invalid register access daddr=%#x", daddr
);
1199 panic("Invalid Request Size");
1206 NSGigE::devIntrPost(uint32_t interrupts
)
1208 if (interrupts
& ISR_RESERVE
)
1209 panic("Cannot set a reserved interrupt");
1211 if (interrupts
& ISR_NOIMPL
)
1212 warn("interrupt not implemented %#x\n", interrupts
);
1214 interrupts
&= ISR_IMPL
;
1215 regs
.isr
|= interrupts
;
1217 if (interrupts
& regs
.imr
) {
1218 if (interrupts
& ISR_SWI
) {
1221 if (interrupts
& ISR_RXIDLE
) {
1224 if (interrupts
& ISR_RXOK
) {
1227 if (interrupts
& ISR_RXDESC
) {
1230 if (interrupts
& ISR_TXOK
) {
1233 if (interrupts
& ISR_TXIDLE
) {
1236 if (interrupts
& ISR_TXDESC
) {
1239 if (interrupts
& ISR_RXORN
) {
1244 DPRINTF(EthernetIntr
,
1245 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1246 interrupts
, regs
.isr
, regs
.imr
);
1248 if ((regs
.isr
& regs
.imr
)) {
1249 Tick when
= curTick
;
1250 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1256 /* writing this interrupt counting stats inside this means that this function
1257 is now limited to being used to clear all interrupts upon the kernel
1258 reading isr and servicing. just telling you in case you were thinking
1262 NSGigE::devIntrClear(uint32_t interrupts
)
1264 if (interrupts
& ISR_RESERVE
)
1265 panic("Cannot clear a reserved interrupt");
1267 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1270 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1273 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1276 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1279 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1282 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1285 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1288 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1292 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1295 interrupts
&= ~ISR_NOIMPL
;
1296 regs
.isr
&= ~interrupts
;
1298 DPRINTF(EthernetIntr
,
1299 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1300 interrupts
, regs
.isr
, regs
.imr
);
1302 if (!(regs
.isr
& regs
.imr
))
1307 NSGigE::devIntrChangeMask()
1309 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1310 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1312 if (regs
.isr
& regs
.imr
)
1313 cpuIntrPost(curTick
);
1319 NSGigE::cpuIntrPost(Tick when
)
1321 // If the interrupt you want to post is later than an interrupt
1322 // already scheduled, just let it post in the coming one and don't
1323 // schedule another.
1324 // HOWEVER, must be sure that the scheduled intrTick is in the
1325 // future (this was formerly the source of a bug)
1327 * @todo this warning should be removed and the intrTick code should
1330 assert(when
>= curTick
);
1331 assert(intrTick
>= curTick
|| intrTick
== 0);
1332 if (when
> intrTick
&& intrTick
!= 0) {
1333 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1339 if (intrTick
< curTick
) {
1344 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1348 intrEvent
->squash();
1349 intrEvent
= new IntrEvent(this, true);
1350 intrEvent
->schedule(intrTick
);
1354 NSGigE::cpuInterrupt()
1356 assert(intrTick
== curTick
);
1358 // Whether or not there's a pending interrupt, we don't care about
1363 // Don't send an interrupt if there's already one
1364 if (cpuPendingIntr
) {
1365 DPRINTF(EthernetIntr
,
1366 "would send an interrupt now, but there's already pending\n");
1369 cpuPendingIntr
= true;
1371 DPRINTF(EthernetIntr
, "posting interrupt\n");
1377 NSGigE::cpuIntrClear()
1379 if (!cpuPendingIntr
)
1383 intrEvent
->squash();
1389 cpuPendingIntr
= false;
1391 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1396 NSGigE::cpuIntrPending() const
1397 { return cpuPendingIntr
; }
1403 DPRINTF(Ethernet
, "transmit reset\n");
1408 assert(txDescCnt
== 0);
1411 assert(txDmaState
== dmaIdle
);
1417 DPRINTF(Ethernet
, "receive reset\n");
1420 assert(rxPktBytes
== 0);
1423 assert(rxDescCnt
== 0);
1424 assert(rxDmaState
== dmaIdle
);
1432 memset(®s
, 0, sizeof(regs
));
1433 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1435 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1436 // fill threshold to 32 bytes
1437 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1438 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1439 regs
.mibc
= MIBC_FRZ
;
1440 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1441 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1442 regs
.brar
= 0xffffffff;
1444 extstsEnable
= false;
1445 acceptBroadcast
= false;
1446 acceptMulticast
= false;
1447 acceptUnicast
= false;
1448 acceptPerfect
= false;
1453 NSGigE::rxDmaReadCopy()
1455 assert(rxDmaState
== dmaReading
);
1457 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1458 rxDmaState
= dmaIdle
;
1460 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1461 rxDmaAddr
, rxDmaLen
);
1462 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1466 NSGigE::doRxDmaRead()
1468 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1469 rxDmaState
= dmaReading
;
1471 if (dmaInterface
&& !rxDmaFree
) {
1472 if (dmaInterface
->busy())
1473 rxDmaState
= dmaReadWaiting
;
1475 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1476 &rxDmaReadEvent
, true);
1480 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1485 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1486 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1487 rxDmaReadEvent
.schedule(start
);
1492 NSGigE::rxDmaReadDone()
1494 assert(rxDmaState
== dmaReading
);
1497 // If the transmit state machine has a pending DMA, let it go first
1498 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1505 NSGigE::rxDmaWriteCopy()
1507 assert(rxDmaState
== dmaWriting
);
1509 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1510 rxDmaState
= dmaIdle
;
1512 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1513 rxDmaAddr
, rxDmaLen
);
1514 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1518 NSGigE::doRxDmaWrite()
1520 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1521 rxDmaState
= dmaWriting
;
1523 if (dmaInterface
&& !rxDmaFree
) {
1524 if (dmaInterface
->busy())
1525 rxDmaState
= dmaWriteWaiting
;
1527 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1528 &rxDmaWriteEvent
, true);
1532 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1537 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1538 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1539 rxDmaWriteEvent
.schedule(start
);
1544 NSGigE::rxDmaWriteDone()
1546 assert(rxDmaState
== dmaWriting
);
1549 // If the transmit state machine has a pending DMA, let it go first
1550 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1559 DPRINTF(EthernetSM
, "receive kick rxState=%s (rxBuf.size=%d)\n",
1560 NsRxStateStrings
[rxState
], rxFifo
.size());
1564 if (rxKickTick
> curTick
) {
1565 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1571 // Go to the next state machine clock tick.
1572 rxKickTick
= curTick
+ cycles(1);
1575 switch(rxDmaState
) {
1576 case dmaReadWaiting
:
1580 case dmaWriteWaiting
:
1588 // see state machine from spec for details
1589 // the way this works is, if you finish work on one state and can
1590 // go directly to another, you do that through jumping to the
1591 // label "next". however, if you have intermediate work, like DMA
1592 // so that you can't go to the next state yet, you go to exit and
1593 // exit the loop. however, when the DMA is done it will trigger
1594 // an event and come back to this loop.
1598 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1603 rxState
= rxDescRefr
;
1605 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1606 rxDmaData
= &rxDescCache
+ offsetof(ns_desc
, link
);
1607 rxDmaLen
= sizeof(rxDescCache
.link
);
1608 rxDmaFree
= dmaDescFree
;
1611 descDmaRdBytes
+= rxDmaLen
;
1616 rxState
= rxDescRead
;
1618 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1619 rxDmaData
= &rxDescCache
;
1620 rxDmaLen
= sizeof(ns_desc
);
1621 rxDmaFree
= dmaDescFree
;
1624 descDmaRdBytes
+= rxDmaLen
;
1632 if (rxDmaState
!= dmaIdle
)
1635 rxState
= rxAdvance
;
1639 if (rxDmaState
!= dmaIdle
)
1642 DPRINTF(EthernetDesc
, "rxDescCache: addr=%08x read descriptor\n",
1643 regs
.rxdp
& 0x3fffffff);
1644 DPRINTF(EthernetDesc
,
1645 "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
1646 rxDescCache
.link
, rxDescCache
.bufptr
, rxDescCache
.cmdsts
,
1647 rxDescCache
.extsts
);
1649 if (rxDescCache
.cmdsts
& CMDSTS_OWN
) {
1650 devIntrPost(ISR_RXIDLE
);
1654 rxState
= rxFifoBlock
;
1655 rxFragPtr
= rxDescCache
.bufptr
;
1656 rxDescCnt
= rxDescCache
.cmdsts
& CMDSTS_LEN_MASK
;
1663 * @todo in reality, we should be able to start processing
1664 * the packet as it arrives, and not have to wait for the
1665 * full packet ot be in the receive fifo.
1670 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1672 // If we don't have a packet, grab a new one from the fifo.
1673 rxPacket
= rxFifo
.front();
1674 rxPktBytes
= rxPacket
->length
;
1675 rxPacketBufPtr
= rxPacket
->data
;
1678 if (DTRACE(Ethernet
)) {
1681 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1685 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1686 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1693 // sanity check - i think the driver behaves like this
1694 assert(rxDescCnt
>= rxPktBytes
);
1699 // dont' need the && rxDescCnt > 0 if driver sanity check
1701 if (rxPktBytes
> 0) {
1702 rxState
= rxFragWrite
;
1703 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1705 rxXferLen
= rxPktBytes
;
1707 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1708 rxDmaData
= rxPacketBufPtr
;
1709 rxDmaLen
= rxXferLen
;
1710 rxDmaFree
= dmaDataFree
;
1716 rxState
= rxDescWrite
;
1718 //if (rxPktBytes == 0) { /* packet is done */
1719 assert(rxPktBytes
== 0);
1720 DPRINTF(EthernetSM
, "done with receiving packet\n");
1722 rxDescCache
.cmdsts
|= CMDSTS_OWN
;
1723 rxDescCache
.cmdsts
&= ~CMDSTS_MORE
;
1724 rxDescCache
.cmdsts
|= CMDSTS_OK
;
1725 rxDescCache
.cmdsts
&= 0xffff0000;
1726 rxDescCache
.cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1730 * all the driver uses these are for its own stats keeping
1731 * which we don't care about, aren't necessary for
1732 * functionality and doing this would just slow us down.
1733 * if they end up using this in a later version for
1734 * functional purposes, just undef
1736 if (rxFilterEnable
) {
1737 rxDescCache
.cmdsts
&= ~CMDSTS_DEST_MASK
;
1738 const EthAddr
&dst
= rxFifoFront()->dst();
1740 rxDescCache
.cmdsts
|= CMDSTS_DEST_SELF
;
1741 if (dst
->multicast())
1742 rxDescCache
.cmdsts
|= CMDSTS_DEST_MULTI
;
1743 if (dst
->broadcast())
1744 rxDescCache
.cmdsts
|= CMDSTS_DEST_MASK
;
1749 if (extstsEnable
&& ip
) {
1750 rxDescCache
.extsts
|= EXTSTS_IPPKT
;
1752 if (cksum(ip
) != 0) {
1753 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1754 rxDescCache
.extsts
|= EXTSTS_IPERR
;
1759 rxDescCache
.extsts
|= EXTSTS_TCPPKT
;
1761 if (cksum(tcp
) != 0) {
1762 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1763 rxDescCache
.extsts
|= EXTSTS_TCPERR
;
1767 rxDescCache
.extsts
|= EXTSTS_UDPPKT
;
1769 if (cksum(udp
) != 0) {
1770 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1771 rxDescCache
.extsts
|= EXTSTS_UDPERR
;
1778 * the driver seems to always receive into desc buffers
1779 * of size 1514, so you never have a pkt that is split
1780 * into multiple descriptors on the receive side, so
1781 * i don't implement that case, hence the assert above.
1784 DPRINTF(EthernetDesc
,
1785 "rxDescCache: addr=%08x writeback cmdsts extsts\n",
1786 regs
.rxdp
& 0x3fffffff);
1787 DPRINTF(EthernetDesc
,
1788 "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
1789 rxDescCache
.link
, rxDescCache
.bufptr
, rxDescCache
.cmdsts
,
1790 rxDescCache
.extsts
);
1792 rxDmaAddr
= (regs
.rxdp
+ offsetof(ns_desc
, cmdsts
)) & 0x3fffffff;
1793 rxDmaData
= &(rxDescCache
.cmdsts
);
1794 rxDmaLen
= sizeof(rxDescCache
.cmdsts
) + sizeof(rxDescCache
.extsts
);
1795 rxDmaFree
= dmaDescFree
;
1798 descDmaWrBytes
+= rxDmaLen
;
1806 if (rxDmaState
!= dmaIdle
)
1809 rxPacketBufPtr
+= rxXferLen
;
1810 rxFragPtr
+= rxXferLen
;
1811 rxPktBytes
-= rxXferLen
;
1813 rxState
= rxFifoBlock
;
1817 if (rxDmaState
!= dmaIdle
)
1820 assert(rxDescCache
.cmdsts
& CMDSTS_OWN
);
1822 assert(rxPacket
== 0);
1823 devIntrPost(ISR_RXOK
);
1825 if (rxDescCache
.cmdsts
& CMDSTS_INTR
)
1826 devIntrPost(ISR_RXDESC
);
1829 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1833 rxState
= rxAdvance
;
1837 if (rxDescCache
.link
== 0) {
1838 devIntrPost(ISR_RXIDLE
);
1843 rxState
= rxDescRead
;
1844 regs
.rxdp
= rxDescCache
.link
;
1847 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1848 rxDmaData
= &rxDescCache
;
1849 rxDmaLen
= sizeof(ns_desc
);
1850 rxDmaFree
= dmaDescFree
;
1858 panic("Invalid rxState!");
1861 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1862 NsRxStateStrings
[rxState
]);
1867 * @todo do we want to schedule a future kick?
1869 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1870 NsRxStateStrings
[rxState
]);
1872 if (clock
&& !rxKickEvent
.scheduled())
1873 rxKickEvent
.schedule(rxKickTick
);
1879 if (txFifo
.empty()) {
1880 DPRINTF(Ethernet
, "nothing to transmit\n");
1884 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1886 if (interface
->sendPacket(txFifo
.front())) {
1888 if (DTRACE(Ethernet
)) {
1889 IpPtr
ip(txFifo
.front());
1891 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1895 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1896 tcp
->sport(), tcp
->dport(), tcp
->seq(), tcp
->ack());
1902 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1903 txBytes
+= txFifo
.front()->length
;
1906 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1911 * normally do a writeback of the descriptor here, and ONLY
1912 * after that is done, send this interrupt. but since our
1913 * stuff never actually fails, just do this interrupt here,
1914 * otherwise the code has to stray from this nice format.
1915 * besides, it's functionally the same.
1917 devIntrPost(ISR_TXOK
);
1920 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1921 DPRINTF(Ethernet
, "reschedule transmit\n");
1922 txEvent
.schedule(curTick
+ retryTime
);
1927 NSGigE::txDmaReadCopy()
1929 assert(txDmaState
== dmaReading
);
1931 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1932 txDmaState
= dmaIdle
;
1934 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1935 txDmaAddr
, txDmaLen
);
1936 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1940 NSGigE::doTxDmaRead()
1942 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1943 txDmaState
= dmaReading
;
1945 if (dmaInterface
&& !txDmaFree
) {
1946 if (dmaInterface
->busy())
1947 txDmaState
= dmaReadWaiting
;
1949 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1950 &txDmaReadEvent
, true);
1954 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1959 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1960 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1961 txDmaReadEvent
.schedule(start
);
1966 NSGigE::txDmaReadDone()
1968 assert(txDmaState
== dmaReading
);
1971 // If the receive state machine has a pending DMA, let it go first
1972 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1979 NSGigE::txDmaWriteCopy()
1981 assert(txDmaState
== dmaWriting
);
1983 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
1984 txDmaState
= dmaIdle
;
1986 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1987 txDmaAddr
, txDmaLen
);
1988 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1992 NSGigE::doTxDmaWrite()
1994 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1995 txDmaState
= dmaWriting
;
1997 if (dmaInterface
&& !txDmaFree
) {
1998 if (dmaInterface
->busy())
1999 txDmaState
= dmaWriteWaiting
;
2001 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2002 &txDmaWriteEvent
, true);
2006 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2011 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2012 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2013 txDmaWriteEvent
.schedule(start
);
2018 NSGigE::txDmaWriteDone()
2020 assert(txDmaState
== dmaWriting
);
2023 // If the receive state machine has a pending DMA, let it go first
2024 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2033 DPRINTF(EthernetSM
, "transmit kick txState=%s\n",
2034 NsTxStateStrings
[txState
]);
2038 if (txKickTick
> curTick
) {
2039 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2044 // Go to the next state machine clock tick.
2045 txKickTick
= curTick
+ cycles(1);
2048 switch(txDmaState
) {
2049 case dmaReadWaiting
:
2053 case dmaWriteWaiting
:
2064 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2069 txState
= txDescRefr
;
2071 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2072 txDmaData
= &txDescCache
+ offsetof(ns_desc
, link
);
2073 txDmaLen
= sizeof(txDescCache
.link
);
2074 txDmaFree
= dmaDescFree
;
2077 descDmaRdBytes
+= txDmaLen
;
2083 txState
= txDescRead
;
2085 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2086 txDmaData
= &txDescCache
;
2087 txDmaLen
= sizeof(ns_desc
);
2088 txDmaFree
= dmaDescFree
;
2091 descDmaRdBytes
+= txDmaLen
;
2099 if (txDmaState
!= dmaIdle
)
2102 txState
= txAdvance
;
2106 if (txDmaState
!= dmaIdle
)
2109 DPRINTF(EthernetDesc
, "txDescCache: addr=%08x read descriptor\n",
2110 regs
.txdp
& 0x3fffffff);
2111 DPRINTF(EthernetDesc
,
2112 "txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
2113 txDescCache
.link
, txDescCache
.bufptr
, txDescCache
.cmdsts
,
2114 txDescCache
.extsts
);
2116 if (txDescCache
.cmdsts
& CMDSTS_OWN
) {
2117 txState
= txFifoBlock
;
2118 txFragPtr
= txDescCache
.bufptr
;
2119 txDescCnt
= txDescCache
.cmdsts
& CMDSTS_LEN_MASK
;
2121 devIntrPost(ISR_TXIDLE
);
2129 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2130 txPacket
= new PacketData(16384);
2131 txPacketBufPtr
= txPacket
->data
;
2134 if (txDescCnt
== 0) {
2135 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2136 if (txDescCache
.cmdsts
& CMDSTS_MORE
) {
2137 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2138 txState
= txDescWrite
;
2140 txDescCache
.cmdsts
&= ~CMDSTS_OWN
;
2142 txDmaAddr
= regs
.txdp
+ offsetof(ns_desc
, cmdsts
);
2143 txDmaAddr
&= 0x3fffffff;
2144 txDmaData
= &(txDescCache
.cmdsts
);
2145 txDmaLen
= sizeof(txDescCache
.cmdsts
);
2146 txDmaFree
= dmaDescFree
;
2151 } else { /* this packet is totally done */
2152 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2153 /* deal with the the packet that just finished */
2154 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2156 if (txDescCache
.extsts
& EXTSTS_UDPPKT
) {
2159 udp
->sum(cksum(udp
));
2161 } else if (txDescCache
.extsts
& EXTSTS_TCPPKT
) {
2164 tcp
->sum(cksum(tcp
));
2167 if (txDescCache
.extsts
& EXTSTS_IPPKT
) {
2174 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2175 // this is just because the receive can't handle a
2176 // packet bigger want to make sure
2177 assert(txPacket
->length
<= 1514);
2181 txFifo
.push(txPacket
);
2185 * this following section is not tqo spec, but
2186 * functionally shouldn't be any different. normally,
2187 * the chip will wait til the transmit has occurred
2188 * before writing back the descriptor because it has
2189 * to wait to see that it was successfully transmitted
2190 * to decide whether to set CMDSTS_OK or not.
2191 * however, in the simulator since it is always
2192 * successfully transmitted, and writing it exactly to
2193 * spec would complicate the code, we just do it here
2196 txDescCache
.cmdsts
&= ~CMDSTS_OWN
;
2197 txDescCache
.cmdsts
|= CMDSTS_OK
;
2199 DPRINTF(EthernetDesc
,
2200 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2201 txDescCache
.cmdsts
, txDescCache
.extsts
);
2203 txDmaAddr
= regs
.txdp
+ offsetof(ns_desc
, cmdsts
);
2204 txDmaAddr
&= 0x3fffffff;
2205 txDmaData
= &(txDescCache
.cmdsts
);
2206 txDmaLen
= sizeof(txDescCache
.cmdsts
) +
2207 sizeof(txDescCache
.extsts
);
2208 txDmaFree
= dmaDescFree
;
2211 descDmaWrBytes
+= txDmaLen
;
2217 DPRINTF(EthernetSM
, "halting TX state machine\n");
2221 txState
= txAdvance
;
2227 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2228 if (!txFifo
.full()) {
2229 txState
= txFragRead
;
2232 * The number of bytes transferred is either whatever
2233 * is left in the descriptor (txDescCnt), or if there
2234 * is not enough room in the fifo, just whatever room
2235 * is left in the fifo
2237 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2239 txDmaAddr
= txFragPtr
& 0x3fffffff;
2240 txDmaData
= txPacketBufPtr
;
2241 txDmaLen
= txXferLen
;
2242 txDmaFree
= dmaDataFree
;
2247 txState
= txFifoBlock
;
2257 if (txDmaState
!= dmaIdle
)
2260 txPacketBufPtr
+= txXferLen
;
2261 txFragPtr
+= txXferLen
;
2262 txDescCnt
-= txXferLen
;
2263 txFifo
.reserve(txXferLen
);
2265 txState
= txFifoBlock
;
2269 if (txDmaState
!= dmaIdle
)
2272 if (txDescCache
.cmdsts
& CMDSTS_INTR
)
2273 devIntrPost(ISR_TXDESC
);
2276 DPRINTF(EthernetSM
, "halting TX state machine\n");
2280 txState
= txAdvance
;
2284 if (txDescCache
.link
== 0) {
2285 devIntrPost(ISR_TXIDLE
);
2289 txState
= txDescRead
;
2290 regs
.txdp
= txDescCache
.link
;
2293 txDmaAddr
= txDescCache
.link
& 0x3fffffff;
2294 txDmaData
= &txDescCache
;
2295 txDmaLen
= sizeof(ns_desc
);
2296 txDmaFree
= dmaDescFree
;
2304 panic("invalid state");
2307 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2308 NsTxStateStrings
[txState
]);
2313 * @todo do we want to schedule a future kick?
2315 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2316 NsTxStateStrings
[txState
]);
2318 if (clock
&& !txKickEvent
.scheduled())
2319 txKickEvent
.schedule(txKickTick
);
2323 * Advance the EEPROM state machine
2324 * Called on rising edge of EEPROM clock bit in MEAR
2327 NSGigE::eepromKick()
2329 switch (eepromState
) {
2333 // Wait for start bit
2334 if (regs
.mear
& MEAR_EEDI
) {
2335 // Set up to get 2 opcode bits
2336 eepromState
= eepromGetOpcode
;
2342 case eepromGetOpcode
:
2344 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2347 // Done getting opcode
2348 if (eepromBitsToRx
== 0) {
2349 if (eepromOpcode
!= EEPROM_READ
)
2350 panic("only EEPROM reads are implemented!");
2352 // Set up to get address
2353 eepromState
= eepromGetAddress
;
2359 case eepromGetAddress
:
2360 eepromAddress
<<= 1;
2361 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2364 // Done getting address
2365 if (eepromBitsToRx
== 0) {
2367 if (eepromAddress
>= EEPROM_SIZE
)
2368 panic("EEPROM read access out of range!");
2370 switch (eepromAddress
) {
2372 case EEPROM_PMATCH2_ADDR
:
2373 eepromData
= rom
.perfectMatch
[5];
2375 eepromData
+= rom
.perfectMatch
[4];
2378 case EEPROM_PMATCH1_ADDR
:
2379 eepromData
= rom
.perfectMatch
[3];
2381 eepromData
+= rom
.perfectMatch
[2];
2384 case EEPROM_PMATCH0_ADDR
:
2385 eepromData
= rom
.perfectMatch
[1];
2387 eepromData
+= rom
.perfectMatch
[0];
2391 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2393 // Set up to read data
2394 eepromState
= eepromRead
;
2395 eepromBitsToRx
= 16;
2397 // Clear data in bit
2398 regs
.mear
&= ~MEAR_EEDI
;
2403 // Clear Data Out bit
2404 regs
.mear
&= ~MEAR_EEDO
;
2405 // Set bit to value of current EEPROM bit
2406 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2412 if (eepromBitsToRx
== 0) {
2413 eepromState
= eepromStart
;
2418 panic("invalid EEPROM state");
2424 NSGigE::transferDone()
2426 if (txFifo
.empty()) {
2427 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2431 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2433 if (txEvent
.scheduled())
2434 txEvent
.reschedule(curTick
+ cycles(1));
2436 txEvent
.schedule(curTick
+ cycles(1));
2440 NSGigE::rxFilter(const PacketPtr
&packet
)
2442 EthPtr eth
= packet
;
2446 const EthAddr
&dst
= eth
->dst();
2447 if (dst
.unicast()) {
2448 // If we're accepting all unicast addresses
2452 // If we make a perfect match
2453 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2456 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2459 } else if (dst
.broadcast()) {
2460 // if we're accepting broadcasts
2461 if (acceptBroadcast
)
2464 } else if (dst
.multicast()) {
2465 // if we're accepting all multicasts
2466 if (acceptMulticast
)
2469 // Multicast hashing faked - all packets accepted
2470 if (multicastHashEnable
)
2475 DPRINTF(Ethernet
, "rxFilter drop\n");
2476 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2483 NSGigE::recvPacket(PacketPtr packet
)
2485 rxBytes
+= packet
->length
;
2488 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2492 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2493 interface
->recvDone();
2497 if (!rxFilterEnable
) {
2499 "receive packet filtering disabled . . . packet dropped\n");
2500 interface
->recvDone();
2504 if (rxFilter(packet
)) {
2505 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2506 interface
->recvDone();
2510 if (rxFifo
.avail() < packet
->length
) {
2516 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2519 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2524 devIntrPost(ISR_RXORN
);
2528 rxFifo
.push(packet
);
2529 interface
->recvDone();
2535 //=====================================================================
2539 NSGigE::serialize(ostream
&os
)
2541 // Serialize the PciDev base class
2542 PciDev::serialize(os
);
2545 * Finalize any DMA events now.
2547 if (rxDmaReadEvent
.scheduled())
2549 if (rxDmaWriteEvent
.scheduled())
2551 if (txDmaReadEvent
.scheduled())
2553 if (txDmaWriteEvent
.scheduled())
2557 * Serialize the device registers
2559 SERIALIZE_SCALAR(regs
.command
);
2560 SERIALIZE_SCALAR(regs
.config
);
2561 SERIALIZE_SCALAR(regs
.mear
);
2562 SERIALIZE_SCALAR(regs
.ptscr
);
2563 SERIALIZE_SCALAR(regs
.isr
);
2564 SERIALIZE_SCALAR(regs
.imr
);
2565 SERIALIZE_SCALAR(regs
.ier
);
2566 SERIALIZE_SCALAR(regs
.ihr
);
2567 SERIALIZE_SCALAR(regs
.txdp
);
2568 SERIALIZE_SCALAR(regs
.txdp_hi
);
2569 SERIALIZE_SCALAR(regs
.txcfg
);
2570 SERIALIZE_SCALAR(regs
.gpior
);
2571 SERIALIZE_SCALAR(regs
.rxdp
);
2572 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2573 SERIALIZE_SCALAR(regs
.rxcfg
);
2574 SERIALIZE_SCALAR(regs
.pqcr
);
2575 SERIALIZE_SCALAR(regs
.wcsr
);
2576 SERIALIZE_SCALAR(regs
.pcr
);
2577 SERIALIZE_SCALAR(regs
.rfcr
);
2578 SERIALIZE_SCALAR(regs
.rfdr
);
2579 SERIALIZE_SCALAR(regs
.brar
);
2580 SERIALIZE_SCALAR(regs
.brdr
);
2581 SERIALIZE_SCALAR(regs
.srr
);
2582 SERIALIZE_SCALAR(regs
.mibc
);
2583 SERIALIZE_SCALAR(regs
.vrcr
);
2584 SERIALIZE_SCALAR(regs
.vtcr
);
2585 SERIALIZE_SCALAR(regs
.vdr
);
2586 SERIALIZE_SCALAR(regs
.ccsr
);
2587 SERIALIZE_SCALAR(regs
.tbicr
);
2588 SERIALIZE_SCALAR(regs
.tbisr
);
2589 SERIALIZE_SCALAR(regs
.tanar
);
2590 SERIALIZE_SCALAR(regs
.tanlpar
);
2591 SERIALIZE_SCALAR(regs
.taner
);
2592 SERIALIZE_SCALAR(regs
.tesr
);
2594 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2595 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2597 SERIALIZE_SCALAR(ioEnable
);
2600 * Serialize the data Fifos
2602 rxFifo
.serialize("rxFifo", os
);
2603 txFifo
.serialize("txFifo", os
);
2606 * Serialize the various helper variables
2608 bool txPacketExists
= txPacket
;
2609 SERIALIZE_SCALAR(txPacketExists
);
2610 if (txPacketExists
) {
2611 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2612 txPacket
->serialize("txPacket", os
);
2613 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2614 SERIALIZE_SCALAR(txPktBufPtr
);
2617 bool rxPacketExists
= rxPacket
;
2618 SERIALIZE_SCALAR(rxPacketExists
);
2619 if (rxPacketExists
) {
2620 rxPacket
->serialize("rxPacket", os
);
2621 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2622 SERIALIZE_SCALAR(rxPktBufPtr
);
2625 SERIALIZE_SCALAR(txXferLen
);
2626 SERIALIZE_SCALAR(rxXferLen
);
2629 * Serialize DescCaches
2631 SERIALIZE_SCALAR(txDescCache
.link
);
2632 SERIALIZE_SCALAR(txDescCache
.bufptr
);
2633 SERIALIZE_SCALAR(txDescCache
.cmdsts
);
2634 SERIALIZE_SCALAR(txDescCache
.extsts
);
2635 SERIALIZE_SCALAR(rxDescCache
.link
);
2636 SERIALIZE_SCALAR(rxDescCache
.bufptr
);
2637 SERIALIZE_SCALAR(rxDescCache
.cmdsts
);
2638 SERIALIZE_SCALAR(rxDescCache
.extsts
);
2639 SERIALIZE_SCALAR(extstsEnable
);
2642 * Serialize tx state machine
2644 int txState
= this->txState
;
2645 SERIALIZE_SCALAR(txState
);
2646 SERIALIZE_SCALAR(txEnable
);
2647 SERIALIZE_SCALAR(CTDD
);
2648 SERIALIZE_SCALAR(txFragPtr
);
2649 SERIALIZE_SCALAR(txDescCnt
);
2650 int txDmaState
= this->txDmaState
;
2651 SERIALIZE_SCALAR(txDmaState
);
2652 SERIALIZE_SCALAR(txKickTick
);
2655 * Serialize rx state machine
2657 int rxState
= this->rxState
;
2658 SERIALIZE_SCALAR(rxState
);
2659 SERIALIZE_SCALAR(rxEnable
);
2660 SERIALIZE_SCALAR(CRDD
);
2661 SERIALIZE_SCALAR(rxPktBytes
);
2662 SERIALIZE_SCALAR(rxFragPtr
);
2663 SERIALIZE_SCALAR(rxDescCnt
);
2664 int rxDmaState
= this->rxDmaState
;
2665 SERIALIZE_SCALAR(rxDmaState
);
2666 SERIALIZE_SCALAR(rxKickTick
);
2669 * Serialize EEPROM state machine
2671 int eepromState
= this->eepromState
;
2672 SERIALIZE_SCALAR(eepromState
);
2673 SERIALIZE_SCALAR(eepromClk
);
2674 SERIALIZE_SCALAR(eepromBitsToRx
);
2675 SERIALIZE_SCALAR(eepromOpcode
);
2676 SERIALIZE_SCALAR(eepromAddress
);
2677 SERIALIZE_SCALAR(eepromData
);
2680 * If there's a pending transmit, store the time so we can
2681 * reschedule it later
2683 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2684 SERIALIZE_SCALAR(transmitTick
);
2687 * receive address filter settings
2689 SERIALIZE_SCALAR(rxFilterEnable
);
2690 SERIALIZE_SCALAR(acceptBroadcast
);
2691 SERIALIZE_SCALAR(acceptMulticast
);
2692 SERIALIZE_SCALAR(acceptUnicast
);
2693 SERIALIZE_SCALAR(acceptPerfect
);
2694 SERIALIZE_SCALAR(acceptArp
);
2695 SERIALIZE_SCALAR(multicastHashEnable
);
2698 * Keep track of pending interrupt status.
2700 SERIALIZE_SCALAR(intrTick
);
2701 SERIALIZE_SCALAR(cpuPendingIntr
);
2702 Tick intrEventTick
= 0;
2704 intrEventTick
= intrEvent
->when();
2705 SERIALIZE_SCALAR(intrEventTick
);
2710 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2712 // Unserialize the PciDev base class
2713 PciDev::unserialize(cp
, section
);
2715 UNSERIALIZE_SCALAR(regs
.command
);
2716 UNSERIALIZE_SCALAR(regs
.config
);
2717 UNSERIALIZE_SCALAR(regs
.mear
);
2718 UNSERIALIZE_SCALAR(regs
.ptscr
);
2719 UNSERIALIZE_SCALAR(regs
.isr
);
2720 UNSERIALIZE_SCALAR(regs
.imr
);
2721 UNSERIALIZE_SCALAR(regs
.ier
);
2722 UNSERIALIZE_SCALAR(regs
.ihr
);
2723 UNSERIALIZE_SCALAR(regs
.txdp
);
2724 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2725 UNSERIALIZE_SCALAR(regs
.txcfg
);
2726 UNSERIALIZE_SCALAR(regs
.gpior
);
2727 UNSERIALIZE_SCALAR(regs
.rxdp
);
2728 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2729 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2730 UNSERIALIZE_SCALAR(regs
.pqcr
);
2731 UNSERIALIZE_SCALAR(regs
.wcsr
);
2732 UNSERIALIZE_SCALAR(regs
.pcr
);
2733 UNSERIALIZE_SCALAR(regs
.rfcr
);
2734 UNSERIALIZE_SCALAR(regs
.rfdr
);
2735 UNSERIALIZE_SCALAR(regs
.brar
);
2736 UNSERIALIZE_SCALAR(regs
.brdr
);
2737 UNSERIALIZE_SCALAR(regs
.srr
);
2738 UNSERIALIZE_SCALAR(regs
.mibc
);
2739 UNSERIALIZE_SCALAR(regs
.vrcr
);
2740 UNSERIALIZE_SCALAR(regs
.vtcr
);
2741 UNSERIALIZE_SCALAR(regs
.vdr
);
2742 UNSERIALIZE_SCALAR(regs
.ccsr
);
2743 UNSERIALIZE_SCALAR(regs
.tbicr
);
2744 UNSERIALIZE_SCALAR(regs
.tbisr
);
2745 UNSERIALIZE_SCALAR(regs
.tanar
);
2746 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2747 UNSERIALIZE_SCALAR(regs
.taner
);
2748 UNSERIALIZE_SCALAR(regs
.tesr
);
2750 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2751 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2753 UNSERIALIZE_SCALAR(ioEnable
);
2756 * unserialize the data fifos
2758 rxFifo
.unserialize("rxFifo", cp
, section
);
2759 txFifo
.unserialize("txFifo", cp
, section
);
2762 * unserialize the various helper variables
2764 bool txPacketExists
;
2765 UNSERIALIZE_SCALAR(txPacketExists
);
2766 if (txPacketExists
) {
2767 txPacket
= new PacketData(16384);
2768 txPacket
->unserialize("txPacket", cp
, section
);
2769 uint32_t txPktBufPtr
;
2770 UNSERIALIZE_SCALAR(txPktBufPtr
);
2771 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2775 bool rxPacketExists
;
2776 UNSERIALIZE_SCALAR(rxPacketExists
);
2778 if (rxPacketExists
) {
2779 rxPacket
= new PacketData(16384);
2780 rxPacket
->unserialize("rxPacket", cp
, section
);
2781 uint32_t rxPktBufPtr
;
2782 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2783 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2787 UNSERIALIZE_SCALAR(txXferLen
);
2788 UNSERIALIZE_SCALAR(rxXferLen
);
2791 * Unserialize DescCaches
2793 UNSERIALIZE_SCALAR(txDescCache
.link
);
2794 UNSERIALIZE_SCALAR(txDescCache
.bufptr
);
2795 UNSERIALIZE_SCALAR(txDescCache
.cmdsts
);
2796 UNSERIALIZE_SCALAR(txDescCache
.extsts
);
2797 UNSERIALIZE_SCALAR(rxDescCache
.link
);
2798 UNSERIALIZE_SCALAR(rxDescCache
.bufptr
);
2799 UNSERIALIZE_SCALAR(rxDescCache
.cmdsts
);
2800 UNSERIALIZE_SCALAR(rxDescCache
.extsts
);
2801 UNSERIALIZE_SCALAR(extstsEnable
);
2804 * unserialize tx state machine
2807 UNSERIALIZE_SCALAR(txState
);
2808 this->txState
= (TxState
) txState
;
2809 UNSERIALIZE_SCALAR(txEnable
);
2810 UNSERIALIZE_SCALAR(CTDD
);
2811 UNSERIALIZE_SCALAR(txFragPtr
);
2812 UNSERIALIZE_SCALAR(txDescCnt
);
2814 UNSERIALIZE_SCALAR(txDmaState
);
2815 this->txDmaState
= (DmaState
) txDmaState
;
2816 UNSERIALIZE_SCALAR(txKickTick
);
2818 txKickEvent
.schedule(txKickTick
);
2821 * unserialize rx state machine
2824 UNSERIALIZE_SCALAR(rxState
);
2825 this->rxState
= (RxState
) rxState
;
2826 UNSERIALIZE_SCALAR(rxEnable
);
2827 UNSERIALIZE_SCALAR(CRDD
);
2828 UNSERIALIZE_SCALAR(rxPktBytes
);
2829 UNSERIALIZE_SCALAR(rxFragPtr
);
2830 UNSERIALIZE_SCALAR(rxDescCnt
);
2832 UNSERIALIZE_SCALAR(rxDmaState
);
2833 this->rxDmaState
= (DmaState
) rxDmaState
;
2834 UNSERIALIZE_SCALAR(rxKickTick
);
2836 rxKickEvent
.schedule(rxKickTick
);
2839 * Unserialize EEPROM state machine
2842 UNSERIALIZE_SCALAR(eepromState
);
2843 this->eepromState
= (EEPROMState
) eepromState
;
2844 UNSERIALIZE_SCALAR(eepromClk
);
2845 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2846 UNSERIALIZE_SCALAR(eepromOpcode
);
2847 UNSERIALIZE_SCALAR(eepromAddress
);
2848 UNSERIALIZE_SCALAR(eepromData
);
2851 * If there's a pending transmit, reschedule it now
2854 UNSERIALIZE_SCALAR(transmitTick
);
2856 txEvent
.schedule(curTick
+ transmitTick
);
2859 * unserialize receive address filter settings
2861 UNSERIALIZE_SCALAR(rxFilterEnable
);
2862 UNSERIALIZE_SCALAR(acceptBroadcast
);
2863 UNSERIALIZE_SCALAR(acceptMulticast
);
2864 UNSERIALIZE_SCALAR(acceptUnicast
);
2865 UNSERIALIZE_SCALAR(acceptPerfect
);
2866 UNSERIALIZE_SCALAR(acceptArp
);
2867 UNSERIALIZE_SCALAR(multicastHashEnable
);
2870 * Keep track of pending interrupt status.
2872 UNSERIALIZE_SCALAR(intrTick
);
2873 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2875 UNSERIALIZE_SCALAR(intrEventTick
);
2876 if (intrEventTick
) {
2877 intrEvent
= new IntrEvent(this, true);
2878 intrEvent
->schedule(intrEventTick
);
2882 * re-add addrRanges to bus bridges
2885 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2886 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2891 NSGigE::cacheAccess(MemReqPtr
&req
)
2893 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2894 req
->paddr
, req
->paddr
- addr
);
2895 return curTick
+ pioLatency
;
2898 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2900 SimObjectParam
<EtherInt
*> peer
;
2901 SimObjectParam
<NSGigE
*> device
;
2903 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2905 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2907 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2908 INIT_PARAM(device
, "Ethernet device of this interface")
2910 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2912 CREATE_SIM_OBJECT(NSGigEInt
)
2914 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2916 EtherInt
*p
= (EtherInt
*)peer
;
2918 dev_int
->setPeer(p
);
2919 p
->setPeer(dev_int
);
2925 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2928 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2932 Param
<Tick
> tx_delay
;
2933 Param
<Tick
> rx_delay
;
2934 Param
<Tick
> intr_delay
;
2935 SimObjectParam
<MemoryController
*> mmu
;
2936 SimObjectParam
<PhysicalMemory
*> physmem
;
2937 Param
<bool> rx_filter
;
2938 Param
<string
> hardware_address
;
2939 SimObjectParam
<Bus
*> io_bus
;
2940 SimObjectParam
<Bus
*> payload_bus
;
2941 SimObjectParam
<HierParams
*> hier
;
2942 Param
<Tick
> pio_latency
;
2943 Param
<bool> dma_desc_free
;
2944 Param
<bool> dma_data_free
;
2945 Param
<Tick
> dma_read_delay
;
2946 Param
<Tick
> dma_write_delay
;
2947 Param
<Tick
> dma_read_factor
;
2948 Param
<Tick
> dma_write_factor
;
2949 SimObjectParam
<PciConfigAll
*> configspace
;
2950 SimObjectParam
<PciConfigData
*> configdata
;
2951 SimObjectParam
<Platform
*> platform
;
2952 Param
<uint32_t> pci_bus
;
2953 Param
<uint32_t> pci_dev
;
2954 Param
<uint32_t> pci_func
;
2955 Param
<uint32_t> tx_fifo_size
;
2956 Param
<uint32_t> rx_fifo_size
;
2957 Param
<uint32_t> m5reg
;
2958 Param
<bool> dma_no_allocate
;
2960 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2962 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2964 INIT_PARAM(addr
, "Device Address"),
2965 INIT_PARAM(clock
, "State machine processor frequency"),
2966 INIT_PARAM(tx_delay
, "Transmit Delay"),
2967 INIT_PARAM(rx_delay
, "Receive Delay"),
2968 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
2969 INIT_PARAM(mmu
, "Memory Controller"),
2970 INIT_PARAM(physmem
, "Physical Memory"),
2971 INIT_PARAM_DFLT(rx_filter
, "Enable Receive Filter", true),
2972 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
2973 INIT_PARAM_DFLT(io_bus
, "The IO Bus to attach to for headers", NULL
),
2974 INIT_PARAM_DFLT(payload_bus
, "The IO Bus to attach to for payload", NULL
),
2975 INIT_PARAM_DFLT(hier
, "Hierarchy global variables", &defaultHierParams
),
2976 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency in bus cycles", 1),
2977 INIT_PARAM_DFLT(dma_desc_free
, "DMA of Descriptors is free", false),
2978 INIT_PARAM_DFLT(dma_data_free
, "DMA of Data is free", false),
2979 INIT_PARAM_DFLT(dma_read_delay
, "fixed delay for dma reads", 0),
2980 INIT_PARAM_DFLT(dma_write_delay
, "fixed delay for dma writes", 0),
2981 INIT_PARAM_DFLT(dma_read_factor
, "multiplier for dma reads", 0),
2982 INIT_PARAM_DFLT(dma_write_factor
, "multiplier for dma writes", 0),
2983 INIT_PARAM(configspace
, "PCI Configspace"),
2984 INIT_PARAM(configdata
, "PCI Config data"),
2985 INIT_PARAM(platform
, "Platform"),
2986 INIT_PARAM(pci_bus
, "PCI bus"),
2987 INIT_PARAM(pci_dev
, "PCI device number"),
2988 INIT_PARAM(pci_func
, "PCI function code"),
2989 INIT_PARAM_DFLT(tx_fifo_size
, "max size in bytes of txFifo", 131072),
2990 INIT_PARAM_DFLT(rx_fifo_size
, "max size in bytes of rxFifo", 131072),
2991 INIT_PARAM(m5reg
, "m5 register"),
2992 INIT_PARAM_DFLT(dma_no_allocate
, "Should DMA reads allocate cache lines", true)
2994 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2997 CREATE_SIM_OBJECT(NSGigE
)
2999 NSGigE::Params
*params
= new NSGigE::Params
;
3001 params
->name
= getInstanceName();
3003 params
->configSpace
= configspace
;
3004 params
->configData
= configdata
;
3005 params
->plat
= platform
;
3006 params
->busNum
= pci_bus
;
3007 params
->deviceNum
= pci_dev
;
3008 params
->functionNum
= pci_func
;
3010 params
->clock
= clock
;
3011 params
->intr_delay
= intr_delay
;
3012 params
->pmem
= physmem
;
3013 params
->tx_delay
= tx_delay
;
3014 params
->rx_delay
= rx_delay
;
3015 params
->hier
= hier
;
3016 params
->header_bus
= io_bus
;
3017 params
->payload_bus
= payload_bus
;
3018 params
->pio_latency
= pio_latency
;
3019 params
->dma_desc_free
= dma_desc_free
;
3020 params
->dma_data_free
= dma_data_free
;
3021 params
->dma_read_delay
= dma_read_delay
;
3022 params
->dma_write_delay
= dma_write_delay
;
3023 params
->dma_read_factor
= dma_read_factor
;
3024 params
->dma_write_factor
= dma_write_factor
;
3025 params
->rx_filter
= rx_filter
;
3026 params
->eaddr
= hardware_address
;
3027 params
->tx_fifo_size
= tx_fifo_size
;
3028 params
->rx_fifo_size
= rx_fifo_size
;
3029 params
->m5reg
= m5reg
;
3030 params
->dma_no_allocate
= dma_no_allocate
;
3031 return new NSGigE(params
);
3034 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)