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 "base/debug.hh"
40 #include "base/inet.hh"
41 #include "base/types.hh"
42 #include "config/the_isa.hh"
43 #include "cpu/thread_context.hh"
44 #include "debug/EthernetAll.hh"
45 #include "dev/etherlink.hh"
46 #include "dev/ns_gige.hh"
47 #include "dev/pciconfigall.hh"
48 #include "mem/packet.hh"
49 #include "mem/packet_access.hh"
50 #include "params/NSGigE.hh"
51 #include "sim/system.hh"
53 // clang complains about std::set being overloaded with Packet::set if
54 // we open up the entire namespace std
59 const char *NsRxStateStrings
[] =
70 const char *NsTxStateStrings
[] =
81 const char *NsDmaState
[] =
91 using namespace TheISA
;
93 ///////////////////////////////////////////////////////////////////////
97 NSGigE::NSGigE(Params
*p
)
98 : EtherDevBase(p
), ioEnable(false),
99 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
100 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
101 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
102 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
103 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
104 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
105 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
106 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
107 eepromOpcode(0), eepromAddress(0), eepromData(0),
108 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
109 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
110 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
111 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
112 rxDmaReadEvent(this), rxDmaWriteEvent(this),
113 txDmaReadEvent(this), txDmaWriteEvent(this),
114 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
115 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
116 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
117 txEvent(this), rxFilterEnable(p
->rx_filter
),
118 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
119 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
120 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
121 intrEvent(0), interface(0)
125 interface
= new NSGigEInt(name() + ".int0", this);
128 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
130 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
131 memset(&txDesc32
, 0, sizeof(txDesc32
));
132 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
133 memset(&txDesc64
, 0, sizeof(txDesc64
));
142 * This is to write to the PCI general configuration registers
145 NSGigE::writeConfig(PacketPtr pkt
)
147 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
148 if (offset
< PCI_DEVICE_SPECIFIC
)
149 PciDev::writeConfig(pkt
);
151 panic("Device specific PCI config space not implemented!\n");
154 // seems to work fine without all these PCI settings, but i
155 // put in the IO to double check, an assertion will fail if we
156 // need to properly implement it
158 if (config
.data
[offset
] & PCI_CMD_IOSE
)
169 NSGigE::getEthPort(const std::string
&if_name
, int idx
)
171 if (if_name
== "interface") {
172 if (interface
->getPeer())
173 panic("interface already connected to\n");
180 * This reads the device registers, which are detailed in the NS83820
184 NSGigE::read(PacketPtr pkt
)
190 //The mask is to give you only the offset into the device register file
191 Addr daddr
= pkt
->getAddr() & 0xfff;
192 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
193 daddr
, pkt
->getAddr(), pkt
->getSize());
196 // there are some reserved registers, you can see ns_gige_reg.h and
197 // the spec sheet for details
198 if (daddr
> LAST
&& daddr
<= RESERVED
) {
199 panic("Accessing reserved register");
200 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
201 return readConfig(pkt
);
202 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
203 // don't implement all the MIB's. hopefully the kernel
204 // doesn't actually DEPEND upon their values
205 // MIB are just hardware stats keepers
206 pkt
->set
<uint32_t>(0);
207 pkt
->makeAtomicResponse();
209 } else if (daddr
> 0x3FC)
210 panic("Something is messed up!\n");
212 assert(pkt
->getSize() == sizeof(uint32_t));
213 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
219 //these are supposed to be cleared on a read
220 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
237 devIntrClear(ISR_ALL
);
292 // see the spec sheet for how RFCR and RFDR work
293 // basically, you write to RFCR to tell the machine
294 // what you want to do next, then you act upon RFDR,
295 // and the device will be prepared b/c of what you
302 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
304 // Read from perfect match ROM octets
306 reg
= rom
.perfectMatch
[1];
308 reg
+= rom
.perfectMatch
[0];
311 reg
= rom
.perfectMatch
[3] << 8;
312 reg
+= rom
.perfectMatch
[2];
315 reg
= rom
.perfectMatch
[5] << 8;
316 reg
+= rom
.perfectMatch
[4];
319 // Read filter hash table
320 if (rfaddr
>= FHASH_ADDR
&&
321 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
323 // Only word-aligned reads supported
325 panic("unaligned read from filter hash table!");
327 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
328 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
332 panic("reading RFDR for something other than pattern"
333 " matching or hashing! %#x\n", rfaddr
);
343 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
388 if (params()->rx_thread
)
389 reg
|= M5REG_RX_THREAD
;
390 if (params()->tx_thread
)
391 reg
|= M5REG_TX_THREAD
;
397 panic("reading unimplemented register: addr=%#x", daddr
);
400 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
403 pkt
->makeAtomicResponse();
408 NSGigE::write(PacketPtr pkt
)
412 Addr daddr
= pkt
->getAddr() & 0xfff;
413 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
414 daddr
, pkt
->getAddr(), pkt
->getSize());
416 if (daddr
> LAST
&& daddr
<= RESERVED
) {
417 panic("Accessing reserved register");
418 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
419 return writeConfig(pkt
);
420 } else if (daddr
> 0x3FC)
421 panic("Something is messed up!\n");
423 if (pkt
->getSize() == sizeof(uint32_t)) {
424 uint32_t reg
= pkt
->get
<uint32_t>();
427 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
434 } else if (reg
& CR_TXE
) {
437 // the kernel is enabling the transmit machine
438 if (txState
== txIdle
)
444 } else if (reg
& CR_RXE
) {
447 if (rxState
== rxIdle
)
458 devIntrPost(ISR_SWI
);
469 if (reg
& CFGR_LNKSTS
||
472 reg
& CFGR_RESERVED
||
473 reg
& CFGR_T64ADDR
||
474 reg
& CFGR_PCI64_DET
) {
475 // First clear all writable bits
476 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
477 CFGR_RESERVED
| CFGR_T64ADDR
|
479 // Now set the appropriate writable bits
480 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
481 CFGR_RESERVED
| CFGR_T64ADDR
|
485 // all these #if 0's are because i don't THINK the kernel needs to
486 // have these implemented. if there is a problem relating to one of
487 // these, you may need to add functionality in.
489 // grouped together and #if 0'ed to avoid empty if body and make clang happy
491 if (reg
& CFGR_TBI_EN
) ;
492 if (reg
& CFGR_MODE_1000
) ;
494 if (reg
& CFGR_PINT_DUPSTS
||
495 reg
& CFGR_PINT_LNKSTS
||
496 reg
& CFGR_PINT_SPDSTS
)
499 if (reg
& CFGR_TMRTEST
) ;
500 if (reg
& CFGR_MRM_DIS
) ;
501 if (reg
& CFGR_MWI_DIS
) ;
503 if (reg
& CFGR_DATA64_EN
) ;
504 if (reg
& CFGR_M64ADDR
) ;
505 if (reg
& CFGR_PHY_RST
) ;
506 if (reg
& CFGR_PHY_DIS
) ;
508 if (reg
& CFGR_REQALG
) ;
510 if (reg
& CFGR_POW
) ;
511 if (reg
& CFGR_EXD
) ;
512 if (reg
& CFGR_PESEL
) ;
513 if (reg
& CFGR_BROM_DIS
) ;
514 if (reg
& CFGR_EXT_125
) ;
515 if (reg
& CFGR_BEM
) ;
517 if (reg
& CFGR_T64ADDR
) ;
518 // panic("CFGR_T64ADDR is read only register!\n");
520 if (reg
& CFGR_AUTO_1000
)
521 panic("CFGR_AUTO_1000 not implemented!\n");
523 if (reg
& CFGR_PCI64_DET
)
524 panic("CFGR_PCI64_DET is read only register!\n");
526 if (reg
& CFGR_EXTSTS_EN
)
529 extstsEnable
= false;
533 // Clear writable bits
534 regs
.mear
&= MEAR_EEDO
;
535 // Set appropriate writable bits
536 regs
.mear
|= reg
& ~MEAR_EEDO
;
538 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
539 // even though it could get it through RFDR
540 if (reg
& MEAR_EESEL
) {
541 // Rising edge of clock
542 if (reg
& MEAR_EECLK
&& !eepromClk
)
546 eepromState
= eepromStart
;
547 regs
.mear
&= ~MEAR_EEDI
;
550 eepromClk
= reg
& MEAR_EECLK
;
552 // since phy is completely faked, MEAR_MD* don't matter
554 // grouped together and #if 0'ed to avoid empty if body and make clang happy
556 if (reg
& MEAR_MDIO
) ;
557 if (reg
& MEAR_MDDIR
) ;
558 if (reg
& MEAR_MDC
) ;
563 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
564 // these control BISTs for various parts of chip - we
565 // don't care or do just fake that the BIST is done
566 if (reg
& PTSCR_RBIST_EN
)
567 regs
.ptscr
|= PTSCR_RBIST_DONE
;
568 if (reg
& PTSCR_EEBIST_EN
)
569 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
570 if (reg
& PTSCR_EELOAD_EN
)
571 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
574 case ISR
: /* writing to the ISR has no effect */
575 panic("ISR is a read only register!\n");
588 /* not going to implement real interrupt holdoff */
592 regs
.txdp
= (reg
& 0xFFFFFFFC);
593 assert(txState
== txIdle
);
604 if (reg
& TX_CFG_CSI
) ;
605 if (reg
& TX_CFG_HBI
) ;
606 if (reg
& TX_CFG_MLB
) ;
607 if (reg
& TX_CFG_ATP
) ;
608 if (reg
& TX_CFG_ECRETRY
) {
610 * this could easily be implemented, but considering
611 * the network is just a fake pipe, wouldn't make
616 if (reg
& TX_CFG_BRST_DIS
) ;
620 /* we handle our own DMA, ignore the kernel's exhortations */
621 if (reg
& TX_CFG_MXDMA
) ;
624 // also, we currently don't care about fill/drain
625 // thresholds though this may change in the future with
626 // more realistic networks or a driver which changes it
627 // according to feedback
632 // Only write writable bits
633 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
634 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
635 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
636 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
637 /* these just control general purpose i/o pins, don't matter */
652 if (reg
& RX_CFG_AEP
) ;
653 if (reg
& RX_CFG_ARP
) ;
654 if (reg
& RX_CFG_STRIPCRC
) ;
655 if (reg
& RX_CFG_RX_RD
) ;
656 if (reg
& RX_CFG_ALP
) ;
657 if (reg
& RX_CFG_AIRL
) ;
659 /* we handle our own DMA, ignore what kernel says about it */
660 if (reg
& RX_CFG_MXDMA
) ;
662 //also, we currently don't care about fill/drain thresholds
663 //though this may change in the future with more realistic
664 //networks or a driver which changes it according to feedback
665 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
670 /* there is no priority queueing used in the linux 2.6 driver */
675 /* not going to implement wake on LAN */
680 /* not going to implement pause control */
687 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
688 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
689 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
690 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
691 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
692 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
693 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
697 panic("RFCR_APAT not implemented!\n");
700 panic("Unicast hash filtering not used by drivers!\n");
703 panic("RFCR_ULM not implemented!\n");
708 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
711 rom
.perfectMatch
[0] = (uint8_t)reg
;
712 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
715 rom
.perfectMatch
[2] = (uint8_t)reg
;
716 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
719 rom
.perfectMatch
[4] = (uint8_t)reg
;
720 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
724 if (rfaddr
>= FHASH_ADDR
&&
725 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
727 // Only word-aligned writes supported
729 panic("unaligned write to filter hash table!");
731 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
732 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
733 = (uint8_t)(reg
>> 8);
736 panic("writing RFDR for something other than pattern matching\
737 or hashing! %#x\n", rfaddr
);
745 panic("the driver never uses BRDR, something is wrong!\n");
748 panic("SRR is read only register!\n");
751 panic("the driver never uses MIBC, something is wrong!\n");
762 panic("the driver never uses VDR, something is wrong!\n");
765 /* not going to implement clockrun stuff */
771 if (reg
& TBICR_MR_LOOPBACK
)
772 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
774 if (reg
& TBICR_MR_AN_ENABLE
) {
775 regs
.tanlpar
= regs
.tanar
;
776 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
780 if (reg
& TBICR_MR_RESTART_AN
) ;
786 panic("TBISR is read only register!\n");
789 // Only write the writable bits
790 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
791 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
793 // Pause capability unimplemented
795 if (reg
& TANAR_PS2
) ;
796 if (reg
& TANAR_PS1
) ;
802 panic("this should only be written to by the fake phy!\n");
805 panic("TANER is read only register!\n");
812 panic("invalid register access daddr=%#x", daddr
);
815 panic("Invalid Request Size");
817 pkt
->makeAtomicResponse();
822 NSGigE::devIntrPost(uint32_t interrupts
)
824 if (interrupts
& ISR_RESERVE
)
825 panic("Cannot set a reserved interrupt");
827 if (interrupts
& ISR_NOIMPL
)
828 warn("interrupt not implemented %#x\n", interrupts
);
830 interrupts
&= ISR_IMPL
;
831 regs
.isr
|= interrupts
;
833 if (interrupts
& regs
.imr
) {
834 if (interrupts
& ISR_SWI
) {
837 if (interrupts
& ISR_RXIDLE
) {
840 if (interrupts
& ISR_RXOK
) {
843 if (interrupts
& ISR_RXDESC
) {
846 if (interrupts
& ISR_TXOK
) {
849 if (interrupts
& ISR_TXIDLE
) {
852 if (interrupts
& ISR_TXDESC
) {
855 if (interrupts
& ISR_RXORN
) {
860 DPRINTF(EthernetIntr
,
861 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
862 interrupts
, regs
.isr
, regs
.imr
);
864 if ((regs
.isr
& regs
.imr
)) {
865 Tick when
= curTick();
866 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
873 /* writing this interrupt counting stats inside this means that this function
874 is now limited to being used to clear all interrupts upon the kernel
875 reading isr and servicing. just telling you in case you were thinking
879 NSGigE::devIntrClear(uint32_t interrupts
)
881 if (interrupts
& ISR_RESERVE
)
882 panic("Cannot clear a reserved interrupt");
884 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
887 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
890 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
893 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
896 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
899 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
902 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
905 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
909 interrupts
&= ~ISR_NOIMPL
;
910 regs
.isr
&= ~interrupts
;
912 DPRINTF(EthernetIntr
,
913 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
914 interrupts
, regs
.isr
, regs
.imr
);
916 if (!(regs
.isr
& regs
.imr
))
921 NSGigE::devIntrChangeMask()
923 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
924 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
926 if (regs
.isr
& regs
.imr
)
927 cpuIntrPost(curTick());
933 NSGigE::cpuIntrPost(Tick when
)
935 // If the interrupt you want to post is later than an interrupt
936 // already scheduled, just let it post in the coming one and don't
938 // HOWEVER, must be sure that the scheduled intrTick is in the
939 // future (this was formerly the source of a bug)
941 * @todo this warning should be removed and the intrTick code should
944 assert(when
>= curTick());
945 assert(intrTick
>= curTick() || intrTick
== 0);
946 if (when
> intrTick
&& intrTick
!= 0) {
947 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
953 if (intrTick
< curTick()) {
955 intrTick
= curTick();
958 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
963 intrEvent
= new IntrEvent(this, true);
964 schedule(intrEvent
, intrTick
);
968 NSGigE::cpuInterrupt()
970 assert(intrTick
== curTick());
972 // Whether or not there's a pending interrupt, we don't care about
977 // Don't send an interrupt if there's already one
978 if (cpuPendingIntr
) {
979 DPRINTF(EthernetIntr
,
980 "would send an interrupt now, but there's already pending\n");
983 cpuPendingIntr
= true;
985 DPRINTF(EthernetIntr
, "posting interrupt\n");
991 NSGigE::cpuIntrClear()
1003 cpuPendingIntr
= false;
1005 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1010 NSGigE::cpuIntrPending() const
1011 { return cpuPendingIntr
; }
1017 DPRINTF(Ethernet
, "transmit reset\n");
1022 assert(txDescCnt
== 0);
1025 assert(txDmaState
== dmaIdle
);
1031 DPRINTF(Ethernet
, "receive reset\n");
1034 assert(rxPktBytes
== 0);
1037 assert(rxDescCnt
== 0);
1038 assert(rxDmaState
== dmaIdle
);
1046 memset(®s
, 0, sizeof(regs
));
1047 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1049 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1050 // fill threshold to 32 bytes
1051 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1052 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1053 regs
.mibc
= MIBC_FRZ
;
1054 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1055 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1056 regs
.brar
= 0xffffffff;
1058 extstsEnable
= false;
1059 acceptBroadcast
= false;
1060 acceptMulticast
= false;
1061 acceptUnicast
= false;
1062 acceptPerfect
= false;
1067 NSGigE::doRxDmaRead()
1069 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1070 rxDmaState
= dmaReading
;
1072 if (dmaPending() || getDrainState() != Drainable::Running
)
1073 rxDmaState
= dmaReadWaiting
;
1075 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1081 NSGigE::rxDmaReadDone()
1083 assert(rxDmaState
== dmaReading
);
1084 rxDmaState
= dmaIdle
;
1086 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1087 rxDmaAddr
, rxDmaLen
);
1088 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1090 // If the transmit state machine has a pending DMA, let it go first
1091 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1098 NSGigE::doRxDmaWrite()
1100 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1101 rxDmaState
= dmaWriting
;
1103 if (dmaPending() || getDrainState() != Running
)
1104 rxDmaState
= dmaWriteWaiting
;
1106 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1111 NSGigE::rxDmaWriteDone()
1113 assert(rxDmaState
== dmaWriting
);
1114 rxDmaState
= dmaIdle
;
1116 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1117 rxDmaAddr
, rxDmaLen
);
1118 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1120 // If the transmit state machine has a pending DMA, let it go first
1121 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1130 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1133 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1134 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1137 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1138 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1141 if (rxKickTick
> curTick()) {
1142 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1148 // Go to the next state machine clock tick.
1149 rxKickTick
= clockEdge(Cycles(1));
1151 switch(rxDmaState
) {
1152 case dmaReadWaiting
:
1156 case dmaWriteWaiting
:
1164 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1165 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1167 // see state machine from spec for details
1168 // the way this works is, if you finish work on one state and can
1169 // go directly to another, you do that through jumping to the
1170 // label "next". however, if you have intermediate work, like DMA
1171 // so that you can't go to the next state yet, you go to exit and
1172 // exit the loop. however, when the DMA is done it will trigger
1173 // an event and come back to this loop.
1177 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1182 rxState
= rxDescRefr
;
1184 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1186 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1187 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1188 rxDmaFree
= dmaDescFree
;
1191 descDmaRdBytes
+= rxDmaLen
;
1196 rxState
= rxDescRead
;
1198 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1199 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1200 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1201 rxDmaFree
= dmaDescFree
;
1204 descDmaRdBytes
+= rxDmaLen
;
1212 if (rxDmaState
!= dmaIdle
)
1215 rxState
= rxAdvance
;
1219 if (rxDmaState
!= dmaIdle
)
1222 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1223 regs
.rxdp
& 0x3fffffff);
1224 DPRINTF(EthernetDesc
,
1225 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1226 link
, bufptr
, cmdsts
, extsts
);
1228 if (cmdsts
& CMDSTS_OWN
) {
1229 devIntrPost(ISR_RXIDLE
);
1233 rxState
= rxFifoBlock
;
1235 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1242 * @todo in reality, we should be able to start processing
1243 * the packet as it arrives, and not have to wait for the
1244 * full packet ot be in the receive fifo.
1249 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1251 // If we don't have a packet, grab a new one from the fifo.
1252 rxPacket
= rxFifo
.front();
1253 rxPktBytes
= rxPacket
->length
;
1254 rxPacketBufPtr
= rxPacket
->data
;
1257 if (DTRACE(Ethernet
)) {
1260 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1264 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1265 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1272 // sanity check - i think the driver behaves like this
1273 assert(rxDescCnt
>= rxPktBytes
);
1278 // dont' need the && rxDescCnt > 0 if driver sanity check
1280 if (rxPktBytes
> 0) {
1281 rxState
= rxFragWrite
;
1282 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1284 rxXferLen
= rxPktBytes
;
1286 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1287 rxDmaData
= rxPacketBufPtr
;
1288 rxDmaLen
= rxXferLen
;
1289 rxDmaFree
= dmaDataFree
;
1295 rxState
= rxDescWrite
;
1297 //if (rxPktBytes == 0) { /* packet is done */
1298 assert(rxPktBytes
== 0);
1299 DPRINTF(EthernetSM
, "done with receiving packet\n");
1301 cmdsts
|= CMDSTS_OWN
;
1302 cmdsts
&= ~CMDSTS_MORE
;
1303 cmdsts
|= CMDSTS_OK
;
1304 cmdsts
&= 0xffff0000;
1305 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1309 * all the driver uses these are for its own stats keeping
1310 * which we don't care about, aren't necessary for
1311 * functionality and doing this would just slow us down.
1312 * if they end up using this in a later version for
1313 * functional purposes, just undef
1315 if (rxFilterEnable
) {
1316 cmdsts
&= ~CMDSTS_DEST_MASK
;
1317 const EthAddr
&dst
= rxFifoFront()->dst();
1319 cmdsts
|= CMDSTS_DEST_SELF
;
1320 if (dst
->multicast())
1321 cmdsts
|= CMDSTS_DEST_MULTI
;
1322 if (dst
->broadcast())
1323 cmdsts
|= CMDSTS_DEST_MASK
;
1328 if (extstsEnable
&& ip
) {
1329 extsts
|= EXTSTS_IPPKT
;
1331 if (cksum(ip
) != 0) {
1332 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1333 extsts
|= EXTSTS_IPERR
;
1338 extsts
|= EXTSTS_TCPPKT
;
1340 if (cksum(tcp
) != 0) {
1341 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1342 extsts
|= EXTSTS_TCPERR
;
1346 extsts
|= EXTSTS_UDPPKT
;
1348 if (cksum(udp
) != 0) {
1349 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1350 extsts
|= EXTSTS_UDPERR
;
1357 * the driver seems to always receive into desc buffers
1358 * of size 1514, so you never have a pkt that is split
1359 * into multiple descriptors on the receive side, so
1360 * i don't implement that case, hence the assert above.
1363 DPRINTF(EthernetDesc
,
1364 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1365 regs
.rxdp
& 0x3fffffff);
1366 DPRINTF(EthernetDesc
,
1367 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1368 link
, bufptr
, cmdsts
, extsts
);
1370 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1371 rxDmaData
= &cmdsts
;
1373 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1374 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1376 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1377 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1379 rxDmaFree
= dmaDescFree
;
1382 descDmaWrBytes
+= rxDmaLen
;
1390 if (rxDmaState
!= dmaIdle
)
1393 rxPacketBufPtr
+= rxXferLen
;
1394 rxFragPtr
+= rxXferLen
;
1395 rxPktBytes
-= rxXferLen
;
1397 rxState
= rxFifoBlock
;
1401 if (rxDmaState
!= dmaIdle
)
1404 assert(cmdsts
& CMDSTS_OWN
);
1406 assert(rxPacket
== 0);
1407 devIntrPost(ISR_RXOK
);
1409 if (cmdsts
& CMDSTS_INTR
)
1410 devIntrPost(ISR_RXDESC
);
1413 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1417 rxState
= rxAdvance
;
1422 devIntrPost(ISR_RXIDLE
);
1427 if (rxDmaState
!= dmaIdle
)
1429 rxState
= rxDescRead
;
1433 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1434 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1435 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1436 rxDmaFree
= dmaDescFree
;
1444 panic("Invalid rxState!");
1447 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1448 NsRxStateStrings
[rxState
]);
1453 * @todo do we want to schedule a future kick?
1455 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1456 NsRxStateStrings
[rxState
]);
1458 if (!rxKickEvent
.scheduled())
1459 schedule(rxKickEvent
, rxKickTick
);
1465 if (txFifo
.empty()) {
1466 DPRINTF(Ethernet
, "nothing to transmit\n");
1470 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1472 if (interface
->sendPacket(txFifo
.front())) {
1474 if (DTRACE(Ethernet
)) {
1475 IpPtr
ip(txFifo
.front());
1477 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1481 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1482 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1489 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1490 txBytes
+= txFifo
.front()->length
;
1493 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1498 * normally do a writeback of the descriptor here, and ONLY
1499 * after that is done, send this interrupt. but since our
1500 * stuff never actually fails, just do this interrupt here,
1501 * otherwise the code has to stray from this nice format.
1502 * besides, it's functionally the same.
1504 devIntrPost(ISR_TXOK
);
1507 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1508 DPRINTF(Ethernet
, "reschedule transmit\n");
1509 schedule(txEvent
, curTick() + retryTime
);
1514 NSGigE::doTxDmaRead()
1516 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1517 txDmaState
= dmaReading
;
1519 if (dmaPending() || getDrainState() != Running
)
1520 txDmaState
= dmaReadWaiting
;
1522 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1528 NSGigE::txDmaReadDone()
1530 assert(txDmaState
== dmaReading
);
1531 txDmaState
= dmaIdle
;
1533 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1534 txDmaAddr
, txDmaLen
);
1535 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1537 // If the receive state machine has a pending DMA, let it go first
1538 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1545 NSGigE::doTxDmaWrite()
1547 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1548 txDmaState
= dmaWriting
;
1550 if (dmaPending() || getDrainState() != Running
)
1551 txDmaState
= dmaWriteWaiting
;
1553 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1558 NSGigE::txDmaWriteDone()
1560 assert(txDmaState
== dmaWriting
);
1561 txDmaState
= dmaIdle
;
1563 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1564 txDmaAddr
, txDmaLen
);
1565 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1567 // If the receive state machine has a pending DMA, let it go first
1568 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1577 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1579 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1580 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1583 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1584 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1587 if (txKickTick
> curTick()) {
1588 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1593 // Go to the next state machine clock tick.
1594 txKickTick
= clockEdge(Cycles(1));
1596 switch(txDmaState
) {
1597 case dmaReadWaiting
:
1601 case dmaWriteWaiting
:
1609 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1610 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1614 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1619 txState
= txDescRefr
;
1621 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1623 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1624 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1625 txDmaFree
= dmaDescFree
;
1628 descDmaRdBytes
+= txDmaLen
;
1634 txState
= txDescRead
;
1636 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1637 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1638 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1639 txDmaFree
= dmaDescFree
;
1642 descDmaRdBytes
+= txDmaLen
;
1650 if (txDmaState
!= dmaIdle
)
1653 txState
= txAdvance
;
1657 if (txDmaState
!= dmaIdle
)
1660 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1661 regs
.txdp
& 0x3fffffff);
1662 DPRINTF(EthernetDesc
,
1663 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1664 link
, bufptr
, cmdsts
, extsts
);
1666 if (cmdsts
& CMDSTS_OWN
) {
1667 txState
= txFifoBlock
;
1669 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1671 devIntrPost(ISR_TXIDLE
);
1679 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1680 txPacket
= new EthPacketData(16384);
1681 txPacketBufPtr
= txPacket
->data
;
1684 if (txDescCnt
== 0) {
1685 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1686 if (cmdsts
& CMDSTS_MORE
) {
1687 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
1688 txState
= txDescWrite
;
1690 cmdsts
&= ~CMDSTS_OWN
;
1692 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1693 txDmaData
= &cmdsts
;
1695 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1696 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1698 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1699 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1701 txDmaFree
= dmaDescFree
;
1706 } else { /* this packet is totally done */
1707 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
1708 /* deal with the the packet that just finished */
1709 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
1711 if (extsts
& EXTSTS_UDPPKT
) {
1715 udp
->sum(cksum(udp
));
1718 Debug::breakpoint();
1719 warn_once("UDPPKT set, but not UDP!\n");
1721 } else if (extsts
& EXTSTS_TCPPKT
) {
1725 tcp
->sum(cksum(tcp
));
1728 Debug::breakpoint();
1729 warn_once("TCPPKT set, but not UDP!\n");
1732 if (extsts
& EXTSTS_IPPKT
) {
1738 Debug::breakpoint();
1739 warn_once("IPPKT set, but not UDP!\n");
1744 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
1745 // this is just because the receive can't handle a
1746 // packet bigger want to make sure
1747 if (txPacket
->length
> 1514)
1748 panic("transmit packet too large, %s > 1514\n",
1754 txFifo
.push(txPacket
);
1758 * this following section is not tqo spec, but
1759 * functionally shouldn't be any different. normally,
1760 * the chip will wait til the transmit has occurred
1761 * before writing back the descriptor because it has
1762 * to wait to see that it was successfully transmitted
1763 * to decide whether to set CMDSTS_OK or not.
1764 * however, in the simulator since it is always
1765 * successfully transmitted, and writing it exactly to
1766 * spec would complicate the code, we just do it here
1769 cmdsts
&= ~CMDSTS_OWN
;
1770 cmdsts
|= CMDSTS_OK
;
1772 DPRINTF(EthernetDesc
,
1773 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1776 txDmaFree
= dmaDescFree
;
1777 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1778 txDmaData
= &cmdsts
;
1780 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1782 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1784 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1786 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1790 descDmaWrBytes
+= txDmaLen
;
1796 DPRINTF(EthernetSM
, "halting TX state machine\n");
1800 txState
= txAdvance
;
1806 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1807 if (!txFifo
.full()) {
1808 txState
= txFragRead
;
1811 * The number of bytes transferred is either whatever
1812 * is left in the descriptor (txDescCnt), or if there
1813 * is not enough room in the fifo, just whatever room
1814 * is left in the fifo
1816 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1818 txDmaAddr
= txFragPtr
& 0x3fffffff;
1819 txDmaData
= txPacketBufPtr
;
1820 txDmaLen
= txXferLen
;
1821 txDmaFree
= dmaDataFree
;
1826 txState
= txFifoBlock
;
1836 if (txDmaState
!= dmaIdle
)
1839 txPacketBufPtr
+= txXferLen
;
1840 txFragPtr
+= txXferLen
;
1841 txDescCnt
-= txXferLen
;
1842 txFifo
.reserve(txXferLen
);
1844 txState
= txFifoBlock
;
1848 if (txDmaState
!= dmaIdle
)
1851 if (cmdsts
& CMDSTS_INTR
)
1852 devIntrPost(ISR_TXDESC
);
1855 DPRINTF(EthernetSM
, "halting TX state machine\n");
1859 txState
= txAdvance
;
1864 devIntrPost(ISR_TXIDLE
);
1868 if (txDmaState
!= dmaIdle
)
1870 txState
= txDescRead
;
1874 txDmaAddr
= link
& 0x3fffffff;
1875 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1876 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1877 txDmaFree
= dmaDescFree
;
1885 panic("invalid state");
1888 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1889 NsTxStateStrings
[txState
]);
1894 * @todo do we want to schedule a future kick?
1896 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1897 NsTxStateStrings
[txState
]);
1899 if (!txKickEvent
.scheduled())
1900 schedule(txKickEvent
, txKickTick
);
1904 * Advance the EEPROM state machine
1905 * Called on rising edge of EEPROM clock bit in MEAR
1908 NSGigE::eepromKick()
1910 switch (eepromState
) {
1914 // Wait for start bit
1915 if (regs
.mear
& MEAR_EEDI
) {
1916 // Set up to get 2 opcode bits
1917 eepromState
= eepromGetOpcode
;
1923 case eepromGetOpcode
:
1925 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1928 // Done getting opcode
1929 if (eepromBitsToRx
== 0) {
1930 if (eepromOpcode
!= EEPROM_READ
)
1931 panic("only EEPROM reads are implemented!");
1933 // Set up to get address
1934 eepromState
= eepromGetAddress
;
1940 case eepromGetAddress
:
1941 eepromAddress
<<= 1;
1942 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1945 // Done getting address
1946 if (eepromBitsToRx
== 0) {
1948 if (eepromAddress
>= EEPROM_SIZE
)
1949 panic("EEPROM read access out of range!");
1951 switch (eepromAddress
) {
1953 case EEPROM_PMATCH2_ADDR
:
1954 eepromData
= rom
.perfectMatch
[5];
1956 eepromData
+= rom
.perfectMatch
[4];
1959 case EEPROM_PMATCH1_ADDR
:
1960 eepromData
= rom
.perfectMatch
[3];
1962 eepromData
+= rom
.perfectMatch
[2];
1965 case EEPROM_PMATCH0_ADDR
:
1966 eepromData
= rom
.perfectMatch
[1];
1968 eepromData
+= rom
.perfectMatch
[0];
1972 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1974 // Set up to read data
1975 eepromState
= eepromRead
;
1976 eepromBitsToRx
= 16;
1978 // Clear data in bit
1979 regs
.mear
&= ~MEAR_EEDI
;
1984 // Clear Data Out bit
1985 regs
.mear
&= ~MEAR_EEDO
;
1986 // Set bit to value of current EEPROM bit
1987 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
1993 if (eepromBitsToRx
== 0) {
1994 eepromState
= eepromStart
;
1999 panic("invalid EEPROM state");
2005 NSGigE::transferDone()
2007 if (txFifo
.empty()) {
2008 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2012 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2014 reschedule(txEvent
, clockEdge(Cycles(1)), true);
2018 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2020 EthPtr eth
= packet
;
2024 const EthAddr
&dst
= eth
->dst();
2025 if (dst
.unicast()) {
2026 // If we're accepting all unicast addresses
2030 // If we make a perfect match
2031 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2034 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2037 } else if (dst
.broadcast()) {
2038 // if we're accepting broadcasts
2039 if (acceptBroadcast
)
2042 } else if (dst
.multicast()) {
2043 // if we're accepting all multicasts
2044 if (acceptMulticast
)
2047 // Multicast hashing faked - all packets accepted
2048 if (multicastHashEnable
)
2053 DPRINTF(Ethernet
, "rxFilter drop\n");
2054 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2061 NSGigE::recvPacket(EthPacketPtr packet
)
2063 rxBytes
+= packet
->length
;
2066 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2070 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2074 if (!rxFilterEnable
) {
2076 "receive packet filtering disabled . . . packet dropped\n");
2080 if (rxFilter(packet
)) {
2081 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2085 if (rxFifo
.avail() < packet
->length
) {
2091 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2094 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2099 devIntrPost(ISR_RXORN
);
2103 rxFifo
.push(packet
);
2111 NSGigE::drainResume()
2113 Drainable::drainResume();
2115 // During drain we could have left the state machines in a waiting state and
2116 // they wouldn't get out until some other event occured to kick them.
2117 // This way they'll get out immediately
2123 //=====================================================================
2127 NSGigE::serialize(ostream
&os
)
2129 // Serialize the PciDev base class
2130 PciDev::serialize(os
);
2133 * Finalize any DMA events now.
2135 // @todo will mem system save pending dma?
2138 * Serialize the device registers
2140 SERIALIZE_SCALAR(regs
.command
);
2141 SERIALIZE_SCALAR(regs
.config
);
2142 SERIALIZE_SCALAR(regs
.mear
);
2143 SERIALIZE_SCALAR(regs
.ptscr
);
2144 SERIALIZE_SCALAR(regs
.isr
);
2145 SERIALIZE_SCALAR(regs
.imr
);
2146 SERIALIZE_SCALAR(regs
.ier
);
2147 SERIALIZE_SCALAR(regs
.ihr
);
2148 SERIALIZE_SCALAR(regs
.txdp
);
2149 SERIALIZE_SCALAR(regs
.txdp_hi
);
2150 SERIALIZE_SCALAR(regs
.txcfg
);
2151 SERIALIZE_SCALAR(regs
.gpior
);
2152 SERIALIZE_SCALAR(regs
.rxdp
);
2153 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2154 SERIALIZE_SCALAR(regs
.rxcfg
);
2155 SERIALIZE_SCALAR(regs
.pqcr
);
2156 SERIALIZE_SCALAR(regs
.wcsr
);
2157 SERIALIZE_SCALAR(regs
.pcr
);
2158 SERIALIZE_SCALAR(regs
.rfcr
);
2159 SERIALIZE_SCALAR(regs
.rfdr
);
2160 SERIALIZE_SCALAR(regs
.brar
);
2161 SERIALIZE_SCALAR(regs
.brdr
);
2162 SERIALIZE_SCALAR(regs
.srr
);
2163 SERIALIZE_SCALAR(regs
.mibc
);
2164 SERIALIZE_SCALAR(regs
.vrcr
);
2165 SERIALIZE_SCALAR(regs
.vtcr
);
2166 SERIALIZE_SCALAR(regs
.vdr
);
2167 SERIALIZE_SCALAR(regs
.ccsr
);
2168 SERIALIZE_SCALAR(regs
.tbicr
);
2169 SERIALIZE_SCALAR(regs
.tbisr
);
2170 SERIALIZE_SCALAR(regs
.tanar
);
2171 SERIALIZE_SCALAR(regs
.tanlpar
);
2172 SERIALIZE_SCALAR(regs
.taner
);
2173 SERIALIZE_SCALAR(regs
.tesr
);
2175 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2176 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2178 SERIALIZE_SCALAR(ioEnable
);
2181 * Serialize the data Fifos
2183 rxFifo
.serialize("rxFifo", os
);
2184 txFifo
.serialize("txFifo", os
);
2187 * Serialize the various helper variables
2189 bool txPacketExists
= txPacket
;
2190 SERIALIZE_SCALAR(txPacketExists
);
2191 if (txPacketExists
) {
2192 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2193 txPacket
->serialize("txPacket", os
);
2194 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2195 SERIALIZE_SCALAR(txPktBufPtr
);
2198 bool rxPacketExists
= rxPacket
;
2199 SERIALIZE_SCALAR(rxPacketExists
);
2200 if (rxPacketExists
) {
2201 rxPacket
->serialize("rxPacket", os
);
2202 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2203 SERIALIZE_SCALAR(rxPktBufPtr
);
2206 SERIALIZE_SCALAR(txXferLen
);
2207 SERIALIZE_SCALAR(rxXferLen
);
2210 * Serialize Cached Descriptors
2212 SERIALIZE_SCALAR(rxDesc64
.link
);
2213 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2214 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2215 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2216 SERIALIZE_SCALAR(txDesc64
.link
);
2217 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2218 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2219 SERIALIZE_SCALAR(txDesc64
.extsts
);
2220 SERIALIZE_SCALAR(rxDesc32
.link
);
2221 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2222 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2223 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2224 SERIALIZE_SCALAR(txDesc32
.link
);
2225 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2226 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2227 SERIALIZE_SCALAR(txDesc32
.extsts
);
2228 SERIALIZE_SCALAR(extstsEnable
);
2231 * Serialize tx state machine
2233 int txState
= this->txState
;
2234 SERIALIZE_SCALAR(txState
);
2235 SERIALIZE_SCALAR(txEnable
);
2236 SERIALIZE_SCALAR(CTDD
);
2237 SERIALIZE_SCALAR(txFragPtr
);
2238 SERIALIZE_SCALAR(txDescCnt
);
2239 int txDmaState
= this->txDmaState
;
2240 SERIALIZE_SCALAR(txDmaState
);
2241 SERIALIZE_SCALAR(txKickTick
);
2244 * Serialize rx state machine
2246 int rxState
= this->rxState
;
2247 SERIALIZE_SCALAR(rxState
);
2248 SERIALIZE_SCALAR(rxEnable
);
2249 SERIALIZE_SCALAR(CRDD
);
2250 SERIALIZE_SCALAR(rxPktBytes
);
2251 SERIALIZE_SCALAR(rxFragPtr
);
2252 SERIALIZE_SCALAR(rxDescCnt
);
2253 int rxDmaState
= this->rxDmaState
;
2254 SERIALIZE_SCALAR(rxDmaState
);
2255 SERIALIZE_SCALAR(rxKickTick
);
2258 * Serialize EEPROM state machine
2260 int eepromState
= this->eepromState
;
2261 SERIALIZE_SCALAR(eepromState
);
2262 SERIALIZE_SCALAR(eepromClk
);
2263 SERIALIZE_SCALAR(eepromBitsToRx
);
2264 SERIALIZE_SCALAR(eepromOpcode
);
2265 SERIALIZE_SCALAR(eepromAddress
);
2266 SERIALIZE_SCALAR(eepromData
);
2269 * If there's a pending transmit, store the time so we can
2270 * reschedule it later
2272 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick() : 0;
2273 SERIALIZE_SCALAR(transmitTick
);
2276 * receive address filter settings
2278 SERIALIZE_SCALAR(rxFilterEnable
);
2279 SERIALIZE_SCALAR(acceptBroadcast
);
2280 SERIALIZE_SCALAR(acceptMulticast
);
2281 SERIALIZE_SCALAR(acceptUnicast
);
2282 SERIALIZE_SCALAR(acceptPerfect
);
2283 SERIALIZE_SCALAR(acceptArp
);
2284 SERIALIZE_SCALAR(multicastHashEnable
);
2287 * Keep track of pending interrupt status.
2289 SERIALIZE_SCALAR(intrTick
);
2290 SERIALIZE_SCALAR(cpuPendingIntr
);
2291 Tick intrEventTick
= 0;
2293 intrEventTick
= intrEvent
->when();
2294 SERIALIZE_SCALAR(intrEventTick
);
2299 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2301 // Unserialize the PciDev base class
2302 PciDev::unserialize(cp
, section
);
2304 UNSERIALIZE_SCALAR(regs
.command
);
2305 UNSERIALIZE_SCALAR(regs
.config
);
2306 UNSERIALIZE_SCALAR(regs
.mear
);
2307 UNSERIALIZE_SCALAR(regs
.ptscr
);
2308 UNSERIALIZE_SCALAR(regs
.isr
);
2309 UNSERIALIZE_SCALAR(regs
.imr
);
2310 UNSERIALIZE_SCALAR(regs
.ier
);
2311 UNSERIALIZE_SCALAR(regs
.ihr
);
2312 UNSERIALIZE_SCALAR(regs
.txdp
);
2313 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2314 UNSERIALIZE_SCALAR(regs
.txcfg
);
2315 UNSERIALIZE_SCALAR(regs
.gpior
);
2316 UNSERIALIZE_SCALAR(regs
.rxdp
);
2317 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2318 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2319 UNSERIALIZE_SCALAR(regs
.pqcr
);
2320 UNSERIALIZE_SCALAR(regs
.wcsr
);
2321 UNSERIALIZE_SCALAR(regs
.pcr
);
2322 UNSERIALIZE_SCALAR(regs
.rfcr
);
2323 UNSERIALIZE_SCALAR(regs
.rfdr
);
2324 UNSERIALIZE_SCALAR(regs
.brar
);
2325 UNSERIALIZE_SCALAR(regs
.brdr
);
2326 UNSERIALIZE_SCALAR(regs
.srr
);
2327 UNSERIALIZE_SCALAR(regs
.mibc
);
2328 UNSERIALIZE_SCALAR(regs
.vrcr
);
2329 UNSERIALIZE_SCALAR(regs
.vtcr
);
2330 UNSERIALIZE_SCALAR(regs
.vdr
);
2331 UNSERIALIZE_SCALAR(regs
.ccsr
);
2332 UNSERIALIZE_SCALAR(regs
.tbicr
);
2333 UNSERIALIZE_SCALAR(regs
.tbisr
);
2334 UNSERIALIZE_SCALAR(regs
.tanar
);
2335 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2336 UNSERIALIZE_SCALAR(regs
.taner
);
2337 UNSERIALIZE_SCALAR(regs
.tesr
);
2339 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2340 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2342 UNSERIALIZE_SCALAR(ioEnable
);
2345 * unserialize the data fifos
2347 rxFifo
.unserialize("rxFifo", cp
, section
);
2348 txFifo
.unserialize("txFifo", cp
, section
);
2351 * unserialize the various helper variables
2353 bool txPacketExists
;
2354 UNSERIALIZE_SCALAR(txPacketExists
);
2355 if (txPacketExists
) {
2356 txPacket
= new EthPacketData(16384);
2357 txPacket
->unserialize("txPacket", cp
, section
);
2358 uint32_t txPktBufPtr
;
2359 UNSERIALIZE_SCALAR(txPktBufPtr
);
2360 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2364 bool rxPacketExists
;
2365 UNSERIALIZE_SCALAR(rxPacketExists
);
2367 if (rxPacketExists
) {
2368 rxPacket
= new EthPacketData(16384);
2369 rxPacket
->unserialize("rxPacket", cp
, section
);
2370 uint32_t rxPktBufPtr
;
2371 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2372 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2376 UNSERIALIZE_SCALAR(txXferLen
);
2377 UNSERIALIZE_SCALAR(rxXferLen
);
2380 * Unserialize Cached Descriptors
2382 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2383 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2384 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2385 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2386 UNSERIALIZE_SCALAR(txDesc64
.link
);
2387 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2388 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2389 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2390 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2391 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2392 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2393 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2394 UNSERIALIZE_SCALAR(txDesc32
.link
);
2395 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2396 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2397 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2398 UNSERIALIZE_SCALAR(extstsEnable
);
2401 * unserialize tx state machine
2404 UNSERIALIZE_SCALAR(txState
);
2405 this->txState
= (TxState
) txState
;
2406 UNSERIALIZE_SCALAR(txEnable
);
2407 UNSERIALIZE_SCALAR(CTDD
);
2408 UNSERIALIZE_SCALAR(txFragPtr
);
2409 UNSERIALIZE_SCALAR(txDescCnt
);
2411 UNSERIALIZE_SCALAR(txDmaState
);
2412 this->txDmaState
= (DmaState
) txDmaState
;
2413 UNSERIALIZE_SCALAR(txKickTick
);
2415 schedule(txKickEvent
, txKickTick
);
2418 * unserialize rx state machine
2421 UNSERIALIZE_SCALAR(rxState
);
2422 this->rxState
= (RxState
) rxState
;
2423 UNSERIALIZE_SCALAR(rxEnable
);
2424 UNSERIALIZE_SCALAR(CRDD
);
2425 UNSERIALIZE_SCALAR(rxPktBytes
);
2426 UNSERIALIZE_SCALAR(rxFragPtr
);
2427 UNSERIALIZE_SCALAR(rxDescCnt
);
2429 UNSERIALIZE_SCALAR(rxDmaState
);
2430 this->rxDmaState
= (DmaState
) rxDmaState
;
2431 UNSERIALIZE_SCALAR(rxKickTick
);
2433 schedule(rxKickEvent
, rxKickTick
);
2436 * Unserialize EEPROM state machine
2439 UNSERIALIZE_SCALAR(eepromState
);
2440 this->eepromState
= (EEPROMState
) eepromState
;
2441 UNSERIALIZE_SCALAR(eepromClk
);
2442 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2443 UNSERIALIZE_SCALAR(eepromOpcode
);
2444 UNSERIALIZE_SCALAR(eepromAddress
);
2445 UNSERIALIZE_SCALAR(eepromData
);
2448 * If there's a pending transmit, reschedule it now
2451 UNSERIALIZE_SCALAR(transmitTick
);
2453 schedule(txEvent
, curTick() + transmitTick
);
2456 * unserialize receive address filter settings
2458 UNSERIALIZE_SCALAR(rxFilterEnable
);
2459 UNSERIALIZE_SCALAR(acceptBroadcast
);
2460 UNSERIALIZE_SCALAR(acceptMulticast
);
2461 UNSERIALIZE_SCALAR(acceptUnicast
);
2462 UNSERIALIZE_SCALAR(acceptPerfect
);
2463 UNSERIALIZE_SCALAR(acceptArp
);
2464 UNSERIALIZE_SCALAR(multicastHashEnable
);
2467 * Keep track of pending interrupt status.
2469 UNSERIALIZE_SCALAR(intrTick
);
2470 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2472 UNSERIALIZE_SCALAR(intrEventTick
);
2473 if (intrEventTick
) {
2474 intrEvent
= new IntrEvent(this, true);
2475 schedule(intrEvent
, intrEventTick
);
2480 NSGigEParams::create()
2482 return new NSGigE(this);