2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Nathan Binkert
33 * Device module for modelling the National Semiconductor
34 * DP83820 ethernet controller. Does not support priority queueing
39 #include "base/debug.hh"
40 #include "base/inet.hh"
41 #include "base/types.hh"
42 #include "config/the_isa.hh"
43 #include "cpu/thread_context.hh"
44 #include "debug/EthernetAll.hh"
45 #include "dev/etherlink.hh"
46 #include "dev/ns_gige.hh"
47 #include "dev/pciconfigall.hh"
48 #include "mem/packet.hh"
49 #include "mem/packet_access.hh"
50 #include "params/NSGigE.hh"
51 #include "sim/system.hh"
53 const char *NsRxStateStrings
[] =
64 const char *NsTxStateStrings
[] =
75 const char *NsDmaState
[] =
86 using namespace TheISA
;
88 ///////////////////////////////////////////////////////////////////////
92 NSGigE::NSGigE(Params
*p
)
93 : EtherDevice(p
), ioEnable(false),
94 txFifo(p
->tx_fifo_size
), rxFifo(p
->rx_fifo_size
),
95 txPacket(0), rxPacket(0), txPacketBufPtr(NULL
), rxPacketBufPtr(NULL
),
96 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
98 txState(txIdle
), txEnable(false), CTDD(false), txHalt(false),
99 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle
), rxState(rxIdle
),
100 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
101 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle
), extstsEnable(false),
102 eepromState(eepromStart
), eepromClk(false), eepromBitsToRx(0),
103 eepromOpcode(0), eepromAddress(0), eepromData(0),
104 dmaReadDelay(p
->dma_read_delay
), dmaWriteDelay(p
->dma_write_delay
),
105 dmaReadFactor(p
->dma_read_factor
), dmaWriteFactor(p
->dma_write_factor
),
106 rxDmaData(NULL
), rxDmaAddr(0), rxDmaLen(0),
107 txDmaData(NULL
), txDmaAddr(0), txDmaLen(0),
108 rxDmaReadEvent(this), rxDmaWriteEvent(this),
109 txDmaReadEvent(this), txDmaWriteEvent(this),
110 dmaDescFree(p
->dma_desc_free
), dmaDataFree(p
->dma_data_free
),
111 txDelay(p
->tx_delay
), rxDelay(p
->rx_delay
),
112 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
113 txEvent(this), rxFilterEnable(p
->rx_filter
),
114 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
115 acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
116 intrDelay(p
->intr_delay
), intrTick(0), cpuPendingIntr(false),
117 intrEvent(0), interface(0)
121 interface
= new NSGigEInt(name() + ".int0", this);
124 memcpy(&rom
.perfectMatch
, p
->hardware_address
.bytes(), ETH_ADDR_LEN
);
126 memset(&rxDesc32
, 0, sizeof(rxDesc32
));
127 memset(&txDesc32
, 0, sizeof(txDesc32
));
128 memset(&rxDesc64
, 0, sizeof(rxDesc64
));
129 memset(&txDesc64
, 0, sizeof(txDesc64
));
136 * This is to write to the PCI general configuration registers
139 NSGigE::writeConfig(PacketPtr pkt
)
141 int offset
= pkt
->getAddr() & PCI_CONFIG_SIZE
;
142 if (offset
< PCI_DEVICE_SPECIFIC
)
143 PciDev::writeConfig(pkt
);
145 panic("Device specific PCI config space not implemented!\n");
148 // seems to work fine without all these PCI settings, but i
149 // put in the IO to double check, an assertion will fail if we
150 // need to properly implement it
152 if (config
.data
[offset
] & PCI_CMD_IOSE
)
163 NSGigE::getEthPort(const std::string
&if_name
, int idx
)
165 if (if_name
== "interface") {
166 if (interface
->getPeer())
167 panic("interface already connected to\n");
174 * This reads the device registers, which are detailed in the NS83820
178 NSGigE::read(PacketPtr pkt
)
184 //The mask is to give you only the offset into the device register file
185 Addr daddr
= pkt
->getAddr() & 0xfff;
186 DPRINTF(EthernetPIO
, "read da=%#x pa=%#x size=%d\n",
187 daddr
, pkt
->getAddr(), pkt
->getSize());
190 // there are some reserved registers, you can see ns_gige_reg.h and
191 // the spec sheet for details
192 if (daddr
> LAST
&& daddr
<= RESERVED
) {
193 panic("Accessing reserved register");
194 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
195 return readConfig(pkt
);
196 } else if (daddr
>= MIB_START
&& daddr
<= MIB_END
) {
197 // don't implement all the MIB's. hopefully the kernel
198 // doesn't actually DEPEND upon their values
199 // MIB are just hardware stats keepers
200 pkt
->set
<uint32_t>(0);
201 pkt
->makeAtomicResponse();
203 } else if (daddr
> 0x3FC)
204 panic("Something is messed up!\n");
206 assert(pkt
->getSize() == sizeof(uint32_t));
207 uint32_t ®
= *pkt
->getPtr
<uint32_t>();
213 //these are supposed to be cleared on a read
214 reg
&= ~(CR_RXD
| CR_TXD
| CR_TXR
| CR_RXR
);
231 devIntrClear(ISR_ALL
);
286 // see the spec sheet for how RFCR and RFDR work
287 // basically, you write to RFCR to tell the machine
288 // what you want to do next, then you act upon RFDR,
289 // and the device will be prepared b/c of what you
296 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
298 // Read from perfect match ROM octets
300 reg
= rom
.perfectMatch
[1];
302 reg
+= rom
.perfectMatch
[0];
305 reg
= rom
.perfectMatch
[3] << 8;
306 reg
+= rom
.perfectMatch
[2];
309 reg
= rom
.perfectMatch
[5] << 8;
310 reg
+= rom
.perfectMatch
[4];
313 // Read filter hash table
314 if (rfaddr
>= FHASH_ADDR
&&
315 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
317 // Only word-aligned reads supported
319 panic("unaligned read from filter hash table!");
321 reg
= rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1] << 8;
322 reg
+= rom
.filterHash
[rfaddr
- FHASH_ADDR
];
326 panic("reading RFDR for something other than pattern"
327 " matching or hashing! %#x\n", rfaddr
);
337 reg
&= ~(MIBC_MIBS
| MIBC_ACLR
);
382 if (params()->rx_thread
)
383 reg
|= M5REG_RX_THREAD
;
384 if (params()->tx_thread
)
385 reg
|= M5REG_TX_THREAD
;
391 panic("reading unimplemented register: addr=%#x", daddr
);
394 DPRINTF(EthernetPIO
, "read from %#x: data=%d data=%#x\n",
397 pkt
->makeAtomicResponse();
402 NSGigE::write(PacketPtr pkt
)
406 Addr daddr
= pkt
->getAddr() & 0xfff;
407 DPRINTF(EthernetPIO
, "write da=%#x pa=%#x size=%d\n",
408 daddr
, pkt
->getAddr(), pkt
->getSize());
410 if (daddr
> LAST
&& daddr
<= RESERVED
) {
411 panic("Accessing reserved register");
412 } else if (daddr
> RESERVED
&& daddr
<= 0x3FC) {
413 return writeConfig(pkt
);
414 } else if (daddr
> 0x3FC)
415 panic("Something is messed up!\n");
417 if (pkt
->getSize() == sizeof(uint32_t)) {
418 uint32_t reg
= pkt
->get
<uint32_t>();
421 DPRINTF(EthernetPIO
, "write data=%d data=%#x\n", reg
, reg
);
428 } else if (reg
& CR_TXE
) {
431 // the kernel is enabling the transmit machine
432 if (txState
== txIdle
)
438 } else if (reg
& CR_RXE
) {
441 if (rxState
== rxIdle
)
452 devIntrPost(ISR_SWI
);
463 if (reg
& CFGR_LNKSTS
||
466 reg
& CFGR_RESERVED
||
467 reg
& CFGR_T64ADDR
||
468 reg
& CFGR_PCI64_DET
)
470 // First clear all writable bits
471 regs
.config
&= CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
472 CFGR_RESERVED
| CFGR_T64ADDR
|
474 // Now set the appropriate writable bits
475 regs
.config
|= reg
& ~(CFGR_LNKSTS
| CFGR_SPDSTS
| CFGR_DUPSTS
|
476 CFGR_RESERVED
| CFGR_T64ADDR
|
479 // all these #if 0's are because i don't THINK the kernel needs to
480 // have these implemented. if there is a problem relating to one of
481 // these, you may need to add functionality in.
482 if (reg
& CFGR_TBI_EN
) ;
483 if (reg
& CFGR_MODE_1000
) ;
485 if (reg
& CFGR_AUTO_1000
)
486 panic("CFGR_AUTO_1000 not implemented!\n");
488 if (reg
& CFGR_PINT_DUPSTS
||
489 reg
& CFGR_PINT_LNKSTS
||
490 reg
& CFGR_PINT_SPDSTS
)
493 if (reg
& CFGR_TMRTEST
) ;
494 if (reg
& CFGR_MRM_DIS
) ;
495 if (reg
& CFGR_MWI_DIS
) ;
497 if (reg
& CFGR_T64ADDR
) ;
498 // panic("CFGR_T64ADDR is read only register!\n");
500 if (reg
& CFGR_PCI64_DET
)
501 panic("CFGR_PCI64_DET is read only register!\n");
503 if (reg
& CFGR_DATA64_EN
) ;
504 if (reg
& CFGR_M64ADDR
) ;
505 if (reg
& CFGR_PHY_RST
) ;
506 if (reg
& CFGR_PHY_DIS
) ;
508 if (reg
& CFGR_EXTSTS_EN
)
511 extstsEnable
= false;
513 if (reg
& CFGR_REQALG
) ;
515 if (reg
& CFGR_POW
) ;
516 if (reg
& CFGR_EXD
) ;
517 if (reg
& CFGR_PESEL
) ;
518 if (reg
& CFGR_BROM_DIS
) ;
519 if (reg
& CFGR_EXT_125
) ;
520 if (reg
& CFGR_BEM
) ;
524 // Clear writable bits
525 regs
.mear
&= MEAR_EEDO
;
526 // Set appropriate writable bits
527 regs
.mear
|= reg
& ~MEAR_EEDO
;
529 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)
530 // even though it could get it through RFDR
531 if (reg
& MEAR_EESEL
) {
532 // Rising edge of clock
533 if (reg
& MEAR_EECLK
&& !eepromClk
)
537 eepromState
= eepromStart
;
538 regs
.mear
&= ~MEAR_EEDI
;
541 eepromClk
= reg
& MEAR_EECLK
;
543 // since phy is completely faked, MEAR_MD* don't matter
544 if (reg
& MEAR_MDIO
) ;
545 if (reg
& MEAR_MDDIR
) ;
546 if (reg
& MEAR_MDC
) ;
550 regs
.ptscr
= reg
& ~(PTSCR_RBIST_RDONLY
);
551 // these control BISTs for various parts of chip - we
552 // don't care or do just fake that the BIST is done
553 if (reg
& PTSCR_RBIST_EN
)
554 regs
.ptscr
|= PTSCR_RBIST_DONE
;
555 if (reg
& PTSCR_EEBIST_EN
)
556 regs
.ptscr
&= ~PTSCR_EEBIST_EN
;
557 if (reg
& PTSCR_EELOAD_EN
)
558 regs
.ptscr
&= ~PTSCR_EELOAD_EN
;
561 case ISR
: /* writing to the ISR has no effect */
562 panic("ISR is a read only register!\n");
575 /* not going to implement real interrupt holdoff */
579 regs
.txdp
= (reg
& 0xFFFFFFFC);
580 assert(txState
== txIdle
);
591 if (reg
& TX_CFG_CSI
) ;
592 if (reg
& TX_CFG_HBI
) ;
593 if (reg
& TX_CFG_MLB
) ;
594 if (reg
& TX_CFG_ATP
) ;
595 if (reg
& TX_CFG_ECRETRY
) {
597 * this could easily be implemented, but considering
598 * the network is just a fake pipe, wouldn't make
603 if (reg
& TX_CFG_BRST_DIS
) ;
607 /* we handle our own DMA, ignore the kernel's exhortations */
608 if (reg
& TX_CFG_MXDMA
) ;
611 // also, we currently don't care about fill/drain
612 // thresholds though this may change in the future with
613 // more realistic networks or a driver which changes it
614 // according to feedback
619 // Only write writable bits
620 regs
.gpior
&= GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
621 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
;
622 regs
.gpior
|= reg
& ~(GPIOR_UNUSED
| GPIOR_GP5_IN
| GPIOR_GP4_IN
623 | GPIOR_GP3_IN
| GPIOR_GP2_IN
| GPIOR_GP1_IN
);
624 /* these just control general purpose i/o pins, don't matter */
639 if (reg
& RX_CFG_AEP
) ;
640 if (reg
& RX_CFG_ARP
) ;
641 if (reg
& RX_CFG_STRIPCRC
) ;
642 if (reg
& RX_CFG_RX_RD
) ;
643 if (reg
& RX_CFG_ALP
) ;
644 if (reg
& RX_CFG_AIRL
) ;
646 /* we handle our own DMA, ignore what kernel says about it */
647 if (reg
& RX_CFG_MXDMA
) ;
649 //also, we currently don't care about fill/drain thresholds
650 //though this may change in the future with more realistic
651 //networks or a driver which changes it according to feedback
652 if (reg
& (RX_CFG_DRTH
| RX_CFG_DRTH0
)) ;
657 /* there is no priority queueing used in the linux 2.6 driver */
662 /* not going to implement wake on LAN */
667 /* not going to implement pause control */
674 rxFilterEnable
= (reg
& RFCR_RFEN
) ? true : false;
675 acceptBroadcast
= (reg
& RFCR_AAB
) ? true : false;
676 acceptMulticast
= (reg
& RFCR_AAM
) ? true : false;
677 acceptUnicast
= (reg
& RFCR_AAU
) ? true : false;
678 acceptPerfect
= (reg
& RFCR_APM
) ? true : false;
679 acceptArp
= (reg
& RFCR_AARP
) ? true : false;
680 multicastHashEnable
= (reg
& RFCR_MHEN
) ? true : false;
684 panic("RFCR_APAT not implemented!\n");
687 panic("Unicast hash filtering not used by drivers!\n");
690 panic("RFCR_ULM not implemented!\n");
695 rfaddr
= (uint16_t)(regs
.rfcr
& RFCR_RFADDR
);
698 rom
.perfectMatch
[0] = (uint8_t)reg
;
699 rom
.perfectMatch
[1] = (uint8_t)(reg
>> 8);
702 rom
.perfectMatch
[2] = (uint8_t)reg
;
703 rom
.perfectMatch
[3] = (uint8_t)(reg
>> 8);
706 rom
.perfectMatch
[4] = (uint8_t)reg
;
707 rom
.perfectMatch
[5] = (uint8_t)(reg
>> 8);
711 if (rfaddr
>= FHASH_ADDR
&&
712 rfaddr
< FHASH_ADDR
+ FHASH_SIZE
) {
714 // Only word-aligned writes supported
716 panic("unaligned write to filter hash table!");
718 rom
.filterHash
[rfaddr
- FHASH_ADDR
] = (uint8_t)reg
;
719 rom
.filterHash
[rfaddr
- FHASH_ADDR
+ 1]
720 = (uint8_t)(reg
>> 8);
723 panic("writing RFDR for something other than pattern matching\
724 or hashing! %#x\n", rfaddr
);
732 panic("the driver never uses BRDR, something is wrong!\n");
735 panic("SRR is read only register!\n");
738 panic("the driver never uses MIBC, something is wrong!\n");
749 panic("the driver never uses VDR, something is wrong!\n");
752 /* not going to implement clockrun stuff */
758 if (reg
& TBICR_MR_LOOPBACK
)
759 panic("TBICR_MR_LOOPBACK never used, something wrong!\n");
761 if (reg
& TBICR_MR_AN_ENABLE
) {
762 regs
.tanlpar
= regs
.tanar
;
763 regs
.tbisr
|= (TBISR_MR_AN_COMPLETE
| TBISR_MR_LINK_STATUS
);
767 if (reg
& TBICR_MR_RESTART_AN
) ;
773 panic("TBISR is read only register!\n");
776 // Only write the writable bits
777 regs
.tanar
&= TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
;
778 regs
.tanar
|= reg
& ~(TANAR_RF1
| TANAR_RF2
| TANAR_UNUSED
);
780 // Pause capability unimplemented
782 if (reg
& TANAR_PS2
) ;
783 if (reg
& TANAR_PS1
) ;
789 panic("this should only be written to by the fake phy!\n");
792 panic("TANER is read only register!\n");
799 panic("invalid register access daddr=%#x", daddr
);
802 panic("Invalid Request Size");
804 pkt
->makeAtomicResponse();
809 NSGigE::devIntrPost(uint32_t interrupts
)
811 if (interrupts
& ISR_RESERVE
)
812 panic("Cannot set a reserved interrupt");
814 if (interrupts
& ISR_NOIMPL
)
815 warn("interrupt not implemented %#x\n", interrupts
);
817 interrupts
&= ISR_IMPL
;
818 regs
.isr
|= interrupts
;
820 if (interrupts
& regs
.imr
) {
821 if (interrupts
& ISR_SWI
) {
824 if (interrupts
& ISR_RXIDLE
) {
827 if (interrupts
& ISR_RXOK
) {
830 if (interrupts
& ISR_RXDESC
) {
833 if (interrupts
& ISR_TXOK
) {
836 if (interrupts
& ISR_TXIDLE
) {
839 if (interrupts
& ISR_TXDESC
) {
842 if (interrupts
& ISR_RXORN
) {
847 DPRINTF(EthernetIntr
,
848 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
849 interrupts
, regs
.isr
, regs
.imr
);
851 if ((regs
.isr
& regs
.imr
)) {
852 Tick when
= curTick();
853 if ((regs
.isr
& regs
.imr
& ISR_NODELAY
) == 0)
860 /* writing this interrupt counting stats inside this means that this function
861 is now limited to being used to clear all interrupts upon the kernel
862 reading isr and servicing. just telling you in case you were thinking
866 NSGigE::devIntrClear(uint32_t interrupts
)
868 if (interrupts
& ISR_RESERVE
)
869 panic("Cannot clear a reserved interrupt");
871 if (regs
.isr
& regs
.imr
& ISR_SWI
) {
874 if (regs
.isr
& regs
.imr
& ISR_RXIDLE
) {
877 if (regs
.isr
& regs
.imr
& ISR_RXOK
) {
880 if (regs
.isr
& regs
.imr
& ISR_RXDESC
) {
883 if (regs
.isr
& regs
.imr
& ISR_TXOK
) {
886 if (regs
.isr
& regs
.imr
& ISR_TXIDLE
) {
889 if (regs
.isr
& regs
.imr
& ISR_TXDESC
) {
892 if (regs
.isr
& regs
.imr
& ISR_RXORN
) {
896 interrupts
&= ~ISR_NOIMPL
;
897 regs
.isr
&= ~interrupts
;
899 DPRINTF(EthernetIntr
,
900 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
901 interrupts
, regs
.isr
, regs
.imr
);
903 if (!(regs
.isr
& regs
.imr
))
908 NSGigE::devIntrChangeMask()
910 DPRINTF(EthernetIntr
, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
911 regs
.isr
, regs
.imr
, regs
.isr
& regs
.imr
);
913 if (regs
.isr
& regs
.imr
)
914 cpuIntrPost(curTick());
920 NSGigE::cpuIntrPost(Tick when
)
922 // If the interrupt you want to post is later than an interrupt
923 // already scheduled, just let it post in the coming one and don't
925 // HOWEVER, must be sure that the scheduled intrTick is in the
926 // future (this was formerly the source of a bug)
928 * @todo this warning should be removed and the intrTick code should
931 assert(when
>= curTick());
932 assert(intrTick
>= curTick() || intrTick
== 0);
933 if (when
> intrTick
&& intrTick
!= 0) {
934 DPRINTF(EthernetIntr
, "don't need to schedule event...intrTick=%d\n",
940 if (intrTick
< curTick()) {
942 intrTick
= curTick();
945 DPRINTF(EthernetIntr
, "going to schedule an interrupt for intrTick=%d\n",
950 intrEvent
= new IntrEvent(this, true);
951 schedule(intrEvent
, intrTick
);
955 NSGigE::cpuInterrupt()
957 assert(intrTick
== curTick());
959 // Whether or not there's a pending interrupt, we don't care about
964 // Don't send an interrupt if there's already one
965 if (cpuPendingIntr
) {
966 DPRINTF(EthernetIntr
,
967 "would send an interrupt now, but there's already pending\n");
970 cpuPendingIntr
= true;
972 DPRINTF(EthernetIntr
, "posting interrupt\n");
978 NSGigE::cpuIntrClear()
990 cpuPendingIntr
= false;
992 DPRINTF(EthernetIntr
, "clearing interrupt\n");
997 NSGigE::cpuIntrPending() const
998 { return cpuPendingIntr
; }
1004 DPRINTF(Ethernet
, "transmit reset\n");
1009 assert(txDescCnt
== 0);
1012 assert(txDmaState
== dmaIdle
);
1018 DPRINTF(Ethernet
, "receive reset\n");
1021 assert(rxPktBytes
== 0);
1024 assert(rxDescCnt
== 0);
1025 assert(rxDmaState
== dmaIdle
);
1033 memset(®s
, 0, sizeof(regs
));
1034 regs
.config
= (CFGR_LNKSTS
| CFGR_TBI_EN
| CFGR_MODE_1000
);
1036 regs
.txcfg
= 0x120; // set drain threshold to 1024 bytes and
1037 // fill threshold to 32 bytes
1038 regs
.rxcfg
= 0x4; // set drain threshold to 16 bytes
1039 regs
.srr
= 0x0103; // set the silicon revision to rev B or 0x103
1040 regs
.mibc
= MIBC_FRZ
;
1041 regs
.vdr
= 0x81; // set the vlan tag type to 802.1q
1042 regs
.tesr
= 0xc000; // TBI capable of both full and half duplex
1043 regs
.brar
= 0xffffffff;
1045 extstsEnable
= false;
1046 acceptBroadcast
= false;
1047 acceptMulticast
= false;
1048 acceptUnicast
= false;
1049 acceptPerfect
= false;
1054 NSGigE::doRxDmaRead()
1056 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaReadWaiting
);
1057 rxDmaState
= dmaReading
;
1059 if (dmaPending() || getState() != Running
)
1060 rxDmaState
= dmaReadWaiting
;
1062 dmaRead(rxDmaAddr
, rxDmaLen
, &rxDmaReadEvent
, (uint8_t*)rxDmaData
);
1068 NSGigE::rxDmaReadDone()
1070 assert(rxDmaState
== dmaReading
);
1071 rxDmaState
= dmaIdle
;
1073 DPRINTF(EthernetDMA
, "rx dma read paddr=%#x len=%d\n",
1074 rxDmaAddr
, rxDmaLen
);
1075 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1077 // If the transmit state machine has a pending DMA, let it go first
1078 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1085 NSGigE::doRxDmaWrite()
1087 assert(rxDmaState
== dmaIdle
|| rxDmaState
== dmaWriteWaiting
);
1088 rxDmaState
= dmaWriting
;
1090 if (dmaPending() || getState() != Running
)
1091 rxDmaState
= dmaWriteWaiting
;
1093 dmaWrite(rxDmaAddr
, rxDmaLen
, &rxDmaWriteEvent
, (uint8_t*)rxDmaData
);
1098 NSGigE::rxDmaWriteDone()
1100 assert(rxDmaState
== dmaWriting
);
1101 rxDmaState
= dmaIdle
;
1103 DPRINTF(EthernetDMA
, "rx dma write paddr=%#x len=%d\n",
1104 rxDmaAddr
, rxDmaLen
);
1105 DDUMP(EthernetDMA
, rxDmaData
, rxDmaLen
);
1107 // If the transmit state machine has a pending DMA, let it go first
1108 if (txDmaState
== dmaReadWaiting
|| txDmaState
== dmaWriteWaiting
)
1117 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1120 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1121 NsRxStateStrings
[rxState
], rxFifo
.size(), is64bit
? 64 : 32);
1124 uint32_t &cmdsts
= is64bit
? rxDesc64
.cmdsts
: rxDesc32
.cmdsts
;
1125 uint32_t &extsts
= is64bit
? rxDesc64
.extsts
: rxDesc32
.extsts
;
1129 if (rxKickTick
> curTick()) {
1130 DPRINTF(EthernetSM
, "receive kick exiting, can't run till %d\n",
1136 // Go to the next state machine clock tick.
1137 rxKickTick
= curTick() + ticks(1);
1140 switch(rxDmaState
) {
1141 case dmaReadWaiting
:
1145 case dmaWriteWaiting
:
1153 link
= is64bit
? (Addr
)rxDesc64
.link
: (Addr
)rxDesc32
.link
;
1154 bufptr
= is64bit
? (Addr
)rxDesc64
.bufptr
: (Addr
)rxDesc32
.bufptr
;
1156 // see state machine from spec for details
1157 // the way this works is, if you finish work on one state and can
1158 // go directly to another, you do that through jumping to the
1159 // label "next". however, if you have intermediate work, like DMA
1160 // so that you can't go to the next state yet, you go to exit and
1161 // exit the loop. however, when the DMA is done it will trigger
1162 // an event and come back to this loop.
1166 DPRINTF(EthernetSM
, "Receive Disabled! Nothing to do.\n");
1171 rxState
= rxDescRefr
;
1173 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1175 is64bit
? (void *)&rxDesc64
.link
: (void *)&rxDesc32
.link
;
1176 rxDmaLen
= is64bit
? sizeof(rxDesc64
.link
) : sizeof(rxDesc32
.link
);
1177 rxDmaFree
= dmaDescFree
;
1180 descDmaRdBytes
+= rxDmaLen
;
1185 rxState
= rxDescRead
;
1187 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1188 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1189 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1190 rxDmaFree
= dmaDescFree
;
1193 descDmaRdBytes
+= rxDmaLen
;
1201 if (rxDmaState
!= dmaIdle
)
1204 rxState
= rxAdvance
;
1208 if (rxDmaState
!= dmaIdle
)
1211 DPRINTF(EthernetDesc
, "rxDesc: addr=%08x read descriptor\n",
1212 regs
.rxdp
& 0x3fffffff);
1213 DPRINTF(EthernetDesc
,
1214 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1215 link
, bufptr
, cmdsts
, extsts
);
1217 if (cmdsts
& CMDSTS_OWN
) {
1218 devIntrPost(ISR_RXIDLE
);
1222 rxState
= rxFifoBlock
;
1224 rxDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1231 * @todo in reality, we should be able to start processing
1232 * the packet as it arrives, and not have to wait for the
1233 * full packet ot be in the receive fifo.
1238 DPRINTF(EthernetSM
, "****processing receive of new packet****\n");
1240 // If we don't have a packet, grab a new one from the fifo.
1241 rxPacket
= rxFifo
.front();
1242 rxPktBytes
= rxPacket
->length
;
1243 rxPacketBufPtr
= rxPacket
->data
;
1246 if (DTRACE(Ethernet
)) {
1249 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1253 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1254 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1261 // sanity check - i think the driver behaves like this
1262 assert(rxDescCnt
>= rxPktBytes
);
1267 // dont' need the && rxDescCnt > 0 if driver sanity check
1269 if (rxPktBytes
> 0) {
1270 rxState
= rxFragWrite
;
1271 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
1273 rxXferLen
= rxPktBytes
;
1275 rxDmaAddr
= rxFragPtr
& 0x3fffffff;
1276 rxDmaData
= rxPacketBufPtr
;
1277 rxDmaLen
= rxXferLen
;
1278 rxDmaFree
= dmaDataFree
;
1284 rxState
= rxDescWrite
;
1286 //if (rxPktBytes == 0) { /* packet is done */
1287 assert(rxPktBytes
== 0);
1288 DPRINTF(EthernetSM
, "done with receiving packet\n");
1290 cmdsts
|= CMDSTS_OWN
;
1291 cmdsts
&= ~CMDSTS_MORE
;
1292 cmdsts
|= CMDSTS_OK
;
1293 cmdsts
&= 0xffff0000;
1294 cmdsts
+= rxPacket
->length
; //i.e. set CMDSTS_SIZE
1298 * all the driver uses these are for its own stats keeping
1299 * which we don't care about, aren't necessary for
1300 * functionality and doing this would just slow us down.
1301 * if they end up using this in a later version for
1302 * functional purposes, just undef
1304 if (rxFilterEnable
) {
1305 cmdsts
&= ~CMDSTS_DEST_MASK
;
1306 const EthAddr
&dst
= rxFifoFront()->dst();
1308 cmdsts
|= CMDSTS_DEST_SELF
;
1309 if (dst
->multicast())
1310 cmdsts
|= CMDSTS_DEST_MULTI
;
1311 if (dst
->broadcast())
1312 cmdsts
|= CMDSTS_DEST_MASK
;
1317 if (extstsEnable
&& ip
) {
1318 extsts
|= EXTSTS_IPPKT
;
1320 if (cksum(ip
) != 0) {
1321 DPRINTF(EthernetCksum
, "Rx IP Checksum Error\n");
1322 extsts
|= EXTSTS_IPERR
;
1327 extsts
|= EXTSTS_TCPPKT
;
1329 if (cksum(tcp
) != 0) {
1330 DPRINTF(EthernetCksum
, "Rx TCP Checksum Error\n");
1331 extsts
|= EXTSTS_TCPERR
;
1335 extsts
|= EXTSTS_UDPPKT
;
1337 if (cksum(udp
) != 0) {
1338 DPRINTF(EthernetCksum
, "Rx UDP Checksum Error\n");
1339 extsts
|= EXTSTS_UDPERR
;
1346 * the driver seems to always receive into desc buffers
1347 * of size 1514, so you never have a pkt that is split
1348 * into multiple descriptors on the receive side, so
1349 * i don't implement that case, hence the assert above.
1352 DPRINTF(EthernetDesc
,
1353 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1354 regs
.rxdp
& 0x3fffffff);
1355 DPRINTF(EthernetDesc
,
1356 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1357 link
, bufptr
, cmdsts
, extsts
);
1359 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1360 rxDmaData
= &cmdsts
;
1362 rxDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1363 rxDmaLen
= sizeof(rxDesc64
.cmdsts
) + sizeof(rxDesc64
.extsts
);
1365 rxDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1366 rxDmaLen
= sizeof(rxDesc32
.cmdsts
) + sizeof(rxDesc32
.extsts
);
1368 rxDmaFree
= dmaDescFree
;
1371 descDmaWrBytes
+= rxDmaLen
;
1379 if (rxDmaState
!= dmaIdle
)
1382 rxPacketBufPtr
+= rxXferLen
;
1383 rxFragPtr
+= rxXferLen
;
1384 rxPktBytes
-= rxXferLen
;
1386 rxState
= rxFifoBlock
;
1390 if (rxDmaState
!= dmaIdle
)
1393 assert(cmdsts
& CMDSTS_OWN
);
1395 assert(rxPacket
== 0);
1396 devIntrPost(ISR_RXOK
);
1398 if (cmdsts
& CMDSTS_INTR
)
1399 devIntrPost(ISR_RXDESC
);
1402 DPRINTF(EthernetSM
, "Halting the RX state machine\n");
1406 rxState
= rxAdvance
;
1411 devIntrPost(ISR_RXIDLE
);
1416 if (rxDmaState
!= dmaIdle
)
1418 rxState
= rxDescRead
;
1422 rxDmaAddr
= regs
.rxdp
& 0x3fffffff;
1423 rxDmaData
= is64bit
? (void *)&rxDesc64
: (void *)&rxDesc32
;
1424 rxDmaLen
= is64bit
? sizeof(rxDesc64
) : sizeof(rxDesc32
);
1425 rxDmaFree
= dmaDescFree
;
1433 panic("Invalid rxState!");
1436 DPRINTF(EthernetSM
, "entering next rxState=%s\n",
1437 NsRxStateStrings
[rxState
]);
1442 * @todo do we want to schedule a future kick?
1444 DPRINTF(EthernetSM
, "rx state machine exited rxState=%s\n",
1445 NsRxStateStrings
[rxState
]);
1447 if (clock
&& !rxKickEvent
.scheduled())
1448 schedule(rxKickEvent
, rxKickTick
);
1454 if (txFifo
.empty()) {
1455 DPRINTF(Ethernet
, "nothing to transmit\n");
1459 DPRINTF(Ethernet
, "Attempt Pkt Transmit: txFifo length=%d\n",
1461 if (interface
->sendPacket(txFifo
.front())) {
1463 if (DTRACE(Ethernet
)) {
1464 IpPtr
ip(txFifo
.front());
1466 DPRINTF(Ethernet
, "ID is %d\n", ip
->id());
1470 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1471 tcp
->sport(), tcp
->dport(), tcp
->seq(),
1478 DDUMP(EthernetData
, txFifo
.front()->data
, txFifo
.front()->length
);
1479 txBytes
+= txFifo
.front()->length
;
1482 DPRINTF(Ethernet
, "Successful Xmit! now txFifoAvail is %d\n",
1487 * normally do a writeback of the descriptor here, and ONLY
1488 * after that is done, send this interrupt. but since our
1489 * stuff never actually fails, just do this interrupt here,
1490 * otherwise the code has to stray from this nice format.
1491 * besides, it's functionally the same.
1493 devIntrPost(ISR_TXOK
);
1496 if (!txFifo
.empty() && !txEvent
.scheduled()) {
1497 DPRINTF(Ethernet
, "reschedule transmit\n");
1498 schedule(txEvent
, curTick() + retryTime
);
1503 NSGigE::doTxDmaRead()
1505 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaReadWaiting
);
1506 txDmaState
= dmaReading
;
1508 if (dmaPending() || getState() != Running
)
1509 txDmaState
= dmaReadWaiting
;
1511 dmaRead(txDmaAddr
, txDmaLen
, &txDmaReadEvent
, (uint8_t*)txDmaData
);
1517 NSGigE::txDmaReadDone()
1519 assert(txDmaState
== dmaReading
);
1520 txDmaState
= dmaIdle
;
1522 DPRINTF(EthernetDMA
, "tx dma read paddr=%#x len=%d\n",
1523 txDmaAddr
, txDmaLen
);
1524 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1526 // If the receive state machine has a pending DMA, let it go first
1527 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1534 NSGigE::doTxDmaWrite()
1536 assert(txDmaState
== dmaIdle
|| txDmaState
== dmaWriteWaiting
);
1537 txDmaState
= dmaWriting
;
1539 if (dmaPending() || getState() != Running
)
1540 txDmaState
= dmaWriteWaiting
;
1542 dmaWrite(txDmaAddr
, txDmaLen
, &txDmaWriteEvent
, (uint8_t*)txDmaData
);
1547 NSGigE::txDmaWriteDone()
1549 assert(txDmaState
== dmaWriting
);
1550 txDmaState
= dmaIdle
;
1552 DPRINTF(EthernetDMA
, "tx dma write paddr=%#x len=%d\n",
1553 txDmaAddr
, txDmaLen
);
1554 DDUMP(EthernetDMA
, txDmaData
, txDmaLen
);
1556 // If the receive state machine has a pending DMA, let it go first
1557 if (rxDmaState
== dmaReadWaiting
|| rxDmaState
== dmaWriteWaiting
)
1566 bool is64bit
= (bool)(regs
.config
& CFGR_M64ADDR
);
1568 DPRINTF(EthernetSM
, "transmit kick txState=%s %d-bit\n",
1569 NsTxStateStrings
[txState
], is64bit
? 64 : 32);
1572 uint32_t &cmdsts
= is64bit
? txDesc64
.cmdsts
: txDesc32
.cmdsts
;
1573 uint32_t &extsts
= is64bit
? txDesc64
.extsts
: txDesc32
.extsts
;
1577 if (txKickTick
> curTick()) {
1578 DPRINTF(EthernetSM
, "transmit kick exiting, can't run till %d\n",
1583 // Go to the next state machine clock tick.
1584 txKickTick
= curTick() + ticks(1);
1587 switch(txDmaState
) {
1588 case dmaReadWaiting
:
1592 case dmaWriteWaiting
:
1600 link
= is64bit
? (Addr
)txDesc64
.link
: (Addr
)txDesc32
.link
;
1601 bufptr
= is64bit
? (Addr
)txDesc64
.bufptr
: (Addr
)txDesc32
.bufptr
;
1605 DPRINTF(EthernetSM
, "Transmit disabled. Nothing to do.\n");
1610 txState
= txDescRefr
;
1612 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1614 is64bit
? (void *)&txDesc64
.link
: (void *)&txDesc32
.link
;
1615 txDmaLen
= is64bit
? sizeof(txDesc64
.link
) : sizeof(txDesc32
.link
);
1616 txDmaFree
= dmaDescFree
;
1619 descDmaRdBytes
+= txDmaLen
;
1625 txState
= txDescRead
;
1627 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1628 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1629 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1630 txDmaFree
= dmaDescFree
;
1633 descDmaRdBytes
+= txDmaLen
;
1641 if (txDmaState
!= dmaIdle
)
1644 txState
= txAdvance
;
1648 if (txDmaState
!= dmaIdle
)
1651 DPRINTF(EthernetDesc
, "txDesc: addr=%08x read descriptor\n",
1652 regs
.txdp
& 0x3fffffff);
1653 DPRINTF(EthernetDesc
,
1654 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1655 link
, bufptr
, cmdsts
, extsts
);
1657 if (cmdsts
& CMDSTS_OWN
) {
1658 txState
= txFifoBlock
;
1660 txDescCnt
= cmdsts
& CMDSTS_LEN_MASK
;
1662 devIntrPost(ISR_TXIDLE
);
1670 DPRINTF(EthernetSM
, "****starting the tx of a new packet****\n");
1671 txPacket
= new EthPacketData(16384);
1672 txPacketBufPtr
= txPacket
->data
;
1675 if (txDescCnt
== 0) {
1676 DPRINTF(EthernetSM
, "the txDescCnt == 0, done with descriptor\n");
1677 if (cmdsts
& CMDSTS_MORE
) {
1678 DPRINTF(EthernetSM
, "there are more descriptors to come\n");
1679 txState
= txDescWrite
;
1681 cmdsts
&= ~CMDSTS_OWN
;
1683 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1684 txDmaData
= &cmdsts
;
1686 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1687 txDmaLen
= sizeof(txDesc64
.cmdsts
);
1689 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1690 txDmaLen
= sizeof(txDesc32
.cmdsts
);
1692 txDmaFree
= dmaDescFree
;
1697 } else { /* this packet is totally done */
1698 DPRINTF(EthernetSM
, "This packet is done, let's wrap it up\n");
1699 /* deal with the the packet that just finished */
1700 if ((regs
.vtcr
& VTCR_PPCHK
) && extstsEnable
) {
1702 if (extsts
& EXTSTS_UDPPKT
) {
1706 udp
->sum(cksum(udp
));
1709 Debug::breakpoint();
1710 warn_once("UDPPKT set, but not UDP!\n");
1712 } else if (extsts
& EXTSTS_TCPPKT
) {
1716 tcp
->sum(cksum(tcp
));
1719 Debug::breakpoint();
1720 warn_once("TCPPKT set, but not UDP!\n");
1723 if (extsts
& EXTSTS_IPPKT
) {
1729 Debug::breakpoint();
1730 warn_once("IPPKT set, but not UDP!\n");
1735 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
1736 // this is just because the receive can't handle a
1737 // packet bigger want to make sure
1738 if (txPacket
->length
> 1514)
1739 panic("transmit packet too large, %s > 1514\n",
1745 txFifo
.push(txPacket
);
1749 * this following section is not tqo spec, but
1750 * functionally shouldn't be any different. normally,
1751 * the chip will wait til the transmit has occurred
1752 * before writing back the descriptor because it has
1753 * to wait to see that it was successfully transmitted
1754 * to decide whether to set CMDSTS_OK or not.
1755 * however, in the simulator since it is always
1756 * successfully transmitted, and writing it exactly to
1757 * spec would complicate the code, we just do it here
1760 cmdsts
&= ~CMDSTS_OWN
;
1761 cmdsts
|= CMDSTS_OK
;
1763 DPRINTF(EthernetDesc
,
1764 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1767 txDmaFree
= dmaDescFree
;
1768 txDmaAddr
= regs
.txdp
& 0x3fffffff;
1769 txDmaData
= &cmdsts
;
1771 txDmaAddr
+= offsetof(ns_desc64
, cmdsts
);
1773 sizeof(txDesc64
.cmdsts
) + sizeof(txDesc64
.extsts
);
1775 txDmaAddr
+= offsetof(ns_desc32
, cmdsts
);
1777 sizeof(txDesc32
.cmdsts
) + sizeof(txDesc32
.extsts
);
1781 descDmaWrBytes
+= txDmaLen
;
1787 DPRINTF(EthernetSM
, "halting TX state machine\n");
1791 txState
= txAdvance
;
1797 DPRINTF(EthernetSM
, "this descriptor isn't done yet\n");
1798 if (!txFifo
.full()) {
1799 txState
= txFragRead
;
1802 * The number of bytes transferred is either whatever
1803 * is left in the descriptor (txDescCnt), or if there
1804 * is not enough room in the fifo, just whatever room
1805 * is left in the fifo
1807 txXferLen
= min
<uint32_t>(txDescCnt
, txFifo
.avail());
1809 txDmaAddr
= txFragPtr
& 0x3fffffff;
1810 txDmaData
= txPacketBufPtr
;
1811 txDmaLen
= txXferLen
;
1812 txDmaFree
= dmaDataFree
;
1817 txState
= txFifoBlock
;
1827 if (txDmaState
!= dmaIdle
)
1830 txPacketBufPtr
+= txXferLen
;
1831 txFragPtr
+= txXferLen
;
1832 txDescCnt
-= txXferLen
;
1833 txFifo
.reserve(txXferLen
);
1835 txState
= txFifoBlock
;
1839 if (txDmaState
!= dmaIdle
)
1842 if (cmdsts
& CMDSTS_INTR
)
1843 devIntrPost(ISR_TXDESC
);
1846 DPRINTF(EthernetSM
, "halting TX state machine\n");
1850 txState
= txAdvance
;
1855 devIntrPost(ISR_TXIDLE
);
1859 if (txDmaState
!= dmaIdle
)
1861 txState
= txDescRead
;
1865 txDmaAddr
= link
& 0x3fffffff;
1866 txDmaData
= is64bit
? (void *)&txDesc64
: (void *)&txDesc32
;
1867 txDmaLen
= is64bit
? sizeof(txDesc64
) : sizeof(txDesc32
);
1868 txDmaFree
= dmaDescFree
;
1876 panic("invalid state");
1879 DPRINTF(EthernetSM
, "entering next txState=%s\n",
1880 NsTxStateStrings
[txState
]);
1885 * @todo do we want to schedule a future kick?
1887 DPRINTF(EthernetSM
, "tx state machine exited txState=%s\n",
1888 NsTxStateStrings
[txState
]);
1890 if (clock
&& !txKickEvent
.scheduled())
1891 schedule(txKickEvent
, txKickTick
);
1895 * Advance the EEPROM state machine
1896 * Called on rising edge of EEPROM clock bit in MEAR
1899 NSGigE::eepromKick()
1901 switch (eepromState
) {
1905 // Wait for start bit
1906 if (regs
.mear
& MEAR_EEDI
) {
1907 // Set up to get 2 opcode bits
1908 eepromState
= eepromGetOpcode
;
1914 case eepromGetOpcode
:
1916 eepromOpcode
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1919 // Done getting opcode
1920 if (eepromBitsToRx
== 0) {
1921 if (eepromOpcode
!= EEPROM_READ
)
1922 panic("only EEPROM reads are implemented!");
1924 // Set up to get address
1925 eepromState
= eepromGetAddress
;
1931 case eepromGetAddress
:
1932 eepromAddress
<<= 1;
1933 eepromAddress
+= (regs
.mear
& MEAR_EEDI
) ? 1 : 0;
1936 // Done getting address
1937 if (eepromBitsToRx
== 0) {
1939 if (eepromAddress
>= EEPROM_SIZE
)
1940 panic("EEPROM read access out of range!");
1942 switch (eepromAddress
) {
1944 case EEPROM_PMATCH2_ADDR
:
1945 eepromData
= rom
.perfectMatch
[5];
1947 eepromData
+= rom
.perfectMatch
[4];
1950 case EEPROM_PMATCH1_ADDR
:
1951 eepromData
= rom
.perfectMatch
[3];
1953 eepromData
+= rom
.perfectMatch
[2];
1956 case EEPROM_PMATCH0_ADDR
:
1957 eepromData
= rom
.perfectMatch
[1];
1959 eepromData
+= rom
.perfectMatch
[0];
1963 panic("FreeBSD driver only uses EEPROM to read PMATCH!");
1965 // Set up to read data
1966 eepromState
= eepromRead
;
1967 eepromBitsToRx
= 16;
1969 // Clear data in bit
1970 regs
.mear
&= ~MEAR_EEDI
;
1975 // Clear Data Out bit
1976 regs
.mear
&= ~MEAR_EEDO
;
1977 // Set bit to value of current EEPROM bit
1978 regs
.mear
|= (eepromData
& 0x8000) ? MEAR_EEDO
: 0x0;
1984 if (eepromBitsToRx
== 0) {
1985 eepromState
= eepromStart
;
1990 panic("invalid EEPROM state");
1996 NSGigE::transferDone()
1998 if (txFifo
.empty()) {
1999 DPRINTF(Ethernet
, "transfer complete: txFifo empty...nothing to do\n");
2003 DPRINTF(Ethernet
, "transfer complete: data in txFifo...schedule xmit\n");
2005 reschedule(txEvent
, curTick() + ticks(1), true);
2009 NSGigE::rxFilter(const EthPacketPtr
&packet
)
2011 EthPtr eth
= packet
;
2015 const EthAddr
&dst
= eth
->dst();
2016 if (dst
.unicast()) {
2017 // If we're accepting all unicast addresses
2021 // If we make a perfect match
2022 if (acceptPerfect
&& dst
== rom
.perfectMatch
)
2025 if (acceptArp
&& eth
->type() == ETH_TYPE_ARP
)
2028 } else if (dst
.broadcast()) {
2029 // if we're accepting broadcasts
2030 if (acceptBroadcast
)
2033 } else if (dst
.multicast()) {
2034 // if we're accepting all multicasts
2035 if (acceptMulticast
)
2038 // Multicast hashing faked - all packets accepted
2039 if (multicastHashEnable
)
2044 DPRINTF(Ethernet
, "rxFilter drop\n");
2045 DDUMP(EthernetData
, packet
->data
, packet
->length
);
2052 NSGigE::recvPacket(EthPacketPtr packet
)
2054 rxBytes
+= packet
->length
;
2057 DPRINTF(Ethernet
, "Receiving packet from wire, rxFifoAvail=%d\n",
2061 DPRINTF(Ethernet
, "receive disabled...packet dropped\n");
2065 if (!rxFilterEnable
) {
2067 "receive packet filtering disabled . . . packet dropped\n");
2071 if (rxFilter(packet
)) {
2072 DPRINTF(Ethernet
, "packet filtered...dropped\n");
2076 if (rxFifo
.avail() < packet
->length
) {
2082 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2085 DPRINTF(Ethernet
, "Seq=%d\n", tcp
->seq());
2090 devIntrPost(ISR_RXORN
);
2094 rxFifo
.push(packet
);
2104 SimObject::resume();
2106 // During drain we could have left the state machines in a waiting state and
2107 // they wouldn't get out until some other event occured to kick them.
2108 // This way they'll get out immediately
2114 //=====================================================================
2118 NSGigE::serialize(ostream
&os
)
2120 // Serialize the PciDev base class
2121 PciDev::serialize(os
);
2124 * Finalize any DMA events now.
2126 // @todo will mem system save pending dma?
2129 * Serialize the device registers
2131 SERIALIZE_SCALAR(regs
.command
);
2132 SERIALIZE_SCALAR(regs
.config
);
2133 SERIALIZE_SCALAR(regs
.mear
);
2134 SERIALIZE_SCALAR(regs
.ptscr
);
2135 SERIALIZE_SCALAR(regs
.isr
);
2136 SERIALIZE_SCALAR(regs
.imr
);
2137 SERIALIZE_SCALAR(regs
.ier
);
2138 SERIALIZE_SCALAR(regs
.ihr
);
2139 SERIALIZE_SCALAR(regs
.txdp
);
2140 SERIALIZE_SCALAR(regs
.txdp_hi
);
2141 SERIALIZE_SCALAR(regs
.txcfg
);
2142 SERIALIZE_SCALAR(regs
.gpior
);
2143 SERIALIZE_SCALAR(regs
.rxdp
);
2144 SERIALIZE_SCALAR(regs
.rxdp_hi
);
2145 SERIALIZE_SCALAR(regs
.rxcfg
);
2146 SERIALIZE_SCALAR(regs
.pqcr
);
2147 SERIALIZE_SCALAR(regs
.wcsr
);
2148 SERIALIZE_SCALAR(regs
.pcr
);
2149 SERIALIZE_SCALAR(regs
.rfcr
);
2150 SERIALIZE_SCALAR(regs
.rfdr
);
2151 SERIALIZE_SCALAR(regs
.brar
);
2152 SERIALIZE_SCALAR(regs
.brdr
);
2153 SERIALIZE_SCALAR(regs
.srr
);
2154 SERIALIZE_SCALAR(regs
.mibc
);
2155 SERIALIZE_SCALAR(regs
.vrcr
);
2156 SERIALIZE_SCALAR(regs
.vtcr
);
2157 SERIALIZE_SCALAR(regs
.vdr
);
2158 SERIALIZE_SCALAR(regs
.ccsr
);
2159 SERIALIZE_SCALAR(regs
.tbicr
);
2160 SERIALIZE_SCALAR(regs
.tbisr
);
2161 SERIALIZE_SCALAR(regs
.tanar
);
2162 SERIALIZE_SCALAR(regs
.tanlpar
);
2163 SERIALIZE_SCALAR(regs
.taner
);
2164 SERIALIZE_SCALAR(regs
.tesr
);
2166 SERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2167 SERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2169 SERIALIZE_SCALAR(ioEnable
);
2172 * Serialize the data Fifos
2174 rxFifo
.serialize("rxFifo", os
);
2175 txFifo
.serialize("txFifo", os
);
2178 * Serialize the various helper variables
2180 bool txPacketExists
= txPacket
;
2181 SERIALIZE_SCALAR(txPacketExists
);
2182 if (txPacketExists
) {
2183 txPacket
->length
= txPacketBufPtr
- txPacket
->data
;
2184 txPacket
->serialize("txPacket", os
);
2185 uint32_t txPktBufPtr
= (uint32_t) (txPacketBufPtr
- txPacket
->data
);
2186 SERIALIZE_SCALAR(txPktBufPtr
);
2189 bool rxPacketExists
= rxPacket
;
2190 SERIALIZE_SCALAR(rxPacketExists
);
2191 if (rxPacketExists
) {
2192 rxPacket
->serialize("rxPacket", os
);
2193 uint32_t rxPktBufPtr
= (uint32_t) (rxPacketBufPtr
- rxPacket
->data
);
2194 SERIALIZE_SCALAR(rxPktBufPtr
);
2197 SERIALIZE_SCALAR(txXferLen
);
2198 SERIALIZE_SCALAR(rxXferLen
);
2201 * Serialize Cached Descriptors
2203 SERIALIZE_SCALAR(rxDesc64
.link
);
2204 SERIALIZE_SCALAR(rxDesc64
.bufptr
);
2205 SERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2206 SERIALIZE_SCALAR(rxDesc64
.extsts
);
2207 SERIALIZE_SCALAR(txDesc64
.link
);
2208 SERIALIZE_SCALAR(txDesc64
.bufptr
);
2209 SERIALIZE_SCALAR(txDesc64
.cmdsts
);
2210 SERIALIZE_SCALAR(txDesc64
.extsts
);
2211 SERIALIZE_SCALAR(rxDesc32
.link
);
2212 SERIALIZE_SCALAR(rxDesc32
.bufptr
);
2213 SERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2214 SERIALIZE_SCALAR(rxDesc32
.extsts
);
2215 SERIALIZE_SCALAR(txDesc32
.link
);
2216 SERIALIZE_SCALAR(txDesc32
.bufptr
);
2217 SERIALIZE_SCALAR(txDesc32
.cmdsts
);
2218 SERIALIZE_SCALAR(txDesc32
.extsts
);
2219 SERIALIZE_SCALAR(extstsEnable
);
2222 * Serialize tx state machine
2224 int txState
= this->txState
;
2225 SERIALIZE_SCALAR(txState
);
2226 SERIALIZE_SCALAR(txEnable
);
2227 SERIALIZE_SCALAR(CTDD
);
2228 SERIALIZE_SCALAR(txFragPtr
);
2229 SERIALIZE_SCALAR(txDescCnt
);
2230 int txDmaState
= this->txDmaState
;
2231 SERIALIZE_SCALAR(txDmaState
);
2232 SERIALIZE_SCALAR(txKickTick
);
2235 * Serialize rx state machine
2237 int rxState
= this->rxState
;
2238 SERIALIZE_SCALAR(rxState
);
2239 SERIALIZE_SCALAR(rxEnable
);
2240 SERIALIZE_SCALAR(CRDD
);
2241 SERIALIZE_SCALAR(rxPktBytes
);
2242 SERIALIZE_SCALAR(rxFragPtr
);
2243 SERIALIZE_SCALAR(rxDescCnt
);
2244 int rxDmaState
= this->rxDmaState
;
2245 SERIALIZE_SCALAR(rxDmaState
);
2246 SERIALIZE_SCALAR(rxKickTick
);
2249 * Serialize EEPROM state machine
2251 int eepromState
= this->eepromState
;
2252 SERIALIZE_SCALAR(eepromState
);
2253 SERIALIZE_SCALAR(eepromClk
);
2254 SERIALIZE_SCALAR(eepromBitsToRx
);
2255 SERIALIZE_SCALAR(eepromOpcode
);
2256 SERIALIZE_SCALAR(eepromAddress
);
2257 SERIALIZE_SCALAR(eepromData
);
2260 * If there's a pending transmit, store the time so we can
2261 * reschedule it later
2263 Tick transmitTick
= txEvent
.scheduled() ? txEvent
.when() - curTick() : 0;
2264 SERIALIZE_SCALAR(transmitTick
);
2267 * receive address filter settings
2269 SERIALIZE_SCALAR(rxFilterEnable
);
2270 SERIALIZE_SCALAR(acceptBroadcast
);
2271 SERIALIZE_SCALAR(acceptMulticast
);
2272 SERIALIZE_SCALAR(acceptUnicast
);
2273 SERIALIZE_SCALAR(acceptPerfect
);
2274 SERIALIZE_SCALAR(acceptArp
);
2275 SERIALIZE_SCALAR(multicastHashEnable
);
2278 * Keep track of pending interrupt status.
2280 SERIALIZE_SCALAR(intrTick
);
2281 SERIALIZE_SCALAR(cpuPendingIntr
);
2282 Tick intrEventTick
= 0;
2284 intrEventTick
= intrEvent
->when();
2285 SERIALIZE_SCALAR(intrEventTick
);
2290 NSGigE::unserialize(Checkpoint
*cp
, const std::string
§ion
)
2292 // Unserialize the PciDev base class
2293 PciDev::unserialize(cp
, section
);
2295 UNSERIALIZE_SCALAR(regs
.command
);
2296 UNSERIALIZE_SCALAR(regs
.config
);
2297 UNSERIALIZE_SCALAR(regs
.mear
);
2298 UNSERIALIZE_SCALAR(regs
.ptscr
);
2299 UNSERIALIZE_SCALAR(regs
.isr
);
2300 UNSERIALIZE_SCALAR(regs
.imr
);
2301 UNSERIALIZE_SCALAR(regs
.ier
);
2302 UNSERIALIZE_SCALAR(regs
.ihr
);
2303 UNSERIALIZE_SCALAR(regs
.txdp
);
2304 UNSERIALIZE_SCALAR(regs
.txdp_hi
);
2305 UNSERIALIZE_SCALAR(regs
.txcfg
);
2306 UNSERIALIZE_SCALAR(regs
.gpior
);
2307 UNSERIALIZE_SCALAR(regs
.rxdp
);
2308 UNSERIALIZE_SCALAR(regs
.rxdp_hi
);
2309 UNSERIALIZE_SCALAR(regs
.rxcfg
);
2310 UNSERIALIZE_SCALAR(regs
.pqcr
);
2311 UNSERIALIZE_SCALAR(regs
.wcsr
);
2312 UNSERIALIZE_SCALAR(regs
.pcr
);
2313 UNSERIALIZE_SCALAR(regs
.rfcr
);
2314 UNSERIALIZE_SCALAR(regs
.rfdr
);
2315 UNSERIALIZE_SCALAR(regs
.brar
);
2316 UNSERIALIZE_SCALAR(regs
.brdr
);
2317 UNSERIALIZE_SCALAR(regs
.srr
);
2318 UNSERIALIZE_SCALAR(regs
.mibc
);
2319 UNSERIALIZE_SCALAR(regs
.vrcr
);
2320 UNSERIALIZE_SCALAR(regs
.vtcr
);
2321 UNSERIALIZE_SCALAR(regs
.vdr
);
2322 UNSERIALIZE_SCALAR(regs
.ccsr
);
2323 UNSERIALIZE_SCALAR(regs
.tbicr
);
2324 UNSERIALIZE_SCALAR(regs
.tbisr
);
2325 UNSERIALIZE_SCALAR(regs
.tanar
);
2326 UNSERIALIZE_SCALAR(regs
.tanlpar
);
2327 UNSERIALIZE_SCALAR(regs
.taner
);
2328 UNSERIALIZE_SCALAR(regs
.tesr
);
2330 UNSERIALIZE_ARRAY(rom
.perfectMatch
, ETH_ADDR_LEN
);
2331 UNSERIALIZE_ARRAY(rom
.filterHash
, FHASH_SIZE
);
2333 UNSERIALIZE_SCALAR(ioEnable
);
2336 * unserialize the data fifos
2338 rxFifo
.unserialize("rxFifo", cp
, section
);
2339 txFifo
.unserialize("txFifo", cp
, section
);
2342 * unserialize the various helper variables
2344 bool txPacketExists
;
2345 UNSERIALIZE_SCALAR(txPacketExists
);
2346 if (txPacketExists
) {
2347 txPacket
= new EthPacketData(16384);
2348 txPacket
->unserialize("txPacket", cp
, section
);
2349 uint32_t txPktBufPtr
;
2350 UNSERIALIZE_SCALAR(txPktBufPtr
);
2351 txPacketBufPtr
= (uint8_t *) txPacket
->data
+ txPktBufPtr
;
2355 bool rxPacketExists
;
2356 UNSERIALIZE_SCALAR(rxPacketExists
);
2358 if (rxPacketExists
) {
2359 rxPacket
= new EthPacketData(16384);
2360 rxPacket
->unserialize("rxPacket", cp
, section
);
2361 uint32_t rxPktBufPtr
;
2362 UNSERIALIZE_SCALAR(rxPktBufPtr
);
2363 rxPacketBufPtr
= (uint8_t *) rxPacket
->data
+ rxPktBufPtr
;
2367 UNSERIALIZE_SCALAR(txXferLen
);
2368 UNSERIALIZE_SCALAR(rxXferLen
);
2371 * Unserialize Cached Descriptors
2373 UNSERIALIZE_SCALAR(rxDesc64
.link
);
2374 UNSERIALIZE_SCALAR(rxDesc64
.bufptr
);
2375 UNSERIALIZE_SCALAR(rxDesc64
.cmdsts
);
2376 UNSERIALIZE_SCALAR(rxDesc64
.extsts
);
2377 UNSERIALIZE_SCALAR(txDesc64
.link
);
2378 UNSERIALIZE_SCALAR(txDesc64
.bufptr
);
2379 UNSERIALIZE_SCALAR(txDesc64
.cmdsts
);
2380 UNSERIALIZE_SCALAR(txDesc64
.extsts
);
2381 UNSERIALIZE_SCALAR(rxDesc32
.link
);
2382 UNSERIALIZE_SCALAR(rxDesc32
.bufptr
);
2383 UNSERIALIZE_SCALAR(rxDesc32
.cmdsts
);
2384 UNSERIALIZE_SCALAR(rxDesc32
.extsts
);
2385 UNSERIALIZE_SCALAR(txDesc32
.link
);
2386 UNSERIALIZE_SCALAR(txDesc32
.bufptr
);
2387 UNSERIALIZE_SCALAR(txDesc32
.cmdsts
);
2388 UNSERIALIZE_SCALAR(txDesc32
.extsts
);
2389 UNSERIALIZE_SCALAR(extstsEnable
);
2392 * unserialize tx state machine
2395 UNSERIALIZE_SCALAR(txState
);
2396 this->txState
= (TxState
) txState
;
2397 UNSERIALIZE_SCALAR(txEnable
);
2398 UNSERIALIZE_SCALAR(CTDD
);
2399 UNSERIALIZE_SCALAR(txFragPtr
);
2400 UNSERIALIZE_SCALAR(txDescCnt
);
2402 UNSERIALIZE_SCALAR(txDmaState
);
2403 this->txDmaState
= (DmaState
) txDmaState
;
2404 UNSERIALIZE_SCALAR(txKickTick
);
2406 schedule(txKickEvent
, txKickTick
);
2409 * unserialize rx state machine
2412 UNSERIALIZE_SCALAR(rxState
);
2413 this->rxState
= (RxState
) rxState
;
2414 UNSERIALIZE_SCALAR(rxEnable
);
2415 UNSERIALIZE_SCALAR(CRDD
);
2416 UNSERIALIZE_SCALAR(rxPktBytes
);
2417 UNSERIALIZE_SCALAR(rxFragPtr
);
2418 UNSERIALIZE_SCALAR(rxDescCnt
);
2420 UNSERIALIZE_SCALAR(rxDmaState
);
2421 this->rxDmaState
= (DmaState
) rxDmaState
;
2422 UNSERIALIZE_SCALAR(rxKickTick
);
2424 schedule(rxKickEvent
, rxKickTick
);
2427 * Unserialize EEPROM state machine
2430 UNSERIALIZE_SCALAR(eepromState
);
2431 this->eepromState
= (EEPROMState
) eepromState
;
2432 UNSERIALIZE_SCALAR(eepromClk
);
2433 UNSERIALIZE_SCALAR(eepromBitsToRx
);
2434 UNSERIALIZE_SCALAR(eepromOpcode
);
2435 UNSERIALIZE_SCALAR(eepromAddress
);
2436 UNSERIALIZE_SCALAR(eepromData
);
2439 * If there's a pending transmit, reschedule it now
2442 UNSERIALIZE_SCALAR(transmitTick
);
2444 schedule(txEvent
, curTick() + transmitTick
);
2447 * unserialize receive address filter settings
2449 UNSERIALIZE_SCALAR(rxFilterEnable
);
2450 UNSERIALIZE_SCALAR(acceptBroadcast
);
2451 UNSERIALIZE_SCALAR(acceptMulticast
);
2452 UNSERIALIZE_SCALAR(acceptUnicast
);
2453 UNSERIALIZE_SCALAR(acceptPerfect
);
2454 UNSERIALIZE_SCALAR(acceptArp
);
2455 UNSERIALIZE_SCALAR(multicastHashEnable
);
2458 * Keep track of pending interrupt status.
2460 UNSERIALIZE_SCALAR(intrTick
);
2461 UNSERIALIZE_SCALAR(cpuPendingIntr
);
2463 UNSERIALIZE_SCALAR(intrEventTick
);
2464 if (intrEventTick
) {
2465 intrEvent
= new IntrEvent(this, true);
2466 schedule(intrEvent
, intrEventTick
);
2471 NSGigEParams::create()
2473 return new NSGigE(this);