ns_gige.hh revision 837
13855Sbinkertn@umich.edu/* 23855Sbinkertn@umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 33855Sbinkertn@umich.edu * All rights reserved. 43855Sbinkertn@umich.edu * 53855Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 63855Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 73855Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 83855Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 93855Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 103855Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 113855Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 123855Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 133855Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 143855Sbinkertn@umich.edu * this software without specific prior written permission. 153855Sbinkertn@umich.edu * 163855Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173855Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183855Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193855Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203855Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213855Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223855Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233855Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243855Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253855Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263855Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273855Sbinkertn@umich.edu */ 283855Sbinkertn@umich.edu 293855Sbinkertn@umich.edu/* @file 303855Sbinkertn@umich.edu * Device module for modelling the National Semiconductor 313855Sbinkertn@umich.edu * DP83820 ethernet controller 323855Sbinkertn@umich.edu */ 333855Sbinkertn@umich.edu 343855Sbinkertn@umich.edu#ifndef __NS_GIGE_HH__ 353855Sbinkertn@umich.edu#define __NS_GIGE_HH__ 363855Sbinkertn@umich.edu 373855Sbinkertn@umich.edu#include "dev/dma.hh" 383855Sbinkertn@umich.edu#include "dev/etherint.hh" 393855Sbinkertn@umich.edu#include "dev/etherpkt.hh" 403855Sbinkertn@umich.edu#include "sim/eventq.hh" 413855Sbinkertn@umich.edu#include "dev/ns_gige_reg.h" 423855Sbinkertn@umich.edu#include "base/statistics.hh" 433855Sbinkertn@umich.edu#include "dev/pcidev.hh" 443855Sbinkertn@umich.edu#include "dev/tsunami.hh" 453855Sbinkertn@umich.edu#include "dev/pciconfigall.hh" 463855Sbinkertn@umich.edu 473855Sbinkertn@umich.edu/** defined by the NS83820 data sheet */ 483855Sbinkertn@umich.edu#define MAX_TX_FIFO_SIZE 8192 493855Sbinkertn@umich.edu#define MAX_RX_FIFO_SIZE 32768 503855Sbinkertn@umich.edu 513855Sbinkertn@umich.edu/** length of ethernet address in bytes */ 523855Sbinkertn@umich.edu#define EADDR_LEN 6 533855Sbinkertn@umich.edu 543855Sbinkertn@umich.edu/** Transmit State Machine states */ 553855Sbinkertn@umich.eduenum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead, 563855Sbinkertn@umich.edu txDescWrite }; 573855Sbinkertn@umich.edu 583855Sbinkertn@umich.edu/** Receive State Machine States */ 593855Sbinkertn@umich.eduenum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite, 603855Sbinkertn@umich.edu rxDescWrite, rxAdvance }; 613855Sbinkertn@umich.edu 623855Sbinkertn@umich.edu/** 633855Sbinkertn@umich.edu * Ethernet device registers 643855Sbinkertn@umich.edu */ 653855Sbinkertn@umich.edustruct dp_regs { 663855Sbinkertn@umich.edu uint32_t command; 673855Sbinkertn@umich.edu uint32_t config; 683855Sbinkertn@umich.edu uint32_t mear; 693855Sbinkertn@umich.edu uint32_t ptscr; 703855Sbinkertn@umich.edu uint32_t isr; 713855Sbinkertn@umich.edu uint32_t imr; 723855Sbinkertn@umich.edu uint32_t ier; 733855Sbinkertn@umich.edu uint32_t ihr; 743855Sbinkertn@umich.edu uint32_t txdp; 753855Sbinkertn@umich.edu uint32_t txdp_hi; 763855Sbinkertn@umich.edu uint32_t txcfg; 773855Sbinkertn@umich.edu uint32_t gpior; 783855Sbinkertn@umich.edu uint32_t rxdp; 793855Sbinkertn@umich.edu uint32_t rxdp_hi; 803855Sbinkertn@umich.edu uint32_t rxcfg; 813855Sbinkertn@umich.edu uint32_t pqcr; 823855Sbinkertn@umich.edu uint32_t wcsr; 833855Sbinkertn@umich.edu uint32_t pcr; 843855Sbinkertn@umich.edu uint32_t rfcr; 853855Sbinkertn@umich.edu uint32_t rfdr; 863855Sbinkertn@umich.edu uint32_t srr; 873855Sbinkertn@umich.edu uint32_t mibc; 883855Sbinkertn@umich.edu uint32_t vrcr; 893855Sbinkertn@umich.edu uint32_t vtcr; 903855Sbinkertn@umich.edu uint32_t vdr; 913855Sbinkertn@umich.edu uint32_t ccsr; 923855Sbinkertn@umich.edu uint32_t tbicr; 933855Sbinkertn@umich.edu uint32_t tbisr; 943855Sbinkertn@umich.edu uint32_t tanar; 953855Sbinkertn@umich.edu uint32_t tanlpar; 963855Sbinkertn@umich.edu uint32_t taner; 973855Sbinkertn@umich.edu uint32_t tesr; 983855Sbinkertn@umich.edu 993855Sbinkertn@umich.edu /** for perfect match memory. the linux driver doesn't use any other ROM */ 1003855Sbinkertn@umich.edu uint8_t perfectMatch[EADDR_LEN]; 1013855Sbinkertn@umich.edu 1023855Sbinkertn@umich.edu virtual void serialize(std::ostream &os); 1033855Sbinkertn@umich.edu virtual void unserialize(Checkpoint *cp, const std::string §ion); 1043855Sbinkertn@umich.edu}; 1053855Sbinkertn@umich.edu 1063855Sbinkertn@umich.edu/** an enum indicating direction, transmit or receive, used as a param for 1073855Sbinkertn@umich.edu some fns */ 1083855Sbinkertn@umich.eduenum dir_t { tx, rx }; 1093855Sbinkertn@umich.edu 1103855Sbinkertn@umich.educlass DmaEngine; 1113855Sbinkertn@umich.educlass IntrControl; 1123855Sbinkertn@umich.educlass EtherDevInt; 1133855Sbinkertn@umich.educlass PhysicalMemory; 1143855Sbinkertn@umich.edu 1153855Sbinkertn@umich.edu/** 1163855Sbinkertn@umich.edu * NS DP82830 Ethernet device model 1173855Sbinkertn@umich.edu */ 1183855Sbinkertn@umich.educlass EtherDev : public PciDev, public DmaHolder 1193855Sbinkertn@umich.edu{ 1203855Sbinkertn@umich.edu private: 1213855Sbinkertn@umich.edu /** pointer to the chipset */ 1223855Sbinkertn@umich.edu Tsunami *tsunami; 1233855Sbinkertn@umich.edu 1243855Sbinkertn@umich.edu protected: 1253855Sbinkertn@umich.edu Addr addr; 1263855Sbinkertn@umich.edu Addr mask; 1273855Sbinkertn@umich.edu 1283855Sbinkertn@umich.edu /** device register file */ 1293855Sbinkertn@umich.edu dp_regs regs; 1303855Sbinkertn@umich.edu 1313855Sbinkertn@umich.edu /*** BASIC STRUCTURES FOR TX/RX ***/ 1323855Sbinkertn@umich.edu /* Data FIFOs */ 1333855Sbinkertn@umich.edu typedef std::deque<PacketPtr> pktbuf_t; 1343855Sbinkertn@umich.edu typedef pktbuf_t::iterator pktiter_t; 1353855Sbinkertn@umich.edu pktbuf_t txFifo; 1363855Sbinkertn@umich.edu pktbuf_t rxFifo; 1373855Sbinkertn@umich.edu 1383855Sbinkertn@umich.edu /** for the tx side, to track addrs to write updated cmdsts to */ 1393855Sbinkertn@umich.edu typedef std::deque<uint32_t> txdpbuf_t; /* ASSUME32 */ 1403855Sbinkertn@umich.edu txdpbuf_t descAddrFifo; 1413855Sbinkertn@umich.edu 1423855Sbinkertn@umich.edu /** various helper vars */ 1433855Sbinkertn@umich.edu uint32_t txPacketLen; 1443855Sbinkertn@umich.edu uint8_t *txPacketBufPtr; 1453855Sbinkertn@umich.edu uint8_t *rxPacketBufPtr; 1463855Sbinkertn@umich.edu uint8_t *rxDescBufPtr; 1473855Sbinkertn@umich.edu uint32_t fragLen; 1483855Sbinkertn@umich.edu uint32_t rxCopied; 1493855Sbinkertn@umich.edu 15011320Ssteve.reinhardt@amd.com /** DescCaches */ 1513855Sbinkertn@umich.edu ns_desc txDescCache; 1523855Sbinkertn@umich.edu ns_desc rxDescCache; 1533855Sbinkertn@umich.edu 1543855Sbinkertn@umich.edu /* tx State Machine */ 1553855Sbinkertn@umich.edu tx_state txState; 1563855Sbinkertn@umich.edu /** Current Transmit Descriptor Done */ 1573855Sbinkertn@umich.edu bool CTDD; 1583855Sbinkertn@umich.edu uint32_t txFifoCnt; /* amt of data in the txDataFifo in bytes (logical) */ 1593855Sbinkertn@umich.edu uint32_t txFifoAvail; /* current amt of free space in txDataFifo in byes */ 1603855Sbinkertn@umich.edu bool txHalt; 1613855Sbinkertn@umich.edu bool txPacketFlag; /* when set, indicates not working on a new packet */ 1623855Sbinkertn@umich.edu Addr txFragPtr; /* ptr to the next byte in the current fragment */ 1633855Sbinkertn@umich.edu uint32_t txDescCnt; /* count of bytes remaining in the current descriptor */ 1643855Sbinkertn@umich.edu 1653855Sbinkertn@umich.edu /** rx State Machine */ 1663855Sbinkertn@umich.edu rx_state rxState; 1673855Sbinkertn@umich.edu bool CRDD; /* Current Receive Descriptor Done */ 1683855Sbinkertn@umich.edu uint32_t rxPktBytes; /* num of bytes in the current packet being drained 1693855Sbinkertn@umich.edu from rxDataFifo */ 1703855Sbinkertn@umich.edu uint32_t rxFifoCnt; /* number of bytes in the rxFifo */ 1713855Sbinkertn@umich.edu bool rxHalt; 1723855Sbinkertn@umich.edu bool rxPacketFlag; /* when set, indicates not working on a new packet */ 1733855Sbinkertn@umich.edu Addr rxFragPtr; /* ptr to the next byte in current fragment */ 1743855Sbinkertn@umich.edu uint32_t rxDescCnt; /* count of bytes remaining in the current descriptor */ 1753855Sbinkertn@umich.edu 1763855Sbinkertn@umich.edu bool extstsEnable; 1773855Sbinkertn@umich.edu uint32_t maxTxBurst; 1783855Sbinkertn@umich.edu uint32_t maxRxBurst; 1793855Sbinkertn@umich.edu 1803855Sbinkertn@umich.edu PhysicalMemory *physmem; 1813855Sbinkertn@umich.edu 1823855Sbinkertn@umich.edu protected: 1833855Sbinkertn@umich.edu /** 1843855Sbinkertn@umich.edu * Receive dma for descriptors done callback 1853855Sbinkertn@umich.edu */ 1863855Sbinkertn@umich.edu class RxDescDone : public DmaCallback 1873855Sbinkertn@umich.edu { 1883855Sbinkertn@umich.edu public: 1893855Sbinkertn@umich.edu EtherDev *ethernet; 1903855Sbinkertn@umich.edu 1913855Sbinkertn@umich.edu public: 1923855Sbinkertn@umich.edu RxDescDone(EtherDev *e); 1933855Sbinkertn@umich.edu std::string name() const; 1943855Sbinkertn@umich.edu virtual void process(); 1953855Sbinkertn@umich.edu }; 1963855Sbinkertn@umich.edu 1973855Sbinkertn@umich.edu /** 1983855Sbinkertn@umich.edu * Receive dma done callback 1993855Sbinkertn@umich.edu */ 2003855Sbinkertn@umich.edu class RxDone : public DmaCallback 2013855Sbinkertn@umich.edu { 2023855Sbinkertn@umich.edu public: 2033855Sbinkertn@umich.edu EtherDev *ethernet; 2043855Sbinkertn@umich.edu 2053855Sbinkertn@umich.edu public: 2063855Sbinkertn@umich.edu RxDone(EtherDev *e); 2073855Sbinkertn@umich.edu std::string name() const; 2083855Sbinkertn@umich.edu virtual void process(); 2093855Sbinkertn@umich.edu }; 2103855Sbinkertn@umich.edu 2113855Sbinkertn@umich.edu /** 2123855Sbinkertn@umich.edu * Transmit dma for descriptors done callback 2133855Sbinkertn@umich.edu */ 2143855Sbinkertn@umich.edu class TxDescDone : public DmaCallback 2153855Sbinkertn@umich.edu { 2163855Sbinkertn@umich.edu public: 2173855Sbinkertn@umich.edu EtherDev *ethernet; 2183855Sbinkertn@umich.edu 2193855Sbinkertn@umich.edu public: 2203855Sbinkertn@umich.edu TxDescDone(EtherDev *e); 2213855Sbinkertn@umich.edu std::string name() const; 2223855Sbinkertn@umich.edu virtual void process(); 2233855Sbinkertn@umich.edu }; 2243855Sbinkertn@umich.edu 2253855Sbinkertn@umich.edu /* 2263855Sbinkertn@umich.edu * Transmit dma done callback 2273855Sbinkertn@umich.edu */ 2283855Sbinkertn@umich.edu class TxDone : public DmaCallback 2293855Sbinkertn@umich.edu { 2303855Sbinkertn@umich.edu public: 2313855Sbinkertn@umich.edu EtherDev *ethernet; 2323855Sbinkertn@umich.edu PacketPtr packet; 2333855Sbinkertn@umich.edu 2343855Sbinkertn@umich.edu public: 2353855Sbinkertn@umich.edu TxDone(EtherDev *e); 2363855Sbinkertn@umich.edu std::string name() const; 2373855Sbinkertn@umich.edu virtual void process(); 2383855Sbinkertn@umich.edu }; 2393855Sbinkertn@umich.edu 2403855Sbinkertn@umich.edu friend class TxDescDone; 2413855Sbinkertn@umich.edu friend class TxDone; 2423855Sbinkertn@umich.edu friend class RxDescDone; 2433855Sbinkertn@umich.edu friend class RxDone; 2443855Sbinkertn@umich.edu 2453855Sbinkertn@umich.edu RxDescDone rxDescDoneCB; 2463855Sbinkertn@umich.edu RxDone rxDoneCB; 2473855Sbinkertn@umich.edu TxDescDone txDescDoneCB; 2483855Sbinkertn@umich.edu TxDone txDoneCB; 2493855Sbinkertn@umich.edu 2503855Sbinkertn@umich.edu DmaEngine *dma; 2513855Sbinkertn@umich.edu DmaRequest readRequest; 2523855Sbinkertn@umich.edu DmaRequest writeRequest; 2533855Sbinkertn@umich.edu DmaRequest readDescRequest; 2543855Sbinkertn@umich.edu DmaRequest writeDescRequest; 2553855Sbinkertn@umich.edu PacketPtr rxPacket; 2563855Sbinkertn@umich.edu DmaPhys readPhys; 2573855Sbinkertn@umich.edu DmaPhys writePhys; 2583855Sbinkertn@umich.edu DmaPhys readDescPhys; 2593855Sbinkertn@umich.edu DmaPhys writeDescPhys; 2603855Sbinkertn@umich.edu 2613855Sbinkertn@umich.edu EtherDevInt *interface; 2623855Sbinkertn@umich.edu 2633855Sbinkertn@umich.edu protected: 2643855Sbinkertn@umich.edu IntrControl *intctrl; 2653855Sbinkertn@umich.edu Tick txDelay; 2663855Sbinkertn@umich.edu Tick rxDelay; 2673855Sbinkertn@umich.edu 2683855Sbinkertn@umich.edu void txReset(); 2693855Sbinkertn@umich.edu void rxReset(); 2703855Sbinkertn@umich.edu void regsReset() { 2713855Sbinkertn@umich.edu memset(®s, 0, sizeof(regs)); 2723855Sbinkertn@umich.edu regs.mear = 0x12; 2733855Sbinkertn@umich.edu regs.isr = 0x00608000; 2743855Sbinkertn@umich.edu regs.txcfg = 0x120; 2753855Sbinkertn@umich.edu regs.rxcfg = 0x4; 2763855Sbinkertn@umich.edu regs.srr = 0x0103; 2773855Sbinkertn@umich.edu regs.mibc = 0x2; 2783855Sbinkertn@umich.edu regs.vdr = 0x81; 2793855Sbinkertn@umich.edu regs.tesr = 0xc000; 2803855Sbinkertn@umich.edu } 2813855Sbinkertn@umich.edu 2823855Sbinkertn@umich.edu void txKick(); 2833855Sbinkertn@umich.edu void rxKick(); 2843855Sbinkertn@umich.edu 2853855Sbinkertn@umich.edu /* 2863855Sbinkertn@umich.edu * Retransmit event 2873855Sbinkertn@umich.edu */ 2883855Sbinkertn@umich.edu class TxEvent : public Event 2893855Sbinkertn@umich.edu { 2903855Sbinkertn@umich.edu protected: 2913855Sbinkertn@umich.edu EtherDev *dev; 2923855Sbinkertn@umich.edu 2933855Sbinkertn@umich.edu public: 2943855Sbinkertn@umich.edu TxEvent(EtherDev *_dev) 2953855Sbinkertn@umich.edu : Event(&mainEventQueue), dev(_dev) {} 2963855Sbinkertn@umich.edu void process() { dev->transmit(); } 2973855Sbinkertn@umich.edu virtual const char *description() { return "retransmit"; } 2983855Sbinkertn@umich.edu }; 2993855Sbinkertn@umich.edu friend class TxEvent; 3003855Sbinkertn@umich.edu TxEvent txEvent; 3013855Sbinkertn@umich.edu void transmit(); 3023855Sbinkertn@umich.edu 3033855Sbinkertn@umich.edu 3043855Sbinkertn@umich.edu void txDescDone(); 3053855Sbinkertn@umich.edu void rxDescDone(); 3063855Sbinkertn@umich.edu void txDone(PacketPtr packet); 3073855Sbinkertn@umich.edu void rxDone(); 3083855Sbinkertn@umich.edu 3093855Sbinkertn@umich.edu void txDump() const; 3103855Sbinkertn@umich.edu void rxDump() const; 3113855Sbinkertn@umich.edu 3123855Sbinkertn@umich.edu void devIntrPost(uint32_t interrupts); 3133855Sbinkertn@umich.edu void devIntrClear(uint32_t interrupts); 3143855Sbinkertn@umich.edu void devIntrChangeMask(); 3153855Sbinkertn@umich.edu 3163855Sbinkertn@umich.edu bool cpuPendingIntr; 3173855Sbinkertn@umich.edu void cpuIntrPost(); 3183855Sbinkertn@umich.edu void cpuIntrClear(); 3193855Sbinkertn@umich.edu 3203855Sbinkertn@umich.edu bool rxFilterEnable; 3213855Sbinkertn@umich.edu bool rxFilter(PacketPtr packet); 3223855Sbinkertn@umich.edu bool acceptBroadcast; 3233855Sbinkertn@umich.edu bool acceptMulticast; 324 bool acceptUnicast; 325 bool acceptPerfect; 326 bool acceptArp; 327 328 bool udpChecksum(PacketPtr packet, bool gen); 329 bool tcpChecksum(PacketPtr packet, bool gen); 330 bool ipChecksum(PacketPtr packet, bool gen); 331 uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len); 332 333 public: 334 EtherDev(const std::string &name, DmaEngine *de, bool use_interface, 335 IntrControl *i, MemoryController *mmu, PhysicalMemory *pmem, 336 PCIConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, 337 uint32_t dev, uint32_t func, bool rx_filter, const int eaddr[6], 338 Tick tx_delay, Tick rx_delay, Addr addr, Addr mask); 339 ~EtherDev(); 340 341 virtual void WriteConfig(int offset, int size, uint32_t data); 342 virtual void ReadConfig(int offset, int size, uint8_t *data); 343 344 345 346 Fault read(MemReqPtr req, uint8_t *data); 347 Fault write(MemReqPtr req, const uint8_t *data); 348 349 bool cpuIntrPending() const; 350 void cpuIntrAck() { cpuIntrClear(); } 351 352 bool recvPacket(PacketPtr packet); 353 void transferDone(); 354 355 void setInterface(EtherDevInt *i) { assert(!interface); interface = i; } 356 357 virtual void serialize(std::ostream &os); 358 virtual void unserialize(Checkpoint *cp, const std::string §ion); 359 360 virtual DmaRequest *find_dmareq(uint32_t &id) { 361 if (id == 0) 362 return(&readRequest); 363 else if (id == 1) 364 return(&writeRequest); 365 else 366 return(NULL); 367 } 368 369 public: 370 void regStats(); 371 372 private: 373 Statistics::Scalar<> txBytes; 374 Statistics::Scalar<> rxBytes; 375 Statistics::Scalar<> txPackets; 376 Statistics::Scalar<> rxPackets; 377 Statistics::Formula txBandwidth; 378 Statistics::Formula rxBandwidth; 379 Statistics::Formula txPacketRate; 380 Statistics::Formula rxPacketRate; 381 382 void readOneDesc(dir_t dir, uint32_t len = sizeof(ns_desc)); 383 void readOneFrag(); 384 void writeOneFrag(); 385}; 386 387/* 388 * Ethernet Interface for an Ethernet Device 389 */ 390class EtherDevInt : public EtherInt 391{ 392 private: 393 EtherDev *dev; 394 395 public: 396 EtherDevInt(const std::string &name, EtherDev *d) 397 : EtherInt(name), dev(d) { dev->setInterface(this); } 398 399 virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); } 400 virtual void sendDone() { dev->transferDone(); } 401}; 402 403#endif // __NS_GIGE_HH__ 404