1a5adb2754c8ba2fbbf3441484561c9bd8b155ba
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
37 #include "dev/net/ns_gige.hh"
43 #include "base/debug.hh"
44 #include "base/inet.hh"
45 #include "base/types.hh"
46 #include "config/the_isa.hh"
47 #include "debug/EthernetAll.hh"
48 #include "dev/net/etherlink.hh"
49 #include "mem/packet.hh"
50 #include "mem/packet_access.hh"
51 #include "params/NSGigE.hh"
52 #include "sim/system.hh"
54 // clang complains about std::set being overloaded with Packet::set if
55 // we open up the entire namespace std
56 using std::make_shared
;
61 const char *NsRxStateStrings
[] =
72 const char *NsTxStateStrings
[] =
83 const char *NsDmaState
[] =
93 using namespace TheISA
;
95 ///////////////////////////////////////////////////////////////////////
99 NSGigE::NSGigE(Params
*p
)
100 : EtherDevBase(p
), ioEnable(false),
101 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
102 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
103 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
104 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
105 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
106 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
107 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
108 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
109 eepromOpcode(0), eepromAddress(0), eepromData(0),
110 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
111 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
112 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
113 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
114 rxDmaReadEvent([this]{ rxDmaReadDone(); }, name()),
115 rxDmaWriteEvent([this]{ rxDmaWriteDone(); }, name()),
116 txDmaReadEvent([this]{ txDmaReadDone(); }, name()),
117 txDmaWriteEvent([this]{ txDmaWriteDone(); }, name()),
118 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
119 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
121 rxKickEvent([this]{ rxKick(); }, name()),
123 txKickEvent([this]{ txKick(); }, name()),
124 txEvent([this]{ txEventTransmit(); }, name()),
125 rxFilterEnable(p
->rx_filter
),
126 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
127 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
128 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
129 intrEvent(0), interface(0)
133 interface
= new NSGigEInt(name() + ".int0", this);
136 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
138 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
139 memset(&txDesc32
, 0, sizeof(txDesc32
));
140 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
141 memset(&txDesc64
, 0, sizeof(txDesc64
));
150 * This is to write to the PCI general configuration registers
153 NSGigE::writeConfig(PacketPtr pkt
)
155 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
156 if (offset
< PCI_DEVICE_SPECIFIC
)
157 PciDevice::writeConfig(pkt
);
159 panic("Device specific PCI config space not implemented!\n");
162 // seems to work fine without all these PCI settings, but i
163 // put in the IO to double check, an assertion will fail if we
164 // need to properly implement it
166 if (config
.data
[offset
] & PCI_CMD_IOSE
)
177 NSGigE::getEthPort(const std::string
&if_name
, int idx
)
179 if (if_name
== "interface") {
180 if (interface
->getPeer())
181 panic("interface already connected to\n");
188 * This reads the device registers, which are detailed in the NS83820
192 NSGigE::read(PacketPtr pkt
)
196 //The mask is to give you only the offset into the device register file
197 Addr daddr
= pkt
->getAddr() & 0xfff;
198 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
199 daddr
, pkt
->getAddr(), pkt
->getSize());
202 // there are some reserved registers, you can see ns_gige_reg.h and
203 // the spec sheet for details
204 if (daddr
> LAST
&& daddr
<= RESERVED
) {
205 panic("Accessing reserved register");
206 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
207 return readConfig(pkt
);
208 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
209 // don't implement all the MIB's. hopefully the kernel
210 // doesn't actually DEPEND upon their values
211 // MIB are just hardware stats keepers
212 pkt
->setLE
<uint32_t>(0);
213 pkt
->makeAtomicResponse();
215 } else if (daddr
> 0x3FC)
216 panic("Something is messed up!\n");
218 assert(pkt
->getSize() == sizeof(uint32_t));
219 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
225 //these are supposed to be cleared on a read
226 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
243 devIntrClear(ISR_ALL
);
298 // see the spec sheet for how RFCR and RFDR work
299 // basically, you write to RFCR to tell the machine
300 // what you want to do next, then you act upon RFDR,
301 // and the device will be prepared b/c of what you
308 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
310 // Read from perfect match ROM octets
312 reg
= rom
.perfectMatch
[1];
314 reg
+= rom
.perfectMatch
[0];
317 reg
= rom
.perfectMatch
[3] << 8;
318 reg
+= rom
.perfectMatch
[2];
321 reg
= rom
.perfectMatch
[5] << 8;
322 reg
+= rom
.perfectMatch
[4];
325 // Read filter hash table
326 if (rfaddr
>= FHASH_ADDR
&&
327 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
329 // Only word-aligned reads supported
331 panic("unaligned read from filter hash table!");
333 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
334 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
338 panic("reading RFDR for something other than pattern"
339 " matching or hashing! %#x\n", rfaddr
);
349 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
394 if (params()->rx_thread
)
395 reg
|= M5REG_RX_THREAD
;
396 if (params()->tx_thread
)
397 reg
|= M5REG_TX_THREAD
;
403 panic("reading unimplemented register: addr=%#x", daddr
);
406 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
409 pkt
->makeAtomicResponse();
414 NSGigE::write(PacketPtr pkt
)
418 Addr daddr
= pkt
->getAddr() & 0xfff;
419 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
420 daddr
, pkt
->getAddr(), pkt
->getSize());
422 if (daddr
> LAST
&& daddr
<= RESERVED
) {
423 panic("Accessing reserved register");
424 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
425 return writeConfig(pkt
);
426 } else if (daddr
> 0x3FC)
427 panic("Something is messed up!\n");
429 if (pkt
->getSize() == sizeof(uint32_t)) {
430 uint32_t reg
= pkt
->getLE
<uint32_t>();
433 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
440 } else if (reg
& CR_TXE
) {
443 // the kernel is enabling the transmit machine
444 if (txState
== txIdle
)
450 } else if (reg
& CR_RXE
) {
453 if (rxState
== rxIdle
)
464 devIntrPost(ISR_SWI
);
475 if (reg
& CFGR_LNKSTS
||
478 reg
& CFGR_RESERVED
||
479 reg
& CFGR_T64ADDR
||
480 reg
& CFGR_PCI64_DET
) {
481 // First clear all writable bits
482 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
483 CFGR_RESERVED
| CFGR_T64ADDR
|
485 // Now set the appropriate writable bits
486 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
487 CFGR_RESERVED
| CFGR_T64ADDR
|
491 // all these #if 0's are because i don't THINK the kernel needs to
492 // have these implemented. if there is a problem relating to one of
493 // these, you may need to add functionality in.
495 // grouped together and #if 0'ed to avoid empty if body and make clang happy
497 if (reg
& CFGR_TBI_EN
) ;
498 if (reg
& CFGR_MODE_1000
) ;
500 if (reg
& CFGR_PINT_DUPSTS
||
501 reg
& CFGR_PINT_LNKSTS
||
502 reg
& CFGR_PINT_SPDSTS
)
505 if (reg
& CFGR_TMRTEST
) ;
506 if (reg
& CFGR_MRM_DIS
) ;
507 if (reg
& CFGR_MWI_DIS
) ;
509 if (reg
& CFGR_DATA64_EN
) ;
510 if (reg
& CFGR_M64ADDR
) ;
511 if (reg
& CFGR_PHY_RST
) ;
512 if (reg
& CFGR_PHY_DIS
) ;
514 if (reg
& CFGR_REQALG
) ;
516 if (reg
& CFGR_POW
) ;
517 if (reg
& CFGR_EXD
) ;
518 if (reg
& CFGR_PESEL
) ;
519 if (reg
& CFGR_BROM_DIS
) ;
520 if (reg
& CFGR_EXT_125
) ;
521 if (reg
& CFGR_BEM
) ;
523 if (reg
& CFGR_T64ADDR
) ;
524 // panic("CFGR_T64ADDR is read only register!\n");
526 if (reg
& CFGR_AUTO_1000
)
527 panic("CFGR_AUTO_1000 not implemented!\n");
529 if (reg
& CFGR_PCI64_DET
)
530 panic("CFGR_PCI64_DET is read only register!\n");
532 if (reg
& CFGR_EXTSTS_EN
)
535 extstsEnable
= false;
539 // Clear writable bits
540 regs
.mear
&= MEAR_EEDO
;
541 // Set appropriate writable bits
542 regs
.mear
|= reg
& ~MEAR_EEDO
;
544 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
545 // even though it could get it through RFDR
546 if (reg
& MEAR_EESEL
) {
547 // Rising edge of clock
548 if (reg
& MEAR_EECLK
&& !eepromClk
)
552 eepromState
= eepromStart
;
553 regs
.mear
&= ~MEAR_EEDI
;
556 eepromClk
= reg
& MEAR_EECLK
;
558 // since phy is completely faked, MEAR_MD* don't matter
560 // grouped together and #if 0'ed to avoid empty if body and make clang happy
562 if (reg
& MEAR_MDIO
) ;
563 if (reg
& MEAR_MDDIR
) ;
564 if (reg
& MEAR_MDC
) ;
569 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
570 // these control BISTs for various parts of chip - we
571 // don't care or do just fake that the BIST is done
572 if (reg
& PTSCR_RBIST_EN
)
573 regs
.ptscr
|= PTSCR_RBIST_DONE
;
574 if (reg
& PTSCR_EEBIST_EN
)
575 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
576 if (reg
& PTSCR_EELOAD_EN
)
577 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
580 case ISR
: /* writing to the ISR has no effect */
581 panic("ISR is a read only register!\n");
594 /* not going to implement real interrupt holdoff */
598 regs
.txdp
= (reg
& 0xFFFFFFFC);
599 assert(txState
== txIdle
);
610 if (reg
& TX_CFG_CSI
) ;
611 if (reg
& TX_CFG_HBI
) ;
612 if (reg
& TX_CFG_MLB
) ;
613 if (reg
& TX_CFG_ATP
) ;
614 if (reg
& TX_CFG_ECRETRY
) {
616 * this could easily be implemented, but considering
617 * the network is just a fake pipe, wouldn't make
622 if (reg
& TX_CFG_BRST_DIS
) ;
626 /* we handle our own DMA, ignore the kernel's exhortations */
627 if (reg
& TX_CFG_MXDMA
) ;
630 // also, we currently don't care about fill/drain
631 // thresholds though this may change in the future with
632 // more realistic networks or a driver which changes it
633 // according to feedback
638 // Only write writable bits
639 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
640 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
641 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
642 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
643 /* these just control general purpose i/o pins, don't matter */
658 if (reg
& RX_CFG_AEP
) ;
659 if (reg
& RX_CFG_ARP
) ;
660 if (reg
& RX_CFG_STRIPCRC
) ;
661 if (reg
& RX_CFG_RX_RD
) ;
662 if (reg
& RX_CFG_ALP
) ;
663 if (reg
& RX_CFG_AIRL
) ;
665 /* we handle our own DMA, ignore what kernel says about it */
666 if (reg
& RX_CFG_MXDMA
) ;
668 //also, we currently don't care about fill/drain thresholds
669 //though this may change in the future with more realistic
670 //networks or a driver which changes it according to feedback
671 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
676 /* there is no priority queueing used in the linux 2.6 driver */
681 /* not going to implement wake on LAN */
686 /* not going to implement pause control */
693 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
694 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
695 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
696 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
697 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
698 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
699 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
703 panic("RFCR_APAT not implemented!\n");
706 panic("Unicast hash filtering not used by drivers!\n");
709 panic("RFCR_ULM not implemented!\n");
714 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
717 rom
.perfectMatch
[0] = (uint8_t)reg
;
718 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
721 rom
.perfectMatch
[2] = (uint8_t)reg
;
722 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
725 rom
.perfectMatch
[4] = (uint8_t)reg
;
726 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
730 if (rfaddr
>= FHASH_ADDR
&&
731 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
733 // Only word-aligned writes supported
735 panic("unaligned write to filter hash table!");
737 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
738 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
739 = (uint8_t)(reg
>> 8);
742 panic("writing RFDR for something other than pattern matching "
743 "or hashing! %#x\n", rfaddr
);
752 panic("the driver never uses BRDR, something is wrong!\n");
755 panic("SRR is read only register!\n");
758 panic("the driver never uses MIBC, something is wrong!\n");
769 panic("the driver never uses VDR, something is wrong!\n");
772 /* not going to implement clockrun stuff */
778 if (reg
& TBICR_MR_LOOPBACK
)
779 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
781 if (reg
& TBICR_MR_AN_ENABLE
) {
782 regs
.tanlpar
= regs
.tanar
;
783 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
787 if (reg
& TBICR_MR_RESTART_AN
) ;
793 panic("TBISR is read only register!\n");
796 // Only write the writable bits
797 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
798 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
800 // Pause capability unimplemented
802 if (reg
& TANAR_PS2
) ;
803 if (reg
& TANAR_PS1
) ;
809 panic("this should only be written to by the fake phy!\n");
812 panic("TANER is read only register!\n");
819 panic("invalid register access daddr=%#x", daddr
);
822 panic("Invalid Request Size");
824 pkt
->makeAtomicResponse();
829 NSGigE::devIntrPost(uint32_t interrupts
)
831 if (interrupts
& ISR_RESERVE
)
832 panic("Cannot set a reserved interrupt");
834 if (interrupts
& ISR_NOIMPL
)
835 warn("interrupt not implemented %#x\n", interrupts
);
837 interrupts
&= ISR_IMPL
;
838 regs
.isr
|= interrupts
;
840 if (interrupts
& regs
.imr
) {
841 if (interrupts
& ISR_SWI
) {
844 if (interrupts
& ISR_RXIDLE
) {
847 if (interrupts
& ISR_RXOK
) {
850 if (interrupts
& ISR_RXDESC
) {
853 if (interrupts
& ISR_TXOK
) {
856 if (interrupts
& ISR_TXIDLE
) {
859 if (interrupts
& ISR_TXDESC
) {
862 if (interrupts
& ISR_RXORN
) {
867 DPRINTF(EthernetIntr
,
868 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
869 interrupts
, regs
.isr
, regs
.imr
);
871 if ((regs
.isr
& regs
.imr
)) {
872 Tick when
= curTick();
873 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
880 /* writing this interrupt counting stats inside this means that this function
881 is now limited to being used to clear all interrupts upon the kernel
882 reading isr and servicing. just telling you in case you were thinking
886 NSGigE::devIntrClear(uint32_t interrupts
)
888 if (interrupts
& ISR_RESERVE
)
889 panic("Cannot clear a reserved interrupt");
891 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
894 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
897 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
900 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
903 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
906 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
909 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
912 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
916 interrupts
&= ~ISR_NOIMPL
;
917 regs
.isr
&= ~interrupts
;
919 DPRINTF(EthernetIntr
,
920 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
921 interrupts
, regs
.isr
, regs
.imr
);
923 if (!(regs
.isr
& regs
.imr
))
928 NSGigE::devIntrChangeMask()
930 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
931 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
933 if (regs
.isr
& regs
.imr
)
934 cpuIntrPost(curTick());
940 NSGigE::cpuIntrPost(Tick when
)
942 // If the interrupt you want to post is later than an interrupt
943 // already scheduled, just let it post in the coming one and don't
945 // HOWEVER, must be sure that the scheduled intrTick is in the
946 // future (this was formerly the source of a bug)
948 * @todo this warning should be removed and the intrTick code should
951 assert(when
>= curTick());
952 assert(intrTick
>= curTick() || intrTick
== 0);
953 if (when
> intrTick
&& intrTick
!= 0) {
954 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
960 if (intrTick
< curTick()) {
961 intrTick
= curTick();
964 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
970 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
972 schedule(intrEvent
, intrTick
);
976 NSGigE::cpuInterrupt()
978 assert(intrTick
== curTick());
980 // Whether or not there's a pending interrupt, we don't care about
985 // Don't send an interrupt if there's already one
986 if (cpuPendingIntr
) {
987 DPRINTF(EthernetIntr
,
988 "would send an interrupt now, but there's already pending\n");
991 cpuPendingIntr
= true;
993 DPRINTF(EthernetIntr
, "posting interrupt\n");
999 NSGigE::cpuIntrClear()
1001 if (!cpuPendingIntr
)
1005 intrEvent
->squash();
1011 cpuPendingIntr
= false;
1013 DPRINTF(EthernetIntr
, "clearing interrupt\n");
1018 NSGigE::cpuIntrPending() const
1019 { return cpuPendingIntr
; }
1025 DPRINTF(Ethernet
, "transmit reset\n");
1030 assert(txDescCnt
== 0);
1033 assert(txDmaState
== dmaIdle
);
1039 DPRINTF(Ethernet
, "receive reset\n");
1042 assert(rxPktBytes
== 0);
1045 assert(rxDescCnt
== 0);
1046 assert(rxDmaState
== dmaIdle
);
1054 memset(®s
, 0, sizeof(regs
));
1055 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1057 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1058 // fill threshold to 32 bytes
1059 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1060 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1061 regs
.mibc
= MIBC_FRZ
;
1062 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1063 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1064 regs
.brar
= 0xffffffff;
1066 extstsEnable
= false;
1067 acceptBroadcast
= false;
1068 acceptMulticast
= false;
1069 acceptUnicast
= false;
1070 acceptPerfect
= false;
1075 NSGigE::doRxDmaRead()
1077 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1078 rxDmaState
= dmaReading
;
1080 if (dmaPending() || drainState() != DrainState::Running
)
1081 rxDmaState
= dmaReadWaiting
;
1083 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1089 NSGigE::rxDmaReadDone()
1091 assert(rxDmaState
== dmaReading
);
1092 rxDmaState
= dmaIdle
;
1094 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1095 rxDmaAddr
, rxDmaLen
);
1096 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1098 // If the transmit state machine has a pending DMA, let it go first
1099 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1106 NSGigE::doRxDmaWrite()
1108 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1109 rxDmaState
= dmaWriting
;
1111 if (dmaPending() || drainState() != DrainState::Running
)
1112 rxDmaState
= dmaWriteWaiting
;
1114 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1119 NSGigE::rxDmaWriteDone()
1121 assert(rxDmaState
== dmaWriting
);
1122 rxDmaState
= dmaIdle
;
1124 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1125 rxDmaAddr
, rxDmaLen
);
1126 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1128 // If the transmit state machine has a pending DMA, let it go first
1129 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1138 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1141 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1142 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1145 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1146 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1149 if (rxKickTick
> curTick()) {
1150 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1156 // Go to the next state machine clock tick.
1157 rxKickTick
= clockEdge(Cycles(1));
1159 switch(rxDmaState
) {
1160 case dmaReadWaiting
:
1164 case dmaWriteWaiting
:
1172 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1173 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1175 // see state machine from spec for details
1176 // the way this works is, if you finish work on one state and can
1177 // go directly to another, you do that through jumping to the
1178 // label "next". however, if you have intermediate work, like DMA
1179 // so that you can't go to the next state yet, you go to exit and
1180 // exit the loop. however, when the DMA is done it will trigger
1181 // an event and come back to this loop.
1185 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1190 rxState
= rxDescRefr
;
1192 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1194 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1195 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1196 rxDmaFree
= dmaDescFree
;
1199 descDmaRdBytes
+= rxDmaLen
;
1204 rxState
= rxDescRead
;
1206 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1207 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1208 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1209 rxDmaFree
= dmaDescFree
;
1212 descDmaRdBytes
+= rxDmaLen
;
1220 if (rxDmaState
!= dmaIdle
)
1223 rxState
= rxAdvance
;
1227 if (rxDmaState
!= dmaIdle
)
1230 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1231 regs
.rxdp
& 0x3fffffff);
1232 DPRINTF(EthernetDesc
,
1233 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1234 link
, bufptr
, cmdsts
, extsts
);
1236 if (cmdsts
& CMDSTS_OWN
) {
1237 devIntrPost(ISR_RXIDLE
);
1241 rxState
= rxFifoBlock
;
1243 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1250 * @todo in reality, we should be able to start processing
1251 * the packet as it arrives, and not have to wait for the
1252 * full packet ot be in the receive fifo.
1257 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1259 // If we don't have a packet, grab a new one from the fifo.
1260 rxPacket
= rxFifo
.front();
1261 rxPktBytes
= rxPacket
->length
;
1262 rxPacketBufPtr
= rxPacket
->data
;
1265 if (DTRACE(Ethernet
)) {
1268 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1272 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1273 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1280 // sanity check - i think the driver behaves like this
1281 assert(rxDescCnt
>= rxPktBytes
);
1286 // dont' need the && rxDescCnt > 0 if driver sanity check
1288 if (rxPktBytes
> 0) {
1289 rxState
= rxFragWrite
;
1290 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1292 rxXferLen
= rxPktBytes
;
1294 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1295 rxDmaData
= rxPacketBufPtr
;
1296 rxDmaLen
= rxXferLen
;
1297 rxDmaFree
= dmaDataFree
;
1303 rxState
= rxDescWrite
;
1305 //if (rxPktBytes == 0) { /* packet is done */
1306 assert(rxPktBytes
== 0);
1307 DPRINTF(EthernetSM
, "done with receiving packet\n");
1309 cmdsts
|= CMDSTS_OWN
;
1310 cmdsts
&= ~CMDSTS_MORE
;
1311 cmdsts
|= CMDSTS_OK
;
1312 cmdsts
&= 0xffff0000;
1313 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1317 * all the driver uses these are for its own stats keeping
1318 * which we don't care about, aren't necessary for
1319 * functionality and doing this would just slow us down.
1320 * if they end up using this in a later version for
1321 * functional purposes, just undef
1323 if (rxFilterEnable
) {
1324 cmdsts
&= ~CMDSTS_DEST_MASK
;
1325 const EthAddr
&dst
= rxFifoFront()->dst();
1327 cmdsts
|= CMDSTS_DEST_SELF
;
1328 if (dst
->multicast())
1329 cmdsts
|= CMDSTS_DEST_MULTI
;
1330 if (dst
->broadcast())
1331 cmdsts
|= CMDSTS_DEST_MASK
;
1336 if (extstsEnable
&& ip
) {
1337 extsts
|= EXTSTS_IPPKT
;
1339 if (cksum(ip
) != 0) {
1340 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1341 extsts
|= EXTSTS_IPERR
;
1346 extsts
|= EXTSTS_TCPPKT
;
1348 if (cksum(tcp
) != 0) {
1349 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1350 extsts
|= EXTSTS_TCPERR
;
1354 extsts
|= EXTSTS_UDPPKT
;
1356 if (cksum(udp
) != 0) {
1357 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1358 extsts
|= EXTSTS_UDPERR
;
1365 * the driver seems to always receive into desc buffers
1366 * of size 1514, so you never have a pkt that is split
1367 * into multiple descriptors on the receive side, so
1368 * i don't implement that case, hence the assert above.
1371 DPRINTF(EthernetDesc
,
1372 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1373 regs
.rxdp
& 0x3fffffff);
1374 DPRINTF(EthernetDesc
,
1375 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1376 link
, bufptr
, cmdsts
, extsts
);
1378 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1379 rxDmaData
= &cmdsts
;
1381 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1382 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1384 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1385 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1387 rxDmaFree
= dmaDescFree
;
1390 descDmaWrBytes
+= rxDmaLen
;
1398 if (rxDmaState
!= dmaIdle
)
1401 rxPacketBufPtr
+= rxXferLen
;
1402 rxFragPtr
+= rxXferLen
;
1403 rxPktBytes
-= rxXferLen
;
1405 rxState
= rxFifoBlock
;
1409 if (rxDmaState
!= dmaIdle
)
1412 assert(cmdsts
& CMDSTS_OWN
);
1414 assert(rxPacket
== 0);
1415 devIntrPost(ISR_RXOK
);
1417 if (cmdsts
& CMDSTS_INTR
)
1418 devIntrPost(ISR_RXDESC
);
1421 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1425 rxState
= rxAdvance
;
1430 devIntrPost(ISR_RXIDLE
);
1435 if (rxDmaState
!= dmaIdle
)
1437 rxState
= rxDescRead
;
1441 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1442 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1443 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1444 rxDmaFree
= dmaDescFree
;
1452 panic("Invalid rxState!");
1455 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1456 NsRxStateStrings
[rxState
]);
1461 * @todo do we want to schedule a future kick?
1463 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1464 NsRxStateStrings
[rxState
]);
1466 if (!rxKickEvent
.scheduled())
1467 schedule(rxKickEvent
, rxKickTick
);
1473 if (txFifo
.empty()) {
1474 DPRINTF(Ethernet
, "nothing to transmit\n");
1478 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1480 if (interface
->sendPacket(txFifo
.front())) {
1482 if (DTRACE(Ethernet
)) {
1483 IpPtr
ip(txFifo
.front());
1485 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1489 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1490 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1497 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1498 txBytes
+= txFifo
.front()->length
;
1501 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1506 * normally do a writeback of the descriptor here, and ONLY
1507 * after that is done, send this interrupt. but since our
1508 * stuff never actually fails, just do this interrupt here,
1509 * otherwise the code has to stray from this nice format.
1510 * besides, it's functionally the same.
1512 devIntrPost(ISR_TXOK
);
1515 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1516 DPRINTF(Ethernet
, "reschedule transmit\n");
1517 schedule(txEvent
, curTick() + retryTime
);
1522 NSGigE::doTxDmaRead()
1524 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1525 txDmaState
= dmaReading
;
1527 if (dmaPending() || drainState() != DrainState::Running
)
1528 txDmaState
= dmaReadWaiting
;
1530 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1536 NSGigE::txDmaReadDone()
1538 assert(txDmaState
== dmaReading
);
1539 txDmaState
= dmaIdle
;
1541 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1542 txDmaAddr
, txDmaLen
);
1543 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1545 // If the receive state machine has a pending DMA, let it go first
1546 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1553 NSGigE::doTxDmaWrite()
1555 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1556 txDmaState
= dmaWriting
;
1558 if (dmaPending() || drainState() != DrainState::Running
)
1559 txDmaState
= dmaWriteWaiting
;
1561 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1566 NSGigE::txDmaWriteDone()
1568 assert(txDmaState
== dmaWriting
);
1569 txDmaState
= dmaIdle
;
1571 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1572 txDmaAddr
, txDmaLen
);
1573 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1575 // If the receive state machine has a pending DMA, let it go first
1576 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1585 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1587 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1588 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1591 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1592 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1595 if (txKickTick
> curTick()) {
1596 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1601 // Go to the next state machine clock tick.
1602 txKickTick
= clockEdge(Cycles(1));
1604 switch(txDmaState
) {
1605 case dmaReadWaiting
:
1609 case dmaWriteWaiting
:
1617 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1618 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1622 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1627 txState
= txDescRefr
;
1629 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1631 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1632 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1633 txDmaFree
= dmaDescFree
;
1636 descDmaRdBytes
+= txDmaLen
;
1642 txState
= txDescRead
;
1644 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1645 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1646 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1647 txDmaFree
= dmaDescFree
;
1650 descDmaRdBytes
+= txDmaLen
;
1658 if (txDmaState
!= dmaIdle
)
1661 txState
= txAdvance
;
1665 if (txDmaState
!= dmaIdle
)
1668 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1669 regs
.txdp
& 0x3fffffff);
1670 DPRINTF(EthernetDesc
,
1671 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1672 link
, bufptr
, cmdsts
, extsts
);
1674 if (cmdsts
& CMDSTS_OWN
) {
1675 txState
= txFifoBlock
;
1677 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1679 devIntrPost(ISR_TXIDLE
);
1687 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1688 txPacket
= make_shared
<EthPacketData
>(16384);
1689 txPacketBufPtr
= txPacket
->data
;
1692 if (txDescCnt
== 0) {
1693 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1694 if (cmdsts
& CMDSTS_MORE
) {
1695 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
1696 txState
= txDescWrite
;
1698 cmdsts
&= ~CMDSTS_OWN
;
1700 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1701 txDmaData
= &cmdsts
;
1703 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1704 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1706 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1707 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1709 txDmaFree
= dmaDescFree
;
1714 } else { /* this packet is totally done */
1715 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
1716 /* deal with the the packet that just finished */
1717 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
1719 if (extsts
& EXTSTS_UDPPKT
) {
1723 udp
->sum(cksum(udp
));
1726 Debug::breakpoint();
1727 warn_once("UDPPKT set, but not UDP!\n");
1729 } else if (extsts
& EXTSTS_TCPPKT
) {
1733 tcp
->sum(cksum(tcp
));
1736 warn_once("TCPPKT set, but not UDP!\n");
1739 if (extsts
& EXTSTS_IPPKT
) {
1745 warn_once("IPPKT set, but not UDP!\n");
1750 txPacket
->simLength
= txPacketBufPtr
- txPacket
->data
;
1751 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
1752 // this is just because the receive can't handle a
1753 // packet bigger want to make sure
1754 if (txPacket
->length
> 1514)
1755 panic("transmit packet too large, %s > 1514\n",
1761 txFifo
.push(txPacket
);
1765 * this following section is not tqo spec, but
1766 * functionally shouldn't be any different. normally,
1767 * the chip will wait til the transmit has occurred
1768 * before writing back the descriptor because it has
1769 * to wait to see that it was successfully transmitted
1770 * to decide whether to set CMDSTS_OK or not.
1771 * however, in the simulator since it is always
1772 * successfully transmitted, and writing it exactly to
1773 * spec would complicate the code, we just do it here
1776 cmdsts
&= ~CMDSTS_OWN
;
1777 cmdsts
|= CMDSTS_OK
;
1779 DPRINTF(EthernetDesc
,
1780 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1783 txDmaFree
= dmaDescFree
;
1784 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1785 txDmaData
= &cmdsts
;
1787 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1789 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1791 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1793 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1797 descDmaWrBytes
+= txDmaLen
;
1803 DPRINTF(EthernetSM
, "halting TX state machine\n");
1807 txState
= txAdvance
;
1813 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1814 if (!txFifo
.full()) {
1815 txState
= txFragRead
;
1818 * The number of bytes transferred is either whatever
1819 * is left in the descriptor (txDescCnt), or if there
1820 * is not enough room in the fifo, just whatever room
1821 * is left in the fifo
1823 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1825 txDmaAddr
= txFragPtr
& 0x3fffffff;
1826 txDmaData
= txPacketBufPtr
;
1827 txDmaLen
= txXferLen
;
1828 txDmaFree
= dmaDataFree
;
1833 txState
= txFifoBlock
;
1843 if (txDmaState
!= dmaIdle
)
1846 txPacketBufPtr
+= txXferLen
;
1847 txFragPtr
+= txXferLen
;
1848 txDescCnt
-= txXferLen
;
1849 txFifo
.reserve(txXferLen
);
1851 txState
= txFifoBlock
;
1855 if (txDmaState
!= dmaIdle
)
1858 if (cmdsts
& CMDSTS_INTR
)
1859 devIntrPost(ISR_TXDESC
);
1862 DPRINTF(EthernetSM
, "halting TX state machine\n");
1866 txState
= txAdvance
;
1871 devIntrPost(ISR_TXIDLE
);
1875 if (txDmaState
!= dmaIdle
)
1877 txState
= txDescRead
;
1881 txDmaAddr
= link
& 0x3fffffff;
1882 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1883 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1884 txDmaFree
= dmaDescFree
;
1892 panic("invalid state");
1895 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1896 NsTxStateStrings
[txState
]);
1901 * @todo do we want to schedule a future kick?
1903 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1904 NsTxStateStrings
[txState
]);
1906 if (!txKickEvent
.scheduled())
1907 schedule(txKickEvent
, txKickTick
);
1911 * Advance the EEPROM state machine
1912 * Called on rising edge of EEPROM clock bit in MEAR
1915 NSGigE::eepromKick()
1917 switch (eepromState
) {
1921 // Wait for start bit
1922 if (regs
.mear
& MEAR_EEDI
) {
1923 // Set up to get 2 opcode bits
1924 eepromState
= eepromGetOpcode
;
1930 case eepromGetOpcode
:
1932 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1935 // Done getting opcode
1936 if (eepromBitsToRx
== 0) {
1937 if (eepromOpcode
!= EEPROM_READ
)
1938 panic("only EEPROM reads are implemented!");
1940 // Set up to get address
1941 eepromState
= eepromGetAddress
;
1947 case eepromGetAddress
:
1948 eepromAddress
<<= 1;
1949 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1952 // Done getting address
1953 if (eepromBitsToRx
== 0) {
1955 if (eepromAddress
>= EEPROM_SIZE
)
1956 panic("EEPROM read access out of range!");
1958 switch (eepromAddress
) {
1960 case EEPROM_PMATCH2_ADDR
:
1961 eepromData
= rom
.perfectMatch
[5];
1963 eepromData
+= rom
.perfectMatch
[4];
1966 case EEPROM_PMATCH1_ADDR
:
1967 eepromData
= rom
.perfectMatch
[3];
1969 eepromData
+= rom
.perfectMatch
[2];
1972 case EEPROM_PMATCH0_ADDR
:
1973 eepromData
= rom
.perfectMatch
[1];
1975 eepromData
+= rom
.perfectMatch
[0];
1979 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1981 // Set up to read data
1982 eepromState
= eepromRead
;
1983 eepromBitsToRx
= 16;
1985 // Clear data in bit
1986 regs
.mear
&= ~MEAR_EEDI
;
1991 // Clear Data Out bit
1992 regs
.mear
&= ~MEAR_EEDO
;
1993 // Set bit to value of current EEPROM bit
1994 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
2000 if (eepromBitsToRx
== 0) {
2001 eepromState
= eepromStart
;
2006 panic("invalid EEPROM state");
2012 NSGigE::transferDone()
2014 if (txFifo
.empty()) {
2015 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2019 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2021 reschedule(txEvent
, clockEdge(Cycles(1)), true);
2025 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2027 EthPtr eth
= packet
;
2031 const EthAddr
&dst
= eth
->dst();
2032 if (dst
.unicast()) {
2033 // If we're accepting all unicast addresses
2037 // If we make a perfect match
2038 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2041 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2044 } else if (dst
.broadcast()) {
2045 // if we're accepting broadcasts
2046 if (acceptBroadcast
)
2049 } else if (dst
.multicast()) {
2050 // if we're accepting all multicasts
2051 if (acceptMulticast
)
2054 // Multicast hashing faked - all packets accepted
2055 if (multicastHashEnable
)
2060 DPRINTF(Ethernet
, "rxFilter drop\n");
2061 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2068 NSGigE::recvPacket(EthPacketPtr packet
)
2070 rxBytes
+= packet
->length
;
2073 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2077 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2081 if (!rxFilterEnable
) {
2083 "receive packet filtering disabled . . . packet dropped\n");
2087 if (rxFilter(packet
)) {
2088 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2092 if (rxFifo
.avail() < packet
->length
) {
2098 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2101 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2106 devIntrPost(ISR_RXORN
);
2110 rxFifo
.push(packet
);
2118 NSGigE::drainResume()
2120 Drainable::drainResume();
2122 // During drain we could have left the state machines in a waiting state and
2123 // they wouldn't get out until some other event occured to kick them.
2124 // This way they'll get out immediately
2130 //=====================================================================
2134 NSGigE::serialize(CheckpointOut
&cp
) const
2136 // Serialize the PciDevice base class
2137 PciDevice::serialize(cp
);
2140 * Finalize any DMA events now.
2142 // @todo will mem system save pending dma?
2145 * Serialize the device registers
2147 SERIALIZE_SCALAR(regs
.command
);
2148 SERIALIZE_SCALAR(regs
.config
);
2149 SERIALIZE_SCALAR(regs
.mear
);
2150 SERIALIZE_SCALAR(regs
.ptscr
);
2151 SERIALIZE_SCALAR(regs
.isr
);
2152 SERIALIZE_SCALAR(regs
.imr
);
2153 SERIALIZE_SCALAR(regs
.ier
);
2154 SERIALIZE_SCALAR(regs
.ihr
);
2155 SERIALIZE_SCALAR(regs
.txdp
);
2156 SERIALIZE_SCALAR(regs
.txdp_hi
);
2157 SERIALIZE_SCALAR(regs
.txcfg
);
2158 SERIALIZE_SCALAR(regs
.gpior
);
2159 SERIALIZE_SCALAR(regs
.rxdp
);
2160 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2161 SERIALIZE_SCALAR(regs
.rxcfg
);
2162 SERIALIZE_SCALAR(regs
.pqcr
);
2163 SERIALIZE_SCALAR(regs
.wcsr
);
2164 SERIALIZE_SCALAR(regs
.pcr
);
2165 SERIALIZE_SCALAR(regs
.rfcr
);
2166 SERIALIZE_SCALAR(regs
.rfdr
);
2167 SERIALIZE_SCALAR(regs
.brar
);
2168 SERIALIZE_SCALAR(regs
.brdr
);
2169 SERIALIZE_SCALAR(regs
.srr
);
2170 SERIALIZE_SCALAR(regs
.mibc
);
2171 SERIALIZE_SCALAR(regs
.vrcr
);
2172 SERIALIZE_SCALAR(regs
.vtcr
);
2173 SERIALIZE_SCALAR(regs
.vdr
);
2174 SERIALIZE_SCALAR(regs
.ccsr
);
2175 SERIALIZE_SCALAR(regs
.tbicr
);
2176 SERIALIZE_SCALAR(regs
.tbisr
);
2177 SERIALIZE_SCALAR(regs
.tanar
);
2178 SERIALIZE_SCALAR(regs
.tanlpar
);
2179 SERIALIZE_SCALAR(regs
.taner
);
2180 SERIALIZE_SCALAR(regs
.tesr
);
2182 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2183 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2185 SERIALIZE_SCALAR(ioEnable
);
2188 * Serialize the data Fifos
2190 rxFifo
.serialize("rxFifo", cp
);
2191 txFifo
.serialize("txFifo", cp
);
2194 * Serialize the various helper variables
2196 bool txPacketExists
= txPacket
!= nullptr;
2197 SERIALIZE_SCALAR(txPacketExists
);
2198 if (txPacketExists
) {
2199 txPacket
->simLength
= txPacketBufPtr
- txPacket
->data
;
2200 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2201 txPacket
->serialize("txPacket", cp
);
2202 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2203 SERIALIZE_SCALAR(txPktBufPtr
);
2206 bool rxPacketExists
= rxPacket
!= nullptr;
2207 SERIALIZE_SCALAR(rxPacketExists
);
2208 if (rxPacketExists
) {
2209 rxPacket
->serialize("rxPacket", cp
);
2210 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2211 SERIALIZE_SCALAR(rxPktBufPtr
);
2214 SERIALIZE_SCALAR(txXferLen
);
2215 SERIALIZE_SCALAR(rxXferLen
);
2218 * Serialize Cached Descriptors
2220 SERIALIZE_SCALAR(rxDesc64
.link
);
2221 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2222 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2223 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2224 SERIALIZE_SCALAR(txDesc64
.link
);
2225 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2226 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2227 SERIALIZE_SCALAR(txDesc64
.extsts
);
2228 SERIALIZE_SCALAR(rxDesc32
.link
);
2229 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2230 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2231 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2232 SERIALIZE_SCALAR(txDesc32
.link
);
2233 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2234 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2235 SERIALIZE_SCALAR(txDesc32
.extsts
);
2236 SERIALIZE_SCALAR(extstsEnable
);
2239 * Serialize tx state machine
2241 int txState
= this->txState
;
2242 SERIALIZE_SCALAR(txState
);
2243 SERIALIZE_SCALAR(txEnable
);
2244 SERIALIZE_SCALAR(CTDD
);
2245 SERIALIZE_SCALAR(txFragPtr
);
2246 SERIALIZE_SCALAR(txDescCnt
);
2247 int txDmaState
= this->txDmaState
;
2248 SERIALIZE_SCALAR(txDmaState
);
2249 SERIALIZE_SCALAR(txKickTick
);
2252 * Serialize rx state machine
2254 int rxState
= this->rxState
;
2255 SERIALIZE_SCALAR(rxState
);
2256 SERIALIZE_SCALAR(rxEnable
);
2257 SERIALIZE_SCALAR(CRDD
);
2258 SERIALIZE_SCALAR(rxPktBytes
);
2259 SERIALIZE_SCALAR(rxFragPtr
);
2260 SERIALIZE_SCALAR(rxDescCnt
);
2261 int rxDmaState
= this->rxDmaState
;
2262 SERIALIZE_SCALAR(rxDmaState
);
2263 SERIALIZE_SCALAR(rxKickTick
);
2266 * Serialize EEPROM state machine
2268 int eepromState
= this->eepromState
;
2269 SERIALIZE_SCALAR(eepromState
);
2270 SERIALIZE_SCALAR(eepromClk
);
2271 SERIALIZE_SCALAR(eepromBitsToRx
);
2272 SERIALIZE_SCALAR(eepromOpcode
);
2273 SERIALIZE_SCALAR(eepromAddress
);
2274 SERIALIZE_SCALAR(eepromData
);
2277 * If there's a pending transmit, store the time so we can
2278 * reschedule it later
2280 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick() : 0;
2281 SERIALIZE_SCALAR(transmitTick
);
2284 * receive address filter settings
2286 SERIALIZE_SCALAR(rxFilterEnable
);
2287 SERIALIZE_SCALAR(acceptBroadcast
);
2288 SERIALIZE_SCALAR(acceptMulticast
);
2289 SERIALIZE_SCALAR(acceptUnicast
);
2290 SERIALIZE_SCALAR(acceptPerfect
);
2291 SERIALIZE_SCALAR(acceptArp
);
2292 SERIALIZE_SCALAR(multicastHashEnable
);
2295 * Keep track of pending interrupt status.
2297 SERIALIZE_SCALAR(intrTick
);
2298 SERIALIZE_SCALAR(cpuPendingIntr
);
2299 Tick intrEventTick
= 0;
2301 intrEventTick
= intrEvent
->when();
2302 SERIALIZE_SCALAR(intrEventTick
);
2307 NSGigE::unserialize(CheckpointIn
&cp
)
2309 // Unserialize the PciDevice base class
2310 PciDevice::unserialize(cp
);
2312 UNSERIALIZE_SCALAR(regs
.command
);
2313 UNSERIALIZE_SCALAR(regs
.config
);
2314 UNSERIALIZE_SCALAR(regs
.mear
);
2315 UNSERIALIZE_SCALAR(regs
.ptscr
);
2316 UNSERIALIZE_SCALAR(regs
.isr
);
2317 UNSERIALIZE_SCALAR(regs
.imr
);
2318 UNSERIALIZE_SCALAR(regs
.ier
);
2319 UNSERIALIZE_SCALAR(regs
.ihr
);
2320 UNSERIALIZE_SCALAR(regs
.txdp
);
2321 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2322 UNSERIALIZE_SCALAR(regs
.txcfg
);
2323 UNSERIALIZE_SCALAR(regs
.gpior
);
2324 UNSERIALIZE_SCALAR(regs
.rxdp
);
2325 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2326 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2327 UNSERIALIZE_SCALAR(regs
.pqcr
);
2328 UNSERIALIZE_SCALAR(regs
.wcsr
);
2329 UNSERIALIZE_SCALAR(regs
.pcr
);
2330 UNSERIALIZE_SCALAR(regs
.rfcr
);
2331 UNSERIALIZE_SCALAR(regs
.rfdr
);
2332 UNSERIALIZE_SCALAR(regs
.brar
);
2333 UNSERIALIZE_SCALAR(regs
.brdr
);
2334 UNSERIALIZE_SCALAR(regs
.srr
);
2335 UNSERIALIZE_SCALAR(regs
.mibc
);
2336 UNSERIALIZE_SCALAR(regs
.vrcr
);
2337 UNSERIALIZE_SCALAR(regs
.vtcr
);
2338 UNSERIALIZE_SCALAR(regs
.vdr
);
2339 UNSERIALIZE_SCALAR(regs
.ccsr
);
2340 UNSERIALIZE_SCALAR(regs
.tbicr
);
2341 UNSERIALIZE_SCALAR(regs
.tbisr
);
2342 UNSERIALIZE_SCALAR(regs
.tanar
);
2343 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2344 UNSERIALIZE_SCALAR(regs
.taner
);
2345 UNSERIALIZE_SCALAR(regs
.tesr
);
2347 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2348 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2350 UNSERIALIZE_SCALAR(ioEnable
);
2353 * unserialize the data fifos
2355 rxFifo
.unserialize("rxFifo", cp
);
2356 txFifo
.unserialize("txFifo", cp
);
2359 * unserialize the various helper variables
2361 bool txPacketExists
;
2362 UNSERIALIZE_SCALAR(txPacketExists
);
2363 if (txPacketExists
) {
2364 txPacket
= make_shared
<EthPacketData
>(16384);
2365 txPacket
->unserialize("txPacket", cp
);
2366 uint32_t txPktBufPtr
;
2367 UNSERIALIZE_SCALAR(txPktBufPtr
);
2368 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2372 bool rxPacketExists
;
2373 UNSERIALIZE_SCALAR(rxPacketExists
);
2375 if (rxPacketExists
) {
2376 rxPacket
= make_shared
<EthPacketData
>();
2377 rxPacket
->unserialize("rxPacket", cp
);
2378 uint32_t rxPktBufPtr
;
2379 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2380 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2384 UNSERIALIZE_SCALAR(txXferLen
);
2385 UNSERIALIZE_SCALAR(rxXferLen
);
2388 * Unserialize Cached Descriptors
2390 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2391 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2392 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2393 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2394 UNSERIALIZE_SCALAR(txDesc64
.link
);
2395 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2396 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2397 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2398 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2399 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2400 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2401 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2402 UNSERIALIZE_SCALAR(txDesc32
.link
);
2403 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2404 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2405 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2406 UNSERIALIZE_SCALAR(extstsEnable
);
2409 * unserialize tx state machine
2412 UNSERIALIZE_SCALAR(txState
);
2413 this->txState
= (TxState
) txState
;
2414 UNSERIALIZE_SCALAR(txEnable
);
2415 UNSERIALIZE_SCALAR(CTDD
);
2416 UNSERIALIZE_SCALAR(txFragPtr
);
2417 UNSERIALIZE_SCALAR(txDescCnt
);
2419 UNSERIALIZE_SCALAR(txDmaState
);
2420 this->txDmaState
= (DmaState
) txDmaState
;
2421 UNSERIALIZE_SCALAR(txKickTick
);
2423 schedule(txKickEvent
, txKickTick
);
2426 * unserialize rx state machine
2429 UNSERIALIZE_SCALAR(rxState
);
2430 this->rxState
= (RxState
) rxState
;
2431 UNSERIALIZE_SCALAR(rxEnable
);
2432 UNSERIALIZE_SCALAR(CRDD
);
2433 UNSERIALIZE_SCALAR(rxPktBytes
);
2434 UNSERIALIZE_SCALAR(rxFragPtr
);
2435 UNSERIALIZE_SCALAR(rxDescCnt
);
2437 UNSERIALIZE_SCALAR(rxDmaState
);
2438 this->rxDmaState
= (DmaState
) rxDmaState
;
2439 UNSERIALIZE_SCALAR(rxKickTick
);
2441 schedule(rxKickEvent
, rxKickTick
);
2444 * Unserialize EEPROM state machine
2447 UNSERIALIZE_SCALAR(eepromState
);
2448 this->eepromState
= (EEPROMState
) eepromState
;
2449 UNSERIALIZE_SCALAR(eepromClk
);
2450 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2451 UNSERIALIZE_SCALAR(eepromOpcode
);
2452 UNSERIALIZE_SCALAR(eepromAddress
);
2453 UNSERIALIZE_SCALAR(eepromData
);
2456 * If there's a pending transmit, reschedule it now
2459 UNSERIALIZE_SCALAR(transmitTick
);
2461 schedule(txEvent
, curTick() + transmitTick
);
2464 * unserialize receive address filter settings
2466 UNSERIALIZE_SCALAR(rxFilterEnable
);
2467 UNSERIALIZE_SCALAR(acceptBroadcast
);
2468 UNSERIALIZE_SCALAR(acceptMulticast
);
2469 UNSERIALIZE_SCALAR(acceptUnicast
);
2470 UNSERIALIZE_SCALAR(acceptPerfect
);
2471 UNSERIALIZE_SCALAR(acceptArp
);
2472 UNSERIALIZE_SCALAR(multicastHashEnable
);
2475 * Keep track of pending interrupt status.
2477 UNSERIALIZE_SCALAR(intrTick
);
2478 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2480 UNSERIALIZE_SCALAR(intrEventTick
);
2481 if (intrEventTick
) {
2482 intrEvent
= new EventFunctionWrapper([this]{ cpuInterrupt(); },
2484 schedule(intrEvent
, intrEventTick
);
2489 NSGigEParams::create()
2491 return new NSGigE(this);