43 #include "debug/EthernetAll.hh" 47 #include "params/NSGigE.hh" 52 using std::make_shared;
96 txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
97 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
98 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
99 txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
100 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
101 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
102 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
103 eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
104 eepromOpcode(0), eepromAddress(0), eepromData(0),
105 dmaReadDelay(p->dma_read_delay), dmaWriteDelay(p->dma_write_delay),
106 dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor),
107 rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
108 txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
128 interface = new NSGigEInt(name() + ".int0", this);
154 panic(
"Device specific PCI config space not implemented!\n");
174 if (if_name ==
"interface")
190 DPRINTF(EthernetPIO,
"read da=%#x pa=%#x size=%d\n",
197 panic(
"Accessing reserved register");
198 }
else if (daddr >
RESERVED && daddr <= 0x3FC) {
204 pkt->
setLE<uint32_t>(0);
207 }
else if (daddr > 0x3FC)
208 panic(
"Something is messed up!\n");
210 assert(pkt->
getSize() ==
sizeof(uint32_t));
211 uint32_t &
reg = *pkt->
getPtr<uint32_t>();
323 panic(
"unaligned read from filter hash table!");
330 panic(
"reading RFDR for something other than pattern" 331 " matching or hashing! %#x\n", rfaddr);
395 panic(
"reading unimplemented register: addr=%#x", daddr);
398 DPRINTF(EthernetPIO,
"read from %#x: data=%d data=%#x\n",
411 DPRINTF(EthernetPIO,
"write da=%#x pa=%#x size=%d\n",
415 panic(
"Accessing reserved register");
416 }
else if (daddr >
RESERVED && daddr <= 0x3FC) {
418 }
else if (daddr > 0x3FC)
419 panic(
"Something is messed up!\n");
421 if (pkt->
getSize() ==
sizeof(uint32_t)) {
422 uint32_t
reg = pkt->
getLE<uint32_t>();
425 DPRINTF(EthernetPIO,
"write data=%d data=%#x\n", reg, reg);
432 }
else if (reg &
CR_TXE) {
442 }
else if (reg &
CR_RXE) {
484 panic(
"CFGR_AUTO_1000 not implemented!\n");
486 if (reg & CFGR_PCI64_DET)
487 panic(
"CFGR_PCI64_DET is read only register!\n");
531 panic(
"ISR is a read only register!\n");
616 panic(
"Unicast hash filtering not used by drivers!\n");
619 panic(
"RFCR_ULM not implemented!\n");
645 panic(
"unaligned write to filter hash table!");
649 = (uint8_t)(reg >> 8);
652 panic(
"writing RFDR for something other than pattern matching " 653 "or hashing! %#x\n", rfaddr);
662 panic(
"the driver never uses BRDR, something is wrong!\n");
665 panic(
"SRR is read only register!\n");
668 panic(
"the driver never uses MIBC, something is wrong!\n");
679 panic(
"the driver never uses VDR, something is wrong!\n");
689 panic(
"TBICR_MR_LOOPBACK never used, something wrong!\n");
699 panic(
"TBISR is read only register!\n");
710 panic(
"this should only be written to by the fake phy!\n");
713 panic(
"TANER is read only register!\n");
720 panic(
"invalid register access daddr=%#x", daddr);
723 panic(
"Invalid Request Size");
733 panic(
"Cannot set a reserved interrupt");
736 warn(
"interrupt not implemented %#x\n", interrupts);
769 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
790 panic(
"Cannot clear a reserved interrupt");
821 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
831 DPRINTF(EthernetIntr,
"interrupt mask changed: isr=%x imr=%x masked=%x\n",
855 DPRINTF(EthernetIntr,
"don't need to schedule event...intrTick=%d\n",
865 DPRINTF(EthernetIntr,
"going to schedule an interrupt for intrTick=%d\n",
889 "would send an interrupt now, but there's already pending\n");
894 DPRINTF(EthernetIntr,
"posting interrupt\n");
914 DPRINTF(EthernetIntr,
"clearing interrupt\n");
926 DPRINTF(Ethernet,
"transmit reset\n");
940 DPRINTF(Ethernet,
"receive reset\n");
995 DPRINTF(EthernetDMA,
"rx dma read paddr=%#x len=%d\n",
1025 DPRINTF(EthernetDMA,
"rx dma write paddr=%#x len=%d\n",
1042 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1051 DPRINTF(EthernetSM,
"receive kick exiting, can't run till %d\n",
1086 DPRINTF(EthernetSM,
"Receive Disabled! Nothing to do.\n");
1131 DPRINTF(EthernetDesc,
"rxDesc: addr=%08x read descriptor\n",
1134 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1135 link, bufptr, cmdsts, extsts);
1158 DPRINTF(EthernetSM,
"****processing receive of new packet****\n");
1169 DPRINTF(Ethernet,
"ID is %d\n", ip->
id());
1173 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1174 tcp->sport(), tcp->dport(), tcp->seq(),
1208 DPRINTF(EthernetSM,
"done with receiving packet\n");
1213 cmdsts &= 0xffff0000;
1220 if (
cksum(ip) != 0) {
1221 DPRINTF(EthernetCksum,
"Rx IP Checksum Error\n");
1229 if (
cksum(tcp) != 0) {
1230 DPRINTF(EthernetCksum,
"Rx TCP Checksum Error\n");
1237 if (
cksum(udp) != 0) {
1238 DPRINTF(EthernetCksum,
"Rx UDP Checksum Error\n");
1253 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1256 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1257 link, bufptr, cmdsts, extsts);
1293 assert(cmdsts & CMDSTS_OWN);
1302 DPRINTF(EthernetSM,
"Halting the RX state machine\n");
1333 panic(
"Invalid rxState!");
1336 DPRINTF(EthernetSM,
"entering next rxState=%s\n",
1344 DPRINTF(EthernetSM,
"rx state machine exited rxState=%s\n",
1355 DPRINTF(Ethernet,
"nothing to transmit\n");
1359 DPRINTF(Ethernet,
"Attempt Pkt Transmit: txFifo length=%d\n",
1366 DPRINTF(Ethernet,
"ID is %d\n",
ip->id());
1370 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1371 tcp->sport(), tcp->dport(), tcp->seq(),
1382 DPRINTF(Ethernet,
"Successful Xmit! now txFifoAvail is %d\n",
1397 DPRINTF(Ethernet,
"reschedule transmit\n");
1422 DPRINTF(EthernetDMA,
"tx dma read paddr=%#x len=%d\n",
1452 DPRINTF(EthernetDMA,
"tx dma write paddr=%#x len=%d\n",
1468 DPRINTF(EthernetSM,
"transmit kick txState=%s %d-bit\n",
1477 DPRINTF(EthernetSM,
"transmit kick exiting, can't run till %d\n",
1503 DPRINTF(EthernetSM,
"Transmit disabled. Nothing to do.\n");
1549 DPRINTF(EthernetDesc,
"txDesc: addr=%08x read descriptor\n",
1552 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1553 link, bufptr, cmdsts, extsts);
1568 DPRINTF(EthernetSM,
"****starting the tx of a new packet****\n");
1569 txPacket = make_shared<EthPacketData>(16384);
1574 DPRINTF(EthernetSM,
"the txDescCnt == 0, done with descriptor\n");
1576 DPRINTF(EthernetSM,
"there are more descriptors to come\n");
1579 cmdsts &= ~CMDSTS_OWN;
1596 DPRINTF(EthernetSM,
"This packet is done, let's wrap it up\n");
1608 warn_once(
"UDPPKT set, but not UDP!\n");
1617 warn_once(
"TCPPKT set, but not UDP!\n");
1636 panic(
"transmit packet too large, %s > 1514\n",
1657 cmdsts &= ~CMDSTS_OWN;
1661 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1684 DPRINTF(EthernetSM,
"halting TX state machine\n");
1694 DPRINTF(EthernetSM,
"this descriptor isn't done yet\n");
1743 DPRINTF(EthernetSM,
"halting TX state machine\n");
1773 panic(
"invalid state");
1776 DPRINTF(EthernetSM,
"entering next txState=%s\n",
1784 DPRINTF(EthernetSM,
"tx state machine exited txState=%s\n",
1819 panic(
"only EEPROM reads are implemented!");
1837 panic(
"EEPROM read access out of range!");
1860 panic(
"FreeBSD driver only uses EEPROM to read PMATCH!");
1887 panic(
"invalid EEPROM state");
1896 DPRINTF(Ethernet,
"transfer complete: txFifo empty...nothing to do\n");
1900 DPRINTF(Ethernet,
"transfer complete: data in txFifo...schedule xmit\n");
1941 DPRINTF(Ethernet,
"rxFilter drop\n");
1942 DDUMP(EthernetData, packet->data, packet->length);
1954 DPRINTF(Ethernet,
"Receiving packet from wire, rxFifoAvail=%d\n",
1958 DPRINTF(Ethernet,
"receive disabled...packet dropped\n");
1964 "receive packet filtering disabled . . . packet dropped\n");
1969 DPRINTF(Ethernet,
"packet filtered...dropped\n");
1979 "packet won't fit in receive buffer...pkt ID %d dropped\n",
2077 bool txPacketExists =
txPacket !=
nullptr;
2079 if (txPacketExists) {
2082 txPacket->serialize(
"txPacket", cp);
2087 bool rxPacketExists =
rxPacket !=
nullptr;
2089 if (rxPacketExists) {
2090 rxPacket->serialize(
"rxPacket", cp);
2180 Tick intrEventTick = 0;
2242 bool txPacketExists;
2244 if (txPacketExists) {
2245 txPacket = make_shared<EthPacketData>(16384);
2246 txPacket->unserialize(
"txPacket", cp);
2247 uint32_t txPktBufPtr;
2253 bool rxPacketExists;
2256 if (rxPacketExists) {
2257 rxPacket = make_shared<EthPacketData>();
2258 rxPacket->unserialize(
"rxPacket", cp);
2259 uint32_t rxPktBufPtr;
2294 this->txState = (
TxState) txState;
2301 this->txDmaState = (
DmaState) txDmaState;
2311 this->rxState = (
RxState) rxState;
2319 this->rxDmaState = (
DmaState) rxDmaState;
2362 if (intrEventTick) {
2370 NSGigEParams::create()
#define panic(...)
This implements a cprintf based panic() function.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Ports are used to interface objects to each other.
Cycles is a wrapper class for representing cycle counts, i.e.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Stats::Scalar totalRxIdle
EventFunctionWrapper txDmaReadEvent
const uint8_t EEPROM_READ
virtual void drainResume()
Resume execution after a successful drain.
Stats::Scalar descDmaReads
Addr rxFragPtr
ptr to the next byte in current fragment
void unserialize(const std::string &base, CheckpointIn &cp)
Stats::Scalar descDmaWrites
void cpuIntrPost(Tick when)
Dummy class to keep the Python class hierarchy in sync with the C++ object hierarchy.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
dp_regs regs
device register file
uint16_t cksum(const IpPtr &ptr)
EEPROMState
EEPROM State Machine States.
const char * NsRxStateStrings[]
EventFunctionWrapper rxDmaWriteEvent
void squash()
Squash the current event.
Stats::Scalar rxIpChecksums
const uint8_t EEPROM_PMATCH2_ADDR
const Params * params() const
Stats::Scalar rxUdpChecksums
EventFunctionWrapper txDmaWriteEvent
#define DDUMP(x, data, count)
TxState
Transmit State Machine states.
Stats::Scalar postedRxIdle
EEPROMState eepromState
EEPROM State Machine.
const EthAddr & dst() const
Stats::Scalar totalRxDesc
Stats::Scalar rxTcpChecksums
const uint16_t FHASH_SIZE
T * getPtr()
get a pointer to the data ptr.
uint32_t rxDescCnt
count of bytes remaining in the current descriptor
EventFunctionWrapper rxDmaReadEvent
void setLE(T v)
Set the value in the data pointer to v as little endian.
Stats::Scalar postedTxDesc
Device module for modelling the National Semiconductor DP83820 ethernet controller.
DrainState drainState() const
Return the current drain state of an object.
Addr txFragPtr
ptr to the next byte in the current fragment
#define UNSERIALIZE_SCALAR(scalar)
ns_desc32 txDesc32
DescCaches.
Tick curTick()
The current simulated tick.
const uint8_t EEPROM_PMATCH0_ADDR
bool cpuIntrPending() const
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void makeAtomicResponse()
Stats::Scalar totalTxDesc
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
uint64_t Tick
Tick count type.
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
const uint8_t EEPROM_SIZE
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
void drainResume() override
Resume execution after a successful drain.
const uint8_t EEPROM_PMATCH1_ADDR
bool CTDD
Current Transmit Descriptor Done.
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Stats::Scalar descDmaWrBytes
Stats::Scalar txIpChecksums
Stats::Scalar postedTxIdle
std::shared_ptr< EthPacketData > EthPacketPtr
void schedule(Event &event, Tick when)
Stats::Scalar droppedPackets
Stats::Scalar descDmaRdBytes
#define PCI_DEVICE_SPECIFIC
unsigned reserve(unsigned len=0)
void transmit()
Retransmit event.
void reschedule(Event &event, Tick when, bool always=false)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool ioEnable
pci settings
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const uint16_t FHASH_ADDR
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
#define SERIALIZE_ARRAY(member, size)
bool rxFilter(const EthPacketPtr &packet)
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Stats::Scalar totalTxIdle
RxState
Receive State Machine States.
#define SERIALIZE_SCALAR(scalar)
const char * NsTxStateStrings[]
EventFunctionWrapper * intrEvent
bool scheduled() const
Determine if the current event is scheduled.
EventFunctionWrapper rxKickEvent
bool sendPacket(EthPacketPtr packet)
void serialize(CheckpointOut &cp) const override
Serialize an object.
Stats::Scalar txUdpChecksums
EthPacketPtr txPacket
various helper vars
Stats::Scalar postedRxOrn
virtual const std::string name() const
#define UNSERIALIZE_ARRAY(member, size)
uint8_t filterHash[FHASH_SIZE]
for hash table memory.
EventFunctionWrapper txKickEvent
Stats::Scalar postedRxDesc
Tick writeConfig(PacketPtr pkt) override
This is to write to the PCI general configuration registers.
Tick read(PacketPtr pkt) override
This reads the device registers, which are detailed in the NS83820 spec sheet.
Declaration of the Packet class.
std::ostream CheckpointOut
EventFunctionWrapper txEvent
uint8_t perfectMatch[ETH_ADDR_LEN]
for perfect match memory.
uint32_t txDescCnt
count of bytes remaining in the current descriptor
void devIntrPost(uint32_t interrupts)
Interrupt management.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
bool rxFilterEnable
receive address filter
RxState rxState
rx State Machine
NS DP83820 Ethernet device model.
bool CRDD
Current Receive Descriptor Done.
void devIntrClear(uint32_t interrupts)
bool push(EthPacketPtr ptr)
void serialize(const std::string &base, CheckpointOut &cp) const
Serialization stuff.
PCIConfig config
The current config space.
Stats::Scalar postedInterrupts
Tick when() const
Get the time that the event is scheduled.
const char * NsDmaState[]
void eepromKick()
Advance the EEPROM state machine Called on rising edge of EEPROM clock bit in MEAR.
uint32_t rxPktBytes
num of bytes in the current packet being drained from rxDataFifo
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Stats::Scalar txTcpChecksums
bool recvPacket(EthPacketPtr packet)