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.
28 * Authors: Nathan Binkert
33 * Device module for modelling the National Semiconductor
34 * DP83820 ethernet controller. Does not support priority queueing
39 #include "arch/alpha/ev5.hh"
40 #include "base/inet.hh"
41 #include "cpu/thread_context.hh"
42 #include "dev/etherlink.hh"
43 #include "dev/ns_gige.hh"
44 #include "dev/pciconfigall.hh"
45 #include "mem/packet.hh"
46 #include "sim/builder.hh"
47 #include "sim/debug.hh"
48 #include "sim/host.hh"
49 #include "sim/stats.hh"
50 #include "sim/system.hh"
52 const char *NsRxStateStrings
[] =
63 const char *NsTxStateStrings
[] =
74 const char *NsDmaState
[] =
85 using namespace TheISA
;
87 ///////////////////////////////////////////////////////////////////////
91 NSGigE::NSGigE(Params
*p
)
92 : PciDev(p
), ioEnable(false),
93 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
94 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
95 txXferLen(0), rxXferLen(0), clock(p
->clock
),
96 txState(txIdle
), txEnable(false), CTDD(false),
97 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
98 rxEnable(false), CRDD(false), rxPktBytes(0),
99 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
100 eepromState(eepromStart
), rxDmaReadEvent(this), rxDmaWriteEvent(this),
101 txDmaReadEvent(this), txDmaWriteEvent(this),
102 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
103 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
104 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
105 txEvent(this), rxFilterEnable(p
->rx_filter
), acceptBroadcast(false),
106 acceptMulticast(false), acceptUnicast(false),
107 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
108 intrTick(0), cpuPendingIntr(false),
109 intrEvent(0), interface(0)
112 intrDelay
= p
->intr_delay
;
113 dmaReadDelay
= p
->dma_read_delay
;
114 dmaWriteDelay
= p
->dma_write_delay
;
115 dmaReadFactor
= p
->dma_read_factor
;
116 dmaWriteFactor
= p
->dma_write_factor
;
119 memcpy(&rom
.perfectMatch
, p
->eaddr
.bytes(), ETH_ADDR_LEN
);
121 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
122 memset(&txDesc32
, 0, sizeof(txDesc32
));
123 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
124 memset(&txDesc64
, 0, sizeof(txDesc64
));
134 .name(name() + ".txBytes")
135 .desc("Bytes Transmitted")
140 .name(name() + ".rxBytes")
141 .desc("Bytes Received")
146 .name(name() + ".txPackets")
147 .desc("Number of Packets Transmitted")
152 .name(name() + ".rxPackets")
153 .desc("Number of Packets Received")
158 .name(name() + ".txIpChecksums")
159 .desc("Number of tx IP Checksums done by device")
165 .name(name() + ".rxIpChecksums")
166 .desc("Number of rx IP Checksums done by device")
172 .name(name() + ".txTcpChecksums")
173 .desc("Number of tx TCP Checksums done by device")
179 .name(name() + ".rxTcpChecksums")
180 .desc("Number of rx TCP Checksums done by device")
186 .name(name() + ".txUdpChecksums")
187 .desc("Number of tx UDP Checksums done by device")
193 .name(name() + ".rxUdpChecksums")
194 .desc("Number of rx UDP Checksums done by device")
200 .name(name() + ".descDMAReads")
201 .desc("Number of descriptors the device read w/ DMA")
206 .name(name() + ".descDMAWrites")
207 .desc("Number of descriptors the device wrote w/ DMA")
212 .name(name() + ".descDmaReadBytes")
213 .desc("number of descriptor bytes read w/ DMA")
218 .name(name() + ".descDmaWriteBytes")
219 .desc("number of descriptor bytes write w/ DMA")
224 .name(name() + ".txBandwidth")
225 .desc("Transmit Bandwidth (bits/s)")
231 .name(name() + ".rxBandwidth")
232 .desc("Receive Bandwidth (bits/s)")
238 .name(name() + ".totBandwidth")
239 .desc("Total Bandwidth (bits/s)")
245 .name(name() + ".totPackets")
246 .desc("Total Packets")
252 .name(name() + ".totBytes")
259 .name(name() + ".totPPS")
260 .desc("Total Tranmission Rate (packets/s)")
266 .name(name() + ".txPPS")
267 .desc("Packet Tranmission Rate (packets/s)")
273 .name(name() + ".rxPPS")
274 .desc("Packet Reception Rate (packets/s)")
280 .name(name() + ".postedSwi")
281 .desc("number of software interrupts posted to CPU")
286 .name(name() + ".totalSwi")
287 .desc("total number of Swi written to ISR")
292 .name(name() + ".coalescedSwi")
293 .desc("average number of Swi's coalesced into each post")
298 .name(name() + ".postedRxIdle")
299 .desc("number of rxIdle interrupts posted to CPU")
304 .name(name() + ".totalRxIdle")
305 .desc("total number of RxIdle written to ISR")
310 .name(name() + ".coalescedRxIdle")
311 .desc("average number of RxIdle's coalesced into each post")
316 .name(name() + ".postedRxOk")
317 .desc("number of RxOk interrupts posted to CPU")
322 .name(name() + ".totalRxOk")
323 .desc("total number of RxOk written to ISR")
328 .name(name() + ".coalescedRxOk")
329 .desc("average number of RxOk's coalesced into each post")
334 .name(name() + ".postedRxDesc")
335 .desc("number of RxDesc interrupts posted to CPU")
340 .name(name() + ".totalRxDesc")
341 .desc("total number of RxDesc written to ISR")
346 .name(name() + ".coalescedRxDesc")
347 .desc("average number of RxDesc's coalesced into each post")
352 .name(name() + ".postedTxOk")
353 .desc("number of TxOk interrupts posted to CPU")
358 .name(name() + ".totalTxOk")
359 .desc("total number of TxOk written to ISR")
364 .name(name() + ".coalescedTxOk")
365 .desc("average number of TxOk's coalesced into each post")
370 .name(name() + ".postedTxIdle")
371 .desc("number of TxIdle interrupts posted to CPU")
376 .name(name() + ".totalTxIdle")
377 .desc("total number of TxIdle written to ISR")
382 .name(name() + ".coalescedTxIdle")
383 .desc("average number of TxIdle's coalesced into each post")
388 .name(name() + ".postedTxDesc")
389 .desc("number of TxDesc interrupts posted to CPU")
394 .name(name() + ".totalTxDesc")
395 .desc("total number of TxDesc written to ISR")
400 .name(name() + ".coalescedTxDesc")
401 .desc("average number of TxDesc's coalesced into each post")
406 .name(name() + ".postedRxOrn")
407 .desc("number of RxOrn posted to CPU")
412 .name(name() + ".totalRxOrn")
413 .desc("total number of RxOrn written to ISR")
418 .name(name() + ".coalescedRxOrn")
419 .desc("average number of RxOrn's coalesced into each post")
424 .name(name() + ".coalescedTotal")
425 .desc("average number of interrupts coalesced into each post")
430 .name(name() + ".postedInterrupts")
431 .desc("number of posts to CPU")
436 .name(name() + ".droppedPackets")
437 .desc("number of packets dropped")
441 coalescedSwi
= totalSwi
/ postedInterrupts
;
442 coalescedRxIdle
= totalRxIdle
/ postedInterrupts
;
443 coalescedRxOk
= totalRxOk
/ postedInterrupts
;
444 coalescedRxDesc
= totalRxDesc
/ postedInterrupts
;
445 coalescedTxOk
= totalTxOk
/ postedInterrupts
;
446 coalescedTxIdle
= totalTxIdle
/ postedInterrupts
;
447 coalescedTxDesc
= totalTxDesc
/ postedInterrupts
;
448 coalescedRxOrn
= totalRxOrn
/ postedInterrupts
;
450 coalescedTotal
= (totalSwi
+ totalRxIdle
+ totalRxOk
+ totalRxDesc
+
451 totalTxOk
+ totalTxIdle
+ totalTxDesc
+
452 totalRxOrn
) / postedInterrupts
;
454 txBandwidth
= txBytes
* Stats::constant(8) / simSeconds
;
455 rxBandwidth
= rxBytes
* Stats::constant(8) / simSeconds
;
456 totBandwidth
= txBandwidth
+ rxBandwidth
;
457 totBytes
= txBytes
+ rxBytes
;
458 totPackets
= txPackets
+ rxPackets
;
460 txPacketRate
= txPackets
/ simSeconds
;
461 rxPacketRate
= rxPackets
/ simSeconds
;
466 * This is to write to the PCI general configuration registers
469 NSGigE::writeConfig(int offset
, const uint16_t data
)
471 if (offset
< PCI_DEVICE_SPECIFIC
)
472 PciDev::writeConfig(offset
, data
);
474 panic("Device specific PCI config space not implemented!\n");
477 // seems to work fine without all these PCI settings, but i
478 // put in the IO to double check, an assertion will fail if we
479 // need to properly implement it
481 if (config
.data
[offset
] & PCI_CMD_IOSE
)
490 * This reads the device registers, which are detailed in the NS83820
494 NSGigE::read(Packet
*pkt
)
500 //The mask is to give you only the offset into the device register file
501 Addr daddr
= pkt
->getAddr() & 0xfff;
502 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
503 daddr
, pkt
->getAddr(), pkt
->getSize());
506 // there are some reserved registers, you can see ns_gige_reg.h and
507 // the spec sheet for details
508 if (daddr
> LAST
&& daddr
<= RESERVED
) {
509 panic("Accessing reserved register");
510 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
511 if (pkt
->getSize() == sizeof(uint8_t))
512 readConfig(daddr
& 0xff, pkt
->getPtr
<uint8_t>());
513 if (pkt
->getSize() == sizeof(uint16_t))
514 readConfig(daddr
& 0xff, pkt
->getPtr
<uint16_t>());
515 if (pkt
->getSize() == sizeof(uint32_t))
516 readConfig(daddr
& 0xff, pkt
->getPtr
<uint32_t>());
517 pkt
->result
= Packet::Success
;
519 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
520 // don't implement all the MIB's. hopefully the kernel
521 // doesn't actually DEPEND upon their values
522 // MIB are just hardware stats keepers
523 pkt
->set
<uint32_t>(0);
524 pkt
->result
= Packet::Success
;
526 } else if (daddr
> 0x3FC)
527 panic("Something is messed up!\n");
529 assert(pkt
->getSize() == sizeof(uint32_t));
530 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
536 //these are supposed to be cleared on a read
537 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
554 devIntrClear(ISR_ALL
);
609 // see the spec sheet for how RFCR and RFDR work
610 // basically, you write to RFCR to tell the machine
611 // what you want to do next, then you act upon RFDR,
612 // and the device will be prepared b/c of what you
619 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
621 // Read from perfect match ROM octets
623 reg
= rom
.perfectMatch
[1];
625 reg
+= rom
.perfectMatch
[0];
628 reg
= rom
.perfectMatch
[3] << 8;
629 reg
+= rom
.perfectMatch
[2];
632 reg
= rom
.perfectMatch
[5] << 8;
633 reg
+= rom
.perfectMatch
[4];
636 // Read filter hash table
637 if (rfaddr
>= FHASH_ADDR
&&
638 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
640 // Only word-aligned reads supported
642 panic("unaligned read from filter hash table!");
644 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
645 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
649 panic("reading RFDR for something other than pattern"
650 " matching or hashing! %#x\n", rfaddr
);
660 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
705 if (params()->rx_thread
)
706 reg
|= M5REG_RX_THREAD
;
707 if (params()->tx_thread
)
708 reg
|= M5REG_TX_THREAD
;
714 panic("reading unimplemented register: addr=%#x", daddr
);
717 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
720 pkt
->result
= Packet::Success
;
725 NSGigE::write(Packet
*pkt
)
729 Addr daddr
= pkt
->getAddr() & 0xfff;
730 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
731 daddr
, pkt
->getAddr(), pkt
->getSize());
733 if (daddr
> LAST
&& daddr
<= RESERVED
) {
734 panic("Accessing reserved register");
735 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
736 if (pkt
->getSize() == sizeof(uint8_t))
737 writeConfig(daddr
& 0xff, pkt
->get
<uint8_t>());
738 if (pkt
->getSize() == sizeof(uint16_t))
739 writeConfig(daddr
& 0xff, pkt
->get
<uint16_t>());
740 if (pkt
->getSize() == sizeof(uint32_t))
741 writeConfig(daddr
& 0xff, pkt
->get
<uint32_t>());
742 pkt
->result
= Packet::Success
;
744 } else if (daddr
> 0x3FC)
745 panic("Something is messed up!\n");
747 if (pkt
->getSize() == sizeof(uint32_t)) {
748 uint32_t reg
= pkt
->get
<uint32_t>();
751 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
758 } else if (reg
& CR_TXE
) {
761 // the kernel is enabling the transmit machine
762 if (txState
== txIdle
)
768 } else if (reg
& CR_RXE
) {
771 if (rxState
== rxIdle
)
782 devIntrPost(ISR_SWI
);
793 if (reg
& CFGR_LNKSTS
||
796 reg
& CFGR_RESERVED
||
797 reg
& CFGR_T64ADDR
||
798 reg
& CFGR_PCI64_DET
)
800 // First clear all writable bits
801 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
802 CFGR_RESERVED
| CFGR_T64ADDR
|
804 // Now set the appropriate writable bits
805 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
806 CFGR_RESERVED
| CFGR_T64ADDR
|
809 // all these #if 0's are because i don't THINK the kernel needs to
810 // have these implemented. if there is a problem relating to one of
811 // these, you may need to add functionality in.
812 if (reg
& CFGR_TBI_EN
) ;
813 if (reg
& CFGR_MODE_1000
) ;
815 if (reg
& CFGR_AUTO_1000
)
816 panic("CFGR_AUTO_1000 not implemented!\n");
818 if (reg
& CFGR_PINT_DUPSTS
||
819 reg
& CFGR_PINT_LNKSTS
||
820 reg
& CFGR_PINT_SPDSTS
)
823 if (reg
& CFGR_TMRTEST
) ;
824 if (reg
& CFGR_MRM_DIS
) ;
825 if (reg
& CFGR_MWI_DIS
) ;
827 if (reg
& CFGR_T64ADDR
) ;
828 // panic("CFGR_T64ADDR is read only register!\n");
830 if (reg
& CFGR_PCI64_DET
)
831 panic("CFGR_PCI64_DET is read only register!\n");
833 if (reg
& CFGR_DATA64_EN
) ;
834 if (reg
& CFGR_M64ADDR
) ;
835 if (reg
& CFGR_PHY_RST
) ;
836 if (reg
& CFGR_PHY_DIS
) ;
838 if (reg
& CFGR_EXTSTS_EN
)
841 extstsEnable
= false;
843 if (reg
& CFGR_REQALG
) ;
845 if (reg
& CFGR_POW
) ;
846 if (reg
& CFGR_EXD
) ;
847 if (reg
& CFGR_PESEL
) ;
848 if (reg
& CFGR_BROM_DIS
) ;
849 if (reg
& CFGR_EXT_125
) ;
850 if (reg
& CFGR_BEM
) ;
854 // Clear writable bits
855 regs
.mear
&= MEAR_EEDO
;
856 // Set appropriate writable bits
857 regs
.mear
|= reg
& ~MEAR_EEDO
;
859 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
860 // even though it could get it through RFDR
861 if (reg
& MEAR_EESEL
) {
862 // Rising edge of clock
863 if (reg
& MEAR_EECLK
&& !eepromClk
)
867 eepromState
= eepromStart
;
868 regs
.mear
&= ~MEAR_EEDI
;
871 eepromClk
= reg
& MEAR_EECLK
;
873 // since phy is completely faked, MEAR_MD* don't matter
874 if (reg
& MEAR_MDIO
) ;
875 if (reg
& MEAR_MDDIR
) ;
876 if (reg
& MEAR_MDC
) ;
880 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
881 // these control BISTs for various parts of chip - we
882 // don't care or do just fake that the BIST is done
883 if (reg
& PTSCR_RBIST_EN
)
884 regs
.ptscr
|= PTSCR_RBIST_DONE
;
885 if (reg
& PTSCR_EEBIST_EN
)
886 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
887 if (reg
& PTSCR_EELOAD_EN
)
888 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
891 case ISR
: /* writing to the ISR has no effect */
892 panic("ISR is a read only register!\n");
905 /* not going to implement real interrupt holdoff */
909 regs
.txdp
= (reg
& 0xFFFFFFFC);
910 assert(txState
== txIdle
);
921 if (reg
& TX_CFG_CSI
) ;
922 if (reg
& TX_CFG_HBI
) ;
923 if (reg
& TX_CFG_MLB
) ;
924 if (reg
& TX_CFG_ATP
) ;
925 if (reg
& TX_CFG_ECRETRY
) {
927 * this could easily be implemented, but considering
928 * the network is just a fake pipe, wouldn't make
933 if (reg
& TX_CFG_BRST_DIS
) ;
937 /* we handle our own DMA, ignore the kernel's exhortations */
938 if (reg
& TX_CFG_MXDMA
) ;
941 // also, we currently don't care about fill/drain
942 // thresholds though this may change in the future with
943 // more realistic networks or a driver which changes it
944 // according to feedback
949 // Only write writable bits
950 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
951 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
952 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
953 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
954 /* these just control general purpose i/o pins, don't matter */
969 if (reg
& RX_CFG_AEP
) ;
970 if (reg
& RX_CFG_ARP
) ;
971 if (reg
& RX_CFG_STRIPCRC
) ;
972 if (reg
& RX_CFG_RX_RD
) ;
973 if (reg
& RX_CFG_ALP
) ;
974 if (reg
& RX_CFG_AIRL
) ;
976 /* we handle our own DMA, ignore what kernel says about it */
977 if (reg
& RX_CFG_MXDMA
) ;
979 //also, we currently don't care about fill/drain thresholds
980 //though this may change in the future with more realistic
981 //networks or a driver which changes it according to feedback
982 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
987 /* there is no priority queueing used in the linux 2.6 driver */
992 /* not going to implement wake on LAN */
997 /* not going to implement pause control */
1004 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
1005 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
1006 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
1007 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
1008 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
1009 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
1010 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
1013 if (reg
& RFCR_APAT
)
1014 panic("RFCR_APAT not implemented!\n");
1016 if (reg
& RFCR_UHEN
)
1017 panic("Unicast hash filtering not used by drivers!\n");
1020 panic("RFCR_ULM not implemented!\n");
1025 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
1028 rom
.perfectMatch
[0] = (uint8_t)reg
;
1029 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
1032 rom
.perfectMatch
[2] = (uint8_t)reg
;
1033 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
1036 rom
.perfectMatch
[4] = (uint8_t)reg
;
1037 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
1041 if (rfaddr
>= FHASH_ADDR
&&
1042 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
1044 // Only word-aligned writes supported
1046 panic("unaligned write to filter hash table!");
1048 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
1049 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
1050 = (uint8_t)(reg
>> 8);
1053 panic("writing RFDR for something other than pattern matching\
1054 or hashing! %#x\n", rfaddr
);
1062 panic("the driver never uses BRDR, something is wrong!\n");
1065 panic("SRR is read only register!\n");
1068 panic("the driver never uses MIBC, something is wrong!\n");
1079 panic("the driver never uses VDR, something is wrong!\n");
1082 /* not going to implement clockrun stuff */
1088 if (reg
& TBICR_MR_LOOPBACK
)
1089 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
1091 if (reg
& TBICR_MR_AN_ENABLE
) {
1092 regs
.tanlpar
= regs
.tanar
;
1093 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
1097 if (reg
& TBICR_MR_RESTART_AN
) ;
1103 panic("TBISR is read only register!\n");
1106 // Only write the writable bits
1107 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
1108 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
1110 // Pause capability unimplemented
1112 if (reg
& TANAR_PS2
) ;
1113 if (reg
& TANAR_PS1
) ;
1119 panic("this should only be written to by the fake phy!\n");
1122 panic("TANER is read only register!\n");
1129 panic("invalid register access daddr=%#x", daddr
);
1132 panic("Invalid Request Size");
1134 pkt
->result
= Packet::Success
;
1139 NSGigE::devIntrPost(uint32_t interrupts
)
1141 if (interrupts
& ISR_RESERVE
)
1142 panic("Cannot set a reserved interrupt");
1144 if (interrupts
& ISR_NOIMPL
)
1145 warn("interrupt not implemented %#x\n", interrupts
);
1147 interrupts
&= ISR_IMPL
;
1148 regs
.isr
|= interrupts
;
1150 if (interrupts
& regs
.imr
) {
1151 if (interrupts
& ISR_SWI
) {
1154 if (interrupts
& ISR_RXIDLE
) {
1157 if (interrupts
& ISR_RXOK
) {
1160 if (interrupts
& ISR_RXDESC
) {
1163 if (interrupts
& ISR_TXOK
) {
1166 if (interrupts
& ISR_TXIDLE
) {
1169 if (interrupts
& ISR_TXDESC
) {
1172 if (interrupts
& ISR_RXORN
) {
1177 DPRINTF(EthernetIntr
,
1178 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
1179 interrupts
, regs
.isr
, regs
.imr
);
1181 if ((regs
.isr
& regs
.imr
)) {
1182 Tick when
= curTick
;
1183 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
1189 /* writing this interrupt counting stats inside this means that this function
1190 is now limited to being used to clear all interrupts upon the kernel
1191 reading isr and servicing. just telling you in case you were thinking
1195 NSGigE::devIntrClear(uint32_t interrupts
)
1197 if (interrupts
& ISR_RESERVE
)
1198 panic("Cannot clear a reserved interrupt");
1200 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
1203 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
1206 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
1209 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
1212 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
1215 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
1218 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
1221 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
1225 if (regs
.isr
& regs
.imr
& ISR_IMPL
)
1228 interrupts
&= ~ISR_NOIMPL
;
1229 regs
.isr
&= ~interrupts
;
1231 DPRINTF(EthernetIntr
,
1232 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
1233 interrupts
, regs
.isr
, regs
.imr
);
1235 if (!(regs
.isr
& regs
.imr
))
1240 NSGigE::devIntrChangeMask()
1242 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
1243 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
1245 if (regs
.isr
& regs
.imr
)
1246 cpuIntrPost(curTick
);
1252 NSGigE::cpuIntrPost(Tick when
)
1254 // If the interrupt you want to post is later than an interrupt
1255 // already scheduled, just let it post in the coming one and don't
1256 // schedule another.
1257 // HOWEVER, must be sure that the scheduled intrTick is in the
1258 // future (this was formerly the source of a bug)
1260 * @todo this warning should be removed and the intrTick code should
1263 assert(when
>= curTick
);
1264 assert(intrTick
>= curTick
|| intrTick
== 0);
1265 if (when
> intrTick
&& intrTick
!= 0) {
1266 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
1272 if (intrTick
< curTick
) {
1277 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
1281 intrEvent
->squash();
1282 intrEvent
= new IntrEvent(this, true);
1283 intrEvent
->schedule(intrTick
);
1287 NSGigE::cpuInterrupt()
1289 assert(intrTick
== curTick
);
1291 // Whether or not there's a pending interrupt, we don't care about
1296 // Don't send an interrupt if there's already one
1297 if (cpuPendingIntr
) {
1298 DPRINTF(EthernetIntr
,
1299 "would send an interrupt now, but there's already pending\n");
1302 cpuPendingIntr
= true;
1304 DPRINTF(EthernetIntr
, "posting interrupt\n");
1310 NSGigE::cpuIntrClear()
1312 if (!cpuPendingIntr
)
1316 intrEvent
->squash();
1322 cpuPendingIntr
= false;
1324 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1329 NSGigE::cpuIntrPending() const
1330 { return cpuPendingIntr
; }
1336 DPRINTF(Ethernet
, "transmit reset\n");
1341 assert(txDescCnt
== 0);
1344 assert(txDmaState
== dmaIdle
);
1350 DPRINTF(Ethernet
, "receive reset\n");
1353 assert(rxPktBytes
== 0);
1356 assert(rxDescCnt
== 0);
1357 assert(rxDmaState
== dmaIdle
);
1365 memset(®s
, 0, sizeof(regs
));
1366 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1368 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1369 // fill threshold to 32 bytes
1370 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1371 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1372 regs
.mibc
= MIBC_FRZ
;
1373 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1374 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1375 regs
.brar
= 0xffffffff;
1377 extstsEnable
= false;
1378 acceptBroadcast
= false;
1379 acceptMulticast
= false;
1380 acceptUnicast
= false;
1381 acceptPerfect
= false;
1386 NSGigE::doRxDmaRead()
1388 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1389 rxDmaState
= dmaReading
;
1392 rxDmaState
= dmaReadWaiting
;
1394 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1400 NSGigE::rxDmaReadDone()
1402 assert(rxDmaState
== dmaReading
);
1403 rxDmaState
= dmaIdle
;
1405 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1406 rxDmaAddr
, rxDmaLen
);
1407 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1409 // If the transmit state machine has a pending DMA, let it go first
1410 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1417 NSGigE::doRxDmaWrite()
1419 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1420 rxDmaState
= dmaWriting
;
1423 rxDmaState
= dmaWriteWaiting
;
1425 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1430 NSGigE::rxDmaWriteDone()
1432 assert(rxDmaState
== dmaWriting
);
1433 rxDmaState
= dmaIdle
;
1435 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1436 rxDmaAddr
, rxDmaLen
);
1437 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1439 // If the transmit state machine has a pending DMA, let it go first
1440 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1449 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1452 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1453 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1456 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1457 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1461 if (rxKickTick
> curTick
) {
1462 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1468 // Go to the next state machine clock tick.
1469 rxKickTick
= curTick
+ cycles(1);
1472 switch(rxDmaState
) {
1473 case dmaReadWaiting
:
1477 case dmaWriteWaiting
:
1485 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1486 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1488 // see state machine from spec for details
1489 // the way this works is, if you finish work on one state and can
1490 // go directly to another, you do that through jumping to the
1491 // label "next". however, if you have intermediate work, like DMA
1492 // so that you can't go to the next state yet, you go to exit and
1493 // exit the loop. however, when the DMA is done it will trigger
1494 // an event and come back to this loop.
1498 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1503 rxState
= rxDescRefr
;
1505 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1507 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1508 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1509 rxDmaFree
= dmaDescFree
;
1512 descDmaRdBytes
+= rxDmaLen
;
1517 rxState
= rxDescRead
;
1519 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1520 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1521 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1522 rxDmaFree
= dmaDescFree
;
1525 descDmaRdBytes
+= rxDmaLen
;
1533 if (rxDmaState
!= dmaIdle
)
1536 rxState
= rxAdvance
;
1540 if (rxDmaState
!= dmaIdle
)
1543 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1544 regs
.rxdp
& 0x3fffffff);
1545 DPRINTF(EthernetDesc
,
1546 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1547 link
, bufptr
, cmdsts
, extsts
);
1549 if (cmdsts
& CMDSTS_OWN
) {
1550 devIntrPost(ISR_RXIDLE
);
1554 rxState
= rxFifoBlock
;
1556 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1563 * @todo in reality, we should be able to start processing
1564 * the packet as it arrives, and not have to wait for the
1565 * full packet ot be in the receive fifo.
1570 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1572 // If we don't have a packet, grab a new one from the fifo.
1573 rxPacket
= rxFifo
.front();
1574 rxPktBytes
= rxPacket
->length
;
1575 rxPacketBufPtr
= rxPacket
->data
;
1578 if (DTRACE(Ethernet
)) {
1581 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1585 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1586 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1593 // sanity check - i think the driver behaves like this
1594 assert(rxDescCnt
>= rxPktBytes
);
1599 // dont' need the && rxDescCnt > 0 if driver sanity check
1601 if (rxPktBytes
> 0) {
1602 rxState
= rxFragWrite
;
1603 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1605 rxXferLen
= rxPktBytes
;
1607 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1608 rxDmaData
= rxPacketBufPtr
;
1609 rxDmaLen
= rxXferLen
;
1610 rxDmaFree
= dmaDataFree
;
1616 rxState
= rxDescWrite
;
1618 //if (rxPktBytes == 0) { /* packet is done */
1619 assert(rxPktBytes
== 0);
1620 DPRINTF(EthernetSM
, "done with receiving packet\n");
1622 cmdsts
|= CMDSTS_OWN
;
1623 cmdsts
&= ~CMDSTS_MORE
;
1624 cmdsts
|= CMDSTS_OK
;
1625 cmdsts
&= 0xffff0000;
1626 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1630 * all the driver uses these are for its own stats keeping
1631 * which we don't care about, aren't necessary for
1632 * functionality and doing this would just slow us down.
1633 * if they end up using this in a later version for
1634 * functional purposes, just undef
1636 if (rxFilterEnable
) {
1637 cmdsts
&= ~CMDSTS_DEST_MASK
;
1638 const EthAddr
&dst
= rxFifoFront()->dst();
1640 cmdsts
|= CMDSTS_DEST_SELF
;
1641 if (dst
->multicast())
1642 cmdsts
|= CMDSTS_DEST_MULTI
;
1643 if (dst
->broadcast())
1644 cmdsts
|= CMDSTS_DEST_MASK
;
1649 if (extstsEnable
&& ip
) {
1650 extsts
|= EXTSTS_IPPKT
;
1652 if (cksum(ip
) != 0) {
1653 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1654 extsts
|= EXTSTS_IPERR
;
1659 extsts
|= EXTSTS_TCPPKT
;
1661 if (cksum(tcp
) != 0) {
1662 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1663 extsts
|= EXTSTS_TCPERR
;
1667 extsts
|= EXTSTS_UDPPKT
;
1669 if (cksum(udp
) != 0) {
1670 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1671 extsts
|= EXTSTS_UDPERR
;
1678 * the driver seems to always receive into desc buffers
1679 * of size 1514, so you never have a pkt that is split
1680 * into multiple descriptors on the receive side, so
1681 * i don't implement that case, hence the assert above.
1684 DPRINTF(EthernetDesc
,
1685 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1686 regs
.rxdp
& 0x3fffffff);
1687 DPRINTF(EthernetDesc
,
1688 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1689 link
, bufptr
, cmdsts
, extsts
);
1691 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1692 rxDmaData
= &cmdsts
;
1694 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1695 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1697 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1698 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1700 rxDmaFree
= dmaDescFree
;
1703 descDmaWrBytes
+= rxDmaLen
;
1711 if (rxDmaState
!= dmaIdle
)
1714 rxPacketBufPtr
+= rxXferLen
;
1715 rxFragPtr
+= rxXferLen
;
1716 rxPktBytes
-= rxXferLen
;
1718 rxState
= rxFifoBlock
;
1722 if (rxDmaState
!= dmaIdle
)
1725 assert(cmdsts
& CMDSTS_OWN
);
1727 assert(rxPacket
== 0);
1728 devIntrPost(ISR_RXOK
);
1730 if (cmdsts
& CMDSTS_INTR
)
1731 devIntrPost(ISR_RXDESC
);
1734 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1738 rxState
= rxAdvance
;
1743 devIntrPost(ISR_RXIDLE
);
1748 if (rxDmaState
!= dmaIdle
)
1750 rxState
= rxDescRead
;
1754 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1755 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1756 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1757 rxDmaFree
= dmaDescFree
;
1765 panic("Invalid rxState!");
1768 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1769 NsRxStateStrings
[rxState
]);
1774 * @todo do we want to schedule a future kick?
1776 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1777 NsRxStateStrings
[rxState
]);
1779 if (clock
&& !rxKickEvent
.scheduled())
1780 rxKickEvent
.schedule(rxKickTick
);
1786 if (txFifo
.empty()) {
1787 DPRINTF(Ethernet
, "nothing to transmit\n");
1791 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1793 if (interface
->sendPacket(txFifo
.front())) {
1795 if (DTRACE(Ethernet
)) {
1796 IpPtr
ip(txFifo
.front());
1798 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1802 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1803 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1810 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1811 txBytes
+= txFifo
.front()->length
;
1814 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1819 * normally do a writeback of the descriptor here, and ONLY
1820 * after that is done, send this interrupt. but since our
1821 * stuff never actually fails, just do this interrupt here,
1822 * otherwise the code has to stray from this nice format.
1823 * besides, it's functionally the same.
1825 devIntrPost(ISR_TXOK
);
1828 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1829 DPRINTF(Ethernet
, "reschedule transmit\n");
1830 txEvent
.schedule(curTick
+ retryTime
);
1835 NSGigE::doTxDmaRead()
1837 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1838 txDmaState
= dmaReading
;
1841 txDmaState
= dmaReadWaiting
;
1843 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1849 NSGigE::txDmaReadDone()
1851 assert(txDmaState
== dmaReading
);
1852 txDmaState
= dmaIdle
;
1854 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1855 txDmaAddr
, txDmaLen
);
1856 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1858 // If the receive state machine has a pending DMA, let it go first
1859 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1866 NSGigE::doTxDmaWrite()
1868 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1869 txDmaState
= dmaWriting
;
1872 txDmaState
= dmaWriteWaiting
;
1874 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1879 NSGigE::txDmaWriteDone()
1881 assert(txDmaState
== dmaWriting
);
1882 txDmaState
= dmaIdle
;
1884 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1885 txDmaAddr
, txDmaLen
);
1886 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1888 // If the receive state machine has a pending DMA, let it go first
1889 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1898 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1900 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1901 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1904 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1905 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1909 if (txKickTick
> curTick
) {
1910 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1915 // Go to the next state machine clock tick.
1916 txKickTick
= curTick
+ cycles(1);
1919 switch(txDmaState
) {
1920 case dmaReadWaiting
:
1924 case dmaWriteWaiting
:
1932 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1933 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1937 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1942 txState
= txDescRefr
;
1944 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1946 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1947 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1948 txDmaFree
= dmaDescFree
;
1951 descDmaRdBytes
+= txDmaLen
;
1957 txState
= txDescRead
;
1959 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1960 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1961 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1962 txDmaFree
= dmaDescFree
;
1965 descDmaRdBytes
+= txDmaLen
;
1973 if (txDmaState
!= dmaIdle
)
1976 txState
= txAdvance
;
1980 if (txDmaState
!= dmaIdle
)
1983 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1984 regs
.txdp
& 0x3fffffff);
1985 DPRINTF(EthernetDesc
,
1986 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1987 link
, bufptr
, cmdsts
, extsts
);
1989 if (cmdsts
& CMDSTS_OWN
) {
1990 txState
= txFifoBlock
;
1992 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1994 devIntrPost(ISR_TXIDLE
);
2002 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
2003 txPacket
= new EthPacketData(16384);
2004 txPacketBufPtr
= txPacket
->data
;
2007 if (txDescCnt
== 0) {
2008 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
2009 if (cmdsts
& CMDSTS_MORE
) {
2010 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
2011 txState
= txDescWrite
;
2013 cmdsts
&= ~CMDSTS_OWN
;
2015 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2016 txDmaData
= &cmdsts
;
2018 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2019 txDmaLen
= sizeof(txDesc64
.cmdsts
);
2021 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2022 txDmaLen
= sizeof(txDesc32
.cmdsts
);
2024 txDmaFree
= dmaDescFree
;
2029 } else { /* this packet is totally done */
2030 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
2031 /* deal with the the packet that just finished */
2032 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
2034 if (extsts
& EXTSTS_UDPPKT
) {
2037 udp
->sum(cksum(udp
));
2039 } else if (extsts
& EXTSTS_TCPPKT
) {
2042 tcp
->sum(cksum(tcp
));
2045 if (extsts
& EXTSTS_IPPKT
) {
2052 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2053 // this is just because the receive can't handle a
2054 // packet bigger want to make sure
2055 if (txPacket
->length
> 1514)
2056 panic("transmit packet too large, %s > 1514\n",
2062 txFifo
.push(txPacket
);
2066 * this following section is not tqo spec, but
2067 * functionally shouldn't be any different. normally,
2068 * the chip will wait til the transmit has occurred
2069 * before writing back the descriptor because it has
2070 * to wait to see that it was successfully transmitted
2071 * to decide whether to set CMDSTS_OK or not.
2072 * however, in the simulator since it is always
2073 * successfully transmitted, and writing it exactly to
2074 * spec would complicate the code, we just do it here
2077 cmdsts
&= ~CMDSTS_OWN
;
2078 cmdsts
|= CMDSTS_OK
;
2080 DPRINTF(EthernetDesc
,
2081 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
2084 txDmaFree
= dmaDescFree
;
2085 txDmaAddr
= regs
.txdp
& 0x3fffffff;
2086 txDmaData
= &cmdsts
;
2088 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
2090 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
2092 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
2094 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
2098 descDmaWrBytes
+= txDmaLen
;
2104 DPRINTF(EthernetSM
, "halting TX state machine\n");
2108 txState
= txAdvance
;
2114 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
2115 if (!txFifo
.full()) {
2116 txState
= txFragRead
;
2119 * The number of bytes transferred is either whatever
2120 * is left in the descriptor (txDescCnt), or if there
2121 * is not enough room in the fifo, just whatever room
2122 * is left in the fifo
2124 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
2126 txDmaAddr
= txFragPtr
& 0x3fffffff;
2127 txDmaData
= txPacketBufPtr
;
2128 txDmaLen
= txXferLen
;
2129 txDmaFree
= dmaDataFree
;
2134 txState
= txFifoBlock
;
2144 if (txDmaState
!= dmaIdle
)
2147 txPacketBufPtr
+= txXferLen
;
2148 txFragPtr
+= txXferLen
;
2149 txDescCnt
-= txXferLen
;
2150 txFifo
.reserve(txXferLen
);
2152 txState
= txFifoBlock
;
2156 if (txDmaState
!= dmaIdle
)
2159 if (cmdsts
& CMDSTS_INTR
)
2160 devIntrPost(ISR_TXDESC
);
2163 DPRINTF(EthernetSM
, "halting TX state machine\n");
2167 txState
= txAdvance
;
2172 devIntrPost(ISR_TXIDLE
);
2176 if (txDmaState
!= dmaIdle
)
2178 txState
= txDescRead
;
2182 txDmaAddr
= link
& 0x3fffffff;
2183 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
2184 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
2185 txDmaFree
= dmaDescFree
;
2193 panic("invalid state");
2196 DPRINTF(EthernetSM
, "entering next txState=%s\n",
2197 NsTxStateStrings
[txState
]);
2202 * @todo do we want to schedule a future kick?
2204 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
2205 NsTxStateStrings
[txState
]);
2207 if (clock
&& !txKickEvent
.scheduled())
2208 txKickEvent
.schedule(txKickTick
);
2212 * Advance the EEPROM state machine
2213 * Called on rising edge of EEPROM clock bit in MEAR
2216 NSGigE::eepromKick()
2218 switch (eepromState
) {
2222 // Wait for start bit
2223 if (regs
.mear
& MEAR_EEDI
) {
2224 // Set up to get 2 opcode bits
2225 eepromState
= eepromGetOpcode
;
2231 case eepromGetOpcode
:
2233 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2236 // Done getting opcode
2237 if (eepromBitsToRx
== 0) {
2238 if (eepromOpcode
!= EEPROM_READ
)
2239 panic("only EEPROM reads are implemented!");
2241 // Set up to get address
2242 eepromState
= eepromGetAddress
;
2248 case eepromGetAddress
:
2249 eepromAddress
<<= 1;
2250 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
2253 // Done getting address
2254 if (eepromBitsToRx
== 0) {
2256 if (eepromAddress
>= EEPROM_SIZE
)
2257 panic("EEPROM read access out of range!");
2259 switch (eepromAddress
) {
2261 case EEPROM_PMATCH2_ADDR
:
2262 eepromData
= rom
.perfectMatch
[5];
2264 eepromData
+= rom
.perfectMatch
[4];
2267 case EEPROM_PMATCH1_ADDR
:
2268 eepromData
= rom
.perfectMatch
[3];
2270 eepromData
+= rom
.perfectMatch
[2];
2273 case EEPROM_PMATCH0_ADDR
:
2274 eepromData
= rom
.perfectMatch
[1];
2276 eepromData
+= rom
.perfectMatch
[0];
2280 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
2282 // Set up to read data
2283 eepromState
= eepromRead
;
2284 eepromBitsToRx
= 16;
2286 // Clear data in bit
2287 regs
.mear
&= ~MEAR_EEDI
;
2292 // Clear Data Out bit
2293 regs
.mear
&= ~MEAR_EEDO
;
2294 // Set bit to value of current EEPROM bit
2295 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2301 if (eepromBitsToRx
== 0) {
2302 eepromState
= eepromStart
;
2307 panic("invalid EEPROM state");
2313 NSGigE::transferDone()
2315 if (txFifo
.empty()) {
2316 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2320 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2322 if (txEvent
.scheduled())
2323 txEvent
.reschedule(curTick
+ cycles(1));
2325 txEvent
.schedule(curTick
+ cycles(1));
2329 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2331 EthPtr eth
= packet
;
2335 const EthAddr
&dst
= eth
->dst();
2336 if (dst
.unicast()) {
2337 // If we're accepting all unicast addresses
2341 // If we make a perfect match
2342 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2345 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2348 } else if (dst
.broadcast()) {
2349 // if we're accepting broadcasts
2350 if (acceptBroadcast
)
2353 } else if (dst
.multicast()) {
2354 // if we're accepting all multicasts
2355 if (acceptMulticast
)
2358 // Multicast hashing faked - all packets accepted
2359 if (multicastHashEnable
)
2364 DPRINTF(Ethernet
, "rxFilter drop\n");
2365 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2372 NSGigE::recvPacket(EthPacketPtr packet
)
2374 rxBytes
+= packet
->length
;
2377 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2381 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2385 if (!rxFilterEnable
) {
2387 "receive packet filtering disabled . . . packet dropped\n");
2391 if (rxFilter(packet
)) {
2392 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2396 if (rxFifo
.avail() < packet
->length
) {
2402 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2405 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2410 devIntrPost(ISR_RXORN
);
2414 rxFifo
.push(packet
);
2420 //=====================================================================
2424 NSGigE::serialize(ostream
&os
)
2426 // Serialize the PciDev base class
2427 PciDev::serialize(os
);
2430 * Finalize any DMA events now.
2432 // @todo will mem system save pending dma?
2435 * Serialize the device registers
2437 SERIALIZE_SCALAR(regs
.command
);
2438 SERIALIZE_SCALAR(regs
.config
);
2439 SERIALIZE_SCALAR(regs
.mear
);
2440 SERIALIZE_SCALAR(regs
.ptscr
);
2441 SERIALIZE_SCALAR(regs
.isr
);
2442 SERIALIZE_SCALAR(regs
.imr
);
2443 SERIALIZE_SCALAR(regs
.ier
);
2444 SERIALIZE_SCALAR(regs
.ihr
);
2445 SERIALIZE_SCALAR(regs
.txdp
);
2446 SERIALIZE_SCALAR(regs
.txdp_hi
);
2447 SERIALIZE_SCALAR(regs
.txcfg
);
2448 SERIALIZE_SCALAR(regs
.gpior
);
2449 SERIALIZE_SCALAR(regs
.rxdp
);
2450 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2451 SERIALIZE_SCALAR(regs
.rxcfg
);
2452 SERIALIZE_SCALAR(regs
.pqcr
);
2453 SERIALIZE_SCALAR(regs
.wcsr
);
2454 SERIALIZE_SCALAR(regs
.pcr
);
2455 SERIALIZE_SCALAR(regs
.rfcr
);
2456 SERIALIZE_SCALAR(regs
.rfdr
);
2457 SERIALIZE_SCALAR(regs
.brar
);
2458 SERIALIZE_SCALAR(regs
.brdr
);
2459 SERIALIZE_SCALAR(regs
.srr
);
2460 SERIALIZE_SCALAR(regs
.mibc
);
2461 SERIALIZE_SCALAR(regs
.vrcr
);
2462 SERIALIZE_SCALAR(regs
.vtcr
);
2463 SERIALIZE_SCALAR(regs
.vdr
);
2464 SERIALIZE_SCALAR(regs
.ccsr
);
2465 SERIALIZE_SCALAR(regs
.tbicr
);
2466 SERIALIZE_SCALAR(regs
.tbisr
);
2467 SERIALIZE_SCALAR(regs
.tanar
);
2468 SERIALIZE_SCALAR(regs
.tanlpar
);
2469 SERIALIZE_SCALAR(regs
.taner
);
2470 SERIALIZE_SCALAR(regs
.tesr
);
2472 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2473 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2475 SERIALIZE_SCALAR(ioEnable
);
2478 * Serialize the data Fifos
2480 rxFifo
.serialize("rxFifo", os
);
2481 txFifo
.serialize("txFifo", os
);
2484 * Serialize the various helper variables
2486 bool txPacketExists
= txPacket
;
2487 SERIALIZE_SCALAR(txPacketExists
);
2488 if (txPacketExists
) {
2489 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2490 txPacket
->serialize("txPacket", os
);
2491 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2492 SERIALIZE_SCALAR(txPktBufPtr
);
2495 bool rxPacketExists
= rxPacket
;
2496 SERIALIZE_SCALAR(rxPacketExists
);
2497 if (rxPacketExists
) {
2498 rxPacket
->serialize("rxPacket", os
);
2499 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2500 SERIALIZE_SCALAR(rxPktBufPtr
);
2503 SERIALIZE_SCALAR(txXferLen
);
2504 SERIALIZE_SCALAR(rxXferLen
);
2507 * Serialize Cached Descriptors
2509 SERIALIZE_SCALAR(rxDesc64
.link
);
2510 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2511 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2512 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2513 SERIALIZE_SCALAR(txDesc64
.link
);
2514 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2515 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2516 SERIALIZE_SCALAR(txDesc64
.extsts
);
2517 SERIALIZE_SCALAR(rxDesc32
.link
);
2518 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2519 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2520 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2521 SERIALIZE_SCALAR(txDesc32
.link
);
2522 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2523 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2524 SERIALIZE_SCALAR(txDesc32
.extsts
);
2525 SERIALIZE_SCALAR(extstsEnable
);
2528 * Serialize tx state machine
2530 int txState
= this->txState
;
2531 SERIALIZE_SCALAR(txState
);
2532 SERIALIZE_SCALAR(txEnable
);
2533 SERIALIZE_SCALAR(CTDD
);
2534 SERIALIZE_SCALAR(txFragPtr
);
2535 SERIALIZE_SCALAR(txDescCnt
);
2536 int txDmaState
= this->txDmaState
;
2537 SERIALIZE_SCALAR(txDmaState
);
2538 SERIALIZE_SCALAR(txKickTick
);
2541 * Serialize rx state machine
2543 int rxState
= this->rxState
;
2544 SERIALIZE_SCALAR(rxState
);
2545 SERIALIZE_SCALAR(rxEnable
);
2546 SERIALIZE_SCALAR(CRDD
);
2547 SERIALIZE_SCALAR(rxPktBytes
);
2548 SERIALIZE_SCALAR(rxFragPtr
);
2549 SERIALIZE_SCALAR(rxDescCnt
);
2550 int rxDmaState
= this->rxDmaState
;
2551 SERIALIZE_SCALAR(rxDmaState
);
2552 SERIALIZE_SCALAR(rxKickTick
);
2555 * Serialize EEPROM state machine
2557 int eepromState
= this->eepromState
;
2558 SERIALIZE_SCALAR(eepromState
);
2559 SERIALIZE_SCALAR(eepromClk
);
2560 SERIALIZE_SCALAR(eepromBitsToRx
);
2561 SERIALIZE_SCALAR(eepromOpcode
);
2562 SERIALIZE_SCALAR(eepromAddress
);
2563 SERIALIZE_SCALAR(eepromData
);
2566 * If there's a pending transmit, store the time so we can
2567 * reschedule it later
2569 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2570 SERIALIZE_SCALAR(transmitTick
);
2573 * receive address filter settings
2575 SERIALIZE_SCALAR(rxFilterEnable
);
2576 SERIALIZE_SCALAR(acceptBroadcast
);
2577 SERIALIZE_SCALAR(acceptMulticast
);
2578 SERIALIZE_SCALAR(acceptUnicast
);
2579 SERIALIZE_SCALAR(acceptPerfect
);
2580 SERIALIZE_SCALAR(acceptArp
);
2581 SERIALIZE_SCALAR(multicastHashEnable
);
2584 * Keep track of pending interrupt status.
2586 SERIALIZE_SCALAR(intrTick
);
2587 SERIALIZE_SCALAR(cpuPendingIntr
);
2588 Tick intrEventTick
= 0;
2590 intrEventTick
= intrEvent
->when();
2591 SERIALIZE_SCALAR(intrEventTick
);
2596 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2598 // Unserialize the PciDev base class
2599 PciDev::unserialize(cp
, section
);
2601 UNSERIALIZE_SCALAR(regs
.command
);
2602 UNSERIALIZE_SCALAR(regs
.config
);
2603 UNSERIALIZE_SCALAR(regs
.mear
);
2604 UNSERIALIZE_SCALAR(regs
.ptscr
);
2605 UNSERIALIZE_SCALAR(regs
.isr
);
2606 UNSERIALIZE_SCALAR(regs
.imr
);
2607 UNSERIALIZE_SCALAR(regs
.ier
);
2608 UNSERIALIZE_SCALAR(regs
.ihr
);
2609 UNSERIALIZE_SCALAR(regs
.txdp
);
2610 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2611 UNSERIALIZE_SCALAR(regs
.txcfg
);
2612 UNSERIALIZE_SCALAR(regs
.gpior
);
2613 UNSERIALIZE_SCALAR(regs
.rxdp
);
2614 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2615 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2616 UNSERIALIZE_SCALAR(regs
.pqcr
);
2617 UNSERIALIZE_SCALAR(regs
.wcsr
);
2618 UNSERIALIZE_SCALAR(regs
.pcr
);
2619 UNSERIALIZE_SCALAR(regs
.rfcr
);
2620 UNSERIALIZE_SCALAR(regs
.rfdr
);
2621 UNSERIALIZE_SCALAR(regs
.brar
);
2622 UNSERIALIZE_SCALAR(regs
.brdr
);
2623 UNSERIALIZE_SCALAR(regs
.srr
);
2624 UNSERIALIZE_SCALAR(regs
.mibc
);
2625 UNSERIALIZE_SCALAR(regs
.vrcr
);
2626 UNSERIALIZE_SCALAR(regs
.vtcr
);
2627 UNSERIALIZE_SCALAR(regs
.vdr
);
2628 UNSERIALIZE_SCALAR(regs
.ccsr
);
2629 UNSERIALIZE_SCALAR(regs
.tbicr
);
2630 UNSERIALIZE_SCALAR(regs
.tbisr
);
2631 UNSERIALIZE_SCALAR(regs
.tanar
);
2632 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2633 UNSERIALIZE_SCALAR(regs
.taner
);
2634 UNSERIALIZE_SCALAR(regs
.tesr
);
2636 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2637 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2639 UNSERIALIZE_SCALAR(ioEnable
);
2642 * unserialize the data fifos
2644 rxFifo
.unserialize("rxFifo", cp
, section
);
2645 txFifo
.unserialize("txFifo", cp
, section
);
2648 * unserialize the various helper variables
2650 bool txPacketExists
;
2651 UNSERIALIZE_SCALAR(txPacketExists
);
2652 if (txPacketExists
) {
2653 txPacket
= new EthPacketData(16384);
2654 txPacket
->unserialize("txPacket", cp
, section
);
2655 uint32_t txPktBufPtr
;
2656 UNSERIALIZE_SCALAR(txPktBufPtr
);
2657 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2661 bool rxPacketExists
;
2662 UNSERIALIZE_SCALAR(rxPacketExists
);
2664 if (rxPacketExists
) {
2665 rxPacket
= new EthPacketData(16384);
2666 rxPacket
->unserialize("rxPacket", cp
, section
);
2667 uint32_t rxPktBufPtr
;
2668 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2669 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2673 UNSERIALIZE_SCALAR(txXferLen
);
2674 UNSERIALIZE_SCALAR(rxXferLen
);
2677 * Unserialize Cached Descriptors
2679 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2680 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2681 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2682 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2683 UNSERIALIZE_SCALAR(txDesc64
.link
);
2684 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2685 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2686 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2687 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2688 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2689 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2690 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2691 UNSERIALIZE_SCALAR(txDesc32
.link
);
2692 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2693 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2694 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2695 UNSERIALIZE_SCALAR(extstsEnable
);
2698 * unserialize tx state machine
2701 UNSERIALIZE_SCALAR(txState
);
2702 this->txState
= (TxState
) txState
;
2703 UNSERIALIZE_SCALAR(txEnable
);
2704 UNSERIALIZE_SCALAR(CTDD
);
2705 UNSERIALIZE_SCALAR(txFragPtr
);
2706 UNSERIALIZE_SCALAR(txDescCnt
);
2708 UNSERIALIZE_SCALAR(txDmaState
);
2709 this->txDmaState
= (DmaState
) txDmaState
;
2710 UNSERIALIZE_SCALAR(txKickTick
);
2712 txKickEvent
.schedule(txKickTick
);
2715 * unserialize rx state machine
2718 UNSERIALIZE_SCALAR(rxState
);
2719 this->rxState
= (RxState
) rxState
;
2720 UNSERIALIZE_SCALAR(rxEnable
);
2721 UNSERIALIZE_SCALAR(CRDD
);
2722 UNSERIALIZE_SCALAR(rxPktBytes
);
2723 UNSERIALIZE_SCALAR(rxFragPtr
);
2724 UNSERIALIZE_SCALAR(rxDescCnt
);
2726 UNSERIALIZE_SCALAR(rxDmaState
);
2727 this->rxDmaState
= (DmaState
) rxDmaState
;
2728 UNSERIALIZE_SCALAR(rxKickTick
);
2730 rxKickEvent
.schedule(rxKickTick
);
2733 * Unserialize EEPROM state machine
2736 UNSERIALIZE_SCALAR(eepromState
);
2737 this->eepromState
= (EEPROMState
) eepromState
;
2738 UNSERIALIZE_SCALAR(eepromClk
);
2739 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2740 UNSERIALIZE_SCALAR(eepromOpcode
);
2741 UNSERIALIZE_SCALAR(eepromAddress
);
2742 UNSERIALIZE_SCALAR(eepromData
);
2745 * If there's a pending transmit, reschedule it now
2748 UNSERIALIZE_SCALAR(transmitTick
);
2750 txEvent
.schedule(curTick
+ transmitTick
);
2753 * unserialize receive address filter settings
2755 UNSERIALIZE_SCALAR(rxFilterEnable
);
2756 UNSERIALIZE_SCALAR(acceptBroadcast
);
2757 UNSERIALIZE_SCALAR(acceptMulticast
);
2758 UNSERIALIZE_SCALAR(acceptUnicast
);
2759 UNSERIALIZE_SCALAR(acceptPerfect
);
2760 UNSERIALIZE_SCALAR(acceptArp
);
2761 UNSERIALIZE_SCALAR(multicastHashEnable
);
2764 * Keep track of pending interrupt status.
2766 UNSERIALIZE_SCALAR(intrTick
);
2767 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2769 UNSERIALIZE_SCALAR(intrEventTick
);
2770 if (intrEventTick
) {
2771 intrEvent
= new IntrEvent(this, true);
2772 intrEvent
->schedule(intrEventTick
);
2776 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2778 SimObjectParam
<EtherInt
*> peer
;
2779 SimObjectParam
<NSGigE
*> device
;
2781 END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt
)
2783 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2785 INIT_PARAM_DFLT(peer
, "peer interface", NULL
),
2786 INIT_PARAM(device
, "Ethernet device of this interface")
2788 END_INIT_SIM_OBJECT_PARAMS(NSGigEInt
)
2790 CREATE_SIM_OBJECT(NSGigEInt
)
2792 NSGigEInt
*dev_int
= new NSGigEInt(getInstanceName(), device
);
2794 EtherInt
*p
= (EtherInt
*)peer
;
2796 dev_int
->setPeer(p
);
2797 p
->setPeer(dev_int
);
2803 REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt
)
2806 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2808 SimObjectParam
<System
*> system
;
2809 SimObjectParam
<Platform
*> platform
;
2810 SimObjectParam
<PciConfigAll
*> configspace
;
2811 SimObjectParam
<PciConfigData
*> configdata
;
2812 Param
<uint32_t> pci_bus
;
2813 Param
<uint32_t> pci_dev
;
2814 Param
<uint32_t> pci_func
;
2815 Param
<Tick
> pio_latency
;
2818 Param
<bool> dma_desc_free
;
2819 Param
<bool> dma_data_free
;
2820 Param
<Tick
> dma_read_delay
;
2821 Param
<Tick
> dma_write_delay
;
2822 Param
<Tick
> dma_read_factor
;
2823 Param
<Tick
> dma_write_factor
;
2824 Param
<bool> dma_no_allocate
;
2825 Param
<Tick
> intr_delay
;
2827 Param
<Tick
> rx_delay
;
2828 Param
<Tick
> tx_delay
;
2829 Param
<uint32_t> rx_fifo_size
;
2830 Param
<uint32_t> tx_fifo_size
;
2832 Param
<bool> rx_filter
;
2833 Param
<string
> hardware_address
;
2834 Param
<bool> rx_thread
;
2835 Param
<bool> tx_thread
;
2838 END_DECLARE_SIM_OBJECT_PARAMS(NSGigE
)
2840 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2842 INIT_PARAM(system
, "System pointer"),
2843 INIT_PARAM(platform
, "Platform pointer"),
2844 INIT_PARAM(configspace
, "PCI Configspace"),
2845 INIT_PARAM(configdata
, "PCI Config data"),
2846 INIT_PARAM(pci_bus
, "PCI bus ID"),
2847 INIT_PARAM(pci_dev
, "PCI device number"),
2848 INIT_PARAM(pci_func
, "PCI function code"),
2849 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency in bus cycles", 1),
2850 INIT_PARAM(clock
, "State machine cycle time"),
2852 INIT_PARAM(dma_desc_free
, "DMA of Descriptors is free"),
2853 INIT_PARAM(dma_data_free
, "DMA of Data is free"),
2854 INIT_PARAM(dma_read_delay
, "fixed delay for dma reads"),
2855 INIT_PARAM(dma_write_delay
, "fixed delay for dma writes"),
2856 INIT_PARAM(dma_read_factor
, "multiplier for dma reads"),
2857 INIT_PARAM(dma_write_factor
, "multiplier for dma writes"),
2858 INIT_PARAM(dma_no_allocate
, "Should DMA reads allocate cache lines"),
2859 INIT_PARAM(intr_delay
, "Interrupt Delay in microseconds"),
2861 INIT_PARAM(rx_delay
, "Receive Delay"),
2862 INIT_PARAM(tx_delay
, "Transmit Delay"),
2863 INIT_PARAM(rx_fifo_size
, "max size in bytes of rxFifo"),
2864 INIT_PARAM(tx_fifo_size
, "max size in bytes of txFifo"),
2866 INIT_PARAM(rx_filter
, "Enable Receive Filter"),
2867 INIT_PARAM(hardware_address
, "Ethernet Hardware Address"),
2868 INIT_PARAM(rx_thread
, ""),
2869 INIT_PARAM(tx_thread
, ""),
2872 END_INIT_SIM_OBJECT_PARAMS(NSGigE
)
2875 CREATE_SIM_OBJECT(NSGigE
)
2877 NSGigE::Params
*params
= new NSGigE::Params
;
2879 params
->name
= getInstanceName();
2880 params
->platform
= platform
;
2881 params
->system
= system
;
2882 params
->configSpace
= configspace
;
2883 params
->configData
= configdata
;
2884 params
->busNum
= pci_bus
;
2885 params
->deviceNum
= pci_dev
;
2886 params
->functionNum
= pci_func
;
2887 params
->pio_delay
= pio_latency
;
2889 params
->clock
= clock
;
2890 params
->dma_desc_free
= dma_desc_free
;
2891 params
->dma_data_free
= dma_data_free
;
2892 params
->dma_read_delay
= dma_read_delay
;
2893 params
->dma_write_delay
= dma_write_delay
;
2894 params
->dma_read_factor
= dma_read_factor
;
2895 params
->dma_write_factor
= dma_write_factor
;
2896 params
->dma_no_allocate
= dma_no_allocate
;
2897 params
->pio_delay
= pio_latency
;
2898 params
->intr_delay
= intr_delay
;
2900 params
->rx_delay
= rx_delay
;
2901 params
->tx_delay
= tx_delay
;
2902 params
->rx_fifo_size
= rx_fifo_size
;
2903 params
->tx_fifo_size
= tx_fifo_size
;
2905 params
->rx_filter
= rx_filter
;
2906 params
->eaddr
= hardware_address
;
2907 params
->rx_thread
= rx_thread
;
2908 params
->tx_thread
= tx_thread
;
2911 return new NSGigE(params
);
2914 REGISTER_SIM_OBJECT("NSGigE", NSGigE
)