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/inet.hh"
40 #include "cpu/thread_context.hh"
41 #include "dev/etherlink.hh"
42 #include "dev/ns_gige.hh"
43 #include "dev/pciconfigall.hh"
44 #include "mem/packet.hh"
45 #include "mem/packet_access.hh"
46 #include "params/NSGigE.hh"
47 #include "sim/debug.hh"
48 #include "sim/host.hh"
49 #include "sim/system.hh"
51 const char *NsRxStateStrings
[] =
62 const char *NsTxStateStrings
[] =
73 const char *NsDmaState
[] =
84 using namespace TheISA
;
86 ///////////////////////////////////////////////////////////////////////
90 NSGigE::NSGigE(Params
*p
)
91 : EtherDevice(p
), ioEnable(false),
92 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
93 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
94 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
96 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
97 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
98 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
99 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
100 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
101 eepromOpcode(0), eepromAddress(0), eepromData(0),
102 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
103 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
104 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
105 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
106 rxDmaReadEvent(this), rxDmaWriteEvent(this),
107 txDmaReadEvent(this), txDmaWriteEvent(this),
108 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
109 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
110 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
111 txEvent(this), rxFilterEnable(p
->rx_filter
),
112 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
113 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
114 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
115 intrEvent(0), interface(0)
119 interface
= new NSGigEInt(name() + ".int0", this);
122 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
124 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
125 memset(&txDesc32
, 0, sizeof(txDesc32
));
126 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
127 memset(&txDesc64
, 0, sizeof(txDesc64
));
134 * This is to write to the PCI general configuration registers
137 NSGigE::writeConfig(PacketPtr pkt
)
139 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
140 if (offset
< PCI_DEVICE_SPECIFIC
)
141 PciDev::writeConfig(pkt
);
143 panic("Device specific PCI config space not implemented!\n");
146 // seems to work fine without all these PCI settings, but i
147 // put in the IO to double check, an assertion will fail if we
148 // need to properly implement it
150 if (config
.data
[offset
] & PCI_CMD_IOSE
)
161 NSGigE::getEthPort(const std::string
&if_name
, int idx
)
163 if (if_name
== "interface") {
164 if (interface
->getPeer())
165 panic("interface already connected to\n");
172 * This reads the device registers, which are detailed in the NS83820
176 NSGigE::read(PacketPtr pkt
)
182 //The mask is to give you only the offset into the device register file
183 Addr daddr
= pkt
->getAddr() & 0xfff;
184 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
185 daddr
, pkt
->getAddr(), pkt
->getSize());
188 // there are some reserved registers, you can see ns_gige_reg.h and
189 // the spec sheet for details
190 if (daddr
> LAST
&& daddr
<= RESERVED
) {
191 panic("Accessing reserved register");
192 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
193 return readConfig(pkt
);
194 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
195 // don't implement all the MIB's. hopefully the kernel
196 // doesn't actually DEPEND upon their values
197 // MIB are just hardware stats keepers
198 pkt
->set
<uint32_t>(0);
199 pkt
->makeAtomicResponse();
201 } else if (daddr
> 0x3FC)
202 panic("Something is messed up!\n");
204 assert(pkt
->getSize() == sizeof(uint32_t));
205 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
211 //these are supposed to be cleared on a read
212 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
229 devIntrClear(ISR_ALL
);
284 // see the spec sheet for how RFCR and RFDR work
285 // basically, you write to RFCR to tell the machine
286 // what you want to do next, then you act upon RFDR,
287 // and the device will be prepared b/c of what you
294 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
296 // Read from perfect match ROM octets
298 reg
= rom
.perfectMatch
[1];
300 reg
+= rom
.perfectMatch
[0];
303 reg
= rom
.perfectMatch
[3] << 8;
304 reg
+= rom
.perfectMatch
[2];
307 reg
= rom
.perfectMatch
[5] << 8;
308 reg
+= rom
.perfectMatch
[4];
311 // Read filter hash table
312 if (rfaddr
>= FHASH_ADDR
&&
313 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
315 // Only word-aligned reads supported
317 panic("unaligned read from filter hash table!");
319 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
320 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
324 panic("reading RFDR for something other than pattern"
325 " matching or hashing! %#x\n", rfaddr
);
335 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
380 if (params()->rx_thread
)
381 reg
|= M5REG_RX_THREAD
;
382 if (params()->tx_thread
)
383 reg
|= M5REG_TX_THREAD
;
389 panic("reading unimplemented register: addr=%#x", daddr
);
392 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
395 pkt
->makeAtomicResponse();
400 NSGigE::write(PacketPtr pkt
)
404 Addr daddr
= pkt
->getAddr() & 0xfff;
405 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
406 daddr
, pkt
->getAddr(), pkt
->getSize());
408 if (daddr
> LAST
&& daddr
<= RESERVED
) {
409 panic("Accessing reserved register");
410 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
411 return writeConfig(pkt
);
412 } else if (daddr
> 0x3FC)
413 panic("Something is messed up!\n");
415 if (pkt
->getSize() == sizeof(uint32_t)) {
416 uint32_t reg
= pkt
->get
<uint32_t>();
419 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
426 } else if (reg
& CR_TXE
) {
429 // the kernel is enabling the transmit machine
430 if (txState
== txIdle
)
436 } else if (reg
& CR_RXE
) {
439 if (rxState
== rxIdle
)
450 devIntrPost(ISR_SWI
);
461 if (reg
& CFGR_LNKSTS
||
464 reg
& CFGR_RESERVED
||
465 reg
& CFGR_T64ADDR
||
466 reg
& CFGR_PCI64_DET
)
468 // First clear all writable bits
469 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
470 CFGR_RESERVED
| CFGR_T64ADDR
|
472 // Now set the appropriate writable bits
473 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
474 CFGR_RESERVED
| CFGR_T64ADDR
|
477 // all these #if 0's are because i don't THINK the kernel needs to
478 // have these implemented. if there is a problem relating to one of
479 // these, you may need to add functionality in.
480 if (reg
& CFGR_TBI_EN
) ;
481 if (reg
& CFGR_MODE_1000
) ;
483 if (reg
& CFGR_AUTO_1000
)
484 panic("CFGR_AUTO_1000 not implemented!\n");
486 if (reg
& CFGR_PINT_DUPSTS
||
487 reg
& CFGR_PINT_LNKSTS
||
488 reg
& CFGR_PINT_SPDSTS
)
491 if (reg
& CFGR_TMRTEST
) ;
492 if (reg
& CFGR_MRM_DIS
) ;
493 if (reg
& CFGR_MWI_DIS
) ;
495 if (reg
& CFGR_T64ADDR
) ;
496 // panic("CFGR_T64ADDR is read only register!\n");
498 if (reg
& CFGR_PCI64_DET
)
499 panic("CFGR_PCI64_DET is read only register!\n");
501 if (reg
& CFGR_DATA64_EN
) ;
502 if (reg
& CFGR_M64ADDR
) ;
503 if (reg
& CFGR_PHY_RST
) ;
504 if (reg
& CFGR_PHY_DIS
) ;
506 if (reg
& CFGR_EXTSTS_EN
)
509 extstsEnable
= false;
511 if (reg
& CFGR_REQALG
) ;
513 if (reg
& CFGR_POW
) ;
514 if (reg
& CFGR_EXD
) ;
515 if (reg
& CFGR_PESEL
) ;
516 if (reg
& CFGR_BROM_DIS
) ;
517 if (reg
& CFGR_EXT_125
) ;
518 if (reg
& CFGR_BEM
) ;
522 // Clear writable bits
523 regs
.mear
&= MEAR_EEDO
;
524 // Set appropriate writable bits
525 regs
.mear
|= reg
& ~MEAR_EEDO
;
527 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
528 // even though it could get it through RFDR
529 if (reg
& MEAR_EESEL
) {
530 // Rising edge of clock
531 if (reg
& MEAR_EECLK
&& !eepromClk
)
535 eepromState
= eepromStart
;
536 regs
.mear
&= ~MEAR_EEDI
;
539 eepromClk
= reg
& MEAR_EECLK
;
541 // since phy is completely faked, MEAR_MD* don't matter
542 if (reg
& MEAR_MDIO
) ;
543 if (reg
& MEAR_MDDIR
) ;
544 if (reg
& MEAR_MDC
) ;
548 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
549 // these control BISTs for various parts of chip - we
550 // don't care or do just fake that the BIST is done
551 if (reg
& PTSCR_RBIST_EN
)
552 regs
.ptscr
|= PTSCR_RBIST_DONE
;
553 if (reg
& PTSCR_EEBIST_EN
)
554 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
555 if (reg
& PTSCR_EELOAD_EN
)
556 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
559 case ISR
: /* writing to the ISR has no effect */
560 panic("ISR is a read only register!\n");
573 /* not going to implement real interrupt holdoff */
577 regs
.txdp
= (reg
& 0xFFFFFFFC);
578 assert(txState
== txIdle
);
589 if (reg
& TX_CFG_CSI
) ;
590 if (reg
& TX_CFG_HBI
) ;
591 if (reg
& TX_CFG_MLB
) ;
592 if (reg
& TX_CFG_ATP
) ;
593 if (reg
& TX_CFG_ECRETRY
) {
595 * this could easily be implemented, but considering
596 * the network is just a fake pipe, wouldn't make
601 if (reg
& TX_CFG_BRST_DIS
) ;
605 /* we handle our own DMA, ignore the kernel's exhortations */
606 if (reg
& TX_CFG_MXDMA
) ;
609 // also, we currently don't care about fill/drain
610 // thresholds though this may change in the future with
611 // more realistic networks or a driver which changes it
612 // according to feedback
617 // Only write writable bits
618 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
619 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
620 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
621 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
622 /* these just control general purpose i/o pins, don't matter */
637 if (reg
& RX_CFG_AEP
) ;
638 if (reg
& RX_CFG_ARP
) ;
639 if (reg
& RX_CFG_STRIPCRC
) ;
640 if (reg
& RX_CFG_RX_RD
) ;
641 if (reg
& RX_CFG_ALP
) ;
642 if (reg
& RX_CFG_AIRL
) ;
644 /* we handle our own DMA, ignore what kernel says about it */
645 if (reg
& RX_CFG_MXDMA
) ;
647 //also, we currently don't care about fill/drain thresholds
648 //though this may change in the future with more realistic
649 //networks or a driver which changes it according to feedback
650 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
655 /* there is no priority queueing used in the linux 2.6 driver */
660 /* not going to implement wake on LAN */
665 /* not going to implement pause control */
672 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
673 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
674 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
675 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
676 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
677 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
678 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
682 panic("RFCR_APAT not implemented!\n");
685 panic("Unicast hash filtering not used by drivers!\n");
688 panic("RFCR_ULM not implemented!\n");
693 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
696 rom
.perfectMatch
[0] = (uint8_t)reg
;
697 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
700 rom
.perfectMatch
[2] = (uint8_t)reg
;
701 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
704 rom
.perfectMatch
[4] = (uint8_t)reg
;
705 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
709 if (rfaddr
>= FHASH_ADDR
&&
710 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
712 // Only word-aligned writes supported
714 panic("unaligned write to filter hash table!");
716 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
717 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
718 = (uint8_t)(reg
>> 8);
721 panic("writing RFDR for something other than pattern matching\
722 or hashing! %#x\n", rfaddr
);
730 panic("the driver never uses BRDR, something is wrong!\n");
733 panic("SRR is read only register!\n");
736 panic("the driver never uses MIBC, something is wrong!\n");
747 panic("the driver never uses VDR, something is wrong!\n");
750 /* not going to implement clockrun stuff */
756 if (reg
& TBICR_MR_LOOPBACK
)
757 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
759 if (reg
& TBICR_MR_AN_ENABLE
) {
760 regs
.tanlpar
= regs
.tanar
;
761 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
765 if (reg
& TBICR_MR_RESTART_AN
) ;
771 panic("TBISR is read only register!\n");
774 // Only write the writable bits
775 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
776 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
778 // Pause capability unimplemented
780 if (reg
& TANAR_PS2
) ;
781 if (reg
& TANAR_PS1
) ;
787 panic("this should only be written to by the fake phy!\n");
790 panic("TANER is read only register!\n");
797 panic("invalid register access daddr=%#x", daddr
);
800 panic("Invalid Request Size");
802 pkt
->makeAtomicResponse();
807 NSGigE::devIntrPost(uint32_t interrupts
)
809 if (interrupts
& ISR_RESERVE
)
810 panic("Cannot set a reserved interrupt");
812 if (interrupts
& ISR_NOIMPL
)
813 warn("interrupt not implemented %#x\n", interrupts
);
815 interrupts
&= ISR_IMPL
;
816 regs
.isr
|= interrupts
;
818 if (interrupts
& regs
.imr
) {
819 if (interrupts
& ISR_SWI
) {
822 if (interrupts
& ISR_RXIDLE
) {
825 if (interrupts
& ISR_RXOK
) {
828 if (interrupts
& ISR_RXDESC
) {
831 if (interrupts
& ISR_TXOK
) {
834 if (interrupts
& ISR_TXIDLE
) {
837 if (interrupts
& ISR_TXDESC
) {
840 if (interrupts
& ISR_RXORN
) {
845 DPRINTF(EthernetIntr
,
846 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
847 interrupts
, regs
.isr
, regs
.imr
);
849 if ((regs
.isr
& regs
.imr
)) {
851 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
858 /* writing this interrupt counting stats inside this means that this function
859 is now limited to being used to clear all interrupts upon the kernel
860 reading isr and servicing. just telling you in case you were thinking
864 NSGigE::devIntrClear(uint32_t interrupts
)
866 if (interrupts
& ISR_RESERVE
)
867 panic("Cannot clear a reserved interrupt");
869 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
872 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
875 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
878 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
881 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
884 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
887 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
890 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
894 interrupts
&= ~ISR_NOIMPL
;
895 regs
.isr
&= ~interrupts
;
897 DPRINTF(EthernetIntr
,
898 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
899 interrupts
, regs
.isr
, regs
.imr
);
901 if (!(regs
.isr
& regs
.imr
))
906 NSGigE::devIntrChangeMask()
908 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
909 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
911 if (regs
.isr
& regs
.imr
)
912 cpuIntrPost(curTick
);
918 NSGigE::cpuIntrPost(Tick when
)
920 // If the interrupt you want to post is later than an interrupt
921 // already scheduled, just let it post in the coming one and don't
923 // HOWEVER, must be sure that the scheduled intrTick is in the
924 // future (this was formerly the source of a bug)
926 * @todo this warning should be removed and the intrTick code should
929 assert(when
>= curTick
);
930 assert(intrTick
>= curTick
|| intrTick
== 0);
931 if (when
> intrTick
&& intrTick
!= 0) {
932 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
938 if (intrTick
< curTick
) {
943 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
948 intrEvent
= new IntrEvent(this, intrTick
, true);
952 NSGigE::cpuInterrupt()
954 assert(intrTick
== curTick
);
956 // Whether or not there's a pending interrupt, we don't care about
961 // Don't send an interrupt if there's already one
962 if (cpuPendingIntr
) {
963 DPRINTF(EthernetIntr
,
964 "would send an interrupt now, but there's already pending\n");
967 cpuPendingIntr
= true;
969 DPRINTF(EthernetIntr
, "posting interrupt\n");
975 NSGigE::cpuIntrClear()
987 cpuPendingIntr
= false;
989 DPRINTF(EthernetIntr
, "clearing interrupt\n");
994 NSGigE::cpuIntrPending() const
995 { return cpuPendingIntr
; }
1001 DPRINTF(Ethernet
, "transmit reset\n");
1006 assert(txDescCnt
== 0);
1009 assert(txDmaState
== dmaIdle
);
1015 DPRINTF(Ethernet
, "receive reset\n");
1018 assert(rxPktBytes
== 0);
1021 assert(rxDescCnt
== 0);
1022 assert(rxDmaState
== dmaIdle
);
1030 memset(®s
, 0, sizeof(regs
));
1031 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1033 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1034 // fill threshold to 32 bytes
1035 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1036 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1037 regs
.mibc
= MIBC_FRZ
;
1038 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1039 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1040 regs
.brar
= 0xffffffff;
1042 extstsEnable
= false;
1043 acceptBroadcast
= false;
1044 acceptMulticast
= false;
1045 acceptUnicast
= false;
1046 acceptPerfect
= false;
1051 NSGigE::doRxDmaRead()
1053 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1054 rxDmaState
= dmaReading
;
1056 if (dmaPending() || getState() != Running
)
1057 rxDmaState
= dmaReadWaiting
;
1059 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1065 NSGigE::rxDmaReadDone()
1067 assert(rxDmaState
== dmaReading
);
1068 rxDmaState
= dmaIdle
;
1070 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1071 rxDmaAddr
, rxDmaLen
);
1072 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1074 // If the transmit state machine has a pending DMA, let it go first
1075 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1082 NSGigE::doRxDmaWrite()
1084 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1085 rxDmaState
= dmaWriting
;
1087 if (dmaPending() || getState() != Running
)
1088 rxDmaState
= dmaWriteWaiting
;
1090 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1095 NSGigE::rxDmaWriteDone()
1097 assert(rxDmaState
== dmaWriting
);
1098 rxDmaState
= dmaIdle
;
1100 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1101 rxDmaAddr
, rxDmaLen
);
1102 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1104 // If the transmit state machine has a pending DMA, let it go first
1105 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1114 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1117 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1118 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1121 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1122 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1126 if (rxKickTick
> curTick
) {
1127 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1133 // Go to the next state machine clock tick.
1134 rxKickTick
= curTick
+ ticks(1);
1137 switch(rxDmaState
) {
1138 case dmaReadWaiting
:
1142 case dmaWriteWaiting
:
1150 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1151 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1153 // see state machine from spec for details
1154 // the way this works is, if you finish work on one state and can
1155 // go directly to another, you do that through jumping to the
1156 // label "next". however, if you have intermediate work, like DMA
1157 // so that you can't go to the next state yet, you go to exit and
1158 // exit the loop. however, when the DMA is done it will trigger
1159 // an event and come back to this loop.
1163 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1168 rxState
= rxDescRefr
;
1170 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1172 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1173 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1174 rxDmaFree
= dmaDescFree
;
1177 descDmaRdBytes
+= rxDmaLen
;
1182 rxState
= rxDescRead
;
1184 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1185 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1186 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1187 rxDmaFree
= dmaDescFree
;
1190 descDmaRdBytes
+= rxDmaLen
;
1198 if (rxDmaState
!= dmaIdle
)
1201 rxState
= rxAdvance
;
1205 if (rxDmaState
!= dmaIdle
)
1208 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1209 regs
.rxdp
& 0x3fffffff);
1210 DPRINTF(EthernetDesc
,
1211 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1212 link
, bufptr
, cmdsts
, extsts
);
1214 if (cmdsts
& CMDSTS_OWN
) {
1215 devIntrPost(ISR_RXIDLE
);
1219 rxState
= rxFifoBlock
;
1221 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1228 * @todo in reality, we should be able to start processing
1229 * the packet as it arrives, and not have to wait for the
1230 * full packet ot be in the receive fifo.
1235 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1237 // If we don't have a packet, grab a new one from the fifo.
1238 rxPacket
= rxFifo
.front();
1239 rxPktBytes
= rxPacket
->length
;
1240 rxPacketBufPtr
= rxPacket
->data
;
1243 if (DTRACE(Ethernet
)) {
1246 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1250 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1251 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1258 // sanity check - i think the driver behaves like this
1259 assert(rxDescCnt
>= rxPktBytes
);
1264 // dont' need the && rxDescCnt > 0 if driver sanity check
1266 if (rxPktBytes
> 0) {
1267 rxState
= rxFragWrite
;
1268 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1270 rxXferLen
= rxPktBytes
;
1272 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1273 rxDmaData
= rxPacketBufPtr
;
1274 rxDmaLen
= rxXferLen
;
1275 rxDmaFree
= dmaDataFree
;
1281 rxState
= rxDescWrite
;
1283 //if (rxPktBytes == 0) { /* packet is done */
1284 assert(rxPktBytes
== 0);
1285 DPRINTF(EthernetSM
, "done with receiving packet\n");
1287 cmdsts
|= CMDSTS_OWN
;
1288 cmdsts
&= ~CMDSTS_MORE
;
1289 cmdsts
|= CMDSTS_OK
;
1290 cmdsts
&= 0xffff0000;
1291 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1295 * all the driver uses these are for its own stats keeping
1296 * which we don't care about, aren't necessary for
1297 * functionality and doing this would just slow us down.
1298 * if they end up using this in a later version for
1299 * functional purposes, just undef
1301 if (rxFilterEnable
) {
1302 cmdsts
&= ~CMDSTS_DEST_MASK
;
1303 const EthAddr
&dst
= rxFifoFront()->dst();
1305 cmdsts
|= CMDSTS_DEST_SELF
;
1306 if (dst
->multicast())
1307 cmdsts
|= CMDSTS_DEST_MULTI
;
1308 if (dst
->broadcast())
1309 cmdsts
|= CMDSTS_DEST_MASK
;
1314 if (extstsEnable
&& ip
) {
1315 extsts
|= EXTSTS_IPPKT
;
1317 if (cksum(ip
) != 0) {
1318 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1319 extsts
|= EXTSTS_IPERR
;
1324 extsts
|= EXTSTS_TCPPKT
;
1326 if (cksum(tcp
) != 0) {
1327 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1328 extsts
|= EXTSTS_TCPERR
;
1332 extsts
|= EXTSTS_UDPPKT
;
1334 if (cksum(udp
) != 0) {
1335 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1336 extsts
|= EXTSTS_UDPERR
;
1343 * the driver seems to always receive into desc buffers
1344 * of size 1514, so you never have a pkt that is split
1345 * into multiple descriptors on the receive side, so
1346 * i don't implement that case, hence the assert above.
1349 DPRINTF(EthernetDesc
,
1350 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1351 regs
.rxdp
& 0x3fffffff);
1352 DPRINTF(EthernetDesc
,
1353 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1354 link
, bufptr
, cmdsts
, extsts
);
1356 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1357 rxDmaData
= &cmdsts
;
1359 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1360 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1362 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1363 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1365 rxDmaFree
= dmaDescFree
;
1368 descDmaWrBytes
+= rxDmaLen
;
1376 if (rxDmaState
!= dmaIdle
)
1379 rxPacketBufPtr
+= rxXferLen
;
1380 rxFragPtr
+= rxXferLen
;
1381 rxPktBytes
-= rxXferLen
;
1383 rxState
= rxFifoBlock
;
1387 if (rxDmaState
!= dmaIdle
)
1390 assert(cmdsts
& CMDSTS_OWN
);
1392 assert(rxPacket
== 0);
1393 devIntrPost(ISR_RXOK
);
1395 if (cmdsts
& CMDSTS_INTR
)
1396 devIntrPost(ISR_RXDESC
);
1399 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1403 rxState
= rxAdvance
;
1408 devIntrPost(ISR_RXIDLE
);
1413 if (rxDmaState
!= dmaIdle
)
1415 rxState
= rxDescRead
;
1419 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1420 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1421 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1422 rxDmaFree
= dmaDescFree
;
1430 panic("Invalid rxState!");
1433 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1434 NsRxStateStrings
[rxState
]);
1439 * @todo do we want to schedule a future kick?
1441 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1442 NsRxStateStrings
[rxState
]);
1444 if (clock
&& !rxKickEvent
.scheduled())
1445 rxKickEvent
.schedule(rxKickTick
);
1451 if (txFifo
.empty()) {
1452 DPRINTF(Ethernet
, "nothing to transmit\n");
1456 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1458 if (interface
->sendPacket(txFifo
.front())) {
1460 if (DTRACE(Ethernet
)) {
1461 IpPtr
ip(txFifo
.front());
1463 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1467 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1468 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1475 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1476 txBytes
+= txFifo
.front()->length
;
1479 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1484 * normally do a writeback of the descriptor here, and ONLY
1485 * after that is done, send this interrupt. but since our
1486 * stuff never actually fails, just do this interrupt here,
1487 * otherwise the code has to stray from this nice format.
1488 * besides, it's functionally the same.
1490 devIntrPost(ISR_TXOK
);
1493 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1494 DPRINTF(Ethernet
, "reschedule transmit\n");
1495 txEvent
.schedule(curTick
+ retryTime
);
1500 NSGigE::doTxDmaRead()
1502 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1503 txDmaState
= dmaReading
;
1505 if (dmaPending() || getState() != Running
)
1506 txDmaState
= dmaReadWaiting
;
1508 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1514 NSGigE::txDmaReadDone()
1516 assert(txDmaState
== dmaReading
);
1517 txDmaState
= dmaIdle
;
1519 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1520 txDmaAddr
, txDmaLen
);
1521 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1523 // If the receive state machine has a pending DMA, let it go first
1524 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1531 NSGigE::doTxDmaWrite()
1533 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1534 txDmaState
= dmaWriting
;
1536 if (dmaPending() || getState() != Running
)
1537 txDmaState
= dmaWriteWaiting
;
1539 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1544 NSGigE::txDmaWriteDone()
1546 assert(txDmaState
== dmaWriting
);
1547 txDmaState
= dmaIdle
;
1549 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1550 txDmaAddr
, txDmaLen
);
1551 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1553 // If the receive state machine has a pending DMA, let it go first
1554 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1563 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1565 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1566 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1569 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1570 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1574 if (txKickTick
> curTick
) {
1575 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1580 // Go to the next state machine clock tick.
1581 txKickTick
= curTick
+ ticks(1);
1584 switch(txDmaState
) {
1585 case dmaReadWaiting
:
1589 case dmaWriteWaiting
:
1597 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1598 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1602 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1607 txState
= txDescRefr
;
1609 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1611 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1612 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1613 txDmaFree
= dmaDescFree
;
1616 descDmaRdBytes
+= txDmaLen
;
1622 txState
= txDescRead
;
1624 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1625 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1626 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1627 txDmaFree
= dmaDescFree
;
1630 descDmaRdBytes
+= txDmaLen
;
1638 if (txDmaState
!= dmaIdle
)
1641 txState
= txAdvance
;
1645 if (txDmaState
!= dmaIdle
)
1648 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1649 regs
.txdp
& 0x3fffffff);
1650 DPRINTF(EthernetDesc
,
1651 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1652 link
, bufptr
, cmdsts
, extsts
);
1654 if (cmdsts
& CMDSTS_OWN
) {
1655 txState
= txFifoBlock
;
1657 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1659 devIntrPost(ISR_TXIDLE
);
1667 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1668 txPacket
= new EthPacketData(16384);
1669 txPacketBufPtr
= txPacket
->data
;
1672 if (txDescCnt
== 0) {
1673 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1674 if (cmdsts
& CMDSTS_MORE
) {
1675 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
1676 txState
= txDescWrite
;
1678 cmdsts
&= ~CMDSTS_OWN
;
1680 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1681 txDmaData
= &cmdsts
;
1683 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1684 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1686 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1687 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1689 txDmaFree
= dmaDescFree
;
1694 } else { /* this packet is totally done */
1695 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
1696 /* deal with the the packet that just finished */
1697 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
1699 if (extsts
& EXTSTS_UDPPKT
) {
1703 udp
->sum(cksum(udp
));
1707 warn_once("UDPPKT set, but not UDP!\n");
1709 } else if (extsts
& EXTSTS_TCPPKT
) {
1713 tcp
->sum(cksum(tcp
));
1717 warn_once("TCPPKT set, but not UDP!\n");
1720 if (extsts
& EXTSTS_IPPKT
) {
1727 warn_once("IPPKT set, but not UDP!\n");
1732 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
1733 // this is just because the receive can't handle a
1734 // packet bigger want to make sure
1735 if (txPacket
->length
> 1514)
1736 panic("transmit packet too large, %s > 1514\n",
1742 txFifo
.push(txPacket
);
1746 * this following section is not tqo spec, but
1747 * functionally shouldn't be any different. normally,
1748 * the chip will wait til the transmit has occurred
1749 * before writing back the descriptor because it has
1750 * to wait to see that it was successfully transmitted
1751 * to decide whether to set CMDSTS_OK or not.
1752 * however, in the simulator since it is always
1753 * successfully transmitted, and writing it exactly to
1754 * spec would complicate the code, we just do it here
1757 cmdsts
&= ~CMDSTS_OWN
;
1758 cmdsts
|= CMDSTS_OK
;
1760 DPRINTF(EthernetDesc
,
1761 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1764 txDmaFree
= dmaDescFree
;
1765 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1766 txDmaData
= &cmdsts
;
1768 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1770 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1772 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1774 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1778 descDmaWrBytes
+= txDmaLen
;
1784 DPRINTF(EthernetSM
, "halting TX state machine\n");
1788 txState
= txAdvance
;
1794 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1795 if (!txFifo
.full()) {
1796 txState
= txFragRead
;
1799 * The number of bytes transferred is either whatever
1800 * is left in the descriptor (txDescCnt), or if there
1801 * is not enough room in the fifo, just whatever room
1802 * is left in the fifo
1804 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1806 txDmaAddr
= txFragPtr
& 0x3fffffff;
1807 txDmaData
= txPacketBufPtr
;
1808 txDmaLen
= txXferLen
;
1809 txDmaFree
= dmaDataFree
;
1814 txState
= txFifoBlock
;
1824 if (txDmaState
!= dmaIdle
)
1827 txPacketBufPtr
+= txXferLen
;
1828 txFragPtr
+= txXferLen
;
1829 txDescCnt
-= txXferLen
;
1830 txFifo
.reserve(txXferLen
);
1832 txState
= txFifoBlock
;
1836 if (txDmaState
!= dmaIdle
)
1839 if (cmdsts
& CMDSTS_INTR
)
1840 devIntrPost(ISR_TXDESC
);
1843 DPRINTF(EthernetSM
, "halting TX state machine\n");
1847 txState
= txAdvance
;
1852 devIntrPost(ISR_TXIDLE
);
1856 if (txDmaState
!= dmaIdle
)
1858 txState
= txDescRead
;
1862 txDmaAddr
= link
& 0x3fffffff;
1863 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1864 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1865 txDmaFree
= dmaDescFree
;
1873 panic("invalid state");
1876 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1877 NsTxStateStrings
[txState
]);
1882 * @todo do we want to schedule a future kick?
1884 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1885 NsTxStateStrings
[txState
]);
1887 if (clock
&& !txKickEvent
.scheduled())
1888 txKickEvent
.schedule(txKickTick
);
1892 * Advance the EEPROM state machine
1893 * Called on rising edge of EEPROM clock bit in MEAR
1896 NSGigE::eepromKick()
1898 switch (eepromState
) {
1902 // Wait for start bit
1903 if (regs
.mear
& MEAR_EEDI
) {
1904 // Set up to get 2 opcode bits
1905 eepromState
= eepromGetOpcode
;
1911 case eepromGetOpcode
:
1913 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1916 // Done getting opcode
1917 if (eepromBitsToRx
== 0) {
1918 if (eepromOpcode
!= EEPROM_READ
)
1919 panic("only EEPROM reads are implemented!");
1921 // Set up to get address
1922 eepromState
= eepromGetAddress
;
1928 case eepromGetAddress
:
1929 eepromAddress
<<= 1;
1930 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1933 // Done getting address
1934 if (eepromBitsToRx
== 0) {
1936 if (eepromAddress
>= EEPROM_SIZE
)
1937 panic("EEPROM read access out of range!");
1939 switch (eepromAddress
) {
1941 case EEPROM_PMATCH2_ADDR
:
1942 eepromData
= rom
.perfectMatch
[5];
1944 eepromData
+= rom
.perfectMatch
[4];
1947 case EEPROM_PMATCH1_ADDR
:
1948 eepromData
= rom
.perfectMatch
[3];
1950 eepromData
+= rom
.perfectMatch
[2];
1953 case EEPROM_PMATCH0_ADDR
:
1954 eepromData
= rom
.perfectMatch
[1];
1956 eepromData
+= rom
.perfectMatch
[0];
1960 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1962 // Set up to read data
1963 eepromState
= eepromRead
;
1964 eepromBitsToRx
= 16;
1966 // Clear data in bit
1967 regs
.mear
&= ~MEAR_EEDI
;
1972 // Clear Data Out bit
1973 regs
.mear
&= ~MEAR_EEDO
;
1974 // Set bit to value of current EEPROM bit
1975 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
1981 if (eepromBitsToRx
== 0) {
1982 eepromState
= eepromStart
;
1987 panic("invalid EEPROM state");
1993 NSGigE::transferDone()
1995 if (txFifo
.empty()) {
1996 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2000 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2002 txEvent
.reschedule(curTick
+ ticks(1), true);
2006 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2008 EthPtr eth
= packet
;
2012 const EthAddr
&dst
= eth
->dst();
2013 if (dst
.unicast()) {
2014 // If we're accepting all unicast addresses
2018 // If we make a perfect match
2019 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2022 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2025 } else if (dst
.broadcast()) {
2026 // if we're accepting broadcasts
2027 if (acceptBroadcast
)
2030 } else if (dst
.multicast()) {
2031 // if we're accepting all multicasts
2032 if (acceptMulticast
)
2035 // Multicast hashing faked - all packets accepted
2036 if (multicastHashEnable
)
2041 DPRINTF(Ethernet
, "rxFilter drop\n");
2042 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2049 NSGigE::recvPacket(EthPacketPtr packet
)
2051 rxBytes
+= packet
->length
;
2054 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2058 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2062 if (!rxFilterEnable
) {
2064 "receive packet filtering disabled . . . packet dropped\n");
2068 if (rxFilter(packet
)) {
2069 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2073 if (rxFifo
.avail() < packet
->length
) {
2079 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2082 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2087 devIntrPost(ISR_RXORN
);
2091 rxFifo
.push(packet
);
2101 SimObject::resume();
2103 // During drain we could have left the state machines in a waiting state and
2104 // they wouldn't get out until some other event occured to kick them.
2105 // This way they'll get out immediately
2111 //=====================================================================
2115 NSGigE::serialize(ostream
&os
)
2117 // Serialize the PciDev base class
2118 PciDev::serialize(os
);
2121 * Finalize any DMA events now.
2123 // @todo will mem system save pending dma?
2126 * Serialize the device registers
2128 SERIALIZE_SCALAR(regs
.command
);
2129 SERIALIZE_SCALAR(regs
.config
);
2130 SERIALIZE_SCALAR(regs
.mear
);
2131 SERIALIZE_SCALAR(regs
.ptscr
);
2132 SERIALIZE_SCALAR(regs
.isr
);
2133 SERIALIZE_SCALAR(regs
.imr
);
2134 SERIALIZE_SCALAR(regs
.ier
);
2135 SERIALIZE_SCALAR(regs
.ihr
);
2136 SERIALIZE_SCALAR(regs
.txdp
);
2137 SERIALIZE_SCALAR(regs
.txdp_hi
);
2138 SERIALIZE_SCALAR(regs
.txcfg
);
2139 SERIALIZE_SCALAR(regs
.gpior
);
2140 SERIALIZE_SCALAR(regs
.rxdp
);
2141 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2142 SERIALIZE_SCALAR(regs
.rxcfg
);
2143 SERIALIZE_SCALAR(regs
.pqcr
);
2144 SERIALIZE_SCALAR(regs
.wcsr
);
2145 SERIALIZE_SCALAR(regs
.pcr
);
2146 SERIALIZE_SCALAR(regs
.rfcr
);
2147 SERIALIZE_SCALAR(regs
.rfdr
);
2148 SERIALIZE_SCALAR(regs
.brar
);
2149 SERIALIZE_SCALAR(regs
.brdr
);
2150 SERIALIZE_SCALAR(regs
.srr
);
2151 SERIALIZE_SCALAR(regs
.mibc
);
2152 SERIALIZE_SCALAR(regs
.vrcr
);
2153 SERIALIZE_SCALAR(regs
.vtcr
);
2154 SERIALIZE_SCALAR(regs
.vdr
);
2155 SERIALIZE_SCALAR(regs
.ccsr
);
2156 SERIALIZE_SCALAR(regs
.tbicr
);
2157 SERIALIZE_SCALAR(regs
.tbisr
);
2158 SERIALIZE_SCALAR(regs
.tanar
);
2159 SERIALIZE_SCALAR(regs
.tanlpar
);
2160 SERIALIZE_SCALAR(regs
.taner
);
2161 SERIALIZE_SCALAR(regs
.tesr
);
2163 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2164 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2166 SERIALIZE_SCALAR(ioEnable
);
2169 * Serialize the data Fifos
2171 rxFifo
.serialize("rxFifo", os
);
2172 txFifo
.serialize("txFifo", os
);
2175 * Serialize the various helper variables
2177 bool txPacketExists
= txPacket
;
2178 SERIALIZE_SCALAR(txPacketExists
);
2179 if (txPacketExists
) {
2180 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2181 txPacket
->serialize("txPacket", os
);
2182 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2183 SERIALIZE_SCALAR(txPktBufPtr
);
2186 bool rxPacketExists
= rxPacket
;
2187 SERIALIZE_SCALAR(rxPacketExists
);
2188 if (rxPacketExists
) {
2189 rxPacket
->serialize("rxPacket", os
);
2190 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2191 SERIALIZE_SCALAR(rxPktBufPtr
);
2194 SERIALIZE_SCALAR(txXferLen
);
2195 SERIALIZE_SCALAR(rxXferLen
);
2198 * Serialize Cached Descriptors
2200 SERIALIZE_SCALAR(rxDesc64
.link
);
2201 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2202 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2203 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2204 SERIALIZE_SCALAR(txDesc64
.link
);
2205 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2206 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2207 SERIALIZE_SCALAR(txDesc64
.extsts
);
2208 SERIALIZE_SCALAR(rxDesc32
.link
);
2209 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2210 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2211 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2212 SERIALIZE_SCALAR(txDesc32
.link
);
2213 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2214 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2215 SERIALIZE_SCALAR(txDesc32
.extsts
);
2216 SERIALIZE_SCALAR(extstsEnable
);
2219 * Serialize tx state machine
2221 int txState
= this->txState
;
2222 SERIALIZE_SCALAR(txState
);
2223 SERIALIZE_SCALAR(txEnable
);
2224 SERIALIZE_SCALAR(CTDD
);
2225 SERIALIZE_SCALAR(txFragPtr
);
2226 SERIALIZE_SCALAR(txDescCnt
);
2227 int txDmaState
= this->txDmaState
;
2228 SERIALIZE_SCALAR(txDmaState
);
2229 SERIALIZE_SCALAR(txKickTick
);
2232 * Serialize rx state machine
2234 int rxState
= this->rxState
;
2235 SERIALIZE_SCALAR(rxState
);
2236 SERIALIZE_SCALAR(rxEnable
);
2237 SERIALIZE_SCALAR(CRDD
);
2238 SERIALIZE_SCALAR(rxPktBytes
);
2239 SERIALIZE_SCALAR(rxFragPtr
);
2240 SERIALIZE_SCALAR(rxDescCnt
);
2241 int rxDmaState
= this->rxDmaState
;
2242 SERIALIZE_SCALAR(rxDmaState
);
2243 SERIALIZE_SCALAR(rxKickTick
);
2246 * Serialize EEPROM state machine
2248 int eepromState
= this->eepromState
;
2249 SERIALIZE_SCALAR(eepromState
);
2250 SERIALIZE_SCALAR(eepromClk
);
2251 SERIALIZE_SCALAR(eepromBitsToRx
);
2252 SERIALIZE_SCALAR(eepromOpcode
);
2253 SERIALIZE_SCALAR(eepromAddress
);
2254 SERIALIZE_SCALAR(eepromData
);
2257 * If there's a pending transmit, store the time so we can
2258 * reschedule it later
2260 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick
: 0;
2261 SERIALIZE_SCALAR(transmitTick
);
2264 * receive address filter settings
2266 SERIALIZE_SCALAR(rxFilterEnable
);
2267 SERIALIZE_SCALAR(acceptBroadcast
);
2268 SERIALIZE_SCALAR(acceptMulticast
);
2269 SERIALIZE_SCALAR(acceptUnicast
);
2270 SERIALIZE_SCALAR(acceptPerfect
);
2271 SERIALIZE_SCALAR(acceptArp
);
2272 SERIALIZE_SCALAR(multicastHashEnable
);
2275 * Keep track of pending interrupt status.
2277 SERIALIZE_SCALAR(intrTick
);
2278 SERIALIZE_SCALAR(cpuPendingIntr
);
2279 Tick intrEventTick
= 0;
2281 intrEventTick
= intrEvent
->when();
2282 SERIALIZE_SCALAR(intrEventTick
);
2287 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2289 // Unserialize the PciDev base class
2290 PciDev::unserialize(cp
, section
);
2292 UNSERIALIZE_SCALAR(regs
.command
);
2293 UNSERIALIZE_SCALAR(regs
.config
);
2294 UNSERIALIZE_SCALAR(regs
.mear
);
2295 UNSERIALIZE_SCALAR(regs
.ptscr
);
2296 UNSERIALIZE_SCALAR(regs
.isr
);
2297 UNSERIALIZE_SCALAR(regs
.imr
);
2298 UNSERIALIZE_SCALAR(regs
.ier
);
2299 UNSERIALIZE_SCALAR(regs
.ihr
);
2300 UNSERIALIZE_SCALAR(regs
.txdp
);
2301 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2302 UNSERIALIZE_SCALAR(regs
.txcfg
);
2303 UNSERIALIZE_SCALAR(regs
.gpior
);
2304 UNSERIALIZE_SCALAR(regs
.rxdp
);
2305 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2306 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2307 UNSERIALIZE_SCALAR(regs
.pqcr
);
2308 UNSERIALIZE_SCALAR(regs
.wcsr
);
2309 UNSERIALIZE_SCALAR(regs
.pcr
);
2310 UNSERIALIZE_SCALAR(regs
.rfcr
);
2311 UNSERIALIZE_SCALAR(regs
.rfdr
);
2312 UNSERIALIZE_SCALAR(regs
.brar
);
2313 UNSERIALIZE_SCALAR(regs
.brdr
);
2314 UNSERIALIZE_SCALAR(regs
.srr
);
2315 UNSERIALIZE_SCALAR(regs
.mibc
);
2316 UNSERIALIZE_SCALAR(regs
.vrcr
);
2317 UNSERIALIZE_SCALAR(regs
.vtcr
);
2318 UNSERIALIZE_SCALAR(regs
.vdr
);
2319 UNSERIALIZE_SCALAR(regs
.ccsr
);
2320 UNSERIALIZE_SCALAR(regs
.tbicr
);
2321 UNSERIALIZE_SCALAR(regs
.tbisr
);
2322 UNSERIALIZE_SCALAR(regs
.tanar
);
2323 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2324 UNSERIALIZE_SCALAR(regs
.taner
);
2325 UNSERIALIZE_SCALAR(regs
.tesr
);
2327 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2328 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2330 UNSERIALIZE_SCALAR(ioEnable
);
2333 * unserialize the data fifos
2335 rxFifo
.unserialize("rxFifo", cp
, section
);
2336 txFifo
.unserialize("txFifo", cp
, section
);
2339 * unserialize the various helper variables
2341 bool txPacketExists
;
2342 UNSERIALIZE_SCALAR(txPacketExists
);
2343 if (txPacketExists
) {
2344 txPacket
= new EthPacketData(16384);
2345 txPacket
->unserialize("txPacket", cp
, section
);
2346 uint32_t txPktBufPtr
;
2347 UNSERIALIZE_SCALAR(txPktBufPtr
);
2348 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2352 bool rxPacketExists
;
2353 UNSERIALIZE_SCALAR(rxPacketExists
);
2355 if (rxPacketExists
) {
2356 rxPacket
= new EthPacketData(16384);
2357 rxPacket
->unserialize("rxPacket", cp
, section
);
2358 uint32_t rxPktBufPtr
;
2359 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2360 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2364 UNSERIALIZE_SCALAR(txXferLen
);
2365 UNSERIALIZE_SCALAR(rxXferLen
);
2368 * Unserialize Cached Descriptors
2370 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2371 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2372 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2373 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2374 UNSERIALIZE_SCALAR(txDesc64
.link
);
2375 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2376 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2377 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2378 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2379 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2380 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2381 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2382 UNSERIALIZE_SCALAR(txDesc32
.link
);
2383 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2384 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2385 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2386 UNSERIALIZE_SCALAR(extstsEnable
);
2389 * unserialize tx state machine
2392 UNSERIALIZE_SCALAR(txState
);
2393 this->txState
= (TxState
) txState
;
2394 UNSERIALIZE_SCALAR(txEnable
);
2395 UNSERIALIZE_SCALAR(CTDD
);
2396 UNSERIALIZE_SCALAR(txFragPtr
);
2397 UNSERIALIZE_SCALAR(txDescCnt
);
2399 UNSERIALIZE_SCALAR(txDmaState
);
2400 this->txDmaState
= (DmaState
) txDmaState
;
2401 UNSERIALIZE_SCALAR(txKickTick
);
2403 txKickEvent
.schedule(txKickTick
);
2406 * unserialize rx state machine
2409 UNSERIALIZE_SCALAR(rxState
);
2410 this->rxState
= (RxState
) rxState
;
2411 UNSERIALIZE_SCALAR(rxEnable
);
2412 UNSERIALIZE_SCALAR(CRDD
);
2413 UNSERIALIZE_SCALAR(rxPktBytes
);
2414 UNSERIALIZE_SCALAR(rxFragPtr
);
2415 UNSERIALIZE_SCALAR(rxDescCnt
);
2417 UNSERIALIZE_SCALAR(rxDmaState
);
2418 this->rxDmaState
= (DmaState
) rxDmaState
;
2419 UNSERIALIZE_SCALAR(rxKickTick
);
2421 rxKickEvent
.schedule(rxKickTick
);
2424 * Unserialize EEPROM state machine
2427 UNSERIALIZE_SCALAR(eepromState
);
2428 this->eepromState
= (EEPROMState
) eepromState
;
2429 UNSERIALIZE_SCALAR(eepromClk
);
2430 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2431 UNSERIALIZE_SCALAR(eepromOpcode
);
2432 UNSERIALIZE_SCALAR(eepromAddress
);
2433 UNSERIALIZE_SCALAR(eepromData
);
2436 * If there's a pending transmit, reschedule it now
2439 UNSERIALIZE_SCALAR(transmitTick
);
2441 txEvent
.schedule(curTick
+ transmitTick
);
2444 * unserialize receive address filter settings
2446 UNSERIALIZE_SCALAR(rxFilterEnable
);
2447 UNSERIALIZE_SCALAR(acceptBroadcast
);
2448 UNSERIALIZE_SCALAR(acceptMulticast
);
2449 UNSERIALIZE_SCALAR(acceptUnicast
);
2450 UNSERIALIZE_SCALAR(acceptPerfect
);
2451 UNSERIALIZE_SCALAR(acceptArp
);
2452 UNSERIALIZE_SCALAR(multicastHashEnable
);
2455 * Keep track of pending interrupt status.
2457 UNSERIALIZE_SCALAR(intrTick
);
2458 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2460 UNSERIALIZE_SCALAR(intrEventTick
);
2461 if (intrEventTick
) {
2462 intrEvent
= new IntrEvent(this, intrEventTick
, true);
2467 NSGigEParams::create()
2469 return new NSGigE(this);