mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-13 14:35:34 +00:00
88 lines
2.3 KiB
C++
88 lines
2.3 KiB
C++
/*
|
|
* \brief Network receive handler per MAC address
|
|
* \author Markus Partheymueller
|
|
* \author Alexander Boettcher
|
|
* \date 2012-07-31
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2012 Intel Corporation
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
|
*
|
|
* This file is distributed under the terms of the GNU General Public License
|
|
* version 2.
|
|
*
|
|
* The code is partially based on the Vancouver VMM, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*
|
|
* Modifications by Intel Corporation are contributed under the terms and
|
|
* conditions of the GNU General Public License version 2.
|
|
*/
|
|
|
|
/* local includes */
|
|
#include "network.h"
|
|
|
|
|
|
Seoul::Network::Network(Genode::Env &env, Genode::Heap &heap,
|
|
Synced_motherboard &mb)
|
|
:
|
|
_motherboard(mb), _tx_block_alloc(&heap),
|
|
_nic(env, &_tx_block_alloc, BUF_SIZE, BUF_SIZE),
|
|
_packet_avail(env.ep(), *this, &Network::_handle_packets)
|
|
{
|
|
_nic.rx_channel()->sigh_packet_avail(_packet_avail);
|
|
}
|
|
|
|
|
|
void Seoul::Network::_handle_packets()
|
|
{
|
|
while (_nic.rx()->packet_avail()) {
|
|
|
|
Nic::Packet_descriptor rx_packet = _nic.rx()->get_packet();
|
|
|
|
/* send it to the network bus */
|
|
char * rx_content = _nic.rx()->packet_content(rx_packet);
|
|
_forward_pkt = rx_content;
|
|
MessageNetwork msg((unsigned char *)rx_content, rx_packet.size(), 0);
|
|
_motherboard()->bus_network.send(msg);
|
|
_forward_pkt = 0;
|
|
|
|
/* acknowledge received packet */
|
|
if (!_nic.rx()->ready_to_ack())
|
|
Logging::printf("not ready for acks");
|
|
|
|
_nic.rx()->acknowledge_packet(rx_packet);
|
|
}
|
|
}
|
|
|
|
|
|
bool Seoul::Network::transmit(void const * const packet, Genode::size_t len)
|
|
{
|
|
if (packet == _forward_pkt)
|
|
/* don't end in an endless forwarding loop */
|
|
return false;
|
|
|
|
/* check for acknowledgements */
|
|
while (_nic.tx()->ack_avail()) {
|
|
Nic::Packet_descriptor const ack = _nic.tx()->get_acked_packet();
|
|
_nic.tx()->release_packet(ack);
|
|
}
|
|
|
|
/* allocate transmit packet */
|
|
Nic::Packet_descriptor tx_packet;
|
|
try {
|
|
tx_packet = _nic.tx()->alloc_packet(len);
|
|
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
|
|
Logging::printf("error: tx packet alloc failed\n");
|
|
return false;
|
|
}
|
|
|
|
/* fill packet with content */
|
|
char * const tx_content = _nic.tx()->packet_content(tx_packet);
|
|
memcpy(tx_content, packet, len);
|
|
|
|
_nic.tx()->submit_packet(tx_packet);
|
|
|
|
return true;
|
|
}
|