ns_gige.cc revision 1893
11156SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31156SN/A * All rights reserved. 41156SN/A * 51156SN/A * Redistribution and use in source and binary forms, with or without 61156SN/A * modification, are permitted provided that the following conditions are 71156SN/A * met: redistributions of source code must retain the above copyright 81156SN/A * notice, this list of conditions and the following disclaimer; 91156SN/A * redistributions in binary form must reproduce the above copyright 101156SN/A * notice, this list of conditions and the following disclaimer in the 111156SN/A * documentation and/or other materials provided with the distribution; 121156SN/A * neither the name of the copyright holders nor the names of its 131156SN/A * contributors may be used to endorse or promote products derived from 141156SN/A * this software without specific prior written permission. 151156SN/A * 161156SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171156SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181156SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191156SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201156SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211156SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221156SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231156SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241156SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251156SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261156SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 291156SN/A/** @file 301156SN/A * Device module for modelling the National Semiconductor 3111263Sandreas.sandberg@arm.com * DP83820 ethernet controller. Does not support priority queueing 3211263Sandreas.sandberg@arm.com */ 331156SN/A#include <cstdio> 342566SN/A#include <deque> 351156SN/A#include <string> 361156SN/A 379850SN/A#include "base/inet.hh" 384762SN/A#include "cpu/exec_context.hh" 3911263Sandreas.sandberg@arm.com#include "dev/etherlink.hh" 409850SN/A#include "dev/ns_gige.hh" 418641SN/A#include "dev/pciconfigall.hh" 425882SN/A#include "mem/bus/bus.hh" 431156SN/A#include "mem/bus/dma_interface.hh" 446216SN/A#include "mem/bus/pio_interface.hh" 456658SN/A#include "mem/bus/pio_interface_impl.hh" 468232SN/A#include "mem/functional/memory_control.hh" 4711263Sandreas.sandberg@arm.com#include "mem/functional/physical.hh" 482566SN/A#include "sim/builder.hh" 493348SN/A#include "sim/debug.hh" 501156SN/A#include "sim/host.hh" 511157SN/A#include "sim/stats.hh" 521156SN/A#include "targetarch/vtophys.hh" 535603SN/A 541156SN/Aconst char *NsRxStateStrings[] = 552107SN/A{ 561156SN/A "rxIdle", 571156SN/A "rxDescRefr", 581156SN/A "rxDescRead", 591156SN/A "rxFifoBlock", 601156SN/A "rxFragWrite", 611156SN/A "rxDescWrite", 621156SN/A "rxAdvance" 631156SN/A}; 641156SN/A 651156SN/Aconst char *NsTxStateStrings[] = 661156SN/A{ 671156SN/A "txIdle", 681156SN/A "txDescRefr", 691156SN/A "txDescRead", 701156SN/A "txFifoBlock", 711156SN/A "txFragRead", 721156SN/A "txDescWrite", 731156SN/A "txAdvance" 741156SN/A}; 751156SN/A 761156SN/Aconst char *NsDmaState[] = 771156SN/A{ 781156SN/A "dmaIdle", 791156SN/A "dmaReading", 801156SN/A "dmaWriting", 811156SN/A "dmaReadWaiting", 824981SN/A "dmaWriteWaiting" 839339SN/A}; 841634SN/A 851634SN/Ausing namespace std; 861156SN/Ausing namespace Net; 871156SN/A 881156SN/A/////////////////////////////////////////////////////////////////////// 894981SN/A// 902627SN/A// NSGigE PCI Device 912282SN/A// 922627SN/ANSGigE::NSGigE(Params *p) 931156SN/A : PciDev(p), ioEnable(false), 941156SN/A txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), 951156SN/A txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), 961156SN/A txXferLen(0), rxXferLen(0), clock(p->clock), 971156SN/A txState(txIdle), txEnable(false), CTDD(false), 984981SN/A txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), 991156SN/A rxEnable(false), CRDD(false), rxPktBytes(0), 1001156SN/A rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), 1011156SN/A eepromState(eepromStart), rxDmaReadEvent(this), rxDmaWriteEvent(this), 1021156SN/A txDmaReadEvent(this), txDmaWriteEvent(this), 1031156SN/A dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), 1041156SN/A txDelay(p->tx_delay), rxDelay(p->rx_delay), 1051156SN/A rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this), 1061156SN/A txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), 1071156SN/A acceptMulticast(false), acceptUnicast(false), 1081156SN/A acceptPerfect(false), acceptArp(false), multicastHashEnable(false), 1099339SN/A physmem(p->pmem), intrTick(0), cpuPendingIntr(false), 1105603SN/A intrEvent(0), interface(0) 1115603SN/A{ 1125603SN/A if (p->header_bus) { 1135603SN/A pioInterface = newPioInterface(name() + ".pio", p->hier, 1145603SN/A p->header_bus, this, 1155603SN/A &NSGigE::cacheAccess); 1165603SN/A 1175603SN/A pioLatency = p->pio_latency * p->header_bus->clockRate; 1185603SN/A 1195603SN/A if (p->payload_bus) 1205603SN/A dmaInterface = new DMAInterface<Bus>(name() + ".dma", 1215603SN/A p->header_bus, 1225603SN/A p->payload_bus, 1, 1235603SN/A p->dma_no_allocate); 1245603SN/A else 1255603SN/A dmaInterface = new DMAInterface<Bus>(name() + ".dma", 1265603SN/A p->header_bus, 1275603SN/A p->header_bus, 1, 1285603SN/A p->dma_no_allocate); 1295603SN/A } else if (p->payload_bus) { 1305603SN/A pioInterface = newPioInterface(name() + ".pio2", p->hier, 1315603SN/A p->payload_bus, this, 1325603SN/A &NSGigE::cacheAccess); 1335603SN/A 1345603SN/A pioLatency = p->pio_latency * p->payload_bus->clockRate; 1355603SN/A 1365603SN/A dmaInterface = new DMAInterface<Bus>(name() + ".dma", 1375603SN/A p->payload_bus, 1389339SN/A p->payload_bus, 1, 1399339SN/A p->dma_no_allocate); 1405603SN/A } 1411156SN/A 1421156SN/A 1434981SN/A intrDelay = p->intr_delay; 1444981SN/A dmaReadDelay = p->dma_read_delay; 1454981SN/A dmaWriteDelay = p->dma_write_delay; 1464981SN/A dmaReadFactor = p->dma_read_factor; 1474981SN/A dmaWriteFactor = p->dma_write_factor; 1484981SN/A 1494981SN/A regsReset(); 1504981SN/A memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN); 1514981SN/A} 1524981SN/A 1534981SN/ANSGigE::~NSGigE() 1544981SN/A{} 1554981SN/A 1561939SN/Avoid 15711005SN/ANSGigE::regStats() 1582008SN/A{ 1592008SN/A txBytes 1602282SN/A .name(name() + ".txBytes") 1612282SN/A .desc("Bytes Transmitted") 1622282SN/A .prereq(txBytes) 1632008SN/A ; 1642008SN/A 1655603SN/A rxBytes 1665603SN/A .name(name() + ".rxBytes") 1675603SN/A .desc("Bytes Received") 1685603SN/A .prereq(rxBytes) 1692008SN/A ; 17011005SN/A 1712008SN/A txPackets 1722008SN/A .name(name() + ".txPackets") 1732008SN/A .desc("Number of Packets Transmitted") 1742008SN/A .prereq(txBytes) 1752008SN/A ; 1762008SN/A 1772008SN/A rxPackets 1782008SN/A .name(name() + ".rxPackets") 1792282SN/A .desc("Number of Packets Received") 1802282SN/A .prereq(rxBytes) 1815603SN/A ; 1822282SN/A 1832008SN/A txIpChecksums 1842008SN/A .name(name() + ".txIpChecksums") 1852008SN/A .desc("Number of tx IP Checksums done by device") 1862008SN/A .precision(0) 1872008SN/A .prereq(txBytes) 1882008SN/A ; 1892008SN/A 1902008SN/A rxIpChecksums 1915603SN/A .name(name() + ".rxIpChecksums") 1922008SN/A .desc("Number of rx IP Checksums done by device") 1932008SN/A .precision(0) 1942008SN/A .prereq(rxBytes) 1955603SN/A ; 1965603SN/A 1975603SN/A txTcpChecksums 1985603SN/A .name(name() + ".txTcpChecksums") 1995603SN/A .desc("Number of tx TCP Checksums done by device") 2005603SN/A .precision(0) 2015603SN/A .prereq(txBytes) 2025603SN/A ; 2035603SN/A 2045603SN/A rxTcpChecksums 2055603SN/A .name(name() + ".rxTcpChecksums") 2065603SN/A .desc("Number of rx TCP Checksums done by device") 2075603SN/A .precision(0) 2082008SN/A .prereq(rxBytes) 2092008SN/A ; 2102008SN/A 21111005SN/A txUdpChecksums 2121997SN/A .name(name() + ".txUdpChecksums") 2132008SN/A .desc("Number of tx UDP Checksums done by device") 2141997SN/A .precision(0) 2151997SN/A .prereq(txBytes) 2161156SN/A ; 2171939SN/A 2181156SN/A rxUdpChecksums 2192566SN/A .name(name() + ".rxUdpChecksums") 2203349SN/A .desc("Number of rx UDP Checksums done by device") 2211156SN/A .precision(0) 2221817SN/A .prereq(rxBytes) 2232641SN/A ; 2241156SN/A 22511005SN/A descDmaReads 2262641SN/A .name(name() + ".descDMAReads") 2272008SN/A .desc("Number of descriptors the device read w/ DMA") 2282008SN/A .precision(0) 2291997SN/A ; 2302008SN/A 2312617SN/A descDmaWrites 2322641SN/A .name(name() + ".descDMAWrites") 2331156SN/A .desc("Number of descriptors the device wrote w/ DMA") 2342008SN/A .precision(0) 2351939SN/A ; 2362279SN/A 2372617SN/A descDmaRdBytes 2382641SN/A .name(name() + ".descDmaReadBytes") 2391939SN/A .desc("number of descriptor bytes read w/ DMA") 2402279SN/A .precision(0) 2412617SN/A ; 2422641SN/A 2431156SN/A descDmaWrBytes 2442008SN/A .name(name() + ".descDmaWriteBytes") 2451156SN/A .desc("number of descriptor bytes write w/ DMA") 2468641SN/A .precision(0) 2472641SN/A ; 2482566SN/A 2492630SN/A txBandwidth 2501939SN/A .name(name() + ".txBandwidth") 2511156SN/A .desc("Transmit Bandwidth (bits/s)") 2521156SN/A .precision(0) 2532641SN/A .prereq(txBytes) 2542566SN/A ; 2552630SN/A 2561939SN/A rxBandwidth 2571939SN/A .name(name() + ".rxBandwidth") 2581939SN/A .desc("Receive Bandwidth (bits/s)") 2591998SN/A .precision(0) 2602617SN/A .prereq(rxBytes) 2612641SN/A ; 2621939SN/A 2631939SN/A totBandwidth 2641939SN/A .name(name() + ".totBandwidth") 2652008SN/A .desc("Total Bandwidth (bits/s)") 2661939SN/A .precision(0) 2671156SN/A .prereq(totBytes) 2682566SN/A ; 2691156SN/A 2701156SN/A totPackets 2711939SN/A .name(name() + ".totPackets") 2721939SN/A .desc("Total Packets") 2732566SN/A .precision(0) 2742566SN/A .prereq(totBytes) 27511005SN/A ; 2761939SN/A 2771939SN/A totBytes 2781939SN/A .name(name() + ".totBytes") 2791939SN/A .desc("Total Bytes") 2801939SN/A .precision(0) 2811939SN/A .prereq(totBytes) 2821998SN/A ; 2831939SN/A 2841998SN/A totPacketRate 2851998SN/A .name(name() + ".totPPS") 2861939SN/A .desc("Total Tranmission Rate (packets/s)") 2872008SN/A .precision(0) 2881939SN/A .prereq(totBytes) 2891939SN/A ; 2901939SN/A 2911939SN/A txPacketRate 2921939SN/A .name(name() + ".txPPS") 2931939SN/A .desc("Packet Tranmission Rate (packets/s)") 2941939SN/A .precision(0) 2951998SN/A .prereq(txBytes) 2961998SN/A ; 2971939SN/A 2982090SN/A rxPacketRate 2991939SN/A .name(name() + ".rxPPS") 3002566SN/A .desc("Packet Reception Rate (packets/s)") 3011939SN/A .precision(0) 3021939SN/A .prereq(rxBytes) 3031939SN/A ; 3042566SN/A 3053349SN/A postedSwi 3061156SN/A .name(name() + ".postedSwi") 3071817SN/A .desc("number of software interrupts posted to CPU") 3082641SN/A .precision(0) 3091939SN/A ; 31011005SN/A 3112641SN/A totalSwi 3122008SN/A .name(name() + ".totalSwi") 3132008SN/A .desc("number of total Swi written to ISR") 3141997SN/A .precision(0) 3152008SN/A ; 3162566SN/A 3172641SN/A coalescedSwi 3181156SN/A .name(name() + ".coalescedSwi") 3192008SN/A .desc("average number of Swi's coalesced into each post") 3201939SN/A .precision(0) 3212279SN/A ; 3222617SN/A 3232641SN/A postedRxIdle 3241939SN/A .name(name() + ".postedRxIdle") 3252641SN/A .desc("number of rxIdle interrupts posted to CPU") 3262279SN/A .precision(0) 3272617SN/A ; 3282641SN/A 3291156SN/A totalRxIdle 3302176SN/A .name(name() + ".totalRxIdle") 3312176SN/A .desc("number of total RxIdle written to ISR") 3321998SN/A .precision(0) 3332617SN/A ; 3342630SN/A 3352641SN/A coalescedRxIdle 3361156SN/A .name(name() + ".coalescedRxIdle") 3372008SN/A .desc("average number of RxIdle's coalesced into each post") 3381156SN/A .precision(0) 3392008SN/A ; 3401156SN/A 3412630SN/A postedRxOk 3421156SN/A .name(name() + ".postedRxOk") 3431156SN/A .desc("number of RxOk interrupts posted to CPU") 3441939SN/A .precision(0) 3452630SN/A ; 3461156SN/A 3471156SN/A totalRxOk 3481939SN/A .name(name() + ".totalRxOk") 3492630SN/A .desc("number of total RxOk written to ISR") 3501156SN/A .precision(0) 3511156SN/A ; 3521156SN/A 3532630SN/A coalescedRxOk 3541156SN/A .name(name() + ".coalescedRxOk") 3551156SN/A .desc("average number of RxOk's coalesced into each post") 3561156SN/A .precision(0) 3572008SN/A ; 3581939SN/A 3591939SN/A postedRxDesc 3601156SN/A .name(name() + ".postedRxDesc") 3612282SN/A .desc("number of RxDesc interrupts posted to CPU") 3622008SN/A .precision(0) 3632630SN/A ; 3645603SN/A 3652282SN/A totalRxDesc 3662630SN/A .name(name() + ".totalRxDesc") 3672627SN/A .desc("number of total RxDesc written to ISR") 3685603SN/A .precision(0) 3695603SN/A ; 3702282SN/A 3712282SN/A coalescedRxDesc 3722282SN/A .name(name() + ".coalescedRxDesc") 3732282SN/A .desc("average number of RxDesc's coalesced into each post") 3742282SN/A .precision(0) 3755603SN/A ; 3765603SN/A 3772282SN/A postedTxOk 3782282SN/A .name(name() + ".postedTxOk") 3792282SN/A .desc("number of TxOk interrupts posted to CPU") 3802282SN/A .precision(0) 3812282SN/A ; 3825603SN/A 3832282SN/A totalTxOk 3842282SN/A .name(name() + ".totalTxOk") 3852282SN/A .desc("number of total TxOk written to ISR") 3862282SN/A .precision(0) 3872282SN/A ; 3882282SN/A 3892282SN/A coalescedTxOk 3902282SN/A .name(name() + ".coalescedTxOk") 3911156SN/A .desc("average number of TxOk's coalesced into each post") 3921156SN/A .precision(0) 3931156SN/A ; 3941156SN/A 3951156SN/A postedTxIdle 3961156SN/A .name(name() + ".postedTxIdle") 3972008SN/A .desc("number of TxIdle interrupts posted to CPU") 3981939SN/A .precision(0) 3991939SN/A ; 4001156SN/A 4012282SN/A totalTxIdle 4022008SN/A .name(name() + ".totalTxIdle") 4032282SN/A .desc("number of total TxIdle written to ISR") 4042630SN/A .precision(0) 4052617SN/A ; 4065603SN/A 4075603SN/A coalescedTxIdle 4082282SN/A .name(name() + ".coalescedTxIdle") 4095603SN/A .desc("average number of TxIdle's coalesced into each post") 4102282SN/A .precision(0) 4112282SN/A ; 4122282SN/A 4135603SN/A postedTxDesc 4145603SN/A .name(name() + ".postedTxDesc") 4152282SN/A .desc("number of TxDesc interrupts posted to CPU") 4165603SN/A .precision(0) 4172282SN/A ; 4182282SN/A 4192282SN/A totalTxDesc 4202008SN/A .name(name() + ".totalTxDesc") 4212008SN/A .desc("number of total TxDesc written to ISR") 4222010SN/A .precision(0) 4231156SN/A ; 4241156SN/A 4251156SN/A coalescedTxDesc 4261156SN/A .name(name() + ".coalescedTxDesc") 4271156SN/A .desc("average number of TxDesc's coalesced into each post") 4282176SN/A .precision(0) 4292566SN/A ; 4301156SN/A 4311156SN/A postedRxOrn 4321156SN/A .name(name() + ".postedRxOrn") 4331156SN/A .desc("number of RxOrn posted to CPU") 4341156SN/A .precision(0) 4351156SN/A ; 4361156SN/A 4371156SN/A totalRxOrn 4381156SN/A .name(name() + ".totalRxOrn") 4391156SN/A .desc("number of total RxOrn written to ISR") 4401156SN/A .precision(0) 4411156SN/A ; 4421156SN/A 4431156SN/A coalescedRxOrn 4441939SN/A .name(name() + ".coalescedRxOrn") 4451939SN/A .desc("average number of RxOrn's coalesced into each post") 4461939SN/A .precision(0) 4471939SN/A ; 4481939SN/A 4491939SN/A coalescedTotal 4501939SN/A .name(name() + ".coalescedTotal") 4511939SN/A .desc("average number of interrupts coalesced into each post") 4521939SN/A .precision(0) 4531939SN/A ; 4541939SN/A 4551939SN/A postedInterrupts 4561939SN/A .name(name() + ".postedInterrupts") 4571939SN/A .desc("number of posts to CPU") 4581939SN/A .precision(0) 4591939SN/A ; 4601939SN/A 4617823SN/A droppedPackets 4621939SN/A .name(name() + ".droppedPackets") 4631156SN/A .desc("number of packets dropped") 4641156SN/A .precision(0) 4651156SN/A ; 4661156SN/A 4671156SN/A coalescedSwi = totalSwi / postedInterrupts; 4681156SN/A coalescedRxIdle = totalRxIdle / postedInterrupts; 4691156SN/A coalescedRxOk = totalRxOk / postedInterrupts; 4701156SN/A coalescedRxDesc = totalRxDesc / postedInterrupts; 4711156SN/A coalescedTxOk = totalTxOk / postedInterrupts; 4721156SN/A coalescedTxIdle = totalTxIdle / postedInterrupts; 4731156SN/A coalescedTxDesc = totalTxDesc / postedInterrupts; 4741156SN/A coalescedRxOrn = totalRxOrn / postedInterrupts; 4751156SN/A 4761156SN/A coalescedTotal = (totalSwi + totalRxIdle + totalRxOk + totalRxDesc + 4771156SN/A totalTxOk + totalTxIdle + totalTxDesc + 4781156SN/A totalRxOrn) / postedInterrupts; 4791156SN/A 4801156SN/A txBandwidth = txBytes * Stats::constant(8) / simSeconds; 4811156SN/A rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; 4821156SN/A totBandwidth = txBandwidth + rxBandwidth; 4831156SN/A totBytes = txBytes + rxBytes; 4841156SN/A totPackets = txPackets + rxPackets; 4851156SN/A 4861156SN/A txPacketRate = txPackets / simSeconds; 4871156SN/A rxPacketRate = rxPackets / simSeconds; 4881156SN/A} 4891156SN/A 4901156SN/A/** 4911156SN/A * This is to read the PCI general configuration registers 4921156SN/A */ 4931156SN/Avoid 4941156SN/ANSGigE::readConfig(int offset, int size, uint8_t *data) 4951156SN/A{ 4961156SN/A if (offset < PCI_DEVICE_SPECIFIC) 4977823SN/A PciDev::readConfig(offset, size, data); 4981156SN/A else 4991156SN/A panic("Device specific PCI config space not implemented!\n"); 5001156SN/A} 5011156SN/A 5021156SN/A/** 5031156SN/A * This is to write to the PCI general configuration registers 5041156SN/A */ 5051156SN/Avoid 5061156SN/ANSGigE::writeConfig(int offset, int size, const uint8_t* data) 5071156SN/A{ 5081156SN/A if (offset < PCI_DEVICE_SPECIFIC) 5091156SN/A PciDev::writeConfig(offset, size, data); 5101156SN/A else 5111156SN/A panic("Device specific PCI config space not implemented!\n"); 5121156SN/A 5131156SN/A // Need to catch writes to BARs to update the PIO interface 5147823SN/A switch (offset) { 5157823SN/A // seems to work fine without all these PCI settings, but i 5161156SN/A // put in the IO to double check, an assertion will fail if we 5171156SN/A // need to properly implement it 5181156SN/A case PCI_COMMAND: 5191156SN/A if (config.data[offset] & PCI_CMD_IOSE) 5201156SN/A ioEnable = true; 5211156SN/A else 5221156SN/A ioEnable = false; 5231156SN/A 5241156SN/A#if 0 5251156SN/A if (config.data[offset] & PCI_CMD_BME) { 5261156SN/A bmEnabled = true; 5271156SN/A } 5281156SN/A else { 5297823SN/A bmEnabled = false; 5307823SN/A } 5311156SN/A 5321156SN/A if (config.data[offset] & PCI_CMD_MSE) { 5331156SN/A memEnable = true; 5341156SN/A } 5351156SN/A else { 5361156SN/A memEnable = false; 5371156SN/A } 5385606SN/A#endif 5395606SN/A break; 5401156SN/A 5411156SN/A case PCI0_BASE_ADDR0: 5421156SN/A if (BARAddrs[0] != 0) { 5431156SN/A if (pioInterface) 5441156SN/A pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); 5457823SN/A 5461156SN/A BARAddrs[0] &= EV5::PAddrUncachedMask; 5471156SN/A } 5481156SN/A break; 5491156SN/A case PCI0_BASE_ADDR1: 5501156SN/A if (BARAddrs[1] != 0) { 5511156SN/A if (pioInterface) 5521156SN/A pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); 5531156SN/A 5541156SN/A BARAddrs[1] &= EV5::PAddrUncachedMask; 5551156SN/A } 5561156SN/A break; 5571156SN/A } 5581156SN/A} 5591156SN/A 5601156SN/A/** 5611156SN/A * This reads the device registers, which are detailed in the NS83820 5621156SN/A * spec sheet 5631156SN/A */ 5641156SN/AFault 5651156SN/ANSGigE::read(MemReqPtr &req, uint8_t *data) 5661156SN/A{ 5671156SN/A assert(ioEnable); 5681156SN/A 5691156SN/A //The mask is to give you only the offset into the device register file 5701156SN/A Addr daddr = req->paddr & 0xfff; 5711156SN/A DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n", 5721156SN/A daddr, req->paddr, req->vaddr, req->size); 5731156SN/A 5741156SN/A 5751156SN/A // there are some reserved registers, you can see ns_gige_reg.h and 5761156SN/A // the spec sheet for details 5771156SN/A if (daddr > LAST && daddr <= RESERVED) { 5781156SN/A panic("Accessing reserved register"); 5791156SN/A } else if (daddr > RESERVED && daddr <= 0x3FC) { 5801156SN/A readConfig(daddr & 0xff, req->size, data); 5811156SN/A return No_Fault; 5821156SN/A } else if (daddr >= MIB_START && daddr <= MIB_END) { 5831156SN/A // don't implement all the MIB's. hopefully the kernel 5841156SN/A // doesn't actually DEPEND upon their values 5851156SN/A // MIB are just hardware stats keepers 5861156SN/A uint32_t ® = *(uint32_t *) data; 5871156SN/A reg = 0; 5881156SN/A return No_Fault; 5891156SN/A } else if (daddr > 0x3FC) 5901156SN/A panic("Something is messed up!\n"); 5911156SN/A 5921156SN/A switch (req->size) { 5931156SN/A case sizeof(uint32_t): 5941156SN/A { 5951156SN/A uint32_t ® = *(uint32_t *)data; 5961156SN/A uint16_t rfaddr; 5971156SN/A 5981156SN/A switch (daddr) { 5991156SN/A case CR: 6001156SN/A reg = regs.command; 6017823SN/A //these are supposed to be cleared on a read 6021156SN/A reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); 6031156SN/A break; 6041156SN/A 6051156SN/A case CFGR: 6061156SN/A reg = regs.config; 6071156SN/A break; 6081156SN/A 6091156SN/A case MEAR: 6101156SN/A reg = regs.mear; 6111156SN/A break; 6121156SN/A 6131156SN/A case PTSCR: 6141156SN/A reg = regs.ptscr; 6151156SN/A break; 6161156SN/A 6171156SN/A case ISR: 6181156SN/A reg = regs.isr; 6191156SN/A devIntrClear(ISR_ALL); 6201156SN/A break; 6211939SN/A 6221939SN/A case IMR: 6232008SN/A reg = regs.imr; 6242008SN/A break; 6252008SN/A 6261939SN/A case IER: 6271939SN/A reg = regs.ier; 6281939SN/A break; 6291939SN/A 6301939SN/A case IHR: 6311156SN/A reg = regs.ihr; 6321156SN/A break; 6331156SN/A 6341939SN/A case TXDP: 6351156SN/A reg = regs.txdp; 6361939SN/A break; 6371939SN/A 6382008SN/A case TXDP_HI: 6392008SN/A reg = regs.txdp_hi; 6402008SN/A break; 6412008SN/A 6422210SN/A case TX_CFG: 6432210SN/A reg = regs.txcfg; 6442282SN/A break; 6452282SN/A 6462282SN/A case GPIOR: 6472282SN/A reg = regs.gpior; 6482282SN/A break; 6492282SN/A 6502282SN/A case RXDP: 6512282SN/A reg = regs.rxdp; 6522282SN/A break; 6532282SN/A 6542008SN/A case RXDP_HI: 6551156SN/A reg = regs.rxdp_hi; 6561156SN/A break; 6575603SN/A 6585603SN/A case RX_CFG: 6595603SN/A reg = regs.rxcfg; 6601939SN/A break; 6611939SN/A 6621939SN/A case PQCR: 6635603SN/A reg = regs.pqcr; 6645603SN/A break; 6655603SN/A 6665603SN/A case WCSR: 6674762SN/A reg = regs.wcsr; 6681156SN/A break; 6695603SN/A 6705603SN/A case PCR: 6715603SN/A reg = regs.pcr; 6725603SN/A break; 6735603SN/A 6745603SN/A // see the spec sheet for how RFCR and RFDR work 6752008SN/A // basically, you write to RFCR to tell the machine 6762282SN/A // what you want to do next, then you act upon RFDR, 6772282SN/A // and the device will be prepared b/c of what you 6782008SN/A // wrote to RFCR 6795603SN/A case RFCR: 6805603SN/A reg = regs.rfcr; 6815603SN/A break; 6822008SN/A 6831156SN/A case RFDR: 6841156SN/A rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 6851156SN/A switch (rfaddr) { 6861156SN/A // Read from perfect match ROM octets 6872008SN/A case 0x000: 6881156SN/A reg = rom.perfectMatch[1]; 6891939SN/A reg = reg << 8; 6902282SN/A reg += rom.perfectMatch[0]; 6911939SN/A break; 6922008SN/A case 0x002: 6932008SN/A reg = rom.perfectMatch[3] << 8; 6942008SN/A reg += rom.perfectMatch[2]; 6952008SN/A break; 6962008SN/A case 0x004: 6975603SN/A reg = rom.perfectMatch[5] << 8; 6981156SN/A reg += rom.perfectMatch[4]; 6991156SN/A break; 7001156SN/A default: 7012566SN/A // Read filter hash table 7021156SN/A if (rfaddr >= FHASH_ADDR && 7031156SN/A rfaddr < FHASH_ADDR + FHASH_SIZE) { 7041156SN/A 7052280SN/A // Only word-aligned reads supported 7061156SN/A if (rfaddr % 2) 7071939SN/A panic("unaligned read from filter hash table!"); 7081939SN/A 7091939SN/A reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; 7101939SN/A reg += rom.filterHash[rfaddr - FHASH_ADDR]; 7111939SN/A break; 7121939SN/A } 7131156SN/A 7141156SN/A panic("reading RFDR for something other than pattern" 7151156SN/A " matching or hashing! %#x\n", rfaddr); 7161156SN/A } 7171156SN/A break; 7181156SN/A 7192282SN/A case SRR: 7202008SN/A reg = regs.srr; 7212279SN/A break; 7221156SN/A 7231156SN/A case MIBC: 7247823SN/A reg = regs.mibc; 7252279SN/A reg &= ~(MIBC_MIBS | MIBC_ACLR); 7261156SN/A break; 7271156SN/A 7281156SN/A case VRCR: 7291156SN/A reg = regs.vrcr; 7301156SN/A break; 7315603SN/A 7322008SN/A case VTCR: 7331156SN/A reg = regs.vtcr; 7341156SN/A break; 7352282SN/A 7362282SN/A case VDR: 7372282SN/A reg = regs.vdr; 7382008SN/A break; 7392282SN/A 7402282SN/A case CCSR: 7412282SN/A reg = regs.ccsr; 7422282SN/A break; 7432282SN/A 7442282SN/A case TBICR: 7452282SN/A reg = regs.tbicr; 7462282SN/A break; 7472008SN/A 7482008SN/A case TBISR: 7491156SN/A reg = regs.tbisr; 7502282SN/A break; 7512282SN/A 7522282SN/A case TANAR: 7532282SN/A reg = regs.tanar; 7542282SN/A break; 7555603SN/A 7565603SN/A case TANLPAR: 7578641SN/A reg = regs.tanlpar; 7585603SN/A break; 7595603SN/A 7605603SN/A case TANER: 7615603SN/A reg = regs.taner; 7625603SN/A break; 7635603SN/A 7645603SN/A case TESR: 7655603SN/A reg = regs.tesr; 7665603SN/A break; 7675603SN/A 7685603SN/A case M5REG: 7695603SN/A reg = params()->m5reg; 7702282SN/A break; 7715603SN/A 7725603SN/A default: 7735603SN/A panic("reading unimplemented register: addr=%#x", daddr); 7745603SN/A } 7758641SN/A 7765603SN/A DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", 7775603SN/A daddr, reg, reg); 7785603SN/A } 7792282SN/A break; 7802282SN/A 7812282SN/A default: 7822282SN/A panic("accessing register with invalid size: addr=%#x, size=%d", 7832282SN/A daddr, req->size); 7842282SN/A } 7852282SN/A 7862282SN/A return No_Fault; 7872282SN/A} 7885603SN/A 7892282SN/AFault 7902282SN/ANSGigE::write(MemReqPtr &req, const uint8_t *data) 7912282SN/A{ 7922282SN/A assert(ioEnable); 7932282SN/A 7942282SN/A Addr daddr = req->paddr & 0xfff; 7951156SN/A DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n", 7962282SN/A daddr, req->paddr, req->vaddr, req->size); 7975603SN/A 7985603SN/A if (daddr > LAST && daddr <= RESERVED) { 7995603SN/A panic("Accessing reserved register"); 8005603SN/A } else if (daddr > RESERVED && daddr <= 0x3FC) { 8015603SN/A writeConfig(daddr & 0xff, req->size, data); 8025603SN/A return No_Fault; 8035603SN/A } else if (daddr > 0x3FC) 8045603SN/A panic("Something is messed up!\n"); 8051156SN/A 8061156SN/A if (req->size == sizeof(uint32_t)) { 8071156SN/A uint32_t reg = *(uint32_t *)data; 8082008SN/A uint16_t rfaddr; 8091156SN/A 8101156SN/A DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); 8111156SN/A 8121156SN/A switch (daddr) { 8132282SN/A case CR: 8142282SN/A regs.command = reg; 8152282SN/A if (reg & CR_TXD) { 8162008SN/A txEnable = false; 8172008SN/A } else if (reg & CR_TXE) { 8182282SN/A txEnable = true; 8192282SN/A 8202282SN/A // the kernel is enabling the transmit machine 8212282SN/A if (txState == txIdle) 8222282SN/A txKick(); 8232282SN/A } 8242282SN/A 8252282SN/A if (reg & CR_RXD) { 8261156SN/A rxEnable = false; 8275603SN/A } else if (reg & CR_RXE) { 8285603SN/A rxEnable = true; 8292008SN/A 8305603SN/A if (rxState == rxIdle) 8312008SN/A rxKick(); 8325603SN/A } 8331156SN/A 8342008SN/A if (reg & CR_TXR) 8351156SN/A txReset(); 8365603SN/A 8371156SN/A if (reg & CR_RXR) 8382280SN/A rxReset(); 8392008SN/A 8401156SN/A if (reg & CR_SWI) 8411156SN/A devIntrPost(ISR_SWI); 8421156SN/A 8432008SN/A if (reg & CR_RST) { 8441156SN/A txReset(); 8451156SN/A rxReset(); 8461156SN/A 8471156SN/A regsReset(); 8482279SN/A } 8492279SN/A break; 8502279SN/A 8512279SN/A case CFGR: 8522008SN/A if (reg & CFGR_LNKSTS || 8531156SN/A reg & CFGR_SPDSTS || 8541156SN/A reg & CFGR_DUPSTS || 8551156SN/A reg & CFGR_RESERVED || 8562008SN/A reg & CFGR_T64ADDR || 8571156SN/A reg & CFGR_PCI64_DET) 8581156SN/A 8592008SN/A // First clear all writable bits 8601156SN/A regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 8611156SN/A CFGR_RESERVED | CFGR_T64ADDR | 8621156SN/A CFGR_PCI64_DET; 8632008SN/A // Now set the appropriate writable bits 8641156SN/A regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 8651156SN/A CFGR_RESERVED | CFGR_T64ADDR | 8661156SN/A CFGR_PCI64_DET); 8671156SN/A 8681156SN/A// all these #if 0's are because i don't THINK the kernel needs to 8691156SN/A// have these implemented. if there is a problem relating to one of 8701156SN/A// these, you may need to add functionality in. 8711156SN/A#if 0 87210913SN/A if (reg & CFGR_TBI_EN) ; 8731939SN/A if (reg & CFGR_MODE_1000) ; 8741939SN/A#endif 87511202SN/A 8766227SN/A if (reg & CFGR_AUTO_1000) 8776227SN/A panic("CFGR_AUTO_1000 not implemented!\n"); 8785603SN/A 8795603SN/A#if 0 8805603SN/A if (reg & CFGR_PINT_DUPSTS || 8815603SN/A reg & CFGR_PINT_LNKSTS || 8825603SN/A reg & CFGR_PINT_SPDSTS) 8835603SN/A ; 8845603SN/A 8855603SN/A if (reg & CFGR_TMRTEST) ; 8865603SN/A if (reg & CFGR_MRM_DIS) ; 8875603SN/A if (reg & CFGR_MWI_DIS) ; 8885603SN/A 8895603SN/A if (reg & CFGR_T64ADDR) 8901939SN/A panic("CFGR_T64ADDR is read only register!\n"); 8912282SN/A 8922282SN/A if (reg & CFGR_PCI64_DET) 8932282SN/A panic("CFGR_PCI64_DET is read only register!\n"); 8942282SN/A 8952282SN/A if (reg & CFGR_DATA64_EN) ; 8962566SN/A if (reg & CFGR_M64ADDR) ; 8971156SN/A if (reg & CFGR_PHY_RST) ; 8981156SN/A if (reg & CFGR_PHY_DIS) ; 8991156SN/A#endif 9001156SN/A 9011156SN/A if (reg & CFGR_EXTSTS_EN) 9021156SN/A extstsEnable = true; 9031156SN/A else 9042282SN/A extstsEnable = false; 9052008SN/A 9065603SN/A#if 0 9071156SN/A if (reg & CFGR_REQALG) ; 9082008SN/A if (reg & CFGR_SB) ; 9095603SN/A if (reg & CFGR_POW) ; 9105603SN/A if (reg & CFGR_EXD) ; 9115603SN/A if (reg & CFGR_PESEL) ; 9122282SN/A if (reg & CFGR_BROM_DIS) ; 9132282SN/A if (reg & CFGR_EXT_125) ; 9142282SN/A if (reg & CFGR_BEM) ; 9152282SN/A#endif 9162282SN/A break; 9172282SN/A 9185603SN/A case MEAR: 9195603SN/A // Clear writable bits 9205603SN/A regs.mear &= MEAR_EEDO; 9211156SN/A // Set appropriate writable bits 9225603SN/A regs.mear |= reg & ~MEAR_EEDO; 9235603SN/A 9245603SN/A // FreeBSD uses the EEPROM to read PMATCH (for the MAC address) 9252008SN/A // even though it could get it through RFDR 9262008SN/A if (reg & MEAR_EESEL) { 9272282SN/A // Rising edge of clock 9282282SN/A if (reg & MEAR_EECLK && !eepromClk) 9292282SN/A eepromKick(); 9302010SN/A } 9312282SN/A else { 9322282SN/A eepromState = eepromStart; 9332282SN/A regs.mear &= ~MEAR_EEDI; 9341156SN/A } 9351156SN/A 9362282SN/A eepromClk = reg & MEAR_EECLK; 9372282SN/A 9382008SN/A // since phy is completely faked, MEAR_MD* don't matter 9392008SN/A#if 0 9402008SN/A if (reg & MEAR_MDIO) ; 9412008SN/A if (reg & MEAR_MDDIR) ; 9422008SN/A if (reg & MEAR_MDC) ; 9432008SN/A#endif 9445603SN/A break; 9452282SN/A 9462282SN/A case PTSCR: 9475603SN/A regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY); 9482282SN/A // these control BISTs for various parts of chip - we 9492282SN/A // don't care or do just fake that the BIST is done 9501939SN/A if (reg & PTSCR_RBIST_EN) 9511156SN/A regs.ptscr |= PTSCR_RBIST_DONE; 9521156SN/A if (reg & PTSCR_EEBIST_EN) 9531156SN/A regs.ptscr &= ~PTSCR_EEBIST_EN; 9541156SN/A if (reg & PTSCR_EELOAD_EN) 9551156SN/A regs.ptscr &= ~PTSCR_EELOAD_EN; 9561156SN/A break; 9571156SN/A 9581156SN/A case ISR: /* writing to the ISR has no effect */ 9591156SN/A panic("ISR is a read only register!\n"); 9601156SN/A 9611156SN/A case IMR: 9621156SN/A regs.imr = reg; 9631156SN/A devIntrChangeMask(); 9641156SN/A break; 9651156SN/A 9661156SN/A case IER: 9671156SN/A regs.ier = reg; 9681156SN/A break; 9691156SN/A 9701156SN/A case IHR: 9712566SN/A regs.ihr = reg; 9721156SN/A /* not going to implement real interrupt holdoff */ 9731156SN/A break; 9741156SN/A 9751156SN/A case TXDP: 9761156SN/A regs.txdp = (reg & 0xFFFFFFFC); 9771939SN/A assert(txState == txIdle); 9781939SN/A CTDD = false; 9791939SN/A break; 9801939SN/A 9811939SN/A case TXDP_HI: 9821939SN/A regs.txdp_hi = reg; 9831156SN/A break; 9841156SN/A 9851156SN/A case TX_CFG: 9861156SN/A regs.txcfg = reg; 9871156SN/A#if 0 9881156SN/A if (reg & TX_CFG_CSI) ; 9891156SN/A if (reg & TX_CFG_HBI) ; 9901156SN/A if (reg & TX_CFG_MLB) ; 9911156SN/A if (reg & TX_CFG_ATP) ; 9921156SN/A if (reg & TX_CFG_ECRETRY) { 9931156SN/A /* 9941939SN/A * this could easily be implemented, but considering 9952566SN/A * the network is just a fake pipe, wouldn't make 9961156SN/A * sense to do this 9971156SN/A */ 9981156SN/A } 9995603SN/A 10001156SN/A if (reg & TX_CFG_BRST_DIS) ; 10011156SN/A#endif 10021156SN/A 10031156SN/A#if 0 10041156SN/A /* we handle our own DMA, ignore the kernel's exhortations */ 10051156SN/A if (reg & TX_CFG_MXDMA) ; 10061156SN/A#endif 10071156SN/A 10081156SN/A // also, we currently don't care about fill/drain 10091156SN/A // thresholds though this may change in the future with 10102280SN/A // more realistic networks or a driver which changes it 10112280SN/A // according to feedback 10122280SN/A 10132280SN/A break; 10141156SN/A 10151156SN/A case GPIOR: 10161156SN/A // Only write writable bits 10171156SN/A regs.gpior &= GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 10181156SN/A | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN; 10191939SN/A regs.gpior |= reg & ~(GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 10201156SN/A | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN); 10211156SN/A /* these just control general purpose i/o pins, don't matter */ 10221156SN/A break; 10231156SN/A 10241156SN/A case RXDP: 10251156SN/A regs.rxdp = reg; 10261939SN/A CRDD = false; 10275603SN/A break; 10281939SN/A 10291939SN/A case RXDP_HI: 10301156SN/A regs.rxdp_hi = reg; 10311156SN/A break; 10321156SN/A 10331156SN/A case RX_CFG: 10341156SN/A regs.rxcfg = reg; 10352008SN/A#if 0 10362279SN/A if (reg & RX_CFG_AEP) ; 10371156SN/A if (reg & RX_CFG_ARP) ; 10381156SN/A if (reg & RX_CFG_STRIPCRC) ; 10397823SN/A if (reg & RX_CFG_RX_RD) ; 10402279SN/A if (reg & RX_CFG_ALP) ; 10411156SN/A if (reg & RX_CFG_AIRL) ; 10421156SN/A 10431156SN/A /* we handle our own DMA, ignore what kernel says about it */ 10441156SN/A if (reg & RX_CFG_MXDMA) ; 10451156SN/A 10462008SN/A //also, we currently don't care about fill/drain thresholds 10471156SN/A //though this may change in the future with more realistic 10481156SN/A //networks or a driver which changes it according to feedback 10492008SN/A if (reg & (RX_CFG_DRTH | RX_CFG_DRTH0)) ; 10502008SN/A#endif 10512008SN/A break; 10522008SN/A 10531156SN/A case PQCR: 10542280SN/A /* there is no priority queueing used in the linux 2.6 driver */ 10551156SN/A regs.pqcr = reg; 10561156SN/A break; 105710469SN/A 10582008SN/A case WCSR: 10591156SN/A /* not going to implement wake on LAN */ 10601156SN/A regs.wcsr = reg; 10611156SN/A break; 10622008SN/A 10631156SN/A case PCR: 10641156SN/A /* not going to implement pause control */ 10651156SN/A regs.pcr = reg; 10661156SN/A break; 10671156SN/A 10681156SN/A case RFCR: 10691156SN/A regs.rfcr = reg; 10701156SN/A 107110913SN/A rxFilterEnable = (reg & RFCR_RFEN) ? true : false; 10721939SN/A acceptBroadcast = (reg & RFCR_AAB) ? true : false; 10731939SN/A acceptMulticast = (reg & RFCR_AAM) ? true : false; 107411202SN/A acceptUnicast = (reg & RFCR_AAU) ? true : false; 10752008SN/A acceptPerfect = (reg & RFCR_APM) ? true : false; 10762008SN/A acceptArp = (reg & RFCR_AARP) ? true : false; 10771939SN/A multicastHashEnable = (reg & RFCR_MHEN) ? true : false; 10781156SN/A 10792566SN/A#if 0 10801156SN/A if (reg & RFCR_APAT) 10811156SN/A panic("RFCR_APAT not implemented!\n"); 10821156SN/A#endif 10831156SN/A if (reg & RFCR_UHEN) 10841156SN/A panic("Unicast hash filtering not used by drivers!\n"); 10851156SN/A 10861156SN/A if (reg & RFCR_ULM) 10872008SN/A panic("RFCR_ULM not implemented!\n"); 108811701Smichael.lebeane@amd.com 10891156SN/A break; 10902008SN/A 10912008SN/A case RFDR: 10922008SN/A rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 10932008SN/A switch (rfaddr) { 10942008SN/A case 0x000: 10951156SN/A rom.perfectMatch[0] = (uint8_t)reg; 10961156SN/A rom.perfectMatch[1] = (uint8_t)(reg >> 8); 10972008SN/A break; 10982008SN/A case 0x002: 10992008SN/A rom.perfectMatch[2] = (uint8_t)reg; 11002008SN/A rom.perfectMatch[3] = (uint8_t)(reg >> 8); 11012008SN/A break; 11022008SN/A case 0x004: 11032008SN/A rom.perfectMatch[4] = (uint8_t)reg; 11042008SN/A rom.perfectMatch[5] = (uint8_t)(reg >> 8); 11052008SN/A break; 11062008SN/A default: 11072008SN/A 11082008SN/A if (rfaddr >= FHASH_ADDR && 11092008SN/A rfaddr < FHASH_ADDR + FHASH_SIZE) { 11102008SN/A 11112008SN/A // Only word-aligned writes supported 11122008SN/A if (rfaddr % 2) 11132008SN/A panic("unaligned write to filter hash table!"); 11142008SN/A 11152008SN/A rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg; 11162008SN/A rom.filterHash[rfaddr - FHASH_ADDR + 1] 11172008SN/A = (uint8_t)(reg >> 8); 11182008SN/A break; 11192008SN/A } 11202008SN/A panic("writing RFDR for something other than pattern matching\ 11212008SN/A or hashing! %#x\n", rfaddr); 11222008SN/A } 11232008SN/A 11242008SN/A case BRAR: 11252008SN/A regs.brar = reg; 11262008SN/A break; 11272008SN/A 11282008SN/A case BRDR: 11292008SN/A panic("the driver never uses BRDR, something is wrong!\n"); 11301939SN/A 11311156SN/A case SRR: 11321156SN/A panic("SRR is read only register!\n"); 11331156SN/A 11341156SN/A case MIBC: 11351156SN/A panic("the driver never uses MIBC, something is wrong!\n"); 11361156SN/A 11371156SN/A case VRCR: 11381156SN/A regs.vrcr = reg; 11391156SN/A break; 11401156SN/A 11411156SN/A case VTCR: 11421156SN/A regs.vtcr = reg; 11431156SN/A break; 11441156SN/A 11451156SN/A case VDR: 11461156SN/A panic("the driver never uses VDR, something is wrong!\n"); 11471156SN/A 11481156SN/A case CCSR: 11491156SN/A /* not going to implement clockrun stuff */ 11501156SN/A regs.ccsr = reg; 11511156SN/A break; 11521156SN/A 11531156SN/A case TBICR: 11541156SN/A regs.tbicr = reg; 11551156SN/A if (reg & TBICR_MR_LOOPBACK) 11561156SN/A panic("TBICR_MR_LOOPBACK never used, something wrong!\n"); 11571156SN/A 11581156SN/A if (reg & TBICR_MR_AN_ENABLE) { 11591156SN/A regs.tanlpar = regs.tanar; 11609417SN/A regs.tbisr |= (TBISR_MR_AN_COMPLETE | TBISR_MR_LINK_STATUS); 11611156SN/A } 11621156SN/A 11631156SN/A#if 0 11642566SN/A if (reg & TBICR_MR_RESTART_AN) ; 11651156SN/A#endif 11661156SN/A 11671156SN/A break; 11681156SN/A 11691156SN/A case TBISR: 11701156SN/A panic("TBISR is read only register!\n"); 11711156SN/A 11721156SN/A case TANAR: 11731156SN/A // Only write the writable bits 11741156SN/A regs.tanar &= TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED; 11751156SN/A regs.tanar |= reg & ~(TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED); 11761156SN/A 11771156SN/A // Pause capability unimplemented 11781156SN/A#if 0 11791156SN/A if (reg & TANAR_PS2) ; 11801156SN/A if (reg & TANAR_PS1) ; 11811156SN/A#endif 11821156SN/A 11831156SN/A break; 11841156SN/A 11851156SN/A case TANLPAR: 11861156SN/A panic("this should only be written to by the fake phy!\n"); 11871156SN/A 11881156SN/A case TANER: 11891156SN/A panic("TANER is read only register!\n"); 11901156SN/A 11911156SN/A case TESR: 11921156SN/A regs.tesr = reg; 11931156SN/A break; 11941156SN/A 11951156SN/A default: 11961156SN/A panic("invalid register access daddr=%#x", daddr); 11971156SN/A } 11981156SN/A } else { 11991156SN/A panic("Invalid Request Size"); 12001156SN/A } 12011156SN/A 12021156SN/A return No_Fault; 12031156SN/A} 12041156SN/A 12051156SN/Avoid 12061156SN/ANSGigE::devIntrPost(uint32_t interrupts) 12071156SN/A{ 12081156SN/A if (interrupts & ISR_RESERVE) 12092566SN/A panic("Cannot set a reserved interrupt"); 12101156SN/A 12111156SN/A if (interrupts & ISR_NOIMPL) 12121156SN/A warn("interrupt not implemented %#x\n", interrupts); 12131156SN/A 12141156SN/A interrupts &= ISR_IMPL; 12151156SN/A regs.isr |= interrupts; 12161156SN/A 12171156SN/A if (interrupts & regs.imr) { 12181156SN/A if (interrupts & ISR_SWI) { 12191156SN/A totalSwi++; 12201156SN/A } 12211156SN/A if (interrupts & ISR_RXIDLE) { 12221156SN/A totalRxIdle++; 12231156SN/A } 12241156SN/A if (interrupts & ISR_RXOK) { 12251156SN/A totalRxOk++; 12261156SN/A } 12275603SN/A if (interrupts & ISR_RXDESC) { 12281939SN/A totalRxDesc++; 12291156SN/A } 12301156SN/A if (interrupts & ISR_TXOK) { 12311156SN/A totalTxOk++; 12321156SN/A } 12331156SN/A if (interrupts & ISR_TXIDLE) { 12341156SN/A totalTxIdle++; 12351156SN/A } 12362008SN/A if (interrupts & ISR_TXDESC) { 12372008SN/A totalTxDesc++; 12382008SN/A } 12392008SN/A if (interrupts & ISR_RXORN) { 12402008SN/A totalRxOrn++; 12411939SN/A } 12421156SN/A } 12431156SN/A 12441156SN/A DPRINTF(EthernetIntr, 12451156SN/A "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n", 12462901SN/A interrupts, regs.isr, regs.imr); 12479342SN/A 12482901SN/A if ((regs.isr & regs.imr)) { 12499342SN/A Tick when = curTick; 12502901SN/A if ((regs.isr & regs.imr & ISR_NODELAY) == 0) 12512901SN/A when += intrDelay; 12522901SN/A cpuIntrPost(when); 12532901SN/A } 12542901SN/A} 12552901SN/A 12562901SN/A/* writing this interrupt counting stats inside this means that this function 12572901SN/A is now limited to being used to clear all interrupts upon the kernel 12581156SN/A reading isr and servicing. just telling you in case you were thinking 12591156SN/A of expanding use. 12601156SN/A*/ 12611156SN/Avoid 126210905SN/ANSGigE::devIntrClear(uint32_t interrupts) 12631156SN/A{ 12649807SN/A if (interrupts & ISR_RESERVE) 126510905SN/A panic("Cannot clear a reserved interrupt"); 12661156SN/A 12671156SN/A if (regs.isr & regs.imr & ISR_SWI) { 12681156SN/A postedSwi++; 12691156SN/A } 12701156SN/A if (regs.isr & regs.imr & ISR_RXIDLE) { 12711156SN/A postedRxIdle++; 12721156SN/A } 12731156SN/A if (regs.isr & regs.imr & ISR_RXOK) { 12741156SN/A postedRxOk++; 12751156SN/A } 12761156SN/A if (regs.isr & regs.imr & ISR_RXDESC) { 12771156SN/A postedRxDesc++; 12781156SN/A } 12791156SN/A if (regs.isr & regs.imr & ISR_TXOK) { 12801156SN/A postedTxOk++; 12811156SN/A } 12821156SN/A if (regs.isr & regs.imr & ISR_TXIDLE) { 128310905SN/A postedTxIdle++; 12841156SN/A } 12859807SN/A if (regs.isr & regs.imr & ISR_TXDESC) { 128610905SN/A postedTxDesc++; 12871156SN/A } 12881156SN/A if (regs.isr & regs.imr & ISR_RXORN) { 12891156SN/A postedRxOrn++; 12901156SN/A } 12911156SN/A 12921156SN/A if (regs.isr & regs.imr & ISR_IMPL) 12931156SN/A postedInterrupts++; 12941156SN/A 12951156SN/A interrupts &= ~ISR_NOIMPL; 12961156SN/A regs.isr &= ~interrupts; 12971156SN/A 12981156SN/A DPRINTF(EthernetIntr, 12991156SN/A "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n", 13005606SN/A interrupts, regs.isr, regs.imr); 13015606SN/A 13021156SN/A if (!(regs.isr & regs.imr)) 13031156SN/A cpuIntrClear(); 13041156SN/A} 13051156SN/A 130611006SN/Avoid 13071156SN/ANSGigE::devIntrChangeMask() 13082287SN/A{ 13092287SN/A DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n", 13109807SN/A regs.isr, regs.imr, regs.isr & regs.imr); 131110905SN/A 13121156SN/A if (regs.isr & regs.imr) 13131939SN/A cpuIntrPost(curTick); 13141939SN/A else 13151939SN/A cpuIntrClear(); 13161156SN/A} 13171939SN/A 13181939SN/Avoid 13191939SN/ANSGigE::cpuIntrPost(Tick when) 13201156SN/A{ 13211156SN/A // If the interrupt you want to post is later than an interrupt 13225603SN/A // already scheduled, just let it post in the coming one and don't 13231156SN/A // schedule another. 13241156SN/A // HOWEVER, must be sure that the scheduled intrTick is in the 13251939SN/A // future (this was formerly the source of a bug) 13261939SN/A /** 13271156SN/A * @todo this warning should be removed and the intrTick code should 13281156SN/A * be fixed. 13291156SN/A */ 13301156SN/A assert(when >= curTick); 13312008SN/A assert(intrTick >= curTick || intrTick == 0); 13322008SN/A if (when > intrTick && intrTick != 0) { 13332008SN/A DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n", 13342008SN/A intrTick); 13352008SN/A return; 133610905SN/A } 13372008SN/A 13382566SN/A intrTick = when; 133910905SN/A if (intrTick < curTick) { 134010905SN/A debug_break(); 134110905SN/A intrTick = curTick; 134210905SN/A } 13432008SN/A 13445603SN/A DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n", 134510905SN/A intrTick); 13462008SN/A 13472008SN/A if (intrEvent) 134811006SN/A intrEvent->squash(); 13495603SN/A intrEvent = new IntrEvent(this, true); 13502008SN/A intrEvent->schedule(intrTick); 13512008SN/A} 13522008SN/A 13532008SN/Avoid 13542008SN/ANSGigE::cpuInterrupt() 135510905SN/A{ 135610905SN/A assert(intrTick == curTick); 135710905SN/A 13582008SN/A // Whether or not there's a pending interrupt, we don't care about 135910905SN/A // it anymore 13602008SN/A intrEvent = 0; 13612008SN/A intrTick = 0; 13625603SN/A 13635603SN/A // Don't send an interrupt if there's already one 13645603SN/A if (cpuPendingIntr) { 13652282SN/A DPRINTF(EthernetIntr, 13662282SN/A "would send an interrupt now, but there's already pending\n"); 13672282SN/A } else { 13685603SN/A // Send interrupt 13695603SN/A cpuPendingIntr = true; 13705603SN/A 13712282SN/A DPRINTF(EthernetIntr, "posting interrupt\n"); 137211006SN/A intrPost(); 13732008SN/A } 137410905SN/A} 13752282SN/A 13762282SN/Avoid 13772008SN/ANSGigE::cpuIntrClear() 13782282SN/A{ 137910905SN/A if (!cpuPendingIntr) 13802282SN/A return; 13812282SN/A 13822282SN/A if (intrEvent) { 13832008SN/A intrEvent->squash(); 138410905SN/A intrEvent = 0; 13852282SN/A } 13862282SN/A 13872008SN/A intrTick = 0; 13882008SN/A 13891156SN/A cpuPendingIntr = false; 13901156SN/A 13911156SN/A DPRINTF(EthernetIntr, "clearing interrupt\n"); 13921156SN/A intrClear(); 13931939SN/A} 13942282SN/A 139510905SN/Abool 13961156SN/ANSGigE::cpuIntrPending() const 13971156SN/A{ return cpuPendingIntr; } 13981156SN/A 13991156SN/Avoid 14001156SN/ANSGigE::txReset() 14011156SN/A{ 14021939SN/A 140310905SN/A DPRINTF(Ethernet, "transmit reset\n"); 140410469SN/A 14051156SN/A CTDD = false; 14061156SN/A txEnable = false;; 140710905SN/A txFragPtr = 0; 14082008SN/A assert(txDescCnt == 0); 14092008SN/A txFifo.clear(); 14101156SN/A txState = txIdle; 14111156SN/A assert(txDmaState == dmaIdle); 14121156SN/A} 14131156SN/A 14141156SN/Avoid 14151156SN/ANSGigE::rxReset() 14167823SN/A{ 14171156SN/A DPRINTF(Ethernet, "receive reset\n"); 14181156SN/A 14191156SN/A CRDD = false; 14201156SN/A assert(rxPktBytes == 0); 142110905SN/A rxEnable = false; 14221156SN/A rxFragPtr = 0; 14239807SN/A assert(rxDescCnt == 0); 142410905SN/A assert(rxDmaState == dmaIdle); 14251156SN/A rxFifo.clear(); 14261156SN/A rxState = rxIdle; 14275603SN/A} 14281156SN/A 14291156SN/Avoid 14301939SN/ANSGigE::regsReset() 14311939SN/A{ 14321156SN/A memset(®s, 0, sizeof(regs)); 14331156SN/A regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000); 14341156SN/A regs.mear = 0x12; 14352282SN/A regs.txcfg = 0x120; // set drain threshold to 1024 bytes and 14365603SN/A // fill threshold to 32 bytes 14375603SN/A regs.rxcfg = 0x4; // set drain threshold to 16 bytes 14385603SN/A regs.srr = 0x0103; // set the silicon revision to rev B or 0x103 14392282SN/A regs.mibc = MIBC_FRZ; 14402008SN/A regs.vdr = 0x81; // set the vlan tag type to 802.1q 14412008SN/A regs.tesr = 0xc000; // TBI capable of both full and half duplex 14422008SN/A regs.brar = 0xffffffff; 14432008SN/A 14442008SN/A extstsEnable = false; 144510905SN/A acceptBroadcast = false; 14462008SN/A acceptMulticast = false; 14472008SN/A acceptUnicast = false; 14482008SN/A acceptPerfect = false; 14492282SN/A acceptArp = false; 14502282SN/A} 14512282SN/A 14522282SN/Avoid 14532282SN/ANSGigE::rxDmaReadCopy() 145410905SN/A{ 14552282SN/A assert(rxDmaState == dmaReading); 14562282SN/A 14572282SN/A physmem->dma_read((uint8_t *)rxDmaData, rxDmaAddr, rxDmaLen); 14582008SN/A rxDmaState = dmaIdle; 14592008SN/A 14602008SN/A DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", 14612008SN/A rxDmaAddr, rxDmaLen); 14622008SN/A DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 146310905SN/A} 14642008SN/A 14652008SN/Abool 14662008SN/ANSGigE::doRxDmaRead() 14671156SN/A{ 14681156SN/A assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); 14691156SN/A rxDmaState = dmaReading; 14701156SN/A 14711156SN/A if (dmaInterface && !rxDmaFree) { 14721939SN/A if (dmaInterface->busy()) 14732282SN/A rxDmaState = dmaReadWaiting; 14741156SN/A else 147510905SN/A dmaInterface->doDMA(Read, rxDmaAddr, rxDmaLen, curTick, 14761156SN/A &rxDmaReadEvent, true); 14772282SN/A return true; 14782282SN/A } 14795603SN/A 14805603SN/A if (dmaReadDelay == 0 && dmaReadFactor == 0) { 14815603SN/A rxDmaReadCopy(); 14825603SN/A return false; 14835603SN/A } 14845603SN/A 14855603SN/A Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; 14862282SN/A Tick start = curTick + dmaReadDelay + factor; 14871156SN/A rxDmaReadEvent.schedule(start); 14881156SN/A return true; 14891156SN/A} 14901156SN/A 14911156SN/Avoid 14921939SN/ANSGigE::rxDmaReadDone() 14931156SN/A{ 149410905SN/A assert(rxDmaState == dmaReading); 14951156SN/A rxDmaReadCopy(); 14961156SN/A 14971156SN/A // If the transmit state machine has a pending DMA, let it go first 14981156SN/A if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 149911719Smichael.lebeane@amd.com txKick(); 150010905SN/A 15012008SN/A rxKick(); 15022008SN/A} 15032008SN/A 15042008SN/Avoid 15052008SN/ANSGigE::rxDmaWriteCopy() 15062008SN/A{ 15072008SN/A assert(rxDmaState == dmaWriting); 15082008SN/A 15092008SN/A physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); 15102008SN/A rxDmaState = dmaIdle; 15112008SN/A 15122008SN/A DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", 15132008SN/A rxDmaAddr, rxDmaLen); 15142008SN/A DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 15152008SN/A} 15162008SN/A 15172566SN/Abool 15182008SN/ANSGigE::doRxDmaWrite() 151910905SN/A{ 152010905SN/A assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); 152110905SN/A rxDmaState = dmaWriting; 152210905SN/A 15232008SN/A if (dmaInterface && !rxDmaFree) { 15242282SN/A if (dmaInterface->busy()) 15252282SN/A rxDmaState = dmaWriteWaiting; 15262282SN/A else 15272008SN/A dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, curTick, 152810905SN/A &rxDmaWriteEvent, true); 15292008SN/A return true; 15302008SN/A } 153110905SN/A 15325603SN/A if (dmaWriteDelay == 0 && dmaWriteFactor == 0) { 15332008SN/A rxDmaWriteCopy(); 15345603SN/A return false; 15352008SN/A } 153610905SN/A 15372008SN/A Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; 153810905SN/A Tick start = curTick + dmaWriteDelay + factor; 15392008SN/A rxDmaWriteEvent.schedule(start); 15405603SN/A return true; 15412008SN/A} 154210905SN/A 15431156SN/Avoid 15441156SN/ANSGigE::rxDmaWriteDone() 15451156SN/A{ 15461156SN/A assert(rxDmaState == dmaWriting); 15471156SN/A rxDmaWriteCopy(); 15481156SN/A 15491156SN/A // If the transmit state machine has a pending DMA, let it go first 15501156SN/A if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 15517823SN/A txKick(); 15521156SN/A 15538851SN/A rxKick(); 15542566SN/A} 15551156SN/A 15561156SN/Avoid 15577811SN/ANSGigE::rxKick() 15581156SN/A{ 15594762SN/A DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n", 15604762SN/A NsRxStateStrings[rxState], rxFifo.size()); 15611156SN/A 15624762SN/A next: 15631156SN/A if (clock) { 1564 if (rxKickTick > curTick) { 1565 DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n", 1566 rxKickTick); 1567 1568 goto exit; 1569 } 1570 1571 // Go to the next state machine clock tick. 1572 rxKickTick = curTick + cycles(1); 1573 } 1574 1575 switch(rxDmaState) { 1576 case dmaReadWaiting: 1577 if (doRxDmaRead()) 1578 goto exit; 1579 break; 1580 case dmaWriteWaiting: 1581 if (doRxDmaWrite()) 1582 goto exit; 1583 break; 1584 default: 1585 break; 1586 } 1587 1588 // see state machine from spec for details 1589 // the way this works is, if you finish work on one state and can 1590 // go directly to another, you do that through jumping to the 1591 // label "next". however, if you have intermediate work, like DMA 1592 // so that you can't go to the next state yet, you go to exit and 1593 // exit the loop. however, when the DMA is done it will trigger 1594 // an event and come back to this loop. 1595 switch (rxState) { 1596 case rxIdle: 1597 if (!rxEnable) { 1598 DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n"); 1599 goto exit; 1600 } 1601 1602 if (CRDD) { 1603 rxState = rxDescRefr; 1604 1605 rxDmaAddr = regs.rxdp & 0x3fffffff; 1606 rxDmaData = &rxDescCache + offsetof(ns_desc, link); 1607 rxDmaLen = sizeof(rxDescCache.link); 1608 rxDmaFree = dmaDescFree; 1609 1610 descDmaReads++; 1611 descDmaRdBytes += rxDmaLen; 1612 1613 if (doRxDmaRead()) 1614 goto exit; 1615 } else { 1616 rxState = rxDescRead; 1617 1618 rxDmaAddr = regs.rxdp & 0x3fffffff; 1619 rxDmaData = &rxDescCache; 1620 rxDmaLen = sizeof(ns_desc); 1621 rxDmaFree = dmaDescFree; 1622 1623 descDmaReads++; 1624 descDmaRdBytes += rxDmaLen; 1625 1626 if (doRxDmaRead()) 1627 goto exit; 1628 } 1629 break; 1630 1631 case rxDescRefr: 1632 if (rxDmaState != dmaIdle) 1633 goto exit; 1634 1635 rxState = rxAdvance; 1636 break; 1637 1638 case rxDescRead: 1639 if (rxDmaState != dmaIdle) 1640 goto exit; 1641 1642 DPRINTF(EthernetDesc, "rxDescCache: addr=%08x read descriptor\n", 1643 regs.rxdp & 0x3fffffff); 1644 DPRINTF(EthernetDesc, 1645 "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", 1646 rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, 1647 rxDescCache.extsts); 1648 1649 if (rxDescCache.cmdsts & CMDSTS_OWN) { 1650 devIntrPost(ISR_RXIDLE); 1651 rxState = rxIdle; 1652 goto exit; 1653 } else { 1654 rxState = rxFifoBlock; 1655 rxFragPtr = rxDescCache.bufptr; 1656 rxDescCnt = rxDescCache.cmdsts & CMDSTS_LEN_MASK; 1657 } 1658 break; 1659 1660 case rxFifoBlock: 1661 if (!rxPacket) { 1662 /** 1663 * @todo in reality, we should be able to start processing 1664 * the packet as it arrives, and not have to wait for the 1665 * full packet ot be in the receive fifo. 1666 */ 1667 if (rxFifo.empty()) 1668 goto exit; 1669 1670 DPRINTF(EthernetSM, "****processing receive of new packet****\n"); 1671 1672 // If we don't have a packet, grab a new one from the fifo. 1673 rxPacket = rxFifo.front(); 1674 rxPktBytes = rxPacket->length; 1675 rxPacketBufPtr = rxPacket->data; 1676 1677#if TRACING_ON 1678 if (DTRACE(Ethernet)) { 1679 IpPtr ip(rxPacket); 1680 if (ip) { 1681 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1682 TcpPtr tcp(ip); 1683 if (tcp) { 1684 DPRINTF(Ethernet, 1685 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1686 tcp->sport(), tcp->dport(), tcp->seq(), 1687 tcp->ack()); 1688 } 1689 } 1690 } 1691#endif 1692 1693 // sanity check - i think the driver behaves like this 1694 assert(rxDescCnt >= rxPktBytes); 1695 rxFifo.pop(); 1696 } 1697 1698 1699 // dont' need the && rxDescCnt > 0 if driver sanity check 1700 // above holds 1701 if (rxPktBytes > 0) { 1702 rxState = rxFragWrite; 1703 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity 1704 // check holds 1705 rxXferLen = rxPktBytes; 1706 1707 rxDmaAddr = rxFragPtr & 0x3fffffff; 1708 rxDmaData = rxPacketBufPtr; 1709 rxDmaLen = rxXferLen; 1710 rxDmaFree = dmaDataFree; 1711 1712 if (doRxDmaWrite()) 1713 goto exit; 1714 1715 } else { 1716 rxState = rxDescWrite; 1717 1718 //if (rxPktBytes == 0) { /* packet is done */ 1719 assert(rxPktBytes == 0); 1720 DPRINTF(EthernetSM, "done with receiving packet\n"); 1721 1722 rxDescCache.cmdsts |= CMDSTS_OWN; 1723 rxDescCache.cmdsts &= ~CMDSTS_MORE; 1724 rxDescCache.cmdsts |= CMDSTS_OK; 1725 rxDescCache.cmdsts &= 0xffff0000; 1726 rxDescCache.cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE 1727 1728#if 0 1729 /* 1730 * all the driver uses these are for its own stats keeping 1731 * which we don't care about, aren't necessary for 1732 * functionality and doing this would just slow us down. 1733 * if they end up using this in a later version for 1734 * functional purposes, just undef 1735 */ 1736 if (rxFilterEnable) { 1737 rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK; 1738 const EthAddr &dst = rxFifoFront()->dst(); 1739 if (dst->unicast()) 1740 rxDescCache.cmdsts |= CMDSTS_DEST_SELF; 1741 if (dst->multicast()) 1742 rxDescCache.cmdsts |= CMDSTS_DEST_MULTI; 1743 if (dst->broadcast()) 1744 rxDescCache.cmdsts |= CMDSTS_DEST_MASK; 1745 } 1746#endif 1747 1748 IpPtr ip(rxPacket); 1749 if (extstsEnable && ip) { 1750 rxDescCache.extsts |= EXTSTS_IPPKT; 1751 rxIpChecksums++; 1752 if (cksum(ip) != 0) { 1753 DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); 1754 rxDescCache.extsts |= EXTSTS_IPERR; 1755 } 1756 TcpPtr tcp(ip); 1757 UdpPtr udp(ip); 1758 if (tcp) { 1759 rxDescCache.extsts |= EXTSTS_TCPPKT; 1760 rxTcpChecksums++; 1761 if (cksum(tcp) != 0) { 1762 DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); 1763 rxDescCache.extsts |= EXTSTS_TCPERR; 1764 1765 } 1766 } else if (udp) { 1767 rxDescCache.extsts |= EXTSTS_UDPPKT; 1768 rxUdpChecksums++; 1769 if (cksum(udp) != 0) { 1770 DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); 1771 rxDescCache.extsts |= EXTSTS_UDPERR; 1772 } 1773 } 1774 } 1775 rxPacket = 0; 1776 1777 /* 1778 * the driver seems to always receive into desc buffers 1779 * of size 1514, so you never have a pkt that is split 1780 * into multiple descriptors on the receive side, so 1781 * i don't implement that case, hence the assert above. 1782 */ 1783 1784 DPRINTF(EthernetDesc, 1785 "rxDescCache: addr=%08x writeback cmdsts extsts\n", 1786 regs.rxdp & 0x3fffffff); 1787 DPRINTF(EthernetDesc, 1788 "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", 1789 rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, 1790 rxDescCache.extsts); 1791 1792 rxDmaAddr = (regs.rxdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; 1793 rxDmaData = &(rxDescCache.cmdsts); 1794 rxDmaLen = sizeof(rxDescCache.cmdsts) + sizeof(rxDescCache.extsts); 1795 rxDmaFree = dmaDescFree; 1796 1797 descDmaWrites++; 1798 descDmaWrBytes += rxDmaLen; 1799 1800 if (doRxDmaWrite()) 1801 goto exit; 1802 } 1803 break; 1804 1805 case rxFragWrite: 1806 if (rxDmaState != dmaIdle) 1807 goto exit; 1808 1809 rxPacketBufPtr += rxXferLen; 1810 rxFragPtr += rxXferLen; 1811 rxPktBytes -= rxXferLen; 1812 1813 rxState = rxFifoBlock; 1814 break; 1815 1816 case rxDescWrite: 1817 if (rxDmaState != dmaIdle) 1818 goto exit; 1819 1820 assert(rxDescCache.cmdsts & CMDSTS_OWN); 1821 1822 assert(rxPacket == 0); 1823 devIntrPost(ISR_RXOK); 1824 1825 if (rxDescCache.cmdsts & CMDSTS_INTR) 1826 devIntrPost(ISR_RXDESC); 1827 1828 if (!rxEnable) { 1829 DPRINTF(EthernetSM, "Halting the RX state machine\n"); 1830 rxState = rxIdle; 1831 goto exit; 1832 } else 1833 rxState = rxAdvance; 1834 break; 1835 1836 case rxAdvance: 1837 if (rxDescCache.link == 0) { 1838 devIntrPost(ISR_RXIDLE); 1839 rxState = rxIdle; 1840 CRDD = true; 1841 goto exit; 1842 } else { 1843 if (rxDmaState != dmaIdle) 1844 goto exit; 1845 rxState = rxDescRead; 1846 regs.rxdp = rxDescCache.link; 1847 CRDD = false; 1848 1849 rxDmaAddr = regs.rxdp & 0x3fffffff; 1850 rxDmaData = &rxDescCache; 1851 rxDmaLen = sizeof(ns_desc); 1852 rxDmaFree = dmaDescFree; 1853 1854 if (doRxDmaRead()) 1855 goto exit; 1856 } 1857 break; 1858 1859 default: 1860 panic("Invalid rxState!"); 1861 } 1862 1863 DPRINTF(EthernetSM, "entering next rxState=%s\n", 1864 NsRxStateStrings[rxState]); 1865 goto next; 1866 1867 exit: 1868 /** 1869 * @todo do we want to schedule a future kick? 1870 */ 1871 DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n", 1872 NsRxStateStrings[rxState]); 1873 1874 if (clock && !rxKickEvent.scheduled()) 1875 rxKickEvent.schedule(rxKickTick); 1876} 1877 1878void 1879NSGigE::transmit() 1880{ 1881 if (txFifo.empty()) { 1882 DPRINTF(Ethernet, "nothing to transmit\n"); 1883 return; 1884 } 1885 1886 DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", 1887 txFifo.size()); 1888 if (interface->sendPacket(txFifo.front())) { 1889#if TRACING_ON 1890 if (DTRACE(Ethernet)) { 1891 IpPtr ip(txFifo.front()); 1892 if (ip) { 1893 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1894 TcpPtr tcp(ip); 1895 if (tcp) { 1896 DPRINTF(Ethernet, 1897 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1898 tcp->sport(), tcp->dport(), tcp->seq(), tcp->ack()); 1899 } 1900 } 1901 } 1902#endif 1903 1904 DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length); 1905 txBytes += txFifo.front()->length; 1906 txPackets++; 1907 1908 DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", 1909 txFifo.avail()); 1910 txFifo.pop(); 1911 1912 /* 1913 * normally do a writeback of the descriptor here, and ONLY 1914 * after that is done, send this interrupt. but since our 1915 * stuff never actually fails, just do this interrupt here, 1916 * otherwise the code has to stray from this nice format. 1917 * besides, it's functionally the same. 1918 */ 1919 devIntrPost(ISR_TXOK); 1920 } 1921 1922 if (!txFifo.empty() && !txEvent.scheduled()) { 1923 DPRINTF(Ethernet, "reschedule transmit\n"); 1924 txEvent.schedule(curTick + retryTime); 1925 } 1926} 1927 1928void 1929NSGigE::txDmaReadCopy() 1930{ 1931 assert(txDmaState == dmaReading); 1932 1933 physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); 1934 txDmaState = dmaIdle; 1935 1936 DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", 1937 txDmaAddr, txDmaLen); 1938 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1939} 1940 1941bool 1942NSGigE::doTxDmaRead() 1943{ 1944 assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); 1945 txDmaState = dmaReading; 1946 1947 if (dmaInterface && !txDmaFree) { 1948 if (dmaInterface->busy()) 1949 txDmaState = dmaReadWaiting; 1950 else 1951 dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, curTick, 1952 &txDmaReadEvent, true); 1953 return true; 1954 } 1955 1956 if (dmaReadDelay == 0 && dmaReadFactor == 0.0) { 1957 txDmaReadCopy(); 1958 return false; 1959 } 1960 1961 Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; 1962 Tick start = curTick + dmaReadDelay + factor; 1963 txDmaReadEvent.schedule(start); 1964 return true; 1965} 1966 1967void 1968NSGigE::txDmaReadDone() 1969{ 1970 assert(txDmaState == dmaReading); 1971 txDmaReadCopy(); 1972 1973 // If the receive state machine has a pending DMA, let it go first 1974 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1975 rxKick(); 1976 1977 txKick(); 1978} 1979 1980void 1981NSGigE::txDmaWriteCopy() 1982{ 1983 assert(txDmaState == dmaWriting); 1984 1985 physmem->dma_write(txDmaAddr, (uint8_t *)txDmaData, txDmaLen); 1986 txDmaState = dmaIdle; 1987 1988 DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", 1989 txDmaAddr, txDmaLen); 1990 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1991} 1992 1993bool 1994NSGigE::doTxDmaWrite() 1995{ 1996 assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); 1997 txDmaState = dmaWriting; 1998 1999 if (dmaInterface && !txDmaFree) { 2000 if (dmaInterface->busy()) 2001 txDmaState = dmaWriteWaiting; 2002 else 2003 dmaInterface->doDMA(WriteInvalidate, txDmaAddr, txDmaLen, curTick, 2004 &txDmaWriteEvent, true); 2005 return true; 2006 } 2007 2008 if (dmaWriteDelay == 0 && dmaWriteFactor == 0.0) { 2009 txDmaWriteCopy(); 2010 return false; 2011 } 2012 2013 Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; 2014 Tick start = curTick + dmaWriteDelay + factor; 2015 txDmaWriteEvent.schedule(start); 2016 return true; 2017} 2018 2019void 2020NSGigE::txDmaWriteDone() 2021{ 2022 assert(txDmaState == dmaWriting); 2023 txDmaWriteCopy(); 2024 2025 // If the receive state machine has a pending DMA, let it go first 2026 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 2027 rxKick(); 2028 2029 txKick(); 2030} 2031 2032void 2033NSGigE::txKick() 2034{ 2035 DPRINTF(EthernetSM, "transmit kick txState=%s\n", 2036 NsTxStateStrings[txState]); 2037 2038 next: 2039 if (clock) { 2040 if (txKickTick > curTick) { 2041 DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n", 2042 txKickTick); 2043 goto exit; 2044 } 2045 2046 // Go to the next state machine clock tick. 2047 txKickTick = curTick + cycles(1); 2048 } 2049 2050 switch(txDmaState) { 2051 case dmaReadWaiting: 2052 if (doTxDmaRead()) 2053 goto exit; 2054 break; 2055 case dmaWriteWaiting: 2056 if (doTxDmaWrite()) 2057 goto exit; 2058 break; 2059 default: 2060 break; 2061 } 2062 2063 switch (txState) { 2064 case txIdle: 2065 if (!txEnable) { 2066 DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n"); 2067 goto exit; 2068 } 2069 2070 if (CTDD) { 2071 txState = txDescRefr; 2072 2073 txDmaAddr = regs.txdp & 0x3fffffff; 2074 txDmaData = &txDescCache + offsetof(ns_desc, link); 2075 txDmaLen = sizeof(txDescCache.link); 2076 txDmaFree = dmaDescFree; 2077 2078 descDmaReads++; 2079 descDmaRdBytes += txDmaLen; 2080 2081 if (doTxDmaRead()) 2082 goto exit; 2083 2084 } else { 2085 txState = txDescRead; 2086 2087 txDmaAddr = regs.txdp & 0x3fffffff; 2088 txDmaData = &txDescCache; 2089 txDmaLen = sizeof(ns_desc); 2090 txDmaFree = dmaDescFree; 2091 2092 descDmaReads++; 2093 descDmaRdBytes += txDmaLen; 2094 2095 if (doTxDmaRead()) 2096 goto exit; 2097 } 2098 break; 2099 2100 case txDescRefr: 2101 if (txDmaState != dmaIdle) 2102 goto exit; 2103 2104 txState = txAdvance; 2105 break; 2106 2107 case txDescRead: 2108 if (txDmaState != dmaIdle) 2109 goto exit; 2110 2111 DPRINTF(EthernetDesc, "txDescCache: addr=%08x read descriptor\n", 2112 regs.txdp & 0x3fffffff); 2113 DPRINTF(EthernetDesc, 2114 "txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", 2115 txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts, 2116 txDescCache.extsts); 2117 2118 if (txDescCache.cmdsts & CMDSTS_OWN) { 2119 txState = txFifoBlock; 2120 txFragPtr = txDescCache.bufptr; 2121 txDescCnt = txDescCache.cmdsts & CMDSTS_LEN_MASK; 2122 } else { 2123 devIntrPost(ISR_TXIDLE); 2124 txState = txIdle; 2125 goto exit; 2126 } 2127 break; 2128 2129 case txFifoBlock: 2130 if (!txPacket) { 2131 DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); 2132 txPacket = new PacketData(16384); 2133 txPacketBufPtr = txPacket->data; 2134 } 2135 2136 if (txDescCnt == 0) { 2137 DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n"); 2138 if (txDescCache.cmdsts & CMDSTS_MORE) { 2139 DPRINTF(EthernetSM, "there are more descriptors to come\n"); 2140 txState = txDescWrite; 2141 2142 txDescCache.cmdsts &= ~CMDSTS_OWN; 2143 2144 txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts); 2145 txDmaAddr &= 0x3fffffff; 2146 txDmaData = &(txDescCache.cmdsts); 2147 txDmaLen = sizeof(txDescCache.cmdsts); 2148 txDmaFree = dmaDescFree; 2149 2150 if (doTxDmaWrite()) 2151 goto exit; 2152 2153 } else { /* this packet is totally done */ 2154 DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n"); 2155 /* deal with the the packet that just finished */ 2156 if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { 2157 IpPtr ip(txPacket); 2158 if (txDescCache.extsts & EXTSTS_UDPPKT) { 2159 UdpPtr udp(ip); 2160 udp->sum(0); 2161 udp->sum(cksum(udp)); 2162 txUdpChecksums++; 2163 } else if (txDescCache.extsts & EXTSTS_TCPPKT) { 2164 TcpPtr tcp(ip); 2165 tcp->sum(0); 2166 tcp->sum(cksum(tcp)); 2167 txTcpChecksums++; 2168 } 2169 if (txDescCache.extsts & EXTSTS_IPPKT) { 2170 ip->sum(0); 2171 ip->sum(cksum(ip)); 2172 txIpChecksums++; 2173 } 2174 } 2175 2176 txPacket->length = txPacketBufPtr - txPacket->data; 2177 // this is just because the receive can't handle a 2178 // packet bigger want to make sure 2179 assert(txPacket->length <= 1514); 2180#ifndef NDEBUG 2181 bool success = 2182#endif 2183 txFifo.push(txPacket); 2184 assert(success); 2185 2186 /* 2187 * this following section is not tqo spec, but 2188 * functionally shouldn't be any different. normally, 2189 * the chip will wait til the transmit has occurred 2190 * before writing back the descriptor because it has 2191 * to wait to see that it was successfully transmitted 2192 * to decide whether to set CMDSTS_OK or not. 2193 * however, in the simulator since it is always 2194 * successfully transmitted, and writing it exactly to 2195 * spec would complicate the code, we just do it here 2196 */ 2197 2198 txDescCache.cmdsts &= ~CMDSTS_OWN; 2199 txDescCache.cmdsts |= CMDSTS_OK; 2200 2201 DPRINTF(EthernetDesc, 2202 "txDesc writeback: cmdsts=%08x extsts=%08x\n", 2203 txDescCache.cmdsts, txDescCache.extsts); 2204 2205 txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts); 2206 txDmaAddr &= 0x3fffffff; 2207 txDmaData = &(txDescCache.cmdsts); 2208 txDmaLen = sizeof(txDescCache.cmdsts) + 2209 sizeof(txDescCache.extsts); 2210 txDmaFree = dmaDescFree; 2211 2212 descDmaWrites++; 2213 descDmaWrBytes += txDmaLen; 2214 2215 transmit(); 2216 txPacket = 0; 2217 2218 if (!txEnable) { 2219 DPRINTF(EthernetSM, "halting TX state machine\n"); 2220 txState = txIdle; 2221 goto exit; 2222 } else 2223 txState = txAdvance; 2224 2225 if (doTxDmaWrite()) 2226 goto exit; 2227 } 2228 } else { 2229 DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); 2230 if (!txFifo.full()) { 2231 txState = txFragRead; 2232 2233 /* 2234 * The number of bytes transferred is either whatever 2235 * is left in the descriptor (txDescCnt), or if there 2236 * is not enough room in the fifo, just whatever room 2237 * is left in the fifo 2238 */ 2239 txXferLen = min<uint32_t>(txDescCnt, txFifo.avail()); 2240 2241 txDmaAddr = txFragPtr & 0x3fffffff; 2242 txDmaData = txPacketBufPtr; 2243 txDmaLen = txXferLen; 2244 txDmaFree = dmaDataFree; 2245 2246 if (doTxDmaRead()) 2247 goto exit; 2248 } else { 2249 txState = txFifoBlock; 2250 transmit(); 2251 2252 goto exit; 2253 } 2254 2255 } 2256 break; 2257 2258 case txFragRead: 2259 if (txDmaState != dmaIdle) 2260 goto exit; 2261 2262 txPacketBufPtr += txXferLen; 2263 txFragPtr += txXferLen; 2264 txDescCnt -= txXferLen; 2265 txFifo.reserve(txXferLen); 2266 2267 txState = txFifoBlock; 2268 break; 2269 2270 case txDescWrite: 2271 if (txDmaState != dmaIdle) 2272 goto exit; 2273 2274 if (txDescCache.cmdsts & CMDSTS_INTR) 2275 devIntrPost(ISR_TXDESC); 2276 2277 if (!txEnable) { 2278 DPRINTF(EthernetSM, "halting TX state machine\n"); 2279 txState = txIdle; 2280 goto exit; 2281 } else 2282 txState = txAdvance; 2283 break; 2284 2285 case txAdvance: 2286 if (txDescCache.link == 0) { 2287 devIntrPost(ISR_TXIDLE); 2288 txState = txIdle; 2289 goto exit; 2290 } else { 2291 if (txDmaState != dmaIdle) 2292 goto exit; 2293 txState = txDescRead; 2294 regs.txdp = txDescCache.link; 2295 CTDD = false; 2296 2297 txDmaAddr = txDescCache.link & 0x3fffffff; 2298 txDmaData = &txDescCache; 2299 txDmaLen = sizeof(ns_desc); 2300 txDmaFree = dmaDescFree; 2301 2302 if (doTxDmaRead()) 2303 goto exit; 2304 } 2305 break; 2306 2307 default: 2308 panic("invalid state"); 2309 } 2310 2311 DPRINTF(EthernetSM, "entering next txState=%s\n", 2312 NsTxStateStrings[txState]); 2313 goto next; 2314 2315 exit: 2316 /** 2317 * @todo do we want to schedule a future kick? 2318 */ 2319 DPRINTF(EthernetSM, "tx state machine exited txState=%s\n", 2320 NsTxStateStrings[txState]); 2321 2322 if (clock && !txKickEvent.scheduled()) 2323 txKickEvent.schedule(txKickTick); 2324} 2325 2326/** 2327 * Advance the EEPROM state machine 2328 * Called on rising edge of EEPROM clock bit in MEAR 2329 */ 2330void 2331NSGigE::eepromKick() 2332{ 2333 switch (eepromState) { 2334 2335 case eepromStart: 2336 2337 // Wait for start bit 2338 if (regs.mear & MEAR_EEDI) { 2339 // Set up to get 2 opcode bits 2340 eepromState = eepromGetOpcode; 2341 eepromBitsToRx = 2; 2342 eepromOpcode = 0; 2343 } 2344 break; 2345 2346 case eepromGetOpcode: 2347 eepromOpcode <<= 1; 2348 eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0; 2349 --eepromBitsToRx; 2350 2351 // Done getting opcode 2352 if (eepromBitsToRx == 0) { 2353 if (eepromOpcode != EEPROM_READ) 2354 panic("only EEPROM reads are implemented!"); 2355 2356 // Set up to get address 2357 eepromState = eepromGetAddress; 2358 eepromBitsToRx = 6; 2359 eepromAddress = 0; 2360 } 2361 break; 2362 2363 case eepromGetAddress: 2364 eepromAddress <<= 1; 2365 eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0; 2366 --eepromBitsToRx; 2367 2368 // Done getting address 2369 if (eepromBitsToRx == 0) { 2370 2371 if (eepromAddress >= EEPROM_SIZE) 2372 panic("EEPROM read access out of range!"); 2373 2374 switch (eepromAddress) { 2375 2376 case EEPROM_PMATCH2_ADDR: 2377 eepromData = rom.perfectMatch[5]; 2378 eepromData <<= 8; 2379 eepromData += rom.perfectMatch[4]; 2380 break; 2381 2382 case EEPROM_PMATCH1_ADDR: 2383 eepromData = rom.perfectMatch[3]; 2384 eepromData <<= 8; 2385 eepromData += rom.perfectMatch[2]; 2386 break; 2387 2388 case EEPROM_PMATCH0_ADDR: 2389 eepromData = rom.perfectMatch[1]; 2390 eepromData <<= 8; 2391 eepromData += rom.perfectMatch[0]; 2392 break; 2393 2394 default: 2395 panic("FreeBSD driver only uses EEPROM to read PMATCH!"); 2396 } 2397 // Set up to read data 2398 eepromState = eepromRead; 2399 eepromBitsToRx = 16; 2400 2401 // Clear data in bit 2402 regs.mear &= ~MEAR_EEDI; 2403 } 2404 break; 2405 2406 case eepromRead: 2407 // Clear Data Out bit 2408 regs.mear &= ~MEAR_EEDO; 2409 // Set bit to value of current EEPROM bit 2410 regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0; 2411 2412 eepromData <<= 1; 2413 --eepromBitsToRx; 2414 2415 // All done 2416 if (eepromBitsToRx == 0) { 2417 eepromState = eepromStart; 2418 } 2419 break; 2420 2421 default: 2422 panic("invalid EEPROM state"); 2423 } 2424 2425} 2426 2427void 2428NSGigE::transferDone() 2429{ 2430 if (txFifo.empty()) { 2431 DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n"); 2432 return; 2433 } 2434 2435 DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); 2436 2437 if (txEvent.scheduled()) 2438 txEvent.reschedule(curTick + cycles(1)); 2439 else 2440 txEvent.schedule(curTick + cycles(1)); 2441} 2442 2443bool 2444NSGigE::rxFilter(const PacketPtr &packet) 2445{ 2446 EthPtr eth = packet; 2447 bool drop = true; 2448 string type; 2449 2450 const EthAddr &dst = eth->dst(); 2451 if (dst.unicast()) { 2452 // If we're accepting all unicast addresses 2453 if (acceptUnicast) 2454 drop = false; 2455 2456 // If we make a perfect match 2457 if (acceptPerfect && dst == rom.perfectMatch) 2458 drop = false; 2459 2460 if (acceptArp && eth->type() == ETH_TYPE_ARP) 2461 drop = false; 2462 2463 } else if (dst.broadcast()) { 2464 // if we're accepting broadcasts 2465 if (acceptBroadcast) 2466 drop = false; 2467 2468 } else if (dst.multicast()) { 2469 // if we're accepting all multicasts 2470 if (acceptMulticast) 2471 drop = false; 2472 2473 // Multicast hashing faked - all packets accepted 2474 if (multicastHashEnable) 2475 drop = false; 2476 } 2477 2478 if (drop) { 2479 DPRINTF(Ethernet, "rxFilter drop\n"); 2480 DDUMP(EthernetData, packet->data, packet->length); 2481 } 2482 2483 return drop; 2484} 2485 2486bool 2487NSGigE::recvPacket(PacketPtr packet) 2488{ 2489 rxBytes += packet->length; 2490 rxPackets++; 2491 2492 DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", 2493 rxFifo.avail()); 2494 2495 if (!rxEnable) { 2496 DPRINTF(Ethernet, "receive disabled...packet dropped\n"); 2497 interface->recvDone(); 2498 return true; 2499 } 2500 2501 if (!rxFilterEnable) { 2502 DPRINTF(Ethernet, 2503 "receive packet filtering disabled . . . packet dropped\n"); 2504 interface->recvDone(); 2505 return true; 2506 } 2507 2508 if (rxFilter(packet)) { 2509 DPRINTF(Ethernet, "packet filtered...dropped\n"); 2510 interface->recvDone(); 2511 return true; 2512 } 2513 2514 if (rxFifo.avail() < packet->length) { 2515#if TRACING_ON 2516 IpPtr ip(packet); 2517 TcpPtr tcp(ip); 2518 if (ip) { 2519 DPRINTF(Ethernet, 2520 "packet won't fit in receive buffer...pkt ID %d dropped\n", 2521 ip->id()); 2522 if (tcp) { 2523 DPRINTF(Ethernet, "Seq=%d\n", tcp->seq()); 2524 } 2525 } 2526#endif 2527 droppedPackets++; 2528 devIntrPost(ISR_RXORN); 2529 return false; 2530 } 2531 2532 rxFifo.push(packet); 2533 interface->recvDone(); 2534 2535 rxKick(); 2536 return true; 2537} 2538 2539//===================================================================== 2540// 2541// 2542void 2543NSGigE::serialize(ostream &os) 2544{ 2545 // Serialize the PciDev base class 2546 PciDev::serialize(os); 2547 2548 /* 2549 * Finalize any DMA events now. 2550 */ 2551 if (rxDmaReadEvent.scheduled()) 2552 rxDmaReadCopy(); 2553 if (rxDmaWriteEvent.scheduled()) 2554 rxDmaWriteCopy(); 2555 if (txDmaReadEvent.scheduled()) 2556 txDmaReadCopy(); 2557 if (txDmaWriteEvent.scheduled()) 2558 txDmaWriteCopy(); 2559 2560 /* 2561 * Serialize the device registers 2562 */ 2563 SERIALIZE_SCALAR(regs.command); 2564 SERIALIZE_SCALAR(regs.config); 2565 SERIALIZE_SCALAR(regs.mear); 2566 SERIALIZE_SCALAR(regs.ptscr); 2567 SERIALIZE_SCALAR(regs.isr); 2568 SERIALIZE_SCALAR(regs.imr); 2569 SERIALIZE_SCALAR(regs.ier); 2570 SERIALIZE_SCALAR(regs.ihr); 2571 SERIALIZE_SCALAR(regs.txdp); 2572 SERIALIZE_SCALAR(regs.txdp_hi); 2573 SERIALIZE_SCALAR(regs.txcfg); 2574 SERIALIZE_SCALAR(regs.gpior); 2575 SERIALIZE_SCALAR(regs.rxdp); 2576 SERIALIZE_SCALAR(regs.rxdp_hi); 2577 SERIALIZE_SCALAR(regs.rxcfg); 2578 SERIALIZE_SCALAR(regs.pqcr); 2579 SERIALIZE_SCALAR(regs.wcsr); 2580 SERIALIZE_SCALAR(regs.pcr); 2581 SERIALIZE_SCALAR(regs.rfcr); 2582 SERIALIZE_SCALAR(regs.rfdr); 2583 SERIALIZE_SCALAR(regs.brar); 2584 SERIALIZE_SCALAR(regs.brdr); 2585 SERIALIZE_SCALAR(regs.srr); 2586 SERIALIZE_SCALAR(regs.mibc); 2587 SERIALIZE_SCALAR(regs.vrcr); 2588 SERIALIZE_SCALAR(regs.vtcr); 2589 SERIALIZE_SCALAR(regs.vdr); 2590 SERIALIZE_SCALAR(regs.ccsr); 2591 SERIALIZE_SCALAR(regs.tbicr); 2592 SERIALIZE_SCALAR(regs.tbisr); 2593 SERIALIZE_SCALAR(regs.tanar); 2594 SERIALIZE_SCALAR(regs.tanlpar); 2595 SERIALIZE_SCALAR(regs.taner); 2596 SERIALIZE_SCALAR(regs.tesr); 2597 2598 SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2599 SERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2600 2601 SERIALIZE_SCALAR(ioEnable); 2602 2603 /* 2604 * Serialize the data Fifos 2605 */ 2606 rxFifo.serialize("rxFifo", os); 2607 txFifo.serialize("txFifo", os); 2608 2609 /* 2610 * Serialize the various helper variables 2611 */ 2612 bool txPacketExists = txPacket; 2613 SERIALIZE_SCALAR(txPacketExists); 2614 if (txPacketExists) { 2615 txPacket->length = txPacketBufPtr - txPacket->data; 2616 txPacket->serialize("txPacket", os); 2617 uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); 2618 SERIALIZE_SCALAR(txPktBufPtr); 2619 } 2620 2621 bool rxPacketExists = rxPacket; 2622 SERIALIZE_SCALAR(rxPacketExists); 2623 if (rxPacketExists) { 2624 rxPacket->serialize("rxPacket", os); 2625 uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); 2626 SERIALIZE_SCALAR(rxPktBufPtr); 2627 } 2628 2629 SERIALIZE_SCALAR(txXferLen); 2630 SERIALIZE_SCALAR(rxXferLen); 2631 2632 /* 2633 * Serialize DescCaches 2634 */ 2635 SERIALIZE_SCALAR(txDescCache.link); 2636 SERIALIZE_SCALAR(txDescCache.bufptr); 2637 SERIALIZE_SCALAR(txDescCache.cmdsts); 2638 SERIALIZE_SCALAR(txDescCache.extsts); 2639 SERIALIZE_SCALAR(rxDescCache.link); 2640 SERIALIZE_SCALAR(rxDescCache.bufptr); 2641 SERIALIZE_SCALAR(rxDescCache.cmdsts); 2642 SERIALIZE_SCALAR(rxDescCache.extsts); 2643 SERIALIZE_SCALAR(extstsEnable); 2644 2645 /* 2646 * Serialize tx state machine 2647 */ 2648 int txState = this->txState; 2649 SERIALIZE_SCALAR(txState); 2650 SERIALIZE_SCALAR(txEnable); 2651 SERIALIZE_SCALAR(CTDD); 2652 SERIALIZE_SCALAR(txFragPtr); 2653 SERIALIZE_SCALAR(txDescCnt); 2654 int txDmaState = this->txDmaState; 2655 SERIALIZE_SCALAR(txDmaState); 2656 SERIALIZE_SCALAR(txKickTick); 2657 2658 /* 2659 * Serialize rx state machine 2660 */ 2661 int rxState = this->rxState; 2662 SERIALIZE_SCALAR(rxState); 2663 SERIALIZE_SCALAR(rxEnable); 2664 SERIALIZE_SCALAR(CRDD); 2665 SERIALIZE_SCALAR(rxPktBytes); 2666 SERIALIZE_SCALAR(rxFragPtr); 2667 SERIALIZE_SCALAR(rxDescCnt); 2668 int rxDmaState = this->rxDmaState; 2669 SERIALIZE_SCALAR(rxDmaState); 2670 SERIALIZE_SCALAR(rxKickTick); 2671 2672 /* 2673 * Serialize EEPROM state machine 2674 */ 2675 int eepromState = this->eepromState; 2676 SERIALIZE_SCALAR(eepromState); 2677 SERIALIZE_SCALAR(eepromClk); 2678 SERIALIZE_SCALAR(eepromBitsToRx); 2679 SERIALIZE_SCALAR(eepromOpcode); 2680 SERIALIZE_SCALAR(eepromAddress); 2681 SERIALIZE_SCALAR(eepromData); 2682 2683 /* 2684 * If there's a pending transmit, store the time so we can 2685 * reschedule it later 2686 */ 2687 Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick : 0; 2688 SERIALIZE_SCALAR(transmitTick); 2689 2690 /* 2691 * receive address filter settings 2692 */ 2693 SERIALIZE_SCALAR(rxFilterEnable); 2694 SERIALIZE_SCALAR(acceptBroadcast); 2695 SERIALIZE_SCALAR(acceptMulticast); 2696 SERIALIZE_SCALAR(acceptUnicast); 2697 SERIALIZE_SCALAR(acceptPerfect); 2698 SERIALIZE_SCALAR(acceptArp); 2699 SERIALIZE_SCALAR(multicastHashEnable); 2700 2701 /* 2702 * Keep track of pending interrupt status. 2703 */ 2704 SERIALIZE_SCALAR(intrTick); 2705 SERIALIZE_SCALAR(cpuPendingIntr); 2706 Tick intrEventTick = 0; 2707 if (intrEvent) 2708 intrEventTick = intrEvent->when(); 2709 SERIALIZE_SCALAR(intrEventTick); 2710 2711} 2712 2713void 2714NSGigE::unserialize(Checkpoint *cp, const std::string §ion) 2715{ 2716 // Unserialize the PciDev base class 2717 PciDev::unserialize(cp, section); 2718 2719 UNSERIALIZE_SCALAR(regs.command); 2720 UNSERIALIZE_SCALAR(regs.config); 2721 UNSERIALIZE_SCALAR(regs.mear); 2722 UNSERIALIZE_SCALAR(regs.ptscr); 2723 UNSERIALIZE_SCALAR(regs.isr); 2724 UNSERIALIZE_SCALAR(regs.imr); 2725 UNSERIALIZE_SCALAR(regs.ier); 2726 UNSERIALIZE_SCALAR(regs.ihr); 2727 UNSERIALIZE_SCALAR(regs.txdp); 2728 UNSERIALIZE_SCALAR(regs.txdp_hi); 2729 UNSERIALIZE_SCALAR(regs.txcfg); 2730 UNSERIALIZE_SCALAR(regs.gpior); 2731 UNSERIALIZE_SCALAR(regs.rxdp); 2732 UNSERIALIZE_SCALAR(regs.rxdp_hi); 2733 UNSERIALIZE_SCALAR(regs.rxcfg); 2734 UNSERIALIZE_SCALAR(regs.pqcr); 2735 UNSERIALIZE_SCALAR(regs.wcsr); 2736 UNSERIALIZE_SCALAR(regs.pcr); 2737 UNSERIALIZE_SCALAR(regs.rfcr); 2738 UNSERIALIZE_SCALAR(regs.rfdr); 2739 UNSERIALIZE_SCALAR(regs.brar); 2740 UNSERIALIZE_SCALAR(regs.brdr); 2741 UNSERIALIZE_SCALAR(regs.srr); 2742 UNSERIALIZE_SCALAR(regs.mibc); 2743 UNSERIALIZE_SCALAR(regs.vrcr); 2744 UNSERIALIZE_SCALAR(regs.vtcr); 2745 UNSERIALIZE_SCALAR(regs.vdr); 2746 UNSERIALIZE_SCALAR(regs.ccsr); 2747 UNSERIALIZE_SCALAR(regs.tbicr); 2748 UNSERIALIZE_SCALAR(regs.tbisr); 2749 UNSERIALIZE_SCALAR(regs.tanar); 2750 UNSERIALIZE_SCALAR(regs.tanlpar); 2751 UNSERIALIZE_SCALAR(regs.taner); 2752 UNSERIALIZE_SCALAR(regs.tesr); 2753 2754 UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2755 UNSERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2756 2757 UNSERIALIZE_SCALAR(ioEnable); 2758 2759 /* 2760 * unserialize the data fifos 2761 */ 2762 rxFifo.unserialize("rxFifo", cp, section); 2763 txFifo.unserialize("txFifo", cp, section); 2764 2765 /* 2766 * unserialize the various helper variables 2767 */ 2768 bool txPacketExists; 2769 UNSERIALIZE_SCALAR(txPacketExists); 2770 if (txPacketExists) { 2771 txPacket = new PacketData(16384); 2772 txPacket->unserialize("txPacket", cp, section); 2773 uint32_t txPktBufPtr; 2774 UNSERIALIZE_SCALAR(txPktBufPtr); 2775 txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; 2776 } else 2777 txPacket = 0; 2778 2779 bool rxPacketExists; 2780 UNSERIALIZE_SCALAR(rxPacketExists); 2781 rxPacket = 0; 2782 if (rxPacketExists) { 2783 rxPacket = new PacketData(16384); 2784 rxPacket->unserialize("rxPacket", cp, section); 2785 uint32_t rxPktBufPtr; 2786 UNSERIALIZE_SCALAR(rxPktBufPtr); 2787 rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; 2788 } else 2789 rxPacket = 0; 2790 2791 UNSERIALIZE_SCALAR(txXferLen); 2792 UNSERIALIZE_SCALAR(rxXferLen); 2793 2794 /* 2795 * Unserialize DescCaches 2796 */ 2797 UNSERIALIZE_SCALAR(txDescCache.link); 2798 UNSERIALIZE_SCALAR(txDescCache.bufptr); 2799 UNSERIALIZE_SCALAR(txDescCache.cmdsts); 2800 UNSERIALIZE_SCALAR(txDescCache.extsts); 2801 UNSERIALIZE_SCALAR(rxDescCache.link); 2802 UNSERIALIZE_SCALAR(rxDescCache.bufptr); 2803 UNSERIALIZE_SCALAR(rxDescCache.cmdsts); 2804 UNSERIALIZE_SCALAR(rxDescCache.extsts); 2805 UNSERIALIZE_SCALAR(extstsEnable); 2806 2807 /* 2808 * unserialize tx state machine 2809 */ 2810 int txState; 2811 UNSERIALIZE_SCALAR(txState); 2812 this->txState = (TxState) txState; 2813 UNSERIALIZE_SCALAR(txEnable); 2814 UNSERIALIZE_SCALAR(CTDD); 2815 UNSERIALIZE_SCALAR(txFragPtr); 2816 UNSERIALIZE_SCALAR(txDescCnt); 2817 int txDmaState; 2818 UNSERIALIZE_SCALAR(txDmaState); 2819 this->txDmaState = (DmaState) txDmaState; 2820 UNSERIALIZE_SCALAR(txKickTick); 2821 if (txKickTick) 2822 txKickEvent.schedule(txKickTick); 2823 2824 /* 2825 * unserialize rx state machine 2826 */ 2827 int rxState; 2828 UNSERIALIZE_SCALAR(rxState); 2829 this->rxState = (RxState) rxState; 2830 UNSERIALIZE_SCALAR(rxEnable); 2831 UNSERIALIZE_SCALAR(CRDD); 2832 UNSERIALIZE_SCALAR(rxPktBytes); 2833 UNSERIALIZE_SCALAR(rxFragPtr); 2834 UNSERIALIZE_SCALAR(rxDescCnt); 2835 int rxDmaState; 2836 UNSERIALIZE_SCALAR(rxDmaState); 2837 this->rxDmaState = (DmaState) rxDmaState; 2838 UNSERIALIZE_SCALAR(rxKickTick); 2839 if (rxKickTick) 2840 rxKickEvent.schedule(rxKickTick); 2841 2842 /* 2843 * Unserialize EEPROM state machine 2844 */ 2845 int eepromState; 2846 UNSERIALIZE_SCALAR(eepromState); 2847 this->eepromState = (EEPROMState) eepromState; 2848 UNSERIALIZE_SCALAR(eepromClk); 2849 UNSERIALIZE_SCALAR(eepromBitsToRx); 2850 UNSERIALIZE_SCALAR(eepromOpcode); 2851 UNSERIALIZE_SCALAR(eepromAddress); 2852 UNSERIALIZE_SCALAR(eepromData); 2853 2854 /* 2855 * If there's a pending transmit, reschedule it now 2856 */ 2857 Tick transmitTick; 2858 UNSERIALIZE_SCALAR(transmitTick); 2859 if (transmitTick) 2860 txEvent.schedule(curTick + transmitTick); 2861 2862 /* 2863 * unserialize receive address filter settings 2864 */ 2865 UNSERIALIZE_SCALAR(rxFilterEnable); 2866 UNSERIALIZE_SCALAR(acceptBroadcast); 2867 UNSERIALIZE_SCALAR(acceptMulticast); 2868 UNSERIALIZE_SCALAR(acceptUnicast); 2869 UNSERIALIZE_SCALAR(acceptPerfect); 2870 UNSERIALIZE_SCALAR(acceptArp); 2871 UNSERIALIZE_SCALAR(multicastHashEnable); 2872 2873 /* 2874 * Keep track of pending interrupt status. 2875 */ 2876 UNSERIALIZE_SCALAR(intrTick); 2877 UNSERIALIZE_SCALAR(cpuPendingIntr); 2878 Tick intrEventTick; 2879 UNSERIALIZE_SCALAR(intrEventTick); 2880 if (intrEventTick) { 2881 intrEvent = new IntrEvent(this, true); 2882 intrEvent->schedule(intrEventTick); 2883 } 2884 2885 /* 2886 * re-add addrRanges to bus bridges 2887 */ 2888 if (pioInterface) { 2889 pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); 2890 pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); 2891 } 2892} 2893 2894Tick 2895NSGigE::cacheAccess(MemReqPtr &req) 2896{ 2897 DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", 2898 req->paddr, req->paddr - addr); 2899 return curTick + pioLatency; 2900} 2901 2902BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) 2903 2904 SimObjectParam<EtherInt *> peer; 2905 SimObjectParam<NSGigE *> device; 2906 2907END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) 2908 2909BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt) 2910 2911 INIT_PARAM_DFLT(peer, "peer interface", NULL), 2912 INIT_PARAM(device, "Ethernet device of this interface") 2913 2914END_INIT_SIM_OBJECT_PARAMS(NSGigEInt) 2915 2916CREATE_SIM_OBJECT(NSGigEInt) 2917{ 2918 NSGigEInt *dev_int = new NSGigEInt(getInstanceName(), device); 2919 2920 EtherInt *p = (EtherInt *)peer; 2921 if (p) { 2922 dev_int->setPeer(p); 2923 p->setPeer(dev_int); 2924 } 2925 2926 return dev_int; 2927} 2928 2929REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) 2930 2931 2932BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) 2933 2934 Param<Addr> addr; 2935 Param<Tick> clock; 2936 Param<Tick> tx_delay; 2937 Param<Tick> rx_delay; 2938 Param<Tick> intr_delay; 2939 SimObjectParam<MemoryController *> mmu; 2940 SimObjectParam<PhysicalMemory *> physmem; 2941 Param<bool> rx_filter; 2942 Param<string> hardware_address; 2943 SimObjectParam<Bus*> io_bus; 2944 SimObjectParam<Bus*> payload_bus; 2945 SimObjectParam<HierParams *> hier; 2946 Param<Tick> pio_latency; 2947 Param<bool> dma_desc_free; 2948 Param<bool> dma_data_free; 2949 Param<Tick> dma_read_delay; 2950 Param<Tick> dma_write_delay; 2951 Param<Tick> dma_read_factor; 2952 Param<Tick> dma_write_factor; 2953 SimObjectParam<PciConfigAll *> configspace; 2954 SimObjectParam<PciConfigData *> configdata; 2955 SimObjectParam<Platform *> platform; 2956 Param<uint32_t> pci_bus; 2957 Param<uint32_t> pci_dev; 2958 Param<uint32_t> pci_func; 2959 Param<uint32_t> tx_fifo_size; 2960 Param<uint32_t> rx_fifo_size; 2961 Param<uint32_t> m5reg; 2962 Param<bool> dma_no_allocate; 2963 2964END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) 2965 2966BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) 2967 2968 INIT_PARAM(addr, "Device Address"), 2969 INIT_PARAM(clock, "State machine processor frequency"), 2970 INIT_PARAM(tx_delay, "Transmit Delay"), 2971 INIT_PARAM(rx_delay, "Receive Delay"), 2972 INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), 2973 INIT_PARAM(mmu, "Memory Controller"), 2974 INIT_PARAM(physmem, "Physical Memory"), 2975 INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), 2976 INIT_PARAM(hardware_address, "Ethernet Hardware Address"), 2977 INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL), 2978 INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), 2979 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), 2980 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), 2981 INIT_PARAM_DFLT(dma_desc_free, "DMA of Descriptors is free", false), 2982 INIT_PARAM_DFLT(dma_data_free, "DMA of Data is free", false), 2983 INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0), 2984 INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0), 2985 INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0), 2986 INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0), 2987 INIT_PARAM(configspace, "PCI Configspace"), 2988 INIT_PARAM(configdata, "PCI Config data"), 2989 INIT_PARAM(platform, "Platform"), 2990 INIT_PARAM(pci_bus, "PCI bus"), 2991 INIT_PARAM(pci_dev, "PCI device number"), 2992 INIT_PARAM(pci_func, "PCI function code"), 2993 INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 131072), 2994 INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 131072), 2995 INIT_PARAM(m5reg, "m5 register"), 2996 INIT_PARAM_DFLT(dma_no_allocate, "Should DMA reads allocate cache lines", true) 2997 2998END_INIT_SIM_OBJECT_PARAMS(NSGigE) 2999 3000 3001CREATE_SIM_OBJECT(NSGigE) 3002{ 3003 NSGigE::Params *params = new NSGigE::Params; 3004 3005 params->name = getInstanceName(); 3006 params->mmu = mmu; 3007 params->configSpace = configspace; 3008 params->configData = configdata; 3009 params->plat = platform; 3010 params->busNum = pci_bus; 3011 params->deviceNum = pci_dev; 3012 params->functionNum = pci_func; 3013 3014 params->clock = clock; 3015 params->intr_delay = intr_delay; 3016 params->pmem = physmem; 3017 params->tx_delay = tx_delay; 3018 params->rx_delay = rx_delay; 3019 params->hier = hier; 3020 params->header_bus = io_bus; 3021 params->payload_bus = payload_bus; 3022 params->pio_latency = pio_latency; 3023 params->dma_desc_free = dma_desc_free; 3024 params->dma_data_free = dma_data_free; 3025 params->dma_read_delay = dma_read_delay; 3026 params->dma_write_delay = dma_write_delay; 3027 params->dma_read_factor = dma_read_factor; 3028 params->dma_write_factor = dma_write_factor; 3029 params->rx_filter = rx_filter; 3030 params->eaddr = hardware_address; 3031 params->tx_fifo_size = tx_fifo_size; 3032 params->rx_fifo_size = rx_fifo_size; 3033 params->m5reg = m5reg; 3034 params->dma_no_allocate = dma_no_allocate; 3035 return new NSGigE(params); 3036} 3037 3038REGISTER_SIM_OBJECT("NSGigE", NSGigE) 3039