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
);
775 if (params()->dedicated
)
776 reg
|= M5REG_DEDICATED
;
780 panic("reading unimplemented register: addr=%#x", daddr
);
783 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
789 panic("accessing register with invalid size: addr=%#x, size=%d",
797 NSGigE::write(MemReqPtr
&req
, const uint8_t *data
)
801 Addr daddr
= req
->paddr
& 0xfff;
802 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x va=%#x size=%d\n",
803 daddr
, req
->paddr
, req
->vaddr
, req
->size
);
805 if (daddr
> LAST
&& daddr
<= RESERVED
) {
806 panic("Accessing reserved register");
807 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
808 writeConfig(daddr
& 0xff, req
->size
, data
);
810 } else if (daddr
> 0x3FC)
811 panic("Something is messed up!\n");
813 if (req
->size
== sizeof(uint32_t)) {
814 uint32_t reg
= *(uint32_t *)data
;
817 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
824 } else if (reg
& CR_TXE
) {
827 // the kernel is enabling the transmit machine
828 if (txState
== txIdle
)
834 } else if (reg
& CR_RXE
) {
837 if (rxState
== rxIdle
)
848 devIntrPost(ISR_SWI
);
859 if (reg
& CFGR_LNKSTS
||
862 reg
& CFGR_RESERVED
||
863 reg
& CFGR_T64ADDR
||
864 reg
& CFGR_PCI64_DET
)
866 // First clear all writable bits
867 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
868 CFGR_RESERVED
| CFGR_T64ADDR
|
870 // Now set the appropriate writable bits
871 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
872 CFGR_RESERVED
| CFGR_T64ADDR
|
875 // all these #if 0's are because i don't THINK the kernel needs to
876 // have these implemented. if there is a problem relating to one of
877 // these, you may need to add functionality in.
878 if (reg
& CFGR_TBI_EN
) ;
879 if (reg
& CFGR_MODE_1000
) ;
881 if (reg
& CFGR_AUTO_1000
)
882 panic("CFGR_AUTO_1000 not implemented!\n");
884 if (reg
& CFGR_PINT_DUPSTS
||
885 reg
& CFGR_PINT_LNKSTS
||
886 reg
& CFGR_PINT_SPDSTS
)
889 if (reg
& CFGR_TMRTEST
) ;
890 if (reg
& CFGR_MRM_DIS
) ;
891 if (reg
& CFGR_MWI_DIS
) ;
893 if (reg
& CFGR_T64ADDR
) ;
894 // panic("CFGR_T64ADDR is read only register!\n");
896 if (reg
& CFGR_PCI64_DET
)
897 panic("CFGR_PCI64_DET is read only register!\n");
899 if (reg
& CFGR_DATA64_EN
) ;
900 if (reg
& CFGR_M64ADDR
) ;
901 if (reg
& CFGR_PHY_RST
) ;
902 if (reg
& CFGR_PHY_DIS
) ;
904 if (reg
& CFGR_EXTSTS_EN
)
907 extstsEnable
= false;
909 if (reg
& CFGR_REQALG
) ;
911 if (reg
& CFGR_POW
) ;
912 if (reg
& CFGR_EXD
) ;
913 if (reg
& CFGR_PESEL
) ;
914 if (reg
& CFGR_BROM_DIS
) ;
915 if (reg
& CFGR_EXT_125
) ;
916 if (reg
& CFGR_BEM
) ;
920 // Clear writable bits
921 regs
.mear
&= MEAR_EEDO
;
922 // Set appropriate writable bits
923 regs
.mear
|= reg
& ~MEAR_EEDO
;
925 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
926 // even though it could get it through RFDR
927 if (reg
& MEAR_EESEL
) {
928 // Rising edge of clock
929 if (reg
& MEAR_EECLK
&& !eepromClk
)
933 eepromState
= eepromStart
;
934 regs
.mear
&= ~MEAR_EEDI
;
937 eepromClk
= reg
& MEAR_EECLK
;
939 // 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
) ;
946 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
947 // these control BISTs for various parts of chip - we
948 // don't care or do just fake that the BIST is done
949 if (reg
& PTSCR_RBIST_EN
)
950 regs
.ptscr
|= PTSCR_RBIST_DONE
;
951 if (reg
& PTSCR_EEBIST_EN
)
952 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
953 if (reg
& PTSCR_EELOAD_EN
)
954 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
957 case ISR
: /* writing to the ISR has no effect */
958 panic("ISR is a read only register!\n");
971 /* not going to implement real interrupt holdoff */
975 regs
.txdp
= (reg
& 0xFFFFFFFC);
976 assert(txState
== txIdle
);
987 if (reg
& TX_CFG_CSI
) ;
988 if (reg
& TX_CFG_HBI
) ;
989 if (reg
& TX_CFG_MLB
) ;
990 if (reg
& TX_CFG_ATP
) ;
991 if (reg
& TX_CFG_ECRETRY
) {
993 * this could easily be implemented, but considering
994 * the network is just a fake pipe, wouldn't make
999 if (reg
& TX_CFG_BRST_DIS
) ;
1003 /* we handle our own DMA, ignore the kernel's exhortations */
1004 if (reg
& TX_CFG_MXDMA
) ;
1007 // also, we currently don't care about fill/drain
1008 // thresholds though this may change in the future with
1009 // more realistic networks or a driver which changes it
1010 // according to feedback
1015 // Only write writable bits
1016 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1017 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
1018 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
1019 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
1020 /* these just control general purpose i/o pins, don't matter */
1035 if (reg
& RX_CFG_AEP
) ;
1036 if (reg
& RX_CFG_ARP
) ;
1037 if (reg
& RX_CFG_STRIPCRC
) ;
1038 if (reg
& RX_CFG_RX_RD
) ;
1039 if (reg
& RX_CFG_ALP
) ;
1040 if (reg
& RX_CFG_AIRL
) ;
1042 /* we handle our own DMA, ignore what kernel says about it */
1043 if (reg
& RX_CFG_MXDMA
) ;
1045 //also, we currently don't care about fill/drain thresholds
1046 //though this may change in the future with more realistic
1047 //networks or a driver which changes it according to feedback
1048 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
1053 /* there is no priority queueing used in the linux 2.6 driver */
1058 /* not going to implement wake on LAN */
1063 /* not going to implement pause control */
1070 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1071 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1072 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1073 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1074 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1075 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1076 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1079 if (reg
& RFCR_APAT
)
1080 panic("RFCR_APAT not implemented!\n");
1082 if (reg
& RFCR_UHEN
)
1083 panic("Unicast hash filtering not used by drivers!\n");
1086 panic("RFCR_ULM not implemented!\n");
1091 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1094 rom
.perfectMatch
[0] = (uint8_t)reg
;
1095 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1098 rom
.perfectMatch
[2] = (uint8_t)reg
;
1099 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1102 rom
.perfectMatch
[4] = (uint8_t)reg
;
1103 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1107 if (rfaddr
>= FHASH_ADDR
&&
1108 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1110 // Only word-aligned writes supported
1112 panic("unaligned write to filter hash table!");
1114 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1115 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1116 = (uint8_t)(reg
>> 8);
1119 panic("writing RFDR for something other than pattern matching\
1120 or hashing! %#x\n", rfaddr
);
1128 panic("the driver never uses BRDR, something is wrong!\n");
1131 panic("SRR is read only register!\n");
1134 panic("the driver never uses MIBC, something is wrong!\n");
1145 panic("the driver never uses VDR, something is wrong!\n");
1148 /* not going to implement clockrun stuff */
1154 if (reg
& TBICR_MR_LOOPBACK
)
1155 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1157 if (reg
& TBICR_MR_AN_ENABLE
) {
1158 regs
.tanlpar
= regs
.tanar
;
1159 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1163 if (reg
& TBICR_MR_RESTART_AN
) ;
1169 panic("TBISR is read only register!\n");
1172 // Only write the writable bits
1173 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1174 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1176 // Pause capability unimplemented
1178 if (reg
& TANAR_PS2
) ;
1179 if (reg
& TANAR_PS1
) ;
1185 panic("this should only be written to by the fake phy!\n");
1188 panic("TANER is read only register!\n");
1195 panic("invalid register access daddr=%#x", daddr
);
1198 panic("Invalid Request Size");
1205 NSGigE::devIntrPost(uint32_t interrupts
)
1207 if (interrupts
& ISR_RESERVE
)
1208 panic("Cannot set a reserved interrupt");
1210 if (interrupts
& ISR_NOIMPL
)
1211 warn("interrupt not implemented %#x\n", interrupts
);
1213 interrupts
&= ISR_IMPL
;
1214 regs
.isr
|= interrupts
;
1216 if (interrupts
& regs
.imr
) {
1217 if (interrupts
& ISR_SWI
) {
1220 if (interrupts
& ISR_RXIDLE
) {
1223 if (interrupts
& ISR_RXOK
) {
1226 if (interrupts
& ISR_RXDESC
) {
1229 if (interrupts
& ISR_TXOK
) {
1232 if (interrupts
& ISR_TXIDLE
) {
1235 if (interrupts
& ISR_TXDESC
) {
1238 if (interrupts
& ISR_RXORN
) {
1243 DPRINTF(EthernetIntr
,
1244 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1245 interrupts
, regs
.isr
, regs
.imr
);
1247 if ((regs
.isr
& regs
.imr
)) {
1248 Tick when
= curTick
;
1249 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1255 /* writing this interrupt counting stats inside this means that this function
1256 is now limited to being used to clear all interrupts upon the kernel
1257 reading isr and servicing. just telling you in case you were thinking
1261 NSGigE::devIntrClear(uint32_t interrupts
)
1263 if (interrupts
& ISR_RESERVE
)
1264 panic("Cannot clear a reserved interrupt");
1266 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1269 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1272 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1275 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1278 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1281 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1284 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1287 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1291 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1294 interrupts
&= ~ISR_NOIMPL
;
1295 regs
.isr
&= ~interrupts
;
1297 DPRINTF(EthernetIntr
,
1298 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1299 interrupts
, regs
.isr
, regs
.imr
);
1301 if (!(regs
.isr
& regs
.imr
))
1306 NSGigE::devIntrChangeMask()
1308 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1309 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1311 if (regs
.isr
& regs
.imr
)
1312 cpuIntrPost(curTick
);
1318 NSGigE::cpuIntrPost(Tick when
)
1320 // If the interrupt you want to post is later than an interrupt
1321 // already scheduled, just let it post in the coming one and don't
1322 // schedule another.
1323 // HOWEVER, must be sure that the scheduled intrTick is in the
1324 // future (this was formerly the source of a bug)
1326 * @todo this warning should be removed and the intrTick code should
1329 assert(when
>= curTick
);
1330 assert(intrTick
>= curTick
|| intrTick
== 0);
1331 if (when
> intrTick
&& intrTick
!= 0) {
1332 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1338 if (intrTick
< curTick
) {
1343 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1347 intrEvent
->squash();
1348 intrEvent
= new IntrEvent(this, true);
1349 intrEvent
->schedule(intrTick
);
1353 NSGigE::cpuInterrupt()
1355 assert(intrTick
== curTick
);
1357 // Whether or not there's a pending interrupt, we don't care about
1362 // Don't send an interrupt if there's already one
1363 if (cpuPendingIntr
) {
1364 DPRINTF(EthernetIntr
,
1365 "would send an interrupt now, but there's already pending\n");
1368 cpuPendingIntr
= true;
1370 DPRINTF(EthernetIntr
, "posting interrupt\n");
1376 NSGigE::cpuIntrClear()
1378 if (!cpuPendingIntr
)
1382 intrEvent
->squash();
1388 cpuPendingIntr
= false;
1390 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1395 NSGigE::cpuIntrPending() const
1396 { return cpuPendingIntr
; }
1402 DPRINTF(Ethernet
, "transmit reset\n");
1407 assert(txDescCnt
== 0);
1410 assert(txDmaState
== dmaIdle
);
1416 DPRINTF(Ethernet
, "receive reset\n");
1419 assert(rxPktBytes
== 0);
1422 assert(rxDescCnt
== 0);
1423 assert(rxDmaState
== dmaIdle
);
1431 memset(®s
, 0, sizeof(regs
));
1432 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1434 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1435 // fill threshold to 32 bytes
1436 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1437 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1438 regs
.mibc
= MIBC_FRZ
;
1439 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1440 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1441 regs
.brar
= 0xffffffff;
1443 extstsEnable
= false;
1444 acceptBroadcast
= false;
1445 acceptMulticast
= false;
1446 acceptUnicast
= false;
1447 acceptPerfect
= false;
1452 NSGigE::rxDmaReadCopy()
1454 assert(rxDmaState
== dmaReading
);
1456 physmem
->dma_read((uint8_t *)rxDmaData
, rxDmaAddr
, rxDmaLen
);
1457 rxDmaState
= dmaIdle
;
1459 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1460 rxDmaAddr
, rxDmaLen
);
1461 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1465 NSGigE::doRxDmaRead()
1467 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1468 rxDmaState
= dmaReading
;
1470 if (dmaInterface
&& !rxDmaFree
) {
1471 if (dmaInterface
->busy())
1472 rxDmaState
= dmaReadWaiting
;
1474 dmaInterface
->doDMA(Read
, rxDmaAddr
, rxDmaLen
, curTick
,
1475 &rxDmaReadEvent
, true);
1479 if (dmaReadDelay
== 0 && dmaReadFactor
== 0) {
1484 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1485 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1486 rxDmaReadEvent
.schedule(start
);
1491 NSGigE::rxDmaReadDone()
1493 assert(rxDmaState
== dmaReading
);
1496 // If the transmit state machine has a pending DMA, let it go first
1497 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1504 NSGigE::rxDmaWriteCopy()
1506 assert(rxDmaState
== dmaWriting
);
1508 physmem
->dma_write(rxDmaAddr
, (uint8_t *)rxDmaData
, rxDmaLen
);
1509 rxDmaState
= dmaIdle
;
1511 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1512 rxDmaAddr
, rxDmaLen
);
1513 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1517 NSGigE::doRxDmaWrite()
1519 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1520 rxDmaState
= dmaWriting
;
1522 if (dmaInterface
&& !rxDmaFree
) {
1523 if (dmaInterface
->busy())
1524 rxDmaState
= dmaWriteWaiting
;
1526 dmaInterface
->doDMA(WriteInvalidate
, rxDmaAddr
, rxDmaLen
, curTick
,
1527 &rxDmaWriteEvent
, true);
1531 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0) {
1536 Tick factor
= ((rxDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
1537 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
1538 rxDmaWriteEvent
.schedule(start
);
1543 NSGigE::rxDmaWriteDone()
1545 assert(rxDmaState
== dmaWriting
);
1548 // If the transmit state machine has a pending DMA, let it go first
1549 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1558 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1561 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1562 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1565 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1566 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1570 if (rxKickTick
> curTick
) {
1571 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1577 // Go to the next state machine clock tick.
1578 rxKickTick
= curTick
+ cycles(1);
1581 switch(rxDmaState
) {
1582 case dmaReadWaiting
:
1586 case dmaWriteWaiting
:
1594 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1595 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1597 // see state machine from spec for details
1598 // the way this works is, if you finish work on one state and can
1599 // go directly to another, you do that through jumping to the
1600 // label "next". however, if you have intermediate work, like DMA
1601 // so that you can't go to the next state yet, you go to exit and
1602 // exit the loop. however, when the DMA is done it will trigger
1603 // an event and come back to this loop.
1607 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1612 rxState
= rxDescRefr
;
1614 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1616 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1617 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1618 rxDmaFree
= dmaDescFree
;
1621 descDmaRdBytes
+= rxDmaLen
;
1626 rxState
= rxDescRead
;
1628 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1629 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1630 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1631 rxDmaFree
= dmaDescFree
;
1634 descDmaRdBytes
+= rxDmaLen
;
1642 if (rxDmaState
!= dmaIdle
)
1645 rxState
= rxAdvance
;
1649 if (rxDmaState
!= dmaIdle
)
1652 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1653 regs
.rxdp
& 0x3fffffff);
1654 DPRINTF(EthernetDesc
,
1655 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1656 link
, bufptr
, cmdsts
, extsts
);
1658 if (cmdsts
& CMDSTS_OWN
) {
1659 devIntrPost(ISR_RXIDLE
);
1663 rxState
= rxFifoBlock
;
1665 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1672 * @todo in reality, we should be able to start processing
1673 * the packet as it arrives, and not have to wait for the
1674 * full packet ot be in the receive fifo.
1679 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1681 // If we don't have a packet, grab a new one from the fifo.
1682 rxPacket
= rxFifo
.front();
1683 rxPktBytes
= rxPacket
->length
;
1684 rxPacketBufPtr
= rxPacket
->data
;
1687 if (DTRACE(Ethernet
)) {
1690 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1694 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1695 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1702 // sanity check - i think the driver behaves like this
1703 assert(rxDescCnt
>= rxPktBytes
);
1708 // dont' need the && rxDescCnt > 0 if driver sanity check
1710 if (rxPktBytes
> 0) {
1711 rxState
= rxFragWrite
;
1712 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1714 rxXferLen
= rxPktBytes
;
1716 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1717 rxDmaData
= rxPacketBufPtr
;
1718 rxDmaLen
= rxXferLen
;
1719 rxDmaFree
= dmaDataFree
;
1725 rxState
= rxDescWrite
;
1727 //if (rxPktBytes == 0) { /* packet is done */
1728 assert(rxPktBytes
== 0);
1729 DPRINTF(EthernetSM
, "done with receiving packet\n");
1731 cmdsts
|= CMDSTS_OWN
;
1732 cmdsts
&= ~CMDSTS_MORE
;
1733 cmdsts
|= CMDSTS_OK
;
1734 cmdsts
&= 0xffff0000;
1735 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1739 * all the driver uses these are for its own stats keeping
1740 * which we don't care about, aren't necessary for
1741 * functionality and doing this would just slow us down.
1742 * if they end up using this in a later version for
1743 * functional purposes, just undef
1745 if (rxFilterEnable
) {
1746 cmdsts
&= ~CMDSTS_DEST_MASK
;
1747 const EthAddr
&dst
= rxFifoFront()->dst();
1749 cmdsts
|= CMDSTS_DEST_SELF
;
1750 if (dst
->multicast())
1751 cmdsts
|= CMDSTS_DEST_MULTI
;
1752 if (dst
->broadcast())
1753 cmdsts
|= CMDSTS_DEST_MASK
;
1758 if (extstsEnable
&& ip
) {
1759 extsts
|= EXTSTS_IPPKT
;
1761 if (cksum(ip
) != 0) {
1762 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1763 extsts
|= EXTSTS_IPERR
;
1768 extsts
|= EXTSTS_TCPPKT
;
1770 if (cksum(tcp
) != 0) {
1771 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1772 extsts
|= EXTSTS_TCPERR
;
1776 extsts
|= EXTSTS_UDPPKT
;
1778 if (cksum(udp
) != 0) {
1779 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1780 extsts
|= EXTSTS_UDPERR
;
1787 * the driver seems to always receive into desc buffers
1788 * of size 1514, so you never have a pkt that is split
1789 * into multiple descriptors on the receive side, so
1790 * i don't implement that case, hence the assert above.
1793 DPRINTF(EthernetDesc
,
1794 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1795 regs
.rxdp
& 0x3fffffff);
1796 DPRINTF(EthernetDesc
,
1797 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1798 link
, bufptr
, cmdsts
, extsts
);
1800 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1801 rxDmaData
= &cmdsts
;
1803 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1804 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1806 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1807 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1809 rxDmaFree
= dmaDescFree
;
1812 descDmaWrBytes
+= rxDmaLen
;
1820 if (rxDmaState
!= dmaIdle
)
1823 rxPacketBufPtr
+= rxXferLen
;
1824 rxFragPtr
+= rxXferLen
;
1825 rxPktBytes
-= rxXferLen
;
1827 rxState
= rxFifoBlock
;
1831 if (rxDmaState
!= dmaIdle
)
1834 assert(cmdsts
& CMDSTS_OWN
);
1836 assert(rxPacket
== 0);
1837 devIntrPost(ISR_RXOK
);
1839 if (cmdsts
& CMDSTS_INTR
)
1840 devIntrPost(ISR_RXDESC
);
1843 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1847 rxState
= rxAdvance
;
1852 devIntrPost(ISR_RXIDLE
);
1857 if (rxDmaState
!= dmaIdle
)
1859 rxState
= rxDescRead
;
1863 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1864 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1865 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1866 rxDmaFree
= dmaDescFree
;
1874 panic("Invalid rxState!");
1877 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1878 NsRxStateStrings
[rxState
]);
1883 * @todo do we want to schedule a future kick?
1885 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1886 NsRxStateStrings
[rxState
]);
1888 if (clock
&& !rxKickEvent
.scheduled())
1889 rxKickEvent
.schedule(rxKickTick
);
1895 if (txFifo
.empty()) {
1896 DPRINTF(Ethernet
, "nothing to transmit\n");
1900 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1902 if (interface
->sendPacket(txFifo
.front())) {
1904 if (DTRACE(Ethernet
)) {
1905 IpPtr
ip(txFifo
.front());
1907 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1911 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1912 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1919 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1920 txBytes
+= txFifo
.front()->length
;
1923 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1928 * normally do a writeback of the descriptor here, and ONLY
1929 * after that is done, send this interrupt. but since our
1930 * stuff never actually fails, just do this interrupt here,
1931 * otherwise the code has to stray from this nice format.
1932 * besides, it's functionally the same.
1934 devIntrPost(ISR_TXOK
);
1937 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1938 DPRINTF(Ethernet
, "reschedule transmit\n");
1939 txEvent
.schedule(curTick
+ retryTime
);
1944 NSGigE::txDmaReadCopy()
1946 assert(txDmaState
== dmaReading
);
1948 physmem
->dma_read((uint8_t *)txDmaData
, txDmaAddr
, txDmaLen
);
1949 txDmaState
= dmaIdle
;
1951 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1952 txDmaAddr
, txDmaLen
);
1953 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1957 NSGigE::doTxDmaRead()
1959 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1960 txDmaState
= dmaReading
;
1962 if (dmaInterface
&& !txDmaFree
) {
1963 if (dmaInterface
->busy())
1964 txDmaState
= dmaReadWaiting
;
1966 dmaInterface
->doDMA(Read
, txDmaAddr
, txDmaLen
, curTick
,
1967 &txDmaReadEvent
, true);
1971 if (dmaReadDelay
== 0 && dmaReadFactor
== 0.0) {
1976 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaReadFactor
;
1977 Tick start
= curTick
+ dmaReadDelay
+ factor
;
1978 txDmaReadEvent
.schedule(start
);
1983 NSGigE::txDmaReadDone()
1985 assert(txDmaState
== dmaReading
);
1988 // If the receive state machine has a pending DMA, let it go first
1989 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1996 NSGigE::txDmaWriteCopy()
1998 assert(txDmaState
== dmaWriting
);
2000 physmem
->dma_write(txDmaAddr
, (uint8_t *)txDmaData
, txDmaLen
);
2001 txDmaState
= dmaIdle
;
2003 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
2004 txDmaAddr
, txDmaLen
);
2005 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
2009 NSGigE::doTxDmaWrite()
2011 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
2012 txDmaState
= dmaWriting
;
2014 if (dmaInterface
&& !txDmaFree
) {
2015 if (dmaInterface
->busy())
2016 txDmaState
= dmaWriteWaiting
;
2018 dmaInterface
->doDMA(WriteInvalidate
, txDmaAddr
, txDmaLen
, curTick
,
2019 &txDmaWriteEvent
, true);
2023 if (dmaWriteDelay
== 0 && dmaWriteFactor
== 0.0) {
2028 Tick factor
= ((txDmaLen
+ ULL(63)) >> ULL(6)) * dmaWriteFactor
;
2029 Tick start
= curTick
+ dmaWriteDelay
+ factor
;
2030 txDmaWriteEvent
.schedule(start
);
2035 NSGigE::txDmaWriteDone()
2037 assert(txDmaState
== dmaWriting
);
2040 // If the receive state machine has a pending DMA, let it go first
2041 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
2050 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
2052 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
2053 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
2056 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
2057 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
2061 if (txKickTick
> curTick
) {
2062 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
2067 // Go to the next state machine clock tick.
2068 txKickTick
= curTick
+ cycles(1);
2071 switch(txDmaState
) {
2072 case dmaReadWaiting
:
2076 case dmaWriteWaiting
:
2084 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
2085 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
2089 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
2094 txState
= txDescRefr
;
2096 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2098 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
2099 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
2100 txDmaFree
= dmaDescFree
;
2103 descDmaRdBytes
+= txDmaLen
;
2109 txState
= txDescRead
;
2111 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2112 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2113 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2114 txDmaFree
= dmaDescFree
;
2117 descDmaRdBytes
+= txDmaLen
;
2125 if (txDmaState
!= dmaIdle
)
2128 txState
= txAdvance
;
2132 if (txDmaState
!= dmaIdle
)
2135 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
2136 regs
.txdp
& 0x3fffffff);
2137 DPRINTF(EthernetDesc
,
2138 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
2139 link
, bufptr
, cmdsts
, extsts
);
2141 if (cmdsts
& CMDSTS_OWN
) {
2142 txState
= txFifoBlock
;
2144 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
2146 devIntrPost(ISR_TXIDLE
);
2154 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2155 txPacket
= new PacketData(16384);
2156 txPacketBufPtr
= txPacket
->data
;
2159 if (txDescCnt
== 0) {
2160 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2161 if (cmdsts
& CMDSTS_MORE
) {
2162 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2163 txState
= txDescWrite
;
2165 cmdsts
&= ~CMDSTS_OWN
;
2167 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2168 txDmaData
= &cmdsts
;
2170 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2171 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2173 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2174 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2176 txDmaFree
= dmaDescFree
;
2181 } else { /* this packet is totally done */
2182 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2183 /* deal with the the packet that just finished */
2184 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2186 if (extsts
& EXTSTS_UDPPKT
) {
2189 udp
->sum(cksum(udp
));
2191 } else if (extsts
& EXTSTS_TCPPKT
) {
2194 tcp
->sum(cksum(tcp
));
2197 if (extsts
& EXTSTS_IPPKT
) {
2204 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2205 // this is just because the receive can't handle a
2206 // packet bigger want to make sure
2207 if (txPacket
->length
> 1514)
2208 panic("transmit packet too large, %s > 1514\n",
2214 txFifo
.push(txPacket
);
2218 * this following section is not tqo spec, but
2219 * functionally shouldn't be any different. normally,
2220 * the chip will wait til the transmit has occurred
2221 * before writing back the descriptor because it has
2222 * to wait to see that it was successfully transmitted
2223 * to decide whether to set CMDSTS_OK or not.
2224 * however, in the simulator since it is always
2225 * successfully transmitted, and writing it exactly to
2226 * spec would complicate the code, we just do it here
2229 cmdsts
&= ~CMDSTS_OWN
;
2230 cmdsts
|= CMDSTS_OK
;
2232 DPRINTF(EthernetDesc
,
2233 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2236 txDmaFree
= dmaDescFree
;
2237 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2238 txDmaData
= &cmdsts
;
2240 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2242 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2244 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2246 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2250 descDmaWrBytes
+= txDmaLen
;
2256 DPRINTF(EthernetSM
, "halting TX state machine\n");
2260 txState
= txAdvance
;
2266 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2267 if (!txFifo
.full()) {
2268 txState
= txFragRead
;
2271 * The number of bytes transferred is either whatever
2272 * is left in the descriptor (txDescCnt), or if there
2273 * is not enough room in the fifo, just whatever room
2274 * is left in the fifo
2276 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2278 txDmaAddr
= txFragPtr
& 0x3fffffff;
2279 txDmaData
= txPacketBufPtr
;
2280 txDmaLen
= txXferLen
;
2281 txDmaFree
= dmaDataFree
;
2286 txState
= txFifoBlock
;
2296 if (txDmaState
!= dmaIdle
)
2299 txPacketBufPtr
+= txXferLen
;
2300 txFragPtr
+= txXferLen
;
2301 txDescCnt
-= txXferLen
;
2302 txFifo
.reserve(txXferLen
);
2304 txState
= txFifoBlock
;
2308 if (txDmaState
!= dmaIdle
)
2311 if (cmdsts
& CMDSTS_INTR
)
2312 devIntrPost(ISR_TXDESC
);
2315 DPRINTF(EthernetSM
, "halting TX state machine\n");
2319 txState
= txAdvance
;
2324 devIntrPost(ISR_TXIDLE
);
2328 if (txDmaState
!= dmaIdle
)
2330 txState
= txDescRead
;
2334 txDmaAddr
= link
& 0x3fffffff;
2335 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2336 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2337 txDmaFree
= dmaDescFree
;
2345 panic("invalid state");
2348 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2349 NsTxStateStrings
[txState
]);
2354 * @todo do we want to schedule a future kick?
2356 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2357 NsTxStateStrings
[txState
]);
2359 if (clock
&& !txKickEvent
.scheduled())
2360 txKickEvent
.schedule(txKickTick
);
2364 * Advance the EEPROM state machine
2365 * Called on rising edge of EEPROM clock bit in MEAR
2368 NSGigE::eepromKick()
2370 switch (eepromState
) {
2374 // Wait for start bit
2375 if (regs
.mear
& MEAR_EEDI
) {
2376 // Set up to get 2 opcode bits
2377 eepromState
= eepromGetOpcode
;
2383 case eepromGetOpcode
:
2385 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2388 // Done getting opcode
2389 if (eepromBitsToRx
== 0) {
2390 if (eepromOpcode
!= EEPROM_READ
)
2391 panic("only EEPROM reads are implemented!");
2393 // Set up to get address
2394 eepromState
= eepromGetAddress
;
2400 case eepromGetAddress
:
2401 eepromAddress
<<= 1;
2402 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2405 // Done getting address
2406 if (eepromBitsToRx
== 0) {
2408 if (eepromAddress
>= EEPROM_SIZE
)
2409 panic("EEPROM read access out of range!");
2411 switch (eepromAddress
) {
2413 case EEPROM_PMATCH2_ADDR
:
2414 eepromData
= rom
.perfectMatch
[5];
2416 eepromData
+= rom
.perfectMatch
[4];
2419 case EEPROM_PMATCH1_ADDR
:
2420 eepromData
= rom
.perfectMatch
[3];
2422 eepromData
+= rom
.perfectMatch
[2];
2425 case EEPROM_PMATCH0_ADDR
:
2426 eepromData
= rom
.perfectMatch
[1];
2428 eepromData
+= rom
.perfectMatch
[0];
2432 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2434 // Set up to read data
2435 eepromState
= eepromRead
;
2436 eepromBitsToRx
= 16;
2438 // Clear data in bit
2439 regs
.mear
&= ~MEAR_EEDI
;
2444 // Clear Data Out bit
2445 regs
.mear
&= ~MEAR_EEDO
;
2446 // Set bit to value of current EEPROM bit
2447 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2453 if (eepromBitsToRx
== 0) {
2454 eepromState
= eepromStart
;
2459 panic("invalid EEPROM state");
2465 NSGigE::transferDone()
2467 if (txFifo
.empty()) {
2468 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2472 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2474 if (txEvent
.scheduled())
2475 txEvent
.reschedule(curTick
+ cycles(1));
2477 txEvent
.schedule(curTick
+ cycles(1));
2481 NSGigE::rxFilter(const PacketPtr
&packet
)
2483 EthPtr eth
= packet
;
2487 const EthAddr
&dst
= eth
->dst();
2488 if (dst
.unicast()) {
2489 // If we're accepting all unicast addresses
2493 // If we make a perfect match
2494 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2497 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2500 } else if (dst
.broadcast()) {
2501 // if we're accepting broadcasts
2502 if (acceptBroadcast
)
2505 } else if (dst
.multicast()) {
2506 // if we're accepting all multicasts
2507 if (acceptMulticast
)
2510 // Multicast hashing faked - all packets accepted
2511 if (multicastHashEnable
)
2516 DPRINTF(Ethernet
, "rxFilter drop\n");
2517 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2524 NSGigE::recvPacket(PacketPtr packet
)
2526 rxBytes
+= packet
->length
;
2529 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2533 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2534 interface
->recvDone();
2538 if (!rxFilterEnable
) {
2540 "receive packet filtering disabled . . . packet dropped\n");
2541 interface
->recvDone();
2545 if (rxFilter(packet
)) {
2546 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2547 interface
->recvDone();
2551 if (rxFifo
.avail() < packet
->length
) {
2557 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2560 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2565 devIntrPost(ISR_RXORN
);
2569 rxFifo
.push(packet
);
2570 interface
->recvDone();
2576 //=====================================================================
2580 NSGigE::serialize(ostream
&os
)
2582 // Serialize the PciDev base class
2583 PciDev::serialize(os
);
2586 * Finalize any DMA events now.
2588 if (rxDmaReadEvent
.scheduled())
2590 if (rxDmaWriteEvent
.scheduled())
2592 if (txDmaReadEvent
.scheduled())
2594 if (txDmaWriteEvent
.scheduled())
2598 * Serialize the device registers
2600 SERIALIZE_SCALAR(regs
.command
);
2601 SERIALIZE_SCALAR(regs
.config
);
2602 SERIALIZE_SCALAR(regs
.mear
);
2603 SERIALIZE_SCALAR(regs
.ptscr
);
2604 SERIALIZE_SCALAR(regs
.isr
);
2605 SERIALIZE_SCALAR(regs
.imr
);
2606 SERIALIZE_SCALAR(regs
.ier
);
2607 SERIALIZE_SCALAR(regs
.ihr
);
2608 SERIALIZE_SCALAR(regs
.txdp
);
2609 SERIALIZE_SCALAR(regs
.txdp_hi
);
2610 SERIALIZE_SCALAR(regs
.txcfg
);
2611 SERIALIZE_SCALAR(regs
.gpior
);
2612 SERIALIZE_SCALAR(regs
.rxdp
);
2613 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2614 SERIALIZE_SCALAR(regs
.rxcfg
);
2615 SERIALIZE_SCALAR(regs
.pqcr
);
2616 SERIALIZE_SCALAR(regs
.wcsr
);
2617 SERIALIZE_SCALAR(regs
.pcr
);
2618 SERIALIZE_SCALAR(regs
.rfcr
);
2619 SERIALIZE_SCALAR(regs
.rfdr
);
2620 SERIALIZE_SCALAR(regs
.brar
);
2621 SERIALIZE_SCALAR(regs
.brdr
);
2622 SERIALIZE_SCALAR(regs
.srr
);
2623 SERIALIZE_SCALAR(regs
.mibc
);
2624 SERIALIZE_SCALAR(regs
.vrcr
);
2625 SERIALIZE_SCALAR(regs
.vtcr
);
2626 SERIALIZE_SCALAR(regs
.vdr
);
2627 SERIALIZE_SCALAR(regs
.ccsr
);
2628 SERIALIZE_SCALAR(regs
.tbicr
);
2629 SERIALIZE_SCALAR(regs
.tbisr
);
2630 SERIALIZE_SCALAR(regs
.tanar
);
2631 SERIALIZE_SCALAR(regs
.tanlpar
);
2632 SERIALIZE_SCALAR(regs
.taner
);
2633 SERIALIZE_SCALAR(regs
.tesr
);
2635 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2636 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2638 SERIALIZE_SCALAR(ioEnable
);
2641 * Serialize the data Fifos
2643 rxFifo
.serialize("rxFifo", os
);
2644 txFifo
.serialize("txFifo", os
);
2647 * Serialize the various helper variables
2649 bool txPacketExists
= txPacket
;
2650 SERIALIZE_SCALAR(txPacketExists
);
2651 if (txPacketExists
) {
2652 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2653 txPacket
->serialize("txPacket", os
);
2654 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2655 SERIALIZE_SCALAR(txPktBufPtr
);
2658 bool rxPacketExists
= rxPacket
;
2659 SERIALIZE_SCALAR(rxPacketExists
);
2660 if (rxPacketExists
) {
2661 rxPacket
->serialize("rxPacket", os
);
2662 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2663 SERIALIZE_SCALAR(rxPktBufPtr
);
2666 SERIALIZE_SCALAR(txXferLen
);
2667 SERIALIZE_SCALAR(rxXferLen
);
2670 * Serialize Cached Descriptors
2672 SERIALIZE_SCALAR(rxDesc64
.link
);
2673 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2674 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2675 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2676 SERIALIZE_SCALAR(txDesc64
.link
);
2677 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2678 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2679 SERIALIZE_SCALAR(txDesc64
.extsts
);
2680 SERIALIZE_SCALAR(rxDesc32
.link
);
2681 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2682 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2683 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2684 SERIALIZE_SCALAR(txDesc32
.link
);
2685 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2686 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2687 SERIALIZE_SCALAR(txDesc32
.extsts
);
2688 SERIALIZE_SCALAR(extstsEnable
);
2691 * Serialize tx state machine
2693 int txState
= this->txState
;
2694 SERIALIZE_SCALAR(txState
);
2695 SERIALIZE_SCALAR(txEnable
);
2696 SERIALIZE_SCALAR(CTDD
);
2697 SERIALIZE_SCALAR(txFragPtr
);
2698 SERIALIZE_SCALAR(txDescCnt
);
2699 int txDmaState
= this->txDmaState
;
2700 SERIALIZE_SCALAR(txDmaState
);
2701 SERIALIZE_SCALAR(txKickTick
);
2704 * Serialize rx state machine
2706 int rxState
= this->rxState
;
2707 SERIALIZE_SCALAR(rxState
);
2708 SERIALIZE_SCALAR(rxEnable
);
2709 SERIALIZE_SCALAR(CRDD
);
2710 SERIALIZE_SCALAR(rxPktBytes
);
2711 SERIALIZE_SCALAR(rxFragPtr
);
2712 SERIALIZE_SCALAR(rxDescCnt
);
2713 int rxDmaState
= this->rxDmaState
;
2714 SERIALIZE_SCALAR(rxDmaState
);
2715 SERIALIZE_SCALAR(rxKickTick
);
2718 * Serialize EEPROM state machine
2720 int eepromState
= this->eepromState
;
2721 SERIALIZE_SCALAR(eepromState
);
2722 SERIALIZE_SCALAR(eepromClk
);
2723 SERIALIZE_SCALAR(eepromBitsToRx
);
2724 SERIALIZE_SCALAR(eepromOpcode
);
2725 SERIALIZE_SCALAR(eepromAddress
);
2726 SERIALIZE_SCALAR(eepromData
);
2729 * If there's a pending transmit, store the time so we can
2730 * reschedule it later
2732 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2733 SERIALIZE_SCALAR(transmitTick
);
2736 * receive address filter settings
2738 SERIALIZE_SCALAR(rxFilterEnable
);
2739 SERIALIZE_SCALAR(acceptBroadcast
);
2740 SERIALIZE_SCALAR(acceptMulticast
);
2741 SERIALIZE_SCALAR(acceptUnicast
);
2742 SERIALIZE_SCALAR(acceptPerfect
);
2743 SERIALIZE_SCALAR(acceptArp
);
2744 SERIALIZE_SCALAR(multicastHashEnable
);
2747 * Keep track of pending interrupt status.
2749 SERIALIZE_SCALAR(intrTick
);
2750 SERIALIZE_SCALAR(cpuPendingIntr
);
2751 Tick intrEventTick
= 0;
2753 intrEventTick
= intrEvent
->when();
2754 SERIALIZE_SCALAR(intrEventTick
);
2759 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2761 // Unserialize the PciDev base class
2762 PciDev::unserialize(cp
, section
);
2764 UNSERIALIZE_SCALAR(regs
.command
);
2765 UNSERIALIZE_SCALAR(regs
.config
);
2766 UNSERIALIZE_SCALAR(regs
.mear
);
2767 UNSERIALIZE_SCALAR(regs
.ptscr
);
2768 UNSERIALIZE_SCALAR(regs
.isr
);
2769 UNSERIALIZE_SCALAR(regs
.imr
);
2770 UNSERIALIZE_SCALAR(regs
.ier
);
2771 UNSERIALIZE_SCALAR(regs
.ihr
);
2772 UNSERIALIZE_SCALAR(regs
.txdp
);
2773 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2774 UNSERIALIZE_SCALAR(regs
.txcfg
);
2775 UNSERIALIZE_SCALAR(regs
.gpior
);
2776 UNSERIALIZE_SCALAR(regs
.rxdp
);
2777 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2778 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2779 UNSERIALIZE_SCALAR(regs
.pqcr
);
2780 UNSERIALIZE_SCALAR(regs
.wcsr
);
2781 UNSERIALIZE_SCALAR(regs
.pcr
);
2782 UNSERIALIZE_SCALAR(regs
.rfcr
);
2783 UNSERIALIZE_SCALAR(regs
.rfdr
);
2784 UNSERIALIZE_SCALAR(regs
.brar
);
2785 UNSERIALIZE_SCALAR(regs
.brdr
);
2786 UNSERIALIZE_SCALAR(regs
.srr
);
2787 UNSERIALIZE_SCALAR(regs
.mibc
);
2788 UNSERIALIZE_SCALAR(regs
.vrcr
);
2789 UNSERIALIZE_SCALAR(regs
.vtcr
);
2790 UNSERIALIZE_SCALAR(regs
.vdr
);
2791 UNSERIALIZE_SCALAR(regs
.ccsr
);
2792 UNSERIALIZE_SCALAR(regs
.tbicr
);
2793 UNSERIALIZE_SCALAR(regs
.tbisr
);
2794 UNSERIALIZE_SCALAR(regs
.tanar
);
2795 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2796 UNSERIALIZE_SCALAR(regs
.taner
);
2797 UNSERIALIZE_SCALAR(regs
.tesr
);
2799 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2800 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2802 UNSERIALIZE_SCALAR(ioEnable
);
2805 * unserialize the data fifos
2807 rxFifo
.unserialize("rxFifo", cp
, section
);
2808 txFifo
.unserialize("txFifo", cp
, section
);
2811 * unserialize the various helper variables
2813 bool txPacketExists
;
2814 UNSERIALIZE_SCALAR(txPacketExists
);
2815 if (txPacketExists
) {
2816 txPacket
= new PacketData(16384);
2817 txPacket
->unserialize("txPacket", cp
, section
);
2818 uint32_t txPktBufPtr
;
2819 UNSERIALIZE_SCALAR(txPktBufPtr
);
2820 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2824 bool rxPacketExists
;
2825 UNSERIALIZE_SCALAR(rxPacketExists
);
2827 if (rxPacketExists
) {
2828 rxPacket
= new PacketData(16384);
2829 rxPacket
->unserialize("rxPacket", cp
, section
);
2830 uint32_t rxPktBufPtr
;
2831 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2832 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2836 UNSERIALIZE_SCALAR(txXferLen
);
2837 UNSERIALIZE_SCALAR(rxXferLen
);
2840 * Unserialize Cached Descriptors
2842 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2843 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2844 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2845 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2846 UNSERIALIZE_SCALAR(txDesc64
.link
);
2847 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2848 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2849 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2850 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2851 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2852 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2853 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2854 UNSERIALIZE_SCALAR(txDesc32
.link
);
2855 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2856 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2857 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2858 UNSERIALIZE_SCALAR(extstsEnable
);
2861 * unserialize tx state machine
2864 UNSERIALIZE_SCALAR(txState
);
2865 this->txState
= (TxState
) txState
;
2866 UNSERIALIZE_SCALAR(txEnable
);
2867 UNSERIALIZE_SCALAR(CTDD
);
2868 UNSERIALIZE_SCALAR(txFragPtr
);
2869 UNSERIALIZE_SCALAR(txDescCnt
);
2871 UNSERIALIZE_SCALAR(txDmaState
);
2872 this->txDmaState
= (DmaState
) txDmaState
;
2873 UNSERIALIZE_SCALAR(txKickTick
);
2875 txKickEvent
.schedule(txKickTick
);
2878 * unserialize rx state machine
2881 UNSERIALIZE_SCALAR(rxState
);
2882 this->rxState
= (RxState
) rxState
;
2883 UNSERIALIZE_SCALAR(rxEnable
);
2884 UNSERIALIZE_SCALAR(CRDD
);
2885 UNSERIALIZE_SCALAR(rxPktBytes
);
2886 UNSERIALIZE_SCALAR(rxFragPtr
);
2887 UNSERIALIZE_SCALAR(rxDescCnt
);
2889 UNSERIALIZE_SCALAR(rxDmaState
);
2890 this->rxDmaState
= (DmaState
) rxDmaState
;
2891 UNSERIALIZE_SCALAR(rxKickTick
);
2893 rxKickEvent
.schedule(rxKickTick
);
2896 * Unserialize EEPROM state machine
2899 UNSERIALIZE_SCALAR(eepromState
);
2900 this->eepromState
= (EEPROMState
) eepromState
;
2901 UNSERIALIZE_SCALAR(eepromClk
);
2902 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2903 UNSERIALIZE_SCALAR(eepromOpcode
);
2904 UNSERIALIZE_SCALAR(eepromAddress
);
2905 UNSERIALIZE_SCALAR(eepromData
);
2908 * If there's a pending transmit, reschedule it now
2911 UNSERIALIZE_SCALAR(transmitTick
);
2913 txEvent
.schedule(curTick
+ transmitTick
);
2916 * unserialize receive address filter settings
2918 UNSERIALIZE_SCALAR(rxFilterEnable
);
2919 UNSERIALIZE_SCALAR(acceptBroadcast
);
2920 UNSERIALIZE_SCALAR(acceptMulticast
);
2921 UNSERIALIZE_SCALAR(acceptUnicast
);
2922 UNSERIALIZE_SCALAR(acceptPerfect
);
2923 UNSERIALIZE_SCALAR(acceptArp
);
2924 UNSERIALIZE_SCALAR(multicastHashEnable
);
2927 * Keep track of pending interrupt status.
2929 UNSERIALIZE_SCALAR(intrTick
);
2930 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2932 UNSERIALIZE_SCALAR(intrEventTick
);
2933 if (intrEventTick
) {
2934 intrEvent
= new IntrEvent(this, true);
2935 intrEvent
->schedule(intrEventTick
);
2939 * re-add addrRanges to bus bridges
2942 pioInterface
->addAddrRange(RangeSize(BARAddrs
[0], BARSize
[0]));
2943 pioInterface
->addAddrRange(RangeSize(BARAddrs
[1], BARSize
[1]));
2948 NSGigE::cacheAccess(MemReqPtr
&req
)
2950 DPRINTF(EthernetPIO
, "timing access to paddr=%#x (daddr=%#x)\n",
2951 req
->paddr
, req
->paddr
- addr
);
2952 return curTick
+ pioLatency
;
2955 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2957 SimObjectParam
<EtherInt
*> peer
;
2958 SimObjectParam
<NSGigE
*> device
;
2960 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2962 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2964 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2965 INIT_PARAM(device
, "Ethernet device of this interface")
2967 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2969 CREATE_SIM_OBJECT(NSGigEInt
)
2971 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2973 EtherInt
*p
= (EtherInt
*)peer
;
2975 dev_int
->setPeer(p
);
2976 p
->setPeer(dev_int
);
2982 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2985 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2990 SimObjectParam
<MemoryController
*> mmu
;
2991 SimObjectParam
<PhysicalMemory
*> physmem
;
2992 SimObjectParam
<PciConfigAll
*> configspace
;
2993 SimObjectParam
<PciConfigData
*> configdata
;
2994 SimObjectParam
<Platform
*> platform
;
2995 Param
<uint32_t> pci_bus
;
2996 Param
<uint32_t> pci_dev
;
2997 Param
<uint32_t> pci_func
;
2999 SimObjectParam
<HierParams
*> hier
;
3000 SimObjectParam
<Bus
*> io_bus
;
3001 SimObjectParam
<Bus
*> payload_bus
;
3002 Param
<bool> dma_desc_free
;
3003 Param
<bool> dma_data_free
;
3004 Param
<Tick
> dma_read_delay
;
3005 Param
<Tick
> dma_write_delay
;
3006 Param
<Tick
> dma_read_factor
;
3007 Param
<Tick
> dma_write_factor
;
3008 Param
<bool> dma_no_allocate
;
3009 Param
<Tick
> pio_latency
;
3010 Param
<Tick
> intr_delay
;
3012 Param
<Tick
> rx_delay
;
3013 Param
<Tick
> tx_delay
;
3014 Param
<uint32_t> rx_fifo_size
;
3015 Param
<uint32_t> tx_fifo_size
;
3017 Param
<bool> rx_filter
;
3018 Param
<string
> hardware_address
;
3019 Param
<bool> dedicated
;
3021 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
3023 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3025 INIT_PARAM(clock
, "State machine processor frequency"),
3027 INIT_PARAM(addr
, "Device Address"),
3028 INIT_PARAM(mmu
, "Memory Controller"),
3029 INIT_PARAM(physmem
, "Physical Memory"),
3030 INIT_PARAM(configspace
, "PCI Configspace"),
3031 INIT_PARAM(configdata
, "PCI Config data"),
3032 INIT_PARAM(platform
, "Platform"),
3033 INIT_PARAM(pci_bus
, "PCI bus"),
3034 INIT_PARAM(pci_dev
, "PCI device number"),
3035 INIT_PARAM(pci_func
, "PCI function code"),
3037 INIT_PARAM(hier
, "Hierarchy global variables"),
3038 INIT_PARAM(io_bus
, "The IO Bus to attach to for headers"),
3039 INIT_PARAM(payload_bus
, "The IO Bus to attach to for payload"),
3040 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
3041 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
3042 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
3043 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
3044 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
3045 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
3046 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
3047 INIT_PARAM(pio_latency
, "Programmed IO latency in bus cycles"),
3048 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
3050 INIT_PARAM(rx_delay
, "Receive Delay"),
3051 INIT_PARAM(tx_delay
, "Transmit Delay"),
3052 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
3053 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
3055 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
3056 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
3057 INIT_PARAM(dedicated
, "dedicate a kernel thread to the driver")
3059 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
3062 CREATE_SIM_OBJECT(NSGigE
)
3064 NSGigE::Params
*params
= new NSGigE::Params
;
3066 params
->name
= getInstanceName();
3068 params
->clock
= clock
;
3071 params
->pmem
= physmem
;
3072 params
->configSpace
= configspace
;
3073 params
->configData
= configdata
;
3074 params
->plat
= platform
;
3075 params
->busNum
= pci_bus
;
3076 params
->deviceNum
= pci_dev
;
3077 params
->functionNum
= pci_func
;
3079 params
->hier
= hier
;
3080 params
->header_bus
= io_bus
;
3081 params
->payload_bus
= payload_bus
;
3082 params
->dma_desc_free
= dma_desc_free
;
3083 params
->dma_data_free
= dma_data_free
;
3084 params
->dma_read_delay
= dma_read_delay
;
3085 params
->dma_write_delay
= dma_write_delay
;
3086 params
->dma_read_factor
= dma_read_factor
;
3087 params
->dma_write_factor
= dma_write_factor
;
3088 params
->dma_no_allocate
= dma_no_allocate
;
3089 params
->pio_latency
= pio_latency
;
3090 params
->intr_delay
= intr_delay
;
3092 params
->rx_delay
= rx_delay
;
3093 params
->tx_delay
= tx_delay
;
3094 params
->rx_fifo_size
= rx_fifo_size
;
3095 params
->tx_fifo_size
= tx_fifo_size
;
3097 params
->rx_filter
= rx_filter
;
3098 params
->eaddr
= hardware_address
;
3099 params
->dedicated
= dedicated
;
3101 return new NSGigE(params
);
3104 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)