Deleted Added
sdiff udiff text old ( 11317:766c3eb44fd8 ) new ( 11533:2aa4d7bd47ec )
full compact
1/*
2 * Copyright (c) 2014 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;

--- 33 unchanged lines hidden (view full) ---

42
43EtherSwitch::EtherSwitch(const Params *p)
44 : EtherObject(p), ttl(p->time_to_live)
45{
46 for (int i = 0; i < p->port_interface_connection_count; ++i) {
47 std::string interfaceName = csprintf("%s.interface%d", name(), i);
48 Interface *interface = new Interface(interfaceName, this,
49 p->output_buffer_size, p->delay,
50 p->delay_var, p->fabric_speed);
51 interfaces.push_back(interface);
52 }
53}
54
55EtherSwitch::~EtherSwitch()
56{
57 for (auto it : interfaces)
58 delete it;

--- 8 unchanged lines hidden (view full) ---

67 return nullptr;
68
69 Interface *interface = interfaces.at(idx);
70 panic_if(interface->getPeer(), "interface already connected\n");
71
72 return interface;
73}
74
75EtherSwitch::Interface::Interface(const std::string &name,
76 EtherSwitch *etherSwitch,
77 uint64_t outputBufferSize, Tick delay,
78 Tick delay_var, double rate)
79 : EtherInt(name), ticksPerByte(rate), switchDelay(delay),
80 delayVar(delay_var), parent(etherSwitch),
81 outputFifo(outputBufferSize), txEvent(this)
82{
83}
84
85bool
86EtherSwitch::Interface::recvPacket(EthPacketPtr packet)
87{
88 Net::EthAddr destMacAddr(packet->data);
89 Net::EthAddr srcMacAddr(&packet->data[6]);
90
91 learnSenderAddr(srcMacAddr, this);
92 Interface *receiver = lookupDestPort(destMacAddr);
93
94 if (!receiver || destMacAddr.multicast() || destMacAddr.broadcast()) {
95 for (auto it : parent->interfaces)
96 if (it != this)
97 it->enqueue(packet);
98 } else {
99 DPRINTF(Ethernet, "sending packet from MAC %x on port "
100 "%s to MAC %x on port %s\n", uint64_t(srcMacAddr),
101 this->name(), uint64_t(destMacAddr), receiver->name());
102
103 receiver->enqueue(packet);
104 }
105 // At the output port, we either have buffer space (no drop) or
106 // don't (drop packet); in both cases packet is received on
107 // the interface successfully and there is no notion of busy
108 // interface here (as we don't have inputFifo)
109 return true;
110}
111
112void
113EtherSwitch::Interface::enqueue(EthPacketPtr packet)
114{
115 if (!outputFifo.push(packet)) {
116 // output buffer full, drop packet
117 DPRINTF(Ethernet, "output buffer full, drop packet\n");
118 return;
119 }
120
121 // assuming per-interface transmission events,
122 // if there was nothing in the Fifo before push the
123 // current packet, then we need to schedule an event at
124 // curTick + switchingDelay to send this packet out the external link
125 // otherwise, there is already a txEvent scheduled
126 if (!txEvent.scheduled()) {
127 parent->schedule(txEvent, curTick() + switchingDelay());
128 }
129}
130
131void
132EtherSwitch::Interface::transmit()
133{
134 // there should be something in the output queue
135 assert(!outputFifo.empty());

--- 70 unchanged lines hidden (view full) ---

206 it->second.lastUseTime = curTick();
207 }
208}
209
210void
211EtherSwitch::serialize(CheckpointOut &cp) const
212{
213 for (auto it : interfaces)
214 it->serialize(it->name(), cp);
215}
216
217void
218EtherSwitch::unserialize(CheckpointIn &cp)
219{
220 for (auto it : interfaces)
221 it->unserialize(it->name(), cp);
222}
223
224void
225EtherSwitch::Interface::serialize(const std::string &base, CheckpointOut &cp)
226const
227{
228 bool event_scheduled = txEvent.scheduled();
229 paramOut(cp, base + ".event_scheduled", event_scheduled);
230 if (event_scheduled) {
231 Tick event_time = txEvent.when();
232 paramOut(cp, base + ".event_time", event_time);
233 }
234
235 outputFifo.serialize(base + "outputFifo", cp);
236}
237
238void
239EtherSwitch::Interface::unserialize(const std::string &base, CheckpointIn &cp)
240{
241 bool event_scheduled;
242 paramIn(cp, base + ".event_scheduled", event_scheduled);
243 if (event_scheduled) {
244 Tick event_time;
245 paramIn(cp, base + ".event_time", event_time);
246 parent->schedule(txEvent, event_time);
247 }
248
249 outputFifo.unserialize(base + "outputFifo", cp);
250}
251
252EtherSwitch *
253EtherSwitchParams::create()
254{
255 return new EtherSwitch(this);
256}