diff options
Diffstat (limited to 'dev/etherlink.cc')
-rw-r--r-- | dev/etherlink.cc | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/dev/etherlink.cc b/dev/etherlink.cc new file mode 100644 index 000000000..1d3578e58 --- /dev/null +++ b/dev/etherlink.cc @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Device module for modelling a fixed bandwidth full duplex ethernet link + */ + +#include <deque> +#include <string> +#include <vector> + +#include <math.h> + +#include "etherlink.hh" +#include "etherdump.hh" +#include "etherint.hh" +#include "etherpkt.hh" +#include "trace.hh" +#include "universe.hh" + +using namespace std; + +EtherLink::EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, + Tick speed, EtherDump *dump) + : SimObject(name) +{ + double rate = ((double)ticksPerSecond * 8.0) / (double)speed; + + link1 = new Link(name + ".link1", rate, dump); + link2 = new Link(name + ".link2", rate, dump); + + int1 = new Interface(name + ".int1", link1, link2); + int2 = new Interface(name + ".int2", link2, link1); + + int1->setPeer(i1); + i1->setPeer(int1); + int2->setPeer(i2); + i2->setPeer(int2); +} + +EtherLink::~EtherLink() +{ + delete link1; + delete link2; + + delete int1; + delete int2; +} + +EtherLink::Interface::Interface(const std::string &name, Link *tx, Link *rx) + : EtherInt(name), txlink(tx) +{ + tx->setTxInt(this); + rx->setRxInt(this); +} + +EtherLink::Link::Link(const std::string &name, double rate, EtherDump *d) + : Serializeable(name), txint(NULL), rxint(NULL), ticks_per_byte(rate), + dump(d), event(&mainEventQueue, this) +{} + +void +EtherLink::Link::txDone() +{ + rxint->sendPacket(packet); + + if (dump) + dump->dump(packet); + + DPRINTF(Ethernet, "EtherLink packet received: len=%d\n", packet->length); + DDUMP(EthernetData, packet->data, packet->length); + + packet = 0; + assert(!busy()); + + txint->sendDone(); +} + +bool +EtherLink::Link::transmit(PacketPtr pkt) +{ + if (busy()) { + DPRINTF(Ethernet, "EtherLink packet not sent, link busy\n"); + return false; + } + + DPRINTF(Ethernet, "EtherLink packet sent: len=%d\n", pkt->length); + DDUMP(EthernetData, pkt->data, pkt->length); + + packet = pkt; + int delay = (int)ceil(((double)pkt->length * ticks_per_byte) + 1.0); + DPRINTF(Ethernet, "EtherLink scheduling packet: delay=%d, (rate=%f)\n", + delay, ticks_per_byte); + event.schedule(curTick + delay); + + return true; +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) + + SimObjectParam<EtherInt *> interface1; + SimObjectParam<EtherInt *> interface2; + Param<int> link_speed; + SimObjectParam<EtherDump *> packet_dump; + +END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) + +BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) + + INIT_PARAM(interface1, "interface 1"), + INIT_PARAM(interface2, "interface 2"), + INIT_PARAM_DFLT(link_speed, "link speed in bits per second", 100000000), + INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL) + +END_INIT_SIM_OBJECT_PARAMS(EtherLink) + +CREATE_SIM_OBJECT(EtherLink) +{ + return new EtherLink(getInstanceName(), interface1, interface2, link_speed, + packet_dump); +} + +REGISTER_SIM_OBJECT("EtherLink", EtherLink) |