2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief NIC driver based on iPXE
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2011-11-17
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2011-2013 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode */
|
|
|
|
#include <base/env.h>
|
|
|
|
#include <base/sleep.h>
|
|
|
|
#include <base/printf.h>
|
|
|
|
#include <cap_session/connection.h>
|
|
|
|
#include <nic/component.h>
|
2015-03-26 13:47:14 +01:00
|
|
|
#include <os/server.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
#include <dde_ipxe/nic.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace Ipxe {
|
|
|
|
|
|
|
|
class Driver : public Nic::Driver
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
static Driver *instance;
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
private:
|
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
Server::Entrypoint &_ep;
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
Nic::Mac_address _mac_addr;
|
|
|
|
Nic::Rx_buffer_alloc &_alloc;
|
|
|
|
Nic::Driver_notification &_notify;
|
|
|
|
|
|
|
|
static void _rx_callback(unsigned if_index,
|
|
|
|
const char *packet,
|
|
|
|
unsigned packet_len)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
instance->rx_handler(packet, packet_len);
|
|
|
|
}
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
static void _link_callback() { instance->link_state_changed(); }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
Driver(Server::Entrypoint &ep, Nic::Rx_buffer_alloc &alloc,
|
|
|
|
Nic::Driver_notification ¬ify)
|
|
|
|
: _ep(ep), _alloc(alloc), _notify(notify)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
PINF("--- init iPXE NIC");
|
2015-03-26 13:47:14 +01:00
|
|
|
int cnt = dde_ipxe_nic_init(&ep);
|
2011-12-22 16:19:25 +01:00
|
|
|
PINF(" number of devices: %d", cnt);
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
PINF("--- init callbacks");
|
|
|
|
dde_ipxe_nic_register_callbacks(_rx_callback, _link_callback);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
|
2013-03-28 10:14:19 +01:00
|
|
|
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
_mac_addr.addr[0] & 0xff, _mac_addr.addr[1] & 0xff,
|
|
|
|
_mac_addr.addr[2] & 0xff, _mac_addr.addr[3] & 0xff,
|
|
|
|
_mac_addr.addr[4] & 0xff, _mac_addr.addr[5] & 0xff);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void rx_handler(const char *packet, unsigned packet_len)
|
|
|
|
{
|
2013-04-16 10:43:58 +02:00
|
|
|
try {
|
|
|
|
void *buffer = _alloc.alloc(packet_len);
|
|
|
|
Genode::memcpy(buffer, packet, packet_len);
|
|
|
|
_alloc.submit();
|
|
|
|
} catch (...) {
|
2015-03-11 11:33:03 +01:00
|
|
|
PDBG("failed to process received packet");
|
2013-04-16 10:43:58 +02:00
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
void link_state_changed() { _notify.link_state_changed(); }
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/***************************
|
|
|
|
** Nic::Driver interface **
|
|
|
|
***************************/
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
Nic::Mac_address mac_address() override { return _mac_addr; }
|
|
|
|
|
|
|
|
bool link_state() override
|
|
|
|
{
|
|
|
|
return dde_ipxe_nic_link_state(1);
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
void tx(char const *packet, Genode::size_t size)
|
|
|
|
{
|
|
|
|
if (dde_ipxe_nic_tx(1, packet, size))
|
|
|
|
PWRN("Sending packet failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************
|
|
|
|
** Irq_activation interface **
|
|
|
|
******************************/
|
|
|
|
|
|
|
|
void handle_irq(int) { /* not used */ }
|
|
|
|
};
|
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
} /* namespace Ipxe */
|
|
|
|
|
|
|
|
|
|
|
|
Ipxe::Driver * Ipxe::Driver::instance = 0;
|
|
|
|
|
|
|
|
|
|
|
|
struct Main
|
|
|
|
{
|
|
|
|
Server::Entrypoint &ep;
|
|
|
|
Genode::Sliced_heap sliced_heap;
|
|
|
|
|
|
|
|
struct Factory : public Nic::Driver_factory
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2015-03-26 13:47:14 +01:00
|
|
|
Server::Entrypoint &ep;
|
|
|
|
|
|
|
|
Factory(Server::Entrypoint &ep) : ep(ep) { }
|
|
|
|
|
2015-03-11 11:33:03 +01:00
|
|
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
|
|
|
|
Nic::Driver_notification ¬ify)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2015-03-26 13:47:14 +01:00
|
|
|
Ipxe::Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(ep, alloc, notify);
|
|
|
|
return Ipxe::Driver::instance;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void destroy(Nic::Driver *)
|
|
|
|
{
|
2015-03-26 13:47:14 +01:00
|
|
|
Genode::destroy(Genode::env()->heap(), Ipxe::Driver::instance);
|
|
|
|
Ipxe::Driver::instance = 0;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
2015-03-26 13:47:14 +01:00
|
|
|
} factory;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
Nic::Root root;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
Main(Server::Entrypoint &ep)
|
|
|
|
:
|
|
|
|
ep(ep),
|
|
|
|
sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()),
|
|
|
|
factory(ep),
|
|
|
|
root(&ep.rpc_ep(), &sliced_heap, factory)
|
|
|
|
{
|
|
|
|
PINF("--- iPXE NIC driver started ---\n");
|
|
|
|
Genode::env()->parent()->announce(ep.manage(root));
|
|
|
|
}
|
|
|
|
};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
/************
|
|
|
|
** Server **
|
|
|
|
************/
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2015-03-26 13:47:14 +01:00
|
|
|
namespace Server {
|
|
|
|
char const *name() { return "nic_drv_ep"; }
|
|
|
|
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
|
|
void construct(Entrypoint &ep) { static Main server(ep); }
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|