d67c6cf95c13f3013c35a958b766d1eaaf30e5f0
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
);
152 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
153 memset(&txDesc32
, 0, sizeof(txDesc32
));
154 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
155 memset(&txDesc64
, 0, sizeof(txDesc64
));
165 .name(name() + ".txBytes")
166 .desc("Bytes Transmitted")
171 .name(name() + ".rxBytes")
172 .desc("Bytes Received")
177 .name(name() + ".txPackets")
178 .desc("Number of Packets Transmitted")
183 .name(name() + ".rxPackets")
184 .desc("Number of Packets Received")
189 .name(name() + ".txIpChecksums")
190 .desc("Number of tx IP Checksums done by device")
196 .name(name() + ".rxIpChecksums")
197 .desc("Number of rx IP Checksums done by device")
203 .name(name() + ".txTcpChecksums")
204 .desc("Number of tx TCP Checksums done by device")
210 .name(name() + ".rxTcpChecksums")
211 .desc("Number of rx TCP Checksums done by device")
217 .name(name() + ".txUdpChecksums")
218 .desc("Number of tx UDP Checksums done by device")
224 .name(name() + ".rxUdpChecksums")
225 .desc("Number of rx UDP Checksums done by device")
231 .name(name() + ".descDMAReads")
232 .desc("Number of descriptors the device read w/ DMA")
237 .name(name() + ".descDMAWrites")
238 .desc("Number of descriptors the device wrote w/ DMA")
243 .name(name() + ".descDmaReadBytes")
244 .desc("number of descriptor bytes read w/ DMA")
249 .name(name() + ".descDmaWriteBytes")
250 .desc("number of descriptor bytes write w/ DMA")
255 .name(name() + ".txBandwidth")
256 .desc("Transmit Bandwidth (bits/s)")
262 .name(name() + ".rxBandwidth")
263 .desc("Receive Bandwidth (bits/s)")
269 .name(name() + ".totBandwidth")
270 .desc("Total Bandwidth (bits/s)")
276 .name(name() + ".totPackets")
277 .desc("Total Packets")
283 .name(name() + ".totBytes")
290 .name(name() + ".totPPS")
291 .desc("Total Tranmission Rate (packets/s)")
297 .name(name() + ".txPPS")
298 .desc("Packet Tranmission Rate (packets/s)")
304 .name(name() + ".rxPPS")
305 .desc("Packet Reception Rate (packets/s)")
311 .name(name() + ".postedSwi")
312 .desc("number of software interrupts posted to CPU")
317 .name(name() + ".totalSwi")
318 .desc("total number of Swi written to ISR")
323 .name(name() + ".coalescedSwi")
324 .desc("average number of Swi's coalesced into each post")
329 .name(name() + ".postedRxIdle")
330 .desc("number of rxIdle interrupts posted to CPU")
335 .name(name() + ".totalRxIdle")
336 .desc("total number of RxIdle written to ISR")
341 .name(name() + ".coalescedRxIdle")
342 .desc("average number of RxIdle's coalesced into each post")
347 .name(name() + ".postedRxOk")
348 .desc("number of RxOk interrupts posted to CPU")
353 .name(name() + ".totalRxOk")
354 .desc("total number of RxOk written to ISR")
359 .name(name() + ".coalescedRxOk")
360 .desc("average number of RxOk's coalesced into each post")
365 .name(name() + ".postedRxDesc")
366 .desc("number of RxDesc interrupts posted to CPU")
371 .name(name() + ".totalRxDesc")
372 .desc("total number of RxDesc written to ISR")
377 .name(name() + ".coalescedRxDesc")
378 .desc("average number of RxDesc's coalesced into each post")
383 .name(name() + ".postedTxOk")
384 .desc("number of TxOk interrupts posted to CPU")
389 .name(name() + ".totalTxOk")
390 .desc("total number of TxOk written to ISR")
395 .name(name() + ".coalescedTxOk")
396 .desc("average number of TxOk's coalesced into each post")
401 .name(name() + ".postedTxIdle")
402 .desc("number of TxIdle interrupts posted to CPU")
407 .name(name() + ".totalTxIdle")
408 .desc("total number of TxIdle written to ISR")
413 .name(name() + ".coalescedTxIdle")
414 .desc("average number of TxIdle's coalesced into each post")
419 .name(name() + ".postedTxDesc")
420 .desc("number of TxDesc interrupts posted to CPU")
425 .name(name() + ".totalTxDesc")
426 .desc("total number of TxDesc written to ISR")
431 .name(name() + ".coalescedTxDesc")
432 .desc("average number of TxDesc's coalesced into each post")
437 .name(name() + ".postedRxOrn")
438 .desc("number of RxOrn posted to CPU")
443 .name(name() + ".totalRxOrn")
444 .desc("total number of RxOrn written to ISR")
449 .name(name() + ".coalescedRxOrn")
450 .desc("average number of RxOrn's coalesced into each post")
455 .name(name() + ".coalescedTotal")
456 .desc("average number of interrupts coalesced into each post")
461 .name(name() + ".postedInterrupts")
462 .desc("number of posts to CPU")
467 .name(name() + ".droppedPackets")
468 .desc("number of packets dropped")
472 coalescedSwi
= totalSwi
/ postedInterrupts
;
473 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
474 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
475 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
476 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
477 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
478 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
479 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
481 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
482 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
483 totalRxOrn
) / postedInterrupts
;
485 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
486 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
487 totBandwidth
= txBandwidth
+ rxBandwidth
;
488 totBytes
= txBytes
+ rxBytes
;
489 totPackets
= txPackets
+ rxPackets
;
491 txPacketRate
= txPackets
/ simSeconds
;
492 rxPacketRate
= rxPackets
/ simSeconds
;
496 * This is to read the PCI general configuration registers
499 NSGigE::readConfig(int offset
, int size
, uint8_t *data
)
501 if (offset
< PCI_DEVICE_SPECIFIC
)
502 PciDev::readConfig(offset
, size
, data
);
504 panic("Device specific PCI config space not implemented!\n");
508 * This is to write to the PCI general configuration registers
511 NSGigE::writeConfig(int offset
, int size
, const uint8_t* data
)
513 if (offset
< PCI_DEVICE_SPECIFIC
)
514 PciDev::writeConfig(offset
, size
, data
);
516 panic("Device specific PCI config space not implemented!\n");
518 // Need to catch writes to BARs to update the PIO interface
520 // seems to work fine without all these PCI settings, but i
521 // put in the IO to double check, an assertion will fail if we
522 // need to properly implement it
524 if (config
.data
[offset
] & PCI_CMD_IOSE
)
530 if (config
.data
[offset
] & PCI_CMD_BME
) {
537 if (config
.data
[offset
] & PCI_CMD_MSE
) {
546 case PCI0_BASE_ADDR0
:
547 if (BARAddrs
[0] != 0) {
549 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
551 BARAddrs
[0] &= EV5::PAddrUncachedMask
;
554 case PCI0_BASE_ADDR1
:
555 if (BARAddrs
[1] != 0) {
557 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
559 BARAddrs
[1] &= EV5::PAddrUncachedMask
;
566 * This reads the device registers, which are detailed in the NS83820
570 NSGigE::read(MemReqPtr
&req
, uint8_t *data
)
574 //The mask is to give you only the offset into the device register file
575 Addr daddr
= req
->paddr
& 0xfff;
576 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x va=%#x size=%d\n",
577 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
580 // there are some reserved registers, you can see ns_gige_reg.h and
581 // the spec sheet for details
582 if (daddr
> LAST
&& daddr
<= RESERVED
) {
583 panic("Accessing reserved register");
584 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
585 readConfig(daddr
& 0xff, req
->size
, data
);
587 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
588 // don't implement all the MIB's. hopefully the kernel
589 // doesn't actually DEPEND upon their values
590 // MIB are just hardware stats keepers
591 uint32_t ®
= *(uint32_t *) data
;
594 } else if (daddr
> 0x3FC)
595 panic("Something is messed up!\n");
598 case sizeof(uint32_t):
600 uint32_t ®
= *(uint32_t *)data
;
606 //these are supposed to be cleared on a read
607 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
624 devIntrClear(ISR_ALL
);
679 // see the spec sheet for how RFCR and RFDR work
680 // basically, you write to RFCR to tell the machine
681 // what you want to do next, then you act upon RFDR,
682 // and the device will be prepared b/c of what you
689 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
691 // Read from perfect match ROM octets
693 reg
= rom
.perfectMatch
[1];
695 reg
+= rom
.perfectMatch
[0];
698 reg
= rom
.perfectMatch
[3] << 8;
699 reg
+= rom
.perfectMatch
[2];
702 reg
= rom
.perfectMatch
[5] << 8;
703 reg
+= rom
.perfectMatch
[4];
706 // Read filter hash table
707 if (rfaddr
>= FHASH_ADDR
&&
708 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
710 // Only word-aligned reads supported
712 panic("unaligned read from filter hash table!");
714 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
715 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
719 panic("reading RFDR for something other than pattern"
720 " matching or hashing! %#x\n", rfaddr
);
730 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
774 reg
= params()->m5reg
;
778 panic("reading unimplemented register: addr=%#x", daddr
);
781 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
787 panic("accessing register with invalid size: addr=%#x, size=%d",
795 NSGigE::write(MemReqPtr
&req
, const uint8_t *data
)
799 Addr daddr
= req
->paddr
& 0xfff;
800 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x va=%#x size=%d\n",
801 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
803 if (daddr
> LAST
&& daddr
<= RESERVED
) {
804 panic("Accessing reserved register");
805 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
806 writeConfig(daddr
& 0xff, req
->size
, data
);
808 } else if (daddr
> 0x3FC)
809 panic("Something is messed up!\n");
811 if (req
->size
== sizeof(uint32_t)) {
812 uint32_t reg
= *(uint32_t *)data
;
815 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
822 } else if (reg
& CR_TXE
) {
825 // the kernel is enabling the transmit machine
826 if (txState
== txIdle
)
832 } else if (reg
& CR_RXE
) {
835 if (rxState
== rxIdle
)
846 devIntrPost(ISR_SWI
);
857 if (reg
& CFGR_LNKSTS
||
860 reg
& CFGR_RESERVED
||
861 reg
& CFGR_T64ADDR
||
862 reg
& CFGR_PCI64_DET
)
864 // First clear all writable bits
865 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
866 CFGR_RESERVED
| CFGR_T64ADDR
|
868 // Now set the appropriate writable bits
869 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
870 CFGR_RESERVED
| CFGR_T64ADDR
|
873 // all these #if 0's are because i don't THINK the kernel needs to
874 // have these implemented. if there is a problem relating to one of
875 // these, you may need to add functionality in.
876 if (reg
& CFGR_TBI_EN
) ;
877 if (reg
& CFGR_MODE_1000
) ;
879 if (reg
& CFGR_AUTO_1000
)
880 panic("CFGR_AUTO_1000 not implemented!\n");
882 if (reg
& CFGR_PINT_DUPSTS
||
883 reg
& CFGR_PINT_LNKSTS
||
884 reg
& CFGR_PINT_SPDSTS
)
887 if (reg
& CFGR_TMRTEST
) ;
888 if (reg
& CFGR_MRM_DIS
) ;
889 if (reg
& CFGR_MWI_DIS
) ;
891 if (reg
& CFGR_T64ADDR
) ;
892 // panic("CFGR_T64ADDR is read only register!\n");
894 if (reg
& CFGR_PCI64_DET
)
895 panic("CFGR_PCI64_DET is read only register!\n");
897 if (reg
& CFGR_DATA64_EN
) ;
898 if (reg
& CFGR_M64ADDR
) ;
899 if (reg
& CFGR_PHY_RST
) ;
900 if (reg
& CFGR_PHY_DIS
) ;
902 if (reg
& CFGR_EXTSTS_EN
)
905 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
) ;
918 // Clear writable bits
919 regs
.mear
&= MEAR_EEDO
;
920 // Set appropriate writable bits
921 regs
.mear
|= reg
& ~MEAR_EEDO
;
923 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
924 // even though it could get it through RFDR
925 if (reg
& MEAR_EESEL
) {
926 // Rising edge of clock
927 if (reg
& MEAR_EECLK
&& !eepromClk
)
931 eepromState
= eepromStart
;
932 regs
.mear
&= ~MEAR_EEDI
;
935 eepromClk
= reg
& MEAR_EECLK
;
937 // since phy is completely faked, MEAR_MD* don't matter
938 if (reg
& MEAR_MDIO
) ;
939 if (reg
& MEAR_MDDIR
) ;
940 if (reg
& MEAR_MDC
) ;
944 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
945 // these control BISTs for various parts of chip - we
946 // don't care or do just fake that the BIST is done
947 if (reg
& PTSCR_RBIST_EN
)
948 regs
.ptscr
|= PTSCR_RBIST_DONE
;
949 if (reg
& PTSCR_EEBIST_EN
)
950 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
951 if (reg
& PTSCR_EELOAD_EN
)
952 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
955 case ISR
: /* writing to the ISR has no effect */
956 panic("ISR is a read only register!\n");
969 /* not going to implement real interrupt holdoff */
973 regs
.txdp
= (reg
& 0xFFFFFFFC);
974 assert(txState
== txIdle
);
985 if (reg
& TX_CFG_CSI
) ;
986 if (reg
& TX_CFG_HBI
) ;
987 if (reg
& TX_CFG_MLB
) ;
988 if (reg
& TX_CFG_ATP
) ;
989 if (reg
& TX_CFG_ECRETRY
) {
991 * this could easily be implemented, but considering
992 * the network is just a fake pipe, wouldn't make
997 if (reg
& TX_CFG_BRST_DIS
) ;
1001 /* we handle our own DMA, ignore the kernel's exhortations */
1002 if (reg
& TX_CFG_MXDMA
) ;
1005 // also, we currently don't care about fill/drain
1006 // thresholds though this may change in the future with
1007 // more realistic networks or a driver which changes it
1008 // according to feedback
1013 // Only write writable bits
1014 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1015 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1016 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1017 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1018 /* these just control general purpose i/o pins, don't matter */
1033 if (reg
& RX_CFG_AEP
) ;
1034 if (reg
& RX_CFG_ARP
) ;
1035 if (reg
& RX_CFG_STRIPCRC
) ;
1036 if (reg
& RX_CFG_RX_RD
) ;
1037 if (reg
& RX_CFG_ALP
) ;
1038 if (reg
& RX_CFG_AIRL
) ;
1040 /* we handle our own DMA, ignore what kernel says about it */
1041 if (reg
& RX_CFG_MXDMA
) ;
1043 //also, we currently don't care about fill/drain thresholds
1044 //though this may change in the future with more realistic
1045 //networks or a driver which changes it according to feedback
1046 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1051 /* there is no priority queueing used in the linux 2.6 driver */
1056 /* not going to implement wake on LAN */
1061 /* not going to implement pause control */
1068 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1069 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1070 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1071 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1072 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1073 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1074 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1077 if (reg
& RFCR_APAT
)
1078 panic("RFCR_APAT not implemented!\n");
1080 if (reg
& RFCR_UHEN
)
1081 panic("Unicast hash filtering not used by drivers!\n");
1084 panic("RFCR_ULM not implemented!\n");
1089 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1092 rom
.perfectMatch
[0] = (uint8_t)reg
;
1093 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1096 rom
.perfectMatch
[2] = (uint8_t)reg
;
1097 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1100 rom
.perfectMatch
[4] = (uint8_t)reg
;
1101 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1105 if (rfaddr
>= FHASH_ADDR
&&
1106 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1108 // Only word-aligned writes supported
1110 panic("unaligned write to filter hash table!");
1112 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1113 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1114 = (uint8_t)(reg
>> 8);
1117 panic("writing RFDR for something other than pattern matching\
1118 or hashing! %#x\n", rfaddr
);
1126 panic("the driver never uses BRDR, something is wrong!\n");
1129 panic("SRR is read only register!\n");
1132 panic("the driver never uses MIBC, something is wrong!\n");
1143 panic("the driver never uses VDR, something is wrong!\n");
1146 /* not going to implement clockrun stuff */
1152 if (reg
& TBICR_MR_LOOPBACK
)
1153 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1155 if (reg
& TBICR_MR_AN_ENABLE
) {
1156 regs
.tanlpar
= regs
.tanar
;
1157 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1161 if (reg
& TBICR_MR_RESTART_AN
) ;
1167 panic("TBISR is read only register!\n");
1170 // Only write the writable bits
1171 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1172 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1174 // Pause capability unimplemented
1176 if (reg
& TANAR_PS2
) ;
1177 if (reg
& TANAR_PS1
) ;
1183 panic("this should only be written to by the fake phy!\n");
1186 panic("TANER is read only register!\n");
1193 panic("invalid register access daddr=%#x", daddr
);
1196 panic("Invalid Request Size");
1203 NSGigE::devIntrPost(uint32_t interrupts
)
1205 if (interrupts
& ISR_RESERVE
)
1206 panic("Cannot set a reserved interrupt");
1208 if (interrupts
& ISR_NOIMPL
)
1209 warn("interrupt not implemented %#x\n", interrupts
);
1211 interrupts
&= ISR_IMPL
;
1212 regs
.isr
|= interrupts
;
1214 if (interrupts
& regs
.imr
) {
1215 if (interrupts
& ISR_SWI
) {
1218 if (interrupts
& ISR_RXIDLE
) {
1221 if (interrupts
& ISR_RXOK
) {
1224 if (interrupts
& ISR_RXDESC
) {
1227 if (interrupts
& ISR_TXOK
) {
1230 if (interrupts
& ISR_TXIDLE
) {
1233 if (interrupts
& ISR_TXDESC
) {
1236 if (interrupts
& ISR_RXORN
) {
1241 DPRINTF(EthernetIntr
,
1242 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1243 interrupts
, regs
.isr
, regs
.imr
);
1245 if ((regs
.isr
& regs
.imr
)) {
1246 Tick when
= curTick
;
1247 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1253 /* writing this interrupt counting stats inside this means that this function
1254 is now limited to being used to clear all interrupts upon the kernel
1255 reading isr and servicing. just telling you in case you were thinking
1259 NSGigE::devIntrClear(uint32_t interrupts
)
1261 if (interrupts
& ISR_RESERVE
)
1262 panic("Cannot clear a reserved interrupt");
1264 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1267 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1270 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1273 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1276 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1279 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1282 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1285 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1289 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1292 interrupts
&= ~ISR_NOIMPL
;
1293 regs
.isr
&= ~interrupts
;
1295 DPRINTF(EthernetIntr
,
1296 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1297 interrupts
, regs
.isr
, regs
.imr
);
1299 if (!(regs
.isr
& regs
.imr
))
1304 NSGigE::devIntrChangeMask()
1306 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1307 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1309 if (regs
.isr
& regs
.imr
)
1310 cpuIntrPost(curTick
);
1316 NSGigE::cpuIntrPost(Tick when
)
1318 // If the interrupt you want to post is later than an interrupt
1319 // already scheduled, just let it post in the coming one and don't
1320 // schedule another.
1321 // HOWEVER, must be sure that the scheduled intrTick is in the
1322 // future (this was formerly the source of a bug)
1324 * @todo this warning should be removed and the intrTick code should
1327 assert(when
>= curTick
);
1328 assert(intrTick
>= curTick
|| intrTick
== 0);
1329 if (when
> intrTick
&& intrTick
!= 0) {
1330 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1336 if (intrTick
< curTick
) {
1341 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1345 intrEvent
->squash();
1346 intrEvent
= new IntrEvent(this, true);
1347 intrEvent
->schedule(intrTick
);
1351 NSGigE::cpuInterrupt()
1353 assert(intrTick
== curTick
);
1355 // Whether or not there's a pending interrupt, we don't care about
1360 // Don't send an interrupt if there's already one
1361 if (cpuPendingIntr
) {
1362 DPRINTF(EthernetIntr
,
1363 "would send an interrupt now, but there's already pending\n");
1366 cpuPendingIntr
= true;
1368 DPRINTF(EthernetIntr
, "posting interrupt\n");
1374 NSGigE::cpuIntrClear()
1376 if (!cpuPendingIntr
)
1380 intrEvent
->squash();
1386 cpuPendingIntr
= false;
1388 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1393 NSGigE::cpuIntrPending() const
1394 { return cpuPendingIntr
; }
1400 DPRINTF(Ethernet
, "transmit reset\n");
1405 assert(txDescCnt
== 0);
1408 assert(txDmaState
== dmaIdle
);
1414 DPRINTF(Ethernet
, "receive reset\n");
1417 assert(rxPktBytes
== 0);
1420 assert(rxDescCnt
== 0);
1421 assert(rxDmaState
== dmaIdle
);
1429 memset(®s
, 0, sizeof(regs
));
1430 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1432 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1433 // fill threshold to 32 bytes
1434 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1435 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1436 regs
.mibc
= MIBC_FRZ
;
1437 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1438 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1439 regs
.brar
= 0xffffffff;
1441 extstsEnable
= false;
1442 acceptBroadcast
= false;
1443 acceptMulticast
= false;
1444 acceptUnicast
= false;
1445 acceptPerfect
= false;
1450 NSGigE::rxDmaReadCopy()
1452 assert(rxDmaState
== dmaReading
);
1454 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1455 rxDmaState
= dmaIdle
;
1457 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1458 rxDmaAddr
, rxDmaLen
);
1459 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1463 NSGigE::doRxDmaRead()
1465 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1466 rxDmaState
= dmaReading
;
1468 if (dmaInterface
&& !rxDmaFree
) {
1469 if (dmaInterface
->busy())
1470 rxDmaState
= dmaReadWaiting
;
1472 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1473 &rxDmaReadEvent
, true);
1477 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1482 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1483 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1484 rxDmaReadEvent
.schedule(start
);
1489 NSGigE::rxDmaReadDone()
1491 assert(rxDmaState
== dmaReading
);
1494 // If the transmit state machine has a pending DMA, let it go first
1495 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1502 NSGigE::rxDmaWriteCopy()
1504 assert(rxDmaState
== dmaWriting
);
1506 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1507 rxDmaState
= dmaIdle
;
1509 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1510 rxDmaAddr
, rxDmaLen
);
1511 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1515 NSGigE::doRxDmaWrite()
1517 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1518 rxDmaState
= dmaWriting
;
1520 if (dmaInterface
&& !rxDmaFree
) {
1521 if (dmaInterface
->busy())
1522 rxDmaState
= dmaWriteWaiting
;
1524 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1525 &rxDmaWriteEvent
, true);
1529 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1534 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1535 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1536 rxDmaWriteEvent
.schedule(start
);
1541 NSGigE::rxDmaWriteDone()
1543 assert(rxDmaState
== dmaWriting
);
1546 // If the transmit state machine has a pending DMA, let it go first
1547 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1556 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1559 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1560 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1563 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1564 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1568 if (rxKickTick
> curTick
) {
1569 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1575 // Go to the next state machine clock tick.
1576 rxKickTick
= curTick
+ cycles(1);
1579 switch(rxDmaState
) {
1580 case dmaReadWaiting
:
1584 case dmaWriteWaiting
:
1592 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1593 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1595 // see state machine from spec for details
1596 // the way this works is, if you finish work on one state and can
1597 // go directly to another, you do that through jumping to the
1598 // label "next". however, if you have intermediate work, like DMA
1599 // so that you can't go to the next state yet, you go to exit and
1600 // exit the loop. however, when the DMA is done it will trigger
1601 // an event and come back to this loop.
1605 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1610 rxState
= rxDescRefr
;
1612 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1614 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1615 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1616 rxDmaFree
= dmaDescFree
;
1619 descDmaRdBytes
+= rxDmaLen
;
1624 rxState
= rxDescRead
;
1626 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1627 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1628 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1629 rxDmaFree
= dmaDescFree
;
1632 descDmaRdBytes
+= rxDmaLen
;
1640 if (rxDmaState
!= dmaIdle
)
1643 rxState
= rxAdvance
;
1647 if (rxDmaState
!= dmaIdle
)
1650 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1651 regs
.rxdp
& 0x3fffffff);
1652 DPRINTF(EthernetDesc
,
1653 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1654 link
, bufptr
, cmdsts
, extsts
);
1656 if (cmdsts
& CMDSTS_OWN
) {
1657 devIntrPost(ISR_RXIDLE
);
1661 rxState
= rxFifoBlock
;
1663 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1670 * @todo in reality, we should be able to start processing
1671 * the packet as it arrives, and not have to wait for the
1672 * full packet ot be in the receive fifo.
1677 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1679 // If we don't have a packet, grab a new one from the fifo.
1680 rxPacket
= rxFifo
.front();
1681 rxPktBytes
= rxPacket
->length
;
1682 rxPacketBufPtr
= rxPacket
->data
;
1685 if (DTRACE(Ethernet
)) {
1688 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1692 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1693 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1700 // sanity check - i think the driver behaves like this
1701 assert(rxDescCnt
>= rxPktBytes
);
1706 // dont' need the && rxDescCnt > 0 if driver sanity check
1708 if (rxPktBytes
> 0) {
1709 rxState
= rxFragWrite
;
1710 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1712 rxXferLen
= rxPktBytes
;
1714 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1715 rxDmaData
= rxPacketBufPtr
;
1716 rxDmaLen
= rxXferLen
;
1717 rxDmaFree
= dmaDataFree
;
1723 rxState
= rxDescWrite
;
1725 //if (rxPktBytes == 0) { /* packet is done */
1726 assert(rxPktBytes
== 0);
1727 DPRINTF(EthernetSM
, "done with receiving packet\n");
1729 cmdsts
|= CMDSTS_OWN
;
1730 cmdsts
&= ~CMDSTS_MORE
;
1731 cmdsts
|= CMDSTS_OK
;
1732 cmdsts
&= 0xffff0000;
1733 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1737 * all the driver uses these are for its own stats keeping
1738 * which we don't care about, aren't necessary for
1739 * functionality and doing this would just slow us down.
1740 * if they end up using this in a later version for
1741 * functional purposes, just undef
1743 if (rxFilterEnable
) {
1744 cmdsts
&= ~CMDSTS_DEST_MASK
;
1745 const EthAddr
&dst
= rxFifoFront()->dst();
1747 cmdsts
|= CMDSTS_DEST_SELF
;
1748 if (dst
->multicast())
1749 cmdsts
|= CMDSTS_DEST_MULTI
;
1750 if (dst
->broadcast())
1751 cmdsts
|= CMDSTS_DEST_MASK
;
1756 if (extstsEnable
&& ip
) {
1757 extsts
|= EXTSTS_IPPKT
;
1759 if (cksum(ip
) != 0) {
1760 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1761 extsts
|= EXTSTS_IPERR
;
1766 extsts
|= EXTSTS_TCPPKT
;
1768 if (cksum(tcp
) != 0) {
1769 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1770 extsts
|= EXTSTS_TCPERR
;
1774 extsts
|= EXTSTS_UDPPKT
;
1776 if (cksum(udp
) != 0) {
1777 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1778 extsts
|= EXTSTS_UDPERR
;
1785 * the driver seems to always receive into desc buffers
1786 * of size 1514, so you never have a pkt that is split
1787 * into multiple descriptors on the receive side, so
1788 * i don't implement that case, hence the assert above.
1791 DPRINTF(EthernetDesc
,
1792 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1793 regs
.rxdp
& 0x3fffffff);
1794 DPRINTF(EthernetDesc
,
1795 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1796 link
, bufptr
, cmdsts
, extsts
);
1798 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1799 rxDmaData
= &cmdsts
;
1801 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1802 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1804 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1805 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1807 rxDmaFree
= dmaDescFree
;
1810 descDmaWrBytes
+= rxDmaLen
;
1818 if (rxDmaState
!= dmaIdle
)
1821 rxPacketBufPtr
+= rxXferLen
;
1822 rxFragPtr
+= rxXferLen
;
1823 rxPktBytes
-= rxXferLen
;
1825 rxState
= rxFifoBlock
;
1829 if (rxDmaState
!= dmaIdle
)
1832 assert(cmdsts
& CMDSTS_OWN
);
1834 assert(rxPacket
== 0);
1835 devIntrPost(ISR_RXOK
);
1837 if (cmdsts
& CMDSTS_INTR
)
1838 devIntrPost(ISR_RXDESC
);
1841 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1845 rxState
= rxAdvance
;
1850 devIntrPost(ISR_RXIDLE
);
1855 if (rxDmaState
!= dmaIdle
)
1857 rxState
= rxDescRead
;
1861 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1862 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1863 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1864 rxDmaFree
= dmaDescFree
;
1872 panic("Invalid rxState!");
1875 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1876 NsRxStateStrings
[rxState
]);
1881 * @todo do we want to schedule a future kick?
1883 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1884 NsRxStateStrings
[rxState
]);
1886 if (clock
&& !rxKickEvent
.scheduled())
1887 rxKickEvent
.schedule(rxKickTick
);
1893 if (txFifo
.empty()) {
1894 DPRINTF(Ethernet
, "nothing to transmit\n");
1898 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1900 if (interface
->sendPacket(txFifo
.front())) {
1902 if (DTRACE(Ethernet
)) {
1903 IpPtr
ip(txFifo
.front());
1905 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1909 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1910 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1917 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1918 txBytes
+= txFifo
.front()->length
;
1921 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1926 * normally do a writeback of the descriptor here, and ONLY
1927 * after that is done, send this interrupt. but since our
1928 * stuff never actually fails, just do this interrupt here,
1929 * otherwise the code has to stray from this nice format.
1930 * besides, it's functionally the same.
1932 devIntrPost(ISR_TXOK
);
1935 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1936 DPRINTF(Ethernet
, "reschedule transmit\n");
1937 txEvent
.schedule(curTick
+ retryTime
);
1942 NSGigE::txDmaReadCopy()
1944 assert(txDmaState
== dmaReading
);
1946 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1947 txDmaState
= dmaIdle
;
1949 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1950 txDmaAddr
, txDmaLen
);
1951 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1955 NSGigE::doTxDmaRead()
1957 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1958 txDmaState
= dmaReading
;
1960 if (dmaInterface
&& !txDmaFree
) {
1961 if (dmaInterface
->busy())
1962 txDmaState
= dmaReadWaiting
;
1964 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1965 &txDmaReadEvent
, true);
1969 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1974 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1975 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1976 txDmaReadEvent
.schedule(start
);
1981 NSGigE::txDmaReadDone()
1983 assert(txDmaState
== dmaReading
);
1986 // If the receive state machine has a pending DMA, let it go first
1987 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1994 NSGigE::txDmaWriteCopy()
1996 assert(txDmaState
== dmaWriting
);
1998 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
1999 txDmaState
= dmaIdle
;
2001 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
2002 txDmaAddr
, txDmaLen
);
2003 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
2007 NSGigE::doTxDmaWrite()
2009 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
2010 txDmaState
= dmaWriting
;
2012 if (dmaInterface
&& !txDmaFree
) {
2013 if (dmaInterface
->busy())
2014 txDmaState
= dmaWriteWaiting
;
2016 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2017 &txDmaWriteEvent
, true);
2021 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2026 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2027 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2028 txDmaWriteEvent
.schedule(start
);
2033 NSGigE::txDmaWriteDone()
2035 assert(txDmaState
== dmaWriting
);
2038 // If the receive state machine has a pending DMA, let it go first
2039 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2048 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
2050 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
2051 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
2054 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
2055 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
2059 if (txKickTick
> curTick
) {
2060 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2065 // Go to the next state machine clock tick.
2066 txKickTick
= curTick
+ cycles(1);
2069 switch(txDmaState
) {
2070 case dmaReadWaiting
:
2074 case dmaWriteWaiting
:
2082 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
2083 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
2087 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2092 txState
= txDescRefr
;
2094 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2096 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
2097 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
2098 txDmaFree
= dmaDescFree
;
2101 descDmaRdBytes
+= txDmaLen
;
2107 txState
= txDescRead
;
2109 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2110 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2111 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2112 txDmaFree
= dmaDescFree
;
2115 descDmaRdBytes
+= txDmaLen
;
2123 if (txDmaState
!= dmaIdle
)
2126 txState
= txAdvance
;
2130 if (txDmaState
!= dmaIdle
)
2133 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
2134 regs
.txdp
& 0x3fffffff);
2135 DPRINTF(EthernetDesc
,
2136 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
2137 link
, bufptr
, cmdsts
, extsts
);
2139 if (cmdsts
& CMDSTS_OWN
) {
2140 txState
= txFifoBlock
;
2142 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
2144 devIntrPost(ISR_TXIDLE
);
2152 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2153 txPacket
= new PacketData(16384);
2154 txPacketBufPtr
= txPacket
->data
;
2157 if (txDescCnt
== 0) {
2158 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2159 if (cmdsts
& CMDSTS_MORE
) {
2160 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2161 txState
= txDescWrite
;
2163 cmdsts
&= ~CMDSTS_OWN
;
2165 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2166 txDmaData
= &cmdsts
;
2168 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2169 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2171 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2172 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2174 txDmaFree
= dmaDescFree
;
2179 } else { /* this packet is totally done */
2180 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2181 /* deal with the the packet that just finished */
2182 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2184 if (extsts
& EXTSTS_UDPPKT
) {
2187 udp
->sum(cksum(udp
));
2189 } else if (extsts
& EXTSTS_TCPPKT
) {
2192 tcp
->sum(cksum(tcp
));
2195 if (extsts
& EXTSTS_IPPKT
) {
2202 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2203 // this is just because the receive can't handle a
2204 // packet bigger want to make sure
2205 if (txPacket
->length
> 1514)
2206 panic("transmit packet too large, %s > 1514\n",
2212 txFifo
.push(txPacket
);
2216 * this following section is not tqo spec, but
2217 * functionally shouldn't be any different. normally,
2218 * the chip will wait til the transmit has occurred
2219 * before writing back the descriptor because it has
2220 * to wait to see that it was successfully transmitted
2221 * to decide whether to set CMDSTS_OK or not.
2222 * however, in the simulator since it is always
2223 * successfully transmitted, and writing it exactly to
2224 * spec would complicate the code, we just do it here
2227 cmdsts
&= ~CMDSTS_OWN
;
2228 cmdsts
|= CMDSTS_OK
;
2230 DPRINTF(EthernetDesc
,
2231 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2234 txDmaFree
= dmaDescFree
;
2235 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2236 txDmaData
= &cmdsts
;
2238 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2240 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2242 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2244 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2248 descDmaWrBytes
+= txDmaLen
;
2254 DPRINTF(EthernetSM
, "halting TX state machine\n");
2258 txState
= txAdvance
;
2264 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2265 if (!txFifo
.full()) {
2266 txState
= txFragRead
;
2269 * The number of bytes transferred is either whatever
2270 * is left in the descriptor (txDescCnt), or if there
2271 * is not enough room in the fifo, just whatever room
2272 * is left in the fifo
2274 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2276 txDmaAddr
= txFragPtr
& 0x3fffffff;
2277 txDmaData
= txPacketBufPtr
;
2278 txDmaLen
= txXferLen
;
2279 txDmaFree
= dmaDataFree
;
2284 txState
= txFifoBlock
;
2294 if (txDmaState
!= dmaIdle
)
2297 txPacketBufPtr
+= txXferLen
;
2298 txFragPtr
+= txXferLen
;
2299 txDescCnt
-= txXferLen
;
2300 txFifo
.reserve(txXferLen
);
2302 txState
= txFifoBlock
;
2306 if (txDmaState
!= dmaIdle
)
2309 if (cmdsts
& CMDSTS_INTR
)
2310 devIntrPost(ISR_TXDESC
);
2313 DPRINTF(EthernetSM
, "halting TX state machine\n");
2317 txState
= txAdvance
;
2322 devIntrPost(ISR_TXIDLE
);
2326 if (txDmaState
!= dmaIdle
)
2328 txState
= txDescRead
;
2332 txDmaAddr
= link
& 0x3fffffff;
2333 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2334 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2335 txDmaFree
= dmaDescFree
;
2343 panic("invalid state");
2346 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2347 NsTxStateStrings
[txState
]);
2352 * @todo do we want to schedule a future kick?
2354 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2355 NsTxStateStrings
[txState
]);
2357 if (clock
&& !txKickEvent
.scheduled())
2358 txKickEvent
.schedule(txKickTick
);
2362 * Advance the EEPROM state machine
2363 * Called on rising edge of EEPROM clock bit in MEAR
2366 NSGigE::eepromKick()
2368 switch (eepromState
) {
2372 // Wait for start bit
2373 if (regs
.mear
& MEAR_EEDI
) {
2374 // Set up to get 2 opcode bits
2375 eepromState
= eepromGetOpcode
;
2381 case eepromGetOpcode
:
2383 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2386 // Done getting opcode
2387 if (eepromBitsToRx
== 0) {
2388 if (eepromOpcode
!= EEPROM_READ
)
2389 panic("only EEPROM reads are implemented!");
2391 // Set up to get address
2392 eepromState
= eepromGetAddress
;
2398 case eepromGetAddress
:
2399 eepromAddress
<<= 1;
2400 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2403 // Done getting address
2404 if (eepromBitsToRx
== 0) {
2406 if (eepromAddress
>= EEPROM_SIZE
)
2407 panic("EEPROM read access out of range!");
2409 switch (eepromAddress
) {
2411 case EEPROM_PMATCH2_ADDR
:
2412 eepromData
= rom
.perfectMatch
[5];
2414 eepromData
+= rom
.perfectMatch
[4];
2417 case EEPROM_PMATCH1_ADDR
:
2418 eepromData
= rom
.perfectMatch
[3];
2420 eepromData
+= rom
.perfectMatch
[2];
2423 case EEPROM_PMATCH0_ADDR
:
2424 eepromData
= rom
.perfectMatch
[1];
2426 eepromData
+= rom
.perfectMatch
[0];
2430 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2432 // Set up to read data
2433 eepromState
= eepromRead
;
2434 eepromBitsToRx
= 16;
2436 // Clear data in bit
2437 regs
.mear
&= ~MEAR_EEDI
;
2442 // Clear Data Out bit
2443 regs
.mear
&= ~MEAR_EEDO
;
2444 // Set bit to value of current EEPROM bit
2445 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2451 if (eepromBitsToRx
== 0) {
2452 eepromState
= eepromStart
;
2457 panic("invalid EEPROM state");
2463 NSGigE::transferDone()
2465 if (txFifo
.empty()) {
2466 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2470 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2472 if (txEvent
.scheduled())
2473 txEvent
.reschedule(curTick
+ cycles(1));
2475 txEvent
.schedule(curTick
+ cycles(1));
2479 NSGigE::rxFilter(const PacketPtr
&packet
)
2481 EthPtr eth
= packet
;
2485 const EthAddr
&dst
= eth
->dst();
2486 if (dst
.unicast()) {
2487 // If we're accepting all unicast addresses
2491 // If we make a perfect match
2492 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2495 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2498 } else if (dst
.broadcast()) {
2499 // if we're accepting broadcasts
2500 if (acceptBroadcast
)
2503 } else if (dst
.multicast()) {
2504 // if we're accepting all multicasts
2505 if (acceptMulticast
)
2508 // Multicast hashing faked - all packets accepted
2509 if (multicastHashEnable
)
2514 DPRINTF(Ethernet
, "rxFilter drop\n");
2515 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2522 NSGigE::recvPacket(PacketPtr packet
)
2524 rxBytes
+= packet
->length
;
2527 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2531 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2532 interface
->recvDone();
2536 if (!rxFilterEnable
) {
2538 "receive packet filtering disabled . . . packet dropped\n");
2539 interface
->recvDone();
2543 if (rxFilter(packet
)) {
2544 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2545 interface
->recvDone();
2549 if (rxFifo
.avail() < packet
->length
) {
2555 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2558 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2563 devIntrPost(ISR_RXORN
);
2567 rxFifo
.push(packet
);
2568 interface
->recvDone();
2574 //=====================================================================
2578 NSGigE::serialize(ostream
&os
)
2580 // Serialize the PciDev base class
2581 PciDev::serialize(os
);
2584 * Finalize any DMA events now.
2586 if (rxDmaReadEvent
.scheduled())
2588 if (rxDmaWriteEvent
.scheduled())
2590 if (txDmaReadEvent
.scheduled())
2592 if (txDmaWriteEvent
.scheduled())
2596 * Serialize the device registers
2598 SERIALIZE_SCALAR(regs
.command
);
2599 SERIALIZE_SCALAR(regs
.config
);
2600 SERIALIZE_SCALAR(regs
.mear
);
2601 SERIALIZE_SCALAR(regs
.ptscr
);
2602 SERIALIZE_SCALAR(regs
.isr
);
2603 SERIALIZE_SCALAR(regs
.imr
);
2604 SERIALIZE_SCALAR(regs
.ier
);
2605 SERIALIZE_SCALAR(regs
.ihr
);
2606 SERIALIZE_SCALAR(regs
.txdp
);
2607 SERIALIZE_SCALAR(regs
.txdp_hi
);
2608 SERIALIZE_SCALAR(regs
.txcfg
);
2609 SERIALIZE_SCALAR(regs
.gpior
);
2610 SERIALIZE_SCALAR(regs
.rxdp
);
2611 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2612 SERIALIZE_SCALAR(regs
.rxcfg
);
2613 SERIALIZE_SCALAR(regs
.pqcr
);
2614 SERIALIZE_SCALAR(regs
.wcsr
);
2615 SERIALIZE_SCALAR(regs
.pcr
);
2616 SERIALIZE_SCALAR(regs
.rfcr
);
2617 SERIALIZE_SCALAR(regs
.rfdr
);
2618 SERIALIZE_SCALAR(regs
.brar
);
2619 SERIALIZE_SCALAR(regs
.brdr
);
2620 SERIALIZE_SCALAR(regs
.srr
);
2621 SERIALIZE_SCALAR(regs
.mibc
);
2622 SERIALIZE_SCALAR(regs
.vrcr
);
2623 SERIALIZE_SCALAR(regs
.vtcr
);
2624 SERIALIZE_SCALAR(regs
.vdr
);
2625 SERIALIZE_SCALAR(regs
.ccsr
);
2626 SERIALIZE_SCALAR(regs
.tbicr
);
2627 SERIALIZE_SCALAR(regs
.tbisr
);
2628 SERIALIZE_SCALAR(regs
.tanar
);
2629 SERIALIZE_SCALAR(regs
.tanlpar
);
2630 SERIALIZE_SCALAR(regs
.taner
);
2631 SERIALIZE_SCALAR(regs
.tesr
);
2633 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2634 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2636 SERIALIZE_SCALAR(ioEnable
);
2639 * Serialize the data Fifos
2641 rxFifo
.serialize("rxFifo", os
);
2642 txFifo
.serialize("txFifo", os
);
2645 * Serialize the various helper variables
2647 bool txPacketExists
= txPacket
;
2648 SERIALIZE_SCALAR(txPacketExists
);
2649 if (txPacketExists
) {
2650 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2651 txPacket
->serialize("txPacket", os
);
2652 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2653 SERIALIZE_SCALAR(txPktBufPtr
);
2656 bool rxPacketExists
= rxPacket
;
2657 SERIALIZE_SCALAR(rxPacketExists
);
2658 if (rxPacketExists
) {
2659 rxPacket
->serialize("rxPacket", os
);
2660 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2661 SERIALIZE_SCALAR(rxPktBufPtr
);
2664 SERIALIZE_SCALAR(txXferLen
);
2665 SERIALIZE_SCALAR(rxXferLen
);
2668 * Serialize Cached Descriptors
2670 SERIALIZE_SCALAR(rxDesc64
.link
);
2671 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2672 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2673 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2674 SERIALIZE_SCALAR(txDesc64
.link
);
2675 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2676 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2677 SERIALIZE_SCALAR(txDesc64
.extsts
);
2678 SERIALIZE_SCALAR(rxDesc32
.link
);
2679 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2680 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2681 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2682 SERIALIZE_SCALAR(txDesc32
.link
);
2683 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2684 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2685 SERIALIZE_SCALAR(txDesc32
.extsts
);
2686 SERIALIZE_SCALAR(extstsEnable
);
2689 * Serialize tx state machine
2691 int txState
= this->txState
;
2692 SERIALIZE_SCALAR(txState
);
2693 SERIALIZE_SCALAR(txEnable
);
2694 SERIALIZE_SCALAR(CTDD
);
2695 SERIALIZE_SCALAR(txFragPtr
);
2696 SERIALIZE_SCALAR(txDescCnt
);
2697 int txDmaState
= this->txDmaState
;
2698 SERIALIZE_SCALAR(txDmaState
);
2699 SERIALIZE_SCALAR(txKickTick
);
2702 * Serialize rx state machine
2704 int rxState
= this->rxState
;
2705 SERIALIZE_SCALAR(rxState
);
2706 SERIALIZE_SCALAR(rxEnable
);
2707 SERIALIZE_SCALAR(CRDD
);
2708 SERIALIZE_SCALAR(rxPktBytes
);
2709 SERIALIZE_SCALAR(rxFragPtr
);
2710 SERIALIZE_SCALAR(rxDescCnt
);
2711 int rxDmaState
= this->rxDmaState
;
2712 SERIALIZE_SCALAR(rxDmaState
);
2713 SERIALIZE_SCALAR(rxKickTick
);
2716 * Serialize EEPROM state machine
2718 int eepromState
= this->eepromState
;
2719 SERIALIZE_SCALAR(eepromState
);
2720 SERIALIZE_SCALAR(eepromClk
);
2721 SERIALIZE_SCALAR(eepromBitsToRx
);
2722 SERIALIZE_SCALAR(eepromOpcode
);
2723 SERIALIZE_SCALAR(eepromAddress
);
2724 SERIALIZE_SCALAR(eepromData
);
2727 * If there's a pending transmit, store the time so we can
2728 * reschedule it later
2730 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2731 SERIALIZE_SCALAR(transmitTick
);
2734 * receive address filter settings
2736 SERIALIZE_SCALAR(rxFilterEnable
);
2737 SERIALIZE_SCALAR(acceptBroadcast
);
2738 SERIALIZE_SCALAR(acceptMulticast
);
2739 SERIALIZE_SCALAR(acceptUnicast
);
2740 SERIALIZE_SCALAR(acceptPerfect
);
2741 SERIALIZE_SCALAR(acceptArp
);
2742 SERIALIZE_SCALAR(multicastHashEnable
);
2745 * Keep track of pending interrupt status.
2747 SERIALIZE_SCALAR(intrTick
);
2748 SERIALIZE_SCALAR(cpuPendingIntr
);
2749 Tick intrEventTick
= 0;
2751 intrEventTick
= intrEvent
->when();
2752 SERIALIZE_SCALAR(intrEventTick
);
2757 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2759 // Unserialize the PciDev base class
2760 PciDev::unserialize(cp
, section
);
2762 UNSERIALIZE_SCALAR(regs
.command
);
2763 UNSERIALIZE_SCALAR(regs
.config
);
2764 UNSERIALIZE_SCALAR(regs
.mear
);
2765 UNSERIALIZE_SCALAR(regs
.ptscr
);
2766 UNSERIALIZE_SCALAR(regs
.isr
);
2767 UNSERIALIZE_SCALAR(regs
.imr
);
2768 UNSERIALIZE_SCALAR(regs
.ier
);
2769 UNSERIALIZE_SCALAR(regs
.ihr
);
2770 UNSERIALIZE_SCALAR(regs
.txdp
);
2771 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2772 UNSERIALIZE_SCALAR(regs
.txcfg
);
2773 UNSERIALIZE_SCALAR(regs
.gpior
);
2774 UNSERIALIZE_SCALAR(regs
.rxdp
);
2775 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2776 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2777 UNSERIALIZE_SCALAR(regs
.pqcr
);
2778 UNSERIALIZE_SCALAR(regs
.wcsr
);
2779 UNSERIALIZE_SCALAR(regs
.pcr
);
2780 UNSERIALIZE_SCALAR(regs
.rfcr
);
2781 UNSERIALIZE_SCALAR(regs
.rfdr
);
2782 UNSERIALIZE_SCALAR(regs
.brar
);
2783 UNSERIALIZE_SCALAR(regs
.brdr
);
2784 UNSERIALIZE_SCALAR(regs
.srr
);
2785 UNSERIALIZE_SCALAR(regs
.mibc
);
2786 UNSERIALIZE_SCALAR(regs
.vrcr
);
2787 UNSERIALIZE_SCALAR(regs
.vtcr
);
2788 UNSERIALIZE_SCALAR(regs
.vdr
);
2789 UNSERIALIZE_SCALAR(regs
.ccsr
);
2790 UNSERIALIZE_SCALAR(regs
.tbicr
);
2791 UNSERIALIZE_SCALAR(regs
.tbisr
);
2792 UNSERIALIZE_SCALAR(regs
.tanar
);
2793 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2794 UNSERIALIZE_SCALAR(regs
.taner
);
2795 UNSERIALIZE_SCALAR(regs
.tesr
);
2797 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2798 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2800 UNSERIALIZE_SCALAR(ioEnable
);
2803 * unserialize the data fifos
2805 rxFifo
.unserialize("rxFifo", cp
, section
);
2806 txFifo
.unserialize("txFifo", cp
, section
);
2809 * unserialize the various helper variables
2811 bool txPacketExists
;
2812 UNSERIALIZE_SCALAR(txPacketExists
);
2813 if (txPacketExists
) {
2814 txPacket
= new PacketData(16384);
2815 txPacket
->unserialize("txPacket", cp
, section
);
2816 uint32_t txPktBufPtr
;
2817 UNSERIALIZE_SCALAR(txPktBufPtr
);
2818 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2822 bool rxPacketExists
;
2823 UNSERIALIZE_SCALAR(rxPacketExists
);
2825 if (rxPacketExists
) {
2826 rxPacket
= new PacketData(16384);
2827 rxPacket
->unserialize("rxPacket", cp
, section
);
2828 uint32_t rxPktBufPtr
;
2829 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2830 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2834 UNSERIALIZE_SCALAR(txXferLen
);
2835 UNSERIALIZE_SCALAR(rxXferLen
);
2838 * Unserialize Cached Descriptors
2840 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2841 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2842 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2843 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2844 UNSERIALIZE_SCALAR(txDesc64
.link
);
2845 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2846 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2847 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2848 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2849 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2850 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2851 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2852 UNSERIALIZE_SCALAR(txDesc32
.link
);
2853 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2854 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2855 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2856 UNSERIALIZE_SCALAR(extstsEnable
);
2859 * unserialize tx state machine
2862 UNSERIALIZE_SCALAR(txState
);
2863 this->txState
= (TxState
) txState
;
2864 UNSERIALIZE_SCALAR(txEnable
);
2865 UNSERIALIZE_SCALAR(CTDD
);
2866 UNSERIALIZE_SCALAR(txFragPtr
);
2867 UNSERIALIZE_SCALAR(txDescCnt
);
2869 UNSERIALIZE_SCALAR(txDmaState
);
2870 this->txDmaState
= (DmaState
) txDmaState
;
2871 UNSERIALIZE_SCALAR(txKickTick
);
2873 txKickEvent
.schedule(txKickTick
);
2876 * unserialize rx state machine
2879 UNSERIALIZE_SCALAR(rxState
);
2880 this->rxState
= (RxState
) rxState
;
2881 UNSERIALIZE_SCALAR(rxEnable
);
2882 UNSERIALIZE_SCALAR(CRDD
);
2883 UNSERIALIZE_SCALAR(rxPktBytes
);
2884 UNSERIALIZE_SCALAR(rxFragPtr
);
2885 UNSERIALIZE_SCALAR(rxDescCnt
);
2887 UNSERIALIZE_SCALAR(rxDmaState
);
2888 this->rxDmaState
= (DmaState
) rxDmaState
;
2889 UNSERIALIZE_SCALAR(rxKickTick
);
2891 rxKickEvent
.schedule(rxKickTick
);
2894 * Unserialize EEPROM state machine
2897 UNSERIALIZE_SCALAR(eepromState
);
2898 this->eepromState
= (EEPROMState
) eepromState
;
2899 UNSERIALIZE_SCALAR(eepromClk
);
2900 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2901 UNSERIALIZE_SCALAR(eepromOpcode
);
2902 UNSERIALIZE_SCALAR(eepromAddress
);
2903 UNSERIALIZE_SCALAR(eepromData
);
2906 * If there's a pending transmit, reschedule it now
2909 UNSERIALIZE_SCALAR(transmitTick
);
2911 txEvent
.schedule(curTick
+ transmitTick
);
2914 * unserialize receive address filter settings
2916 UNSERIALIZE_SCALAR(rxFilterEnable
);
2917 UNSERIALIZE_SCALAR(acceptBroadcast
);
2918 UNSERIALIZE_SCALAR(acceptMulticast
);
2919 UNSERIALIZE_SCALAR(acceptUnicast
);
2920 UNSERIALIZE_SCALAR(acceptPerfect
);
2921 UNSERIALIZE_SCALAR(acceptArp
);
2922 UNSERIALIZE_SCALAR(multicastHashEnable
);
2925 * Keep track of pending interrupt status.
2927 UNSERIALIZE_SCALAR(intrTick
);
2928 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2930 UNSERIALIZE_SCALAR(intrEventTick
);
2931 if (intrEventTick
) {
2932 intrEvent
= new IntrEvent(this, true);
2933 intrEvent
->schedule(intrEventTick
);
2937 * re-add addrRanges to bus bridges
2940 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2941 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2946 NSGigE::cacheAccess(MemReqPtr
&req
)
2948 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2949 req
->paddr
, req
->paddr
- addr
);
2950 return curTick
+ pioLatency
;
2953 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2955 SimObjectParam
<EtherInt
*> peer
;
2956 SimObjectParam
<NSGigE
*> device
;
2958 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2960 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2962 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2963 INIT_PARAM(device
, "Ethernet device of this interface")
2965 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2967 CREATE_SIM_OBJECT(NSGigEInt
)
2969 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2971 EtherInt
*p
= (EtherInt
*)peer
;
2973 dev_int
->setPeer(p
);
2974 p
->setPeer(dev_int
);
2980 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2983 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2987 Param
<Tick
> tx_delay
;
2988 Param
<Tick
> rx_delay
;
2989 Param
<Tick
> intr_delay
;
2990 SimObjectParam
<MemoryController
*> mmu
;
2991 SimObjectParam
<PhysicalMemory
*> physmem
;
2992 Param
<bool> rx_filter
;
2993 Param
<string
> hardware_address
;
2994 SimObjectParam
<Bus
*> io_bus
;
2995 SimObjectParam
<Bus
*> payload_bus
;
2996 SimObjectParam
<HierParams
*> hier
;
2997 Param
<Tick
> pio_latency
;
2998 Param
<bool> dma_desc_free
;
2999 Param
<bool> dma_data_free
;
3000 Param
<Tick
> dma_read_delay
;
3001 Param
<Tick
> dma_write_delay
;
3002 Param
<Tick
> dma_read_factor
;
3003 Param
<Tick
> dma_write_factor
;
3004 SimObjectParam
<PciConfigAll
*> configspace
;
3005 SimObjectParam
<PciConfigData
*> configdata
;
3006 SimObjectParam
<Platform
*> platform
;
3007 Param
<uint32_t> pci_bus
;
3008 Param
<uint32_t> pci_dev
;
3009 Param
<uint32_t> pci_func
;
3010 Param
<uint32_t> tx_fifo_size
;
3011 Param
<uint32_t> rx_fifo_size
;
3012 Param
<uint32_t> m5reg
;
3013 Param
<bool> dma_no_allocate
;
3015 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3017 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3019 INIT_PARAM(addr
, "Device Address"),
3020 INIT_PARAM(clock
, "State machine processor frequency"),
3021 INIT_PARAM(tx_delay
, "Transmit Delay"),
3022 INIT_PARAM(rx_delay
, "Receive Delay"),
3023 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
3024 INIT_PARAM(mmu
, "Memory Controller"),
3025 INIT_PARAM(physmem
, "Physical Memory"),
3026 INIT_PARAM_DFLT(rx_filter
, "Enable Receive Filter", true),
3027 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
3028 INIT_PARAM_DFLT(io_bus
, "The IO Bus to attach to for headers", NULL
),
3029 INIT_PARAM_DFLT(payload_bus
, "The IO Bus to attach to for payload", NULL
),
3030 INIT_PARAM_DFLT(hier
, "Hierarchy global variables", &defaultHierParams
),
3031 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency in bus cycles", 1),
3032 INIT_PARAM_DFLT(dma_desc_free
, "DMA of Descriptors is free", false),
3033 INIT_PARAM_DFLT(dma_data_free
, "DMA of Data is free", false),
3034 INIT_PARAM_DFLT(dma_read_delay
, "fixed delay for dma reads", 0),
3035 INIT_PARAM_DFLT(dma_write_delay
, "fixed delay for dma writes", 0),
3036 INIT_PARAM_DFLT(dma_read_factor
, "multiplier for dma reads", 0),
3037 INIT_PARAM_DFLT(dma_write_factor
, "multiplier for dma writes", 0),
3038 INIT_PARAM(configspace
, "PCI Configspace"),
3039 INIT_PARAM(configdata
, "PCI Config data"),
3040 INIT_PARAM(platform
, "Platform"),
3041 INIT_PARAM(pci_bus
, "PCI bus"),
3042 INIT_PARAM(pci_dev
, "PCI device number"),
3043 INIT_PARAM(pci_func
, "PCI function code"),
3044 INIT_PARAM_DFLT(tx_fifo_size
, "max size in bytes of txFifo", 131072),
3045 INIT_PARAM_DFLT(rx_fifo_size
, "max size in bytes of rxFifo", 131072),
3046 INIT_PARAM(m5reg
, "m5 register"),
3047 INIT_PARAM_DFLT(dma_no_allocate
, "Should DMA reads allocate cache lines", true)
3049 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3052 CREATE_SIM_OBJECT(NSGigE
)
3054 NSGigE::Params
*params
= new NSGigE::Params
;
3056 params
->name
= getInstanceName();
3058 params
->configSpace
= configspace
;
3059 params
->configData
= configdata
;
3060 params
->plat
= platform
;
3061 params
->busNum
= pci_bus
;
3062 params
->deviceNum
= pci_dev
;
3063 params
->functionNum
= pci_func
;
3065 params
->clock
= clock
;
3066 params
->intr_delay
= intr_delay
;
3067 params
->pmem
= physmem
;
3068 params
->tx_delay
= tx_delay
;
3069 params
->rx_delay
= rx_delay
;
3070 params
->hier
= hier
;
3071 params
->header_bus
= io_bus
;
3072 params
->payload_bus
= payload_bus
;
3073 params
->pio_latency
= pio_latency
;
3074 params
->dma_desc_free
= dma_desc_free
;
3075 params
->dma_data_free
= dma_data_free
;
3076 params
->dma_read_delay
= dma_read_delay
;
3077 params
->dma_write_delay
= dma_write_delay
;
3078 params
->dma_read_factor
= dma_read_factor
;
3079 params
->dma_write_factor
= dma_write_factor
;
3080 params
->rx_filter
= rx_filter
;
3081 params
->eaddr
= hardware_address
;
3082 params
->tx_fifo_size
= tx_fifo_size
;
3083 params
->rx_fifo_size
= rx_fifo_size
;
3084 params
->m5reg
= m5reg
;
3085 params
->dma_no_allocate
= dma_no_allocate
;
3086 return new NSGigE(params
);
3089 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)