ns_gige.hh revision 837
1/* 2 * Copyright (c) 2003 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* @file 30 * Device module for modelling the National Semiconductor 31 * DP83820 ethernet controller 32 */ 33 34#ifndef __NS_GIGE_HH__ 35#define __NS_GIGE_HH__ 36 37#include "dev/dma.hh" 38#include "dev/etherint.hh" 39#include "dev/etherpkt.hh" 40#include "sim/eventq.hh" 41#include "dev/ns_gige_reg.h" 42#include "base/statistics.hh" 43#include "dev/pcidev.hh" 44#include "dev/tsunami.hh" 45#include "dev/pciconfigall.hh" 46 47/** defined by the NS83820 data sheet */ 48#define MAX_TX_FIFO_SIZE 8192 49#define MAX_RX_FIFO_SIZE 32768 50 51/** length of ethernet address in bytes */ 52#define EADDR_LEN 6 53 54/** Transmit State Machine states */ 55enum tx_state { txIdle, txDescRefr, txDescRead, txFifoBlock, txFragRead, 56 txDescWrite }; 57 58/** Receive State Machine States */ 59enum rx_state { rxIdle, rxDescRefr, rxDescRead, rxFifoBlock, rxFragWrite, 60 rxDescWrite, rxAdvance }; 61 62/** 63 * Ethernet device registers 64 */ 65struct dp_regs { 66 uint32_t command; 67 uint32_t config; 68 uint32_t mear; 69 uint32_t ptscr; 70 uint32_t isr; 71 uint32_t imr; 72 uint32_t ier; 73 uint32_t ihr; 74 uint32_t txdp; 75 uint32_t txdp_hi; 76 uint32_t txcfg; 77 uint32_t gpior; 78 uint32_t rxdp; 79 uint32_t rxdp_hi; 80 uint32_t rxcfg; 81 uint32_t pqcr; 82 uint32_t wcsr; 83 uint32_t pcr; 84 uint32_t rfcr; 85 uint32_t rfdr; 86 uint32_t srr; 87 uint32_t mibc; 88 uint32_t vrcr; 89 uint32_t vtcr; 90 uint32_t vdr; 91 uint32_t ccsr; 92 uint32_t tbicr; 93 uint32_t tbisr; 94 uint32_t tanar; 95 uint32_t tanlpar; 96 uint32_t taner; 97 uint32_t tesr; 98 99 /** for perfect match memory. the linux driver doesn't use any other ROM */ 100 uint8_t perfectMatch[EADDR_LEN]; 101 102 virtual void serialize(std::ostream &os); 103 virtual void unserialize(Checkpoint *cp, const std::string §ion); 104}; 105 106/** an enum indicating direction, transmit or receive, used as a param for 107 some fns */ 108enum dir_t { tx, rx }; 109 110class DmaEngine; 111class IntrControl; 112class EtherDevInt; 113class PhysicalMemory; 114 115/** 116 * NS DP82830 Ethernet device model 117 */ 118class EtherDev : public PciDev, public DmaHolder 119{ 120 private: 121 /** pointer to the chipset */ 122 Tsunami *tsunami; 123 124 protected: 125 Addr addr; 126 Addr mask; 127 128 /** device register file */ 129 dp_regs regs; 130 131 /*** BASIC STRUCTURES FOR TX/RX ***/ 132 /* Data FIFOs */ 133 typedef std::deque<PacketPtr> pktbuf_t; 134 typedef pktbuf_t::iterator pktiter_t; 135 pktbuf_t txFifo; 136 pktbuf_t rxFifo; 137 138 /** for the tx side, to track addrs to write updated cmdsts to */ 139 typedef std::deque<uint32_t> txdpbuf_t; /* ASSUME32 */ 140 txdpbuf_t descAddrFifo; 141 142 /** various helper vars */ 143 uint32_t txPacketLen; 144 uint8_t *txPacketBufPtr; 145 uint8_t *rxPacketBufPtr; 146 uint8_t *rxDescBufPtr; 147 uint32_t fragLen; 148 uint32_t rxCopied; 149 150 /** DescCaches */ 151 ns_desc txDescCache; 152 ns_desc rxDescCache; 153 154 /* tx State Machine */ 155 tx_state txState; 156 /** Current Transmit Descriptor Done */ 157 bool CTDD; 158 uint32_t txFifoCnt; /* amt of data in the txDataFifo in bytes (logical) */ 159 uint32_t txFifoAvail; /* current amt of free space in txDataFifo in byes */ 160 bool txHalt; 161 bool txPacketFlag; /* when set, indicates not working on a new packet */ 162 Addr txFragPtr; /* ptr to the next byte in the current fragment */ 163 uint32_t txDescCnt; /* count of bytes remaining in the current descriptor */ 164 165 /** rx State Machine */ 166 rx_state rxState; 167 bool CRDD; /* Current Receive Descriptor Done */ 168 uint32_t rxPktBytes; /* num of bytes in the current packet being drained 169 from rxDataFifo */ 170 uint32_t rxFifoCnt; /* number of bytes in the rxFifo */ 171 bool rxHalt; 172 bool rxPacketFlag; /* when set, indicates not working on a new packet */ 173 Addr rxFragPtr; /* ptr to the next byte in current fragment */ 174 uint32_t rxDescCnt; /* count of bytes remaining in the current descriptor */ 175 176 bool extstsEnable; 177 uint32_t maxTxBurst; 178 uint32_t maxRxBurst; 179 180 PhysicalMemory *physmem; 181 182 protected: 183 /** 184 * Receive dma for descriptors done callback 185 */ 186 class RxDescDone : public DmaCallback 187 { 188 public: 189 EtherDev *ethernet; 190 191 public: 192 RxDescDone(EtherDev *e); 193 std::string name() const; 194 virtual void process(); 195 }; 196 197 /** 198 * Receive dma done callback 199 */ 200 class RxDone : public DmaCallback 201 { 202 public: 203 EtherDev *ethernet; 204 205 public: 206 RxDone(EtherDev *e); 207 std::string name() const; 208 virtual void process(); 209 }; 210 211 /** 212 * Transmit dma for descriptors done callback 213 */ 214 class TxDescDone : public DmaCallback 215 { 216 public: 217 EtherDev *ethernet; 218 219 public: 220 TxDescDone(EtherDev *e); 221 std::string name() const; 222 virtual void process(); 223 }; 224 225 /* 226 * Transmit dma done callback 227 */ 228 class TxDone : public DmaCallback 229 { 230 public: 231 EtherDev *ethernet; 232 PacketPtr packet; 233 234 public: 235 TxDone(EtherDev *e); 236 std::string name() const; 237 virtual void process(); 238 }; 239 240 friend class TxDescDone; 241 friend class TxDone; 242 friend class RxDescDone; 243 friend class RxDone; 244 245 RxDescDone rxDescDoneCB; 246 RxDone rxDoneCB; 247 TxDescDone txDescDoneCB; 248 TxDone txDoneCB; 249 250 DmaEngine *dma; 251 DmaRequest readRequest; 252 DmaRequest writeRequest; 253 DmaRequest readDescRequest; 254 DmaRequest writeDescRequest; 255 PacketPtr rxPacket; 256 DmaPhys readPhys; 257 DmaPhys writePhys; 258 DmaPhys readDescPhys; 259 DmaPhys writeDescPhys; 260 261 EtherDevInt *interface; 262 263 protected: 264 IntrControl *intctrl; 265 Tick txDelay; 266 Tick rxDelay; 267 268 void txReset(); 269 void rxReset(); 270 void regsReset() { 271 memset(®s, 0, sizeof(regs)); 272 regs.mear = 0x12; 273 regs.isr = 0x00608000; 274 regs.txcfg = 0x120; 275 regs.rxcfg = 0x4; 276 regs.srr = 0x0103; 277 regs.mibc = 0x2; 278 regs.vdr = 0x81; 279 regs.tesr = 0xc000; 280 } 281 282 void txKick(); 283 void rxKick(); 284 285 /* 286 * Retransmit event 287 */ 288 class TxEvent : public Event 289 { 290 protected: 291 EtherDev *dev; 292 293 public: 294 TxEvent(EtherDev *_dev) 295 : Event(&mainEventQueue), dev(_dev) {} 296 void process() { dev->transmit(); } 297 virtual const char *description() { return "retransmit"; } 298 }; 299 friend class TxEvent; 300 TxEvent txEvent; 301 void transmit(); 302 303 304 void txDescDone(); 305 void rxDescDone(); 306 void txDone(PacketPtr packet); 307 void rxDone(); 308 309 void txDump() const; 310 void rxDump() const; 311 312 void devIntrPost(uint32_t interrupts); 313 void devIntrClear(uint32_t interrupts); 314 void devIntrChangeMask(); 315 316 bool cpuPendingIntr; 317 void cpuIntrPost(); 318 void cpuIntrClear(); 319 320 bool rxFilterEnable; 321 bool rxFilter(PacketPtr packet); 322 bool acceptBroadcast; 323 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