mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
nic session: link-state change handling
A Nic::Session client can install a signal handler that is used to propagate changes of the link-state by calling 'link_state_sigh()'. The actual link state is queried via 'link_state()'. The nic-driver interface now provides a Driver_notification callback, which is used to forward link-state changes from the driver to the Nic::Session_component. The following drivers now provide real link state: dde_ipxe, nic_bridge, and usb_drv. Currently, OpenVPN, Linux nic_drv, and lan9118 do not support link state and always report link up. Fixes #1327
This commit is contained in:
parent
e4f6fca355
commit
dd47129bef
@ -15,6 +15,11 @@
|
|||||||
#ifndef _DDE_IPXE__NIC_H_
|
#ifndef _DDE_IPXE__NIC_H_
|
||||||
#define _DDE_IPXE__NIC_H_
|
#define _DDE_IPXE__NIC_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link-state change callback
|
||||||
|
*/
|
||||||
|
typedef void (*dde_ipxe_nic_link_cb)(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packet reception callback
|
* Packet reception callback
|
||||||
*
|
*
|
||||||
@ -27,14 +32,14 @@ typedef void (*dde_ipxe_nic_rx_cb)(unsigned if_index, const char *packet, unsign
|
|||||||
/**
|
/**
|
||||||
* Register packet reception callback
|
* Register packet reception callback
|
||||||
*
|
*
|
||||||
* \param cb new callback function
|
* \param rx_cb packet-reception callback function
|
||||||
*
|
* \param link_cb link-state change callback function
|
||||||
* \return old callback function pointer
|
|
||||||
*
|
*
|
||||||
* This registers a function pointer as rx callback. Incoming ethernet packets
|
* This registers a function pointer as rx callback. Incoming ethernet packets
|
||||||
* are passed to this function.
|
* are passed to this function.
|
||||||
*/
|
*/
|
||||||
extern dde_ipxe_nic_rx_cb dde_ipxe_nic_register_rx_callback(dde_ipxe_nic_rx_cb cb);
|
extern void dde_ipxe_nic_register_callbacks(dde_ipxe_nic_rx_cb rx_cb,
|
||||||
|
dde_ipxe_nic_link_cb link_cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send packet
|
* Send packet
|
||||||
@ -57,6 +62,15 @@ extern int dde_ipxe_nic_tx(unsigned if_index, const char *packet, unsigned packe
|
|||||||
*/
|
*/
|
||||||
extern int dde_ipxe_nic_get_mac_addr(unsigned if_index, char *out_mac_addr);
|
extern int dde_ipxe_nic_get_mac_addr(unsigned if_index, char *out_mac_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current link-state of device
|
||||||
|
*
|
||||||
|
* \param if_index index of the receiving network interface
|
||||||
|
*
|
||||||
|
* \return 1 if link is up, 0 if no link is detected
|
||||||
|
*/
|
||||||
|
extern int dde_ipxe_nic_link_state(unsigned if_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize network sub-system
|
* Initialize network sub-system
|
||||||
*
|
*
|
||||||
|
@ -32,29 +32,32 @@ namespace Ipxe {
|
|||||||
|
|
||||||
static Driver *instance;
|
static Driver *instance;
|
||||||
|
|
||||||
static void dde_rx_handler(unsigned if_index,
|
private:
|
||||||
const char *packet,
|
|
||||||
unsigned packet_len)
|
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)
|
||||||
{
|
{
|
||||||
instance->rx_handler(packet, packet_len);
|
instance->rx_handler(packet, packet_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
static void _link_callback() { instance->link_state_changed(); }
|
||||||
|
|
||||||
Nic::Mac_address _mac_addr;
|
|
||||||
Nic::Rx_buffer_alloc &_alloc;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Driver(Nic::Rx_buffer_alloc &alloc)
|
Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify)
|
||||||
: _alloc(alloc)
|
: _alloc(alloc), _notify(notify)
|
||||||
{
|
{
|
||||||
PINF("--- init iPXE NIC");
|
PINF("--- init iPXE NIC");
|
||||||
int cnt = dde_ipxe_nic_init();
|
int cnt = dde_ipxe_nic_init();
|
||||||
PINF(" number of devices: %d", cnt);
|
PINF(" number of devices: %d", cnt);
|
||||||
|
|
||||||
PINF("--- init rx_callbacks");
|
PINF("--- init callbacks");
|
||||||
dde_ipxe_nic_register_rx_callback(dde_rx_handler);
|
dde_ipxe_nic_register_callbacks(_rx_callback, _link_callback);
|
||||||
|
|
||||||
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
|
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
|
||||||
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
|
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
@ -70,16 +73,23 @@ namespace Ipxe {
|
|||||||
Genode::memcpy(buffer, packet, packet_len);
|
Genode::memcpy(buffer, packet, packet_len);
|
||||||
_alloc.submit();
|
_alloc.submit();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
PDBG("failed to process received packet");
|
PDBG("failed to process received packet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_state_changed() { _notify.link_state_changed(); }
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Nic::Driver interface **
|
** Nic::Driver interface **
|
||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
Nic::Mac_address mac_address() { return _mac_addr; }
|
Nic::Mac_address mac_address() override { return _mac_addr; }
|
||||||
|
|
||||||
|
bool link_state() override
|
||||||
|
{
|
||||||
|
return dde_ipxe_nic_link_state(1);
|
||||||
|
}
|
||||||
|
|
||||||
void tx(char const *packet, Genode::size_t size)
|
void tx(char const *packet, Genode::size_t size)
|
||||||
{
|
{
|
||||||
@ -87,7 +97,6 @@ namespace Ipxe {
|
|||||||
PWRN("Sending packet failed!");
|
PWRN("Sending packet failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
** Irq_activation interface **
|
** Irq_activation interface **
|
||||||
******************************/
|
******************************/
|
||||||
@ -97,9 +106,10 @@ namespace Ipxe {
|
|||||||
|
|
||||||
class Driver_factory : public Nic::Driver_factory
|
class Driver_factory : public Nic::Driver_factory
|
||||||
{
|
{
|
||||||
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
|
||||||
|
Nic::Driver_notification ¬ify)
|
||||||
{
|
{
|
||||||
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc);
|
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify);
|
||||||
return Driver::instance;
|
return Driver::instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,32 +36,35 @@ namespace Ipxe {
|
|||||||
|
|
||||||
static Driver *instance;
|
static Driver *instance;
|
||||||
|
|
||||||
static void dde_rx_handler(unsigned if_index,
|
private:
|
||||||
const char *packet,
|
|
||||||
unsigned packet_len)
|
Nic::Mac_address _mac_addr;
|
||||||
|
Nic::Rx_buffer_alloc &_alloc;
|
||||||
|
Nic::Driver_notification &_notify;
|
||||||
|
|
||||||
|
Timer::Connection _timer;
|
||||||
|
Nic::Measurement _stat;
|
||||||
|
|
||||||
|
static void _rx_callback(unsigned if_index,
|
||||||
|
const char *packet,
|
||||||
|
unsigned packet_len)
|
||||||
{
|
{
|
||||||
instance->rx_handler_stat(packet, packet_len);
|
instance->rx_handler_stat(packet, packet_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
static void _link_callback() { instance->link_state_changed(); }
|
||||||
|
|
||||||
Nic::Mac_address _mac_addr;
|
|
||||||
Nic::Rx_buffer_alloc &_alloc;
|
|
||||||
|
|
||||||
Timer::Connection _timer;
|
|
||||||
Nic::Measurement _stat;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Driver(Nic::Rx_buffer_alloc &alloc)
|
Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify)
|
||||||
: _alloc(alloc), _stat(_timer)
|
: _alloc(alloc), _notify(notify), _stat(_timer)
|
||||||
{
|
{
|
||||||
PINF("--- init iPXE NIC");
|
PINF("--- init iPXE NIC");
|
||||||
int cnt = dde_ipxe_nic_init();
|
int cnt = dde_ipxe_nic_init();
|
||||||
PINF(" number of devices: %d", cnt);
|
PINF(" number of devices: %d", cnt);
|
||||||
|
|
||||||
PINF("--- init rx_callbacks");
|
PINF("--- init callbacks");
|
||||||
dde_ipxe_nic_register_rx_callback(dde_rx_handler);
|
dde_ipxe_nic_register_callbacks(_rx_callback, _link_callback);
|
||||||
|
|
||||||
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
|
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
|
||||||
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
|
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
@ -90,6 +93,8 @@ namespace Ipxe {
|
|||||||
_alloc.submit();
|
_alloc.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_state_changed() { _notify.link_state_changed(); }
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Nic::Driver interface **
|
** Nic::Driver interface **
|
||||||
@ -97,6 +102,11 @@ namespace Ipxe {
|
|||||||
|
|
||||||
Nic::Mac_address mac_address() { return _mac_addr; }
|
Nic::Mac_address mac_address() { return _mac_addr; }
|
||||||
|
|
||||||
|
bool link_state() override
|
||||||
|
{
|
||||||
|
return dde_ipxe_nic_link_state(1);
|
||||||
|
}
|
||||||
|
|
||||||
void tx(char const *packet, Genode::size_t size)
|
void tx(char const *packet, Genode::size_t size)
|
||||||
{
|
{
|
||||||
if (dde_ipxe_nic_tx(1, packet, size))
|
if (dde_ipxe_nic_tx(1, packet, size))
|
||||||
@ -112,9 +122,9 @@ namespace Ipxe {
|
|||||||
|
|
||||||
class Driver_factory : public Nic::Driver_factory
|
class Driver_factory : public Nic::Driver_factory
|
||||||
{
|
{
|
||||||
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify)
|
||||||
{
|
{
|
||||||
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc);
|
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify);
|
||||||
return Driver::instance;
|
return Driver::instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +48,15 @@ static struct dde_kit_sem *bh_sema;
|
|||||||
static struct net_device *net_dev;
|
static struct net_device *net_dev;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RX callback function pointer
|
* Link-state change detected
|
||||||
*/
|
*/
|
||||||
static dde_ipxe_nic_rx_cb rx_callback;
|
static int link_state_changed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function pointers
|
||||||
|
*/
|
||||||
|
static dde_ipxe_nic_link_cb link_callback;
|
||||||
|
static dde_ipxe_nic_rx_cb rx_callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Known iPXE driver structures (located in the driver binaries)
|
* Known iPXE driver structures (located in the driver binaries)
|
||||||
@ -71,7 +77,6 @@ static struct pci_driver *pci_drivers[] = {
|
|||||||
&pcnet32_driver
|
&pcnet32_driver
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update BARs of PCI device
|
* Update BARs of PCI device
|
||||||
*/
|
*/
|
||||||
@ -201,9 +206,15 @@ static void irq_handler(void *p)
|
|||||||
{
|
{
|
||||||
ENTER;
|
ENTER;
|
||||||
|
|
||||||
|
/* check for the link-state to change on each interrupt */
|
||||||
|
int link_ok = netdev_link_ok(net_dev);
|
||||||
|
|
||||||
|
/* poll the device for packets and also link-state changes */
|
||||||
netdev_poll(net_dev);
|
netdev_poll(net_dev);
|
||||||
dde_kit_sem_up(bh_sema);
|
dde_kit_sem_up(bh_sema);
|
||||||
|
|
||||||
|
link_state_changed = (link_ok != netdev_link_ok(net_dev));
|
||||||
|
|
||||||
LEAVE;
|
LEAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +231,15 @@ static void bh_handler(void *p)
|
|||||||
|
|
||||||
ENTER;
|
ENTER;
|
||||||
|
|
||||||
|
/* report link-state changes */
|
||||||
|
if (link_state_changed) {
|
||||||
|
LEAVE;
|
||||||
|
if (link_callback)
|
||||||
|
link_callback();
|
||||||
|
ENTER;
|
||||||
|
link_state_changed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct io_buffer *iobuf;
|
struct io_buffer *iobuf;
|
||||||
while ((iobuf = netdev_rx_dequeue(net_dev))) {
|
while ((iobuf = netdev_rx_dequeue(net_dev))) {
|
||||||
LEAVE;
|
LEAVE;
|
||||||
@ -238,15 +258,30 @@ static void bh_handler(void *p)
|
|||||||
** API implementation **
|
** API implementation **
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
dde_ipxe_nic_rx_cb dde_ipxe_nic_register_rx_callback(dde_ipxe_nic_rx_cb cb)
|
void dde_ipxe_nic_register_callbacks(dde_ipxe_nic_rx_cb rx_cb,
|
||||||
|
dde_ipxe_nic_link_cb link_cb)
|
||||||
{
|
{
|
||||||
ENTER;
|
ENTER;
|
||||||
|
|
||||||
dde_ipxe_nic_rx_cb old = rx_callback;
|
rx_callback = rx_cb;
|
||||||
rx_callback = cb;
|
link_callback = link_cb;
|
||||||
|
|
||||||
LEAVE;
|
LEAVE;
|
||||||
return old;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int dde_ipxe_nic_link_state(unsigned if_index)
|
||||||
|
{
|
||||||
|
if (if_index != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ENTER;
|
||||||
|
|
||||||
|
int link_state = netdev_link_ok(net_dev);
|
||||||
|
|
||||||
|
LEAVE;
|
||||||
|
|
||||||
|
return link_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +80,11 @@ namespace Nic {
|
|||||||
*/
|
*/
|
||||||
virtual Mac_address mac_address() = 0;
|
virtual Mac_address mac_address() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return current link-state (true if link detected)
|
||||||
|
*/
|
||||||
|
virtual bool link_state() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set session belonging to this driver
|
* Set session belonging to this driver
|
||||||
*/
|
*/
|
||||||
@ -130,6 +135,8 @@ namespace Nic {
|
|||||||
bool _tx_alloc; /* get next packet from client or use _tx_packet */
|
bool _tx_alloc; /* get next packet from client or use _tx_packet */
|
||||||
Packet_descriptor _tx_packet; /* saved packet in case of driver errors */
|
Packet_descriptor _tx_packet; /* saved packet in case of driver errors */
|
||||||
|
|
||||||
|
Signal_context_capability _link_state_sigh;
|
||||||
|
|
||||||
void _send_packet_avail_signal() {
|
void _send_packet_avail_signal() {
|
||||||
Signal_transmitter(_tx.sigh_packet_avail()).submit(); }
|
Signal_transmitter(_tx.sigh_packet_avail()).submit(); }
|
||||||
|
|
||||||
@ -256,8 +263,23 @@ namespace Nic {
|
|||||||
_tx_alloc(true)
|
_tx_alloc(true)
|
||||||
{ _device->session(this); }
|
{ _device->session(this); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link state changed (called from driver)
|
||||||
|
*/
|
||||||
|
void link_state_changed()
|
||||||
|
{
|
||||||
|
if (_link_state_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_link_state_sigh).submit();
|
||||||
|
}
|
||||||
|
|
||||||
Mac_address mac_address() { return _device->mac_address(); }
|
Mac_address mac_address() { return _device->mac_address(); }
|
||||||
|
|
||||||
|
bool link_state() override {
|
||||||
|
return _device->link_state(); }
|
||||||
|
|
||||||
|
void link_state_sigh(Genode::Signal_context_capability sigh) {
|
||||||
|
_link_state_sigh = sigh; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send packet to client (called form driver)
|
* Send packet to client (called form driver)
|
||||||
*/
|
*/
|
||||||
|
@ -144,6 +144,7 @@ class Nic_device : public Nic::Device
|
|||||||
struct net_device *_ndev; /* Linux-net device */
|
struct net_device *_ndev; /* Linux-net device */
|
||||||
fixup_t _tx_fixup;
|
fixup_t _tx_fixup;
|
||||||
bool const _burst;
|
bool const _burst;
|
||||||
|
bool _has_link { false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -177,11 +178,29 @@ class Nic_device : public Nic::Device
|
|||||||
static Nic_device *add(struct net_device *ndev) {
|
static Nic_device *add(struct net_device *ndev) {
|
||||||
return new (Genode::env()->heap()) Nic_device(ndev); }
|
return new (Genode::env()->heap()) Nic_device(ndev); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report link state
|
||||||
|
*/
|
||||||
|
void link_state(bool link)
|
||||||
|
{
|
||||||
|
/* only report changes of the link state */
|
||||||
|
if (link == _has_link)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_has_link = link;
|
||||||
|
|
||||||
|
if (_session)
|
||||||
|
_session->link_state_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
** Device interface **
|
** Device interface **
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
bool link_state() override { return _has_link; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit packet to driver
|
* Submit packet to driver
|
||||||
*/
|
*/
|
||||||
@ -344,12 +363,16 @@ int netif_carrier_ok(const struct net_device *dev)
|
|||||||
void netif_carrier_on(struct net_device *dev)
|
void netif_carrier_on(struct net_device *dev)
|
||||||
{
|
{
|
||||||
dev->state &= ~(1 << __LINK_STATE_NOCARRIER);
|
dev->state &= ~(1 << __LINK_STATE_NOCARRIER);
|
||||||
|
if (_nic)
|
||||||
|
_nic->link_state(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void netif_carrier_off(struct net_device *dev)
|
void netif_carrier_off(struct net_device *dev)
|
||||||
{
|
{
|
||||||
dev->state |= 1 << __LINK_STATE_NOCARRIER;
|
dev->state |= 1 << __LINK_STATE_NOCARRIER;
|
||||||
|
if (_nic)
|
||||||
|
_nic->link_state(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GENODE_NET_STAT
|
#ifdef GENODE_NET_STAT
|
||||||
|
@ -39,13 +39,16 @@ namespace Nic {
|
|||||||
|
|
||||||
|
|
||||||
class Nic::Session_component : public Genode::Allocator_avl,
|
class Nic::Session_component : public Genode::Allocator_avl,
|
||||||
public Session_rpc_object, public Rx_buffer_alloc
|
public Session_rpc_object, public Rx_buffer_alloc,
|
||||||
|
public Driver_notification
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Driver_factory &_driver_factory;
|
Driver_factory &_driver_factory;
|
||||||
Driver &_driver;
|
Driver &_driver;
|
||||||
|
|
||||||
|
Genode::Signal_context_capability _link_state_sigh;
|
||||||
|
|
||||||
/* rx packet descriptor */
|
/* rx packet descriptor */
|
||||||
Genode::Packet_descriptor _curr_rx_packet;
|
Genode::Packet_descriptor _curr_rx_packet;
|
||||||
|
|
||||||
@ -126,7 +129,7 @@ class Nic::Session_component : public Genode::Allocator_avl,
|
|||||||
Genode::env()->ram_session()->alloc(rx_buf_size),
|
Genode::env()->ram_session()->alloc(rx_buf_size),
|
||||||
static_cast<Genode::Range_allocator *>(this), ep),
|
static_cast<Genode::Range_allocator *>(this), ep),
|
||||||
_driver_factory(driver_factory),
|
_driver_factory(driver_factory),
|
||||||
_driver(*driver_factory.create(*this)),
|
_driver(*driver_factory.create(*this, *this)),
|
||||||
_tx_thread(_tx.sink(), _driver)
|
_tx_thread(_tx.sink(), _driver)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -138,12 +141,21 @@ class Nic::Session_component : public Genode::Allocator_avl,
|
|||||||
_driver_factory.destroy(&_driver);
|
_driver_factory.destroy(&_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
** Driver-notification interface **
|
||||||
|
***********************************/
|
||||||
|
|
||||||
|
void link_state_changed() override
|
||||||
|
{
|
||||||
|
if (_link_state_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_link_state_sigh).submit();
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
** Rx_buffer_alloc interface **
|
** Rx_buffer_alloc interface **
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
void *alloc(Genode::size_t size)
|
void *alloc(Genode::size_t size) override
|
||||||
{
|
{
|
||||||
/* assign rx packet descriptor */
|
/* assign rx packet descriptor */
|
||||||
_curr_rx_packet = _rx.source()->alloc_packet(size);
|
_curr_rx_packet = _rx.source()->alloc_packet(size);
|
||||||
@ -151,7 +163,7 @@ class Nic::Session_component : public Genode::Allocator_avl,
|
|||||||
return _rx.source()->packet_content(_curr_rx_packet);
|
return _rx.source()->packet_content(_curr_rx_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void submit()
|
void submit() override
|
||||||
{
|
{
|
||||||
/* check for acknowledgements from the client */
|
/* check for acknowledgements from the client */
|
||||||
while (_rx.source()->ack_avail()) {
|
while (_rx.source()->ack_avail()) {
|
||||||
@ -175,8 +187,14 @@ class Nic::Session_component : public Genode::Allocator_avl,
|
|||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
Mac_address mac_address() { return _driver.mac_address(); }
|
Mac_address mac_address() { return _driver.mac_address(); }
|
||||||
|
bool link_state() { return _driver.link_state(); }
|
||||||
Tx::Sink* tx_sink() { return _tx.sink(); }
|
Tx::Sink* tx_sink() { return _tx.sink(); }
|
||||||
Rx::Source* rx_source() { return _rx.source(); }
|
Rx::Source* rx_source() { return _rx.source(); }
|
||||||
|
|
||||||
|
void link_state_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_link_state_sigh = sigh;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ namespace Nic {
|
|||||||
struct Rx_buffer_alloc;
|
struct Rx_buffer_alloc;
|
||||||
struct Driver;
|
struct Driver;
|
||||||
struct Driver_factory;
|
struct Driver_factory;
|
||||||
|
struct Driver_notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,6 +43,12 @@ struct Nic::Rx_buffer_alloc
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for driver-to-component notifications
|
||||||
|
*/
|
||||||
|
struct Nic::Driver_notification { virtual void link_state_changed() = 0; };
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to be implemented by the device-specific driver code
|
* Interface to be implemented by the device-specific driver code
|
||||||
*/
|
*/
|
||||||
@ -52,6 +59,11 @@ struct Nic::Driver : Genode::Irq_handler
|
|||||||
*/
|
*/
|
||||||
virtual Mac_address mac_address() = 0;
|
virtual Mac_address mac_address() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return link state (true if link detected)
|
||||||
|
*/
|
||||||
|
virtual bool link_state() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transmit packet
|
* Transmit packet
|
||||||
*
|
*
|
||||||
@ -83,8 +95,10 @@ struct Nic::Driver_factory
|
|||||||
*
|
*
|
||||||
* \param rx_buffer_alloc buffer allocator used for storing incoming
|
* \param rx_buffer_alloc buffer allocator used for storing incoming
|
||||||
* packets
|
* packets
|
||||||
|
* \param notifier callback for notifications
|
||||||
*/
|
*/
|
||||||
virtual Driver *create(Rx_buffer_alloc &rx_buffer_alloc) = 0;
|
virtual Driver *create(Rx_buffer_alloc &rx_buffer_alloc,
|
||||||
|
Driver_notification ¬ify) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy driver
|
* Destroy driver
|
||||||
|
@ -56,6 +56,13 @@ class Nic::Session_client : public Genode::Rpc_client<Session>
|
|||||||
Rx *rx_channel() { return &_rx; }
|
Rx *rx_channel() { return &_rx; }
|
||||||
Tx::Source *tx() { return _tx.source(); }
|
Tx::Source *tx() { return _tx.source(); }
|
||||||
Rx::Sink *rx() { return _rx.sink(); }
|
Rx::Sink *rx() { return _rx.sink(); }
|
||||||
|
|
||||||
|
void link_state_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
call<Rpc_link_state_sigh>(sigh);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool link_state() override { return call<Rpc_link_state>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__NIC_SESSION__CLIENT_H_ */
|
#endif /* _INCLUDE__NIC_SESSION__CLIENT_H_ */
|
||||||
|
@ -93,6 +93,15 @@ struct Nic::Session : Genode::Session
|
|||||||
*/
|
*/
|
||||||
virtual Rx::Sink *rx() { return 0; }
|
virtual Rx::Sink *rx() { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request current link state of network adapter (true means link detected)
|
||||||
|
*/
|
||||||
|
virtual bool link_state() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register signal handler for link state changes
|
||||||
|
*/
|
||||||
|
virtual void link_state_sigh(Genode::Signal_context_capability sigh) = 0;
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
** RPC interface **
|
** RPC interface **
|
||||||
@ -101,8 +110,12 @@ struct Nic::Session : Genode::Session
|
|||||||
GENODE_RPC(Rpc_mac_address, Mac_address, mac_address);
|
GENODE_RPC(Rpc_mac_address, Mac_address, mac_address);
|
||||||
GENODE_RPC(Rpc_tx_cap, Genode::Capability<Tx>, _tx_cap);
|
GENODE_RPC(Rpc_tx_cap, Genode::Capability<Tx>, _tx_cap);
|
||||||
GENODE_RPC(Rpc_rx_cap, Genode::Capability<Rx>, _rx_cap);
|
GENODE_RPC(Rpc_rx_cap, Genode::Capability<Rx>, _rx_cap);
|
||||||
|
GENODE_RPC(Rpc_link_state, bool, link_state);
|
||||||
|
GENODE_RPC(Rpc_link_state_sigh, void, link_state_sigh,
|
||||||
|
Genode::Signal_context_capability);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_mac_address, Rpc_tx_cap, Rpc_rx_cap);
|
GENODE_RPC_INTERFACE(Rpc_mac_address, Rpc_link_state,
|
||||||
|
Rpc_link_state_sigh, Rpc_tx_cap, Rpc_rx_cap);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__NIC_SESSION__NIC_SESSION_H_ */
|
#endif /* _INCLUDE__NIC_SESSION__NIC_SESSION_H_ */
|
||||||
|
@ -72,6 +72,7 @@ class Lan9118 : public Nic::Driver
|
|||||||
Timer::Connection _timer;
|
Timer::Connection _timer;
|
||||||
Nic::Rx_buffer_alloc &_rx_buffer_alloc;
|
Nic::Rx_buffer_alloc &_rx_buffer_alloc;
|
||||||
Nic::Mac_address _mac_addr;
|
Nic::Mac_address _mac_addr;
|
||||||
|
Nic::Driver_notification &_notify;
|
||||||
|
|
||||||
enum { IRQ_STACK_SIZE = 4096 };
|
enum { IRQ_STACK_SIZE = 4096 };
|
||||||
Genode::Irq_activation _irq_activation;
|
Genode::Irq_activation _irq_activation;
|
||||||
@ -201,11 +202,13 @@ class Lan9118 : public Nic::Driver
|
|||||||
* \throw Device_not_supported
|
* \throw Device_not_supported
|
||||||
*/
|
*/
|
||||||
Lan9118(Genode::addr_t mmio_base, Genode::size_t mmio_size, int irq,
|
Lan9118(Genode::addr_t mmio_base, Genode::size_t mmio_size, int irq,
|
||||||
Nic::Rx_buffer_alloc &rx_buffer_alloc)
|
Nic::Rx_buffer_alloc &rx_buffer_alloc,
|
||||||
|
Nic::Driver_notification ¬ify)
|
||||||
:
|
:
|
||||||
_mmio(mmio_base, mmio_size),
|
_mmio(mmio_base, mmio_size),
|
||||||
_reg_base(_mmio.local_addr<Genode::uint32_t>()),
|
_reg_base(_mmio.local_addr<Genode::uint32_t>()),
|
||||||
_rx_buffer_alloc(rx_buffer_alloc),
|
_rx_buffer_alloc(rx_buffer_alloc),
|
||||||
|
_notify(notify),
|
||||||
_irq_activation(irq, *this, IRQ_STACK_SIZE)
|
_irq_activation(irq, *this, IRQ_STACK_SIZE)
|
||||||
{
|
{
|
||||||
unsigned long const id_rev = _reg_read(ID_REV),
|
unsigned long const id_rev = _reg_read(ID_REV),
|
||||||
@ -287,6 +290,8 @@ class Lan9118 : public Nic::Driver
|
|||||||
_mac_csr_write(MAC_CR, 0);
|
_mac_csr_write(MAC_CR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_state_changed() { _notify.link_state_changed(); }
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Nic::Driver interface **
|
** Nic::Driver interface **
|
||||||
@ -297,6 +302,12 @@ class Lan9118 : public Nic::Driver
|
|||||||
return _mac_addr;
|
return _mac_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool link_state()
|
||||||
|
{
|
||||||
|
/* XXX always return true for now */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void tx(char const *packet, Genode::size_t size)
|
void tx(char const *packet, Genode::size_t size)
|
||||||
{
|
{
|
||||||
/* limit size to 11 bits, the maximum supported by lan9118 */
|
/* limit size to 11 bits, the maximum supported by lan9118 */
|
||||||
|
@ -37,10 +37,11 @@ int main(int, char **)
|
|||||||
*/
|
*/
|
||||||
struct Lan9118_driver_factory : Nic::Driver_factory
|
struct Lan9118_driver_factory : Nic::Driver_factory
|
||||||
{
|
{
|
||||||
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
|
||||||
|
Nic::Driver_notification ¬ify)
|
||||||
{
|
{
|
||||||
return new (env()->heap())
|
return new (env()->heap())
|
||||||
Lan9118(LAN9118_PHYS, LAN9118_SIZE, LAN9118_IRQ, alloc);
|
Lan9118(LAN9118_PHYS, LAN9118_SIZE, LAN9118_IRQ, alloc, notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy(Nic::Driver *driver)
|
void destroy(Nic::Driver *driver)
|
||||||
|
@ -67,8 +67,9 @@ class Linux_driver : public Nic::Driver
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Nic::Mac_address _mac_addr;
|
Nic::Mac_address _mac_addr;
|
||||||
Nic::Rx_buffer_alloc &_alloc;
|
Nic::Rx_buffer_alloc &_alloc;
|
||||||
|
Nic::Driver_notification &_notify;
|
||||||
|
|
||||||
char _packet_buffer[1514]; /* maximum ethernet packet length */
|
char _packet_buffer[1514]; /* maximum ethernet packet length */
|
||||||
int _tap_fd;
|
int _tap_fd;
|
||||||
@ -114,8 +115,11 @@ class Linux_driver : public Nic::Driver
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Linux_driver(Nic::Rx_buffer_alloc &alloc)
|
Linux_driver(Nic::Rx_buffer_alloc &alloc,
|
||||||
: _alloc(alloc), _tap_fd(_setup_tap_fd()), _rx_thread(_tap_fd, *this)
|
Nic::Driver_notification ¬ify)
|
||||||
|
:
|
||||||
|
_alloc(alloc), _notify(notify),
|
||||||
|
_tap_fd(_setup_tap_fd()), _rx_thread(_tap_fd, *this)
|
||||||
{
|
{
|
||||||
/* try using configured MAC address */
|
/* try using configured MAC address */
|
||||||
try {
|
try {
|
||||||
@ -141,6 +145,8 @@ class Linux_driver : public Nic::Driver
|
|||||||
_rx_thread.start();
|
_rx_thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_state_changed() { _notify.link_state_changed(); }
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Nic::Driver interface **
|
** Nic::Driver interface **
|
||||||
@ -148,6 +154,12 @@ class Linux_driver : public Nic::Driver
|
|||||||
|
|
||||||
Nic::Mac_address mac_address() { return _mac_addr; }
|
Nic::Mac_address mac_address() { return _mac_addr; }
|
||||||
|
|
||||||
|
bool link_state()
|
||||||
|
{
|
||||||
|
/* XXX return always true for now */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void tx(char const *packet, Genode::size_t size)
|
void tx(char const *packet, Genode::size_t size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -200,9 +212,10 @@ int main(int, char **)
|
|||||||
*/
|
*/
|
||||||
struct Linux_driver_factory : Nic::Driver_factory
|
struct Linux_driver_factory : Nic::Driver_factory
|
||||||
{
|
{
|
||||||
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
|
||||||
|
Nic::Driver_notification ¬ify)
|
||||||
{
|
{
|
||||||
return new (env()->heap()) Linux_driver(alloc);
|
return new (env()->heap()) Linux_driver(alloc, notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy(Nic::Driver *driver)
|
void destroy(Nic::Driver *driver)
|
||||||
|
@ -102,6 +102,10 @@ void Session_component::_free_ipv4_node()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Session_component::link_state() {
|
||||||
|
return Net::Env::nic()->link_state(); }
|
||||||
|
|
||||||
|
|
||||||
void Session_component::set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr)
|
void Session_component::set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr)
|
||||||
{
|
{
|
||||||
_free_ipv4_node();
|
_free_ipv4_node();
|
||||||
|
@ -105,6 +105,8 @@ namespace Net {
|
|||||||
Mac_address_node _mac_node;
|
Mac_address_node _mac_node;
|
||||||
Ipv4_address_node *_ipv4_node;
|
Ipv4_address_node *_ipv4_node;
|
||||||
|
|
||||||
|
Genode::Signal_context_capability _link_state_sigh;
|
||||||
|
|
||||||
void _free_ipv4_node();
|
void _free_ipv4_node();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -137,8 +139,23 @@ namespace Net {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_state_changed()
|
||||||
|
{
|
||||||
|
if (_link_state_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_link_state_sigh).submit();
|
||||||
|
}
|
||||||
|
|
||||||
void set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr);
|
void set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr);
|
||||||
|
|
||||||
|
/****************************************
|
||||||
|
** Nic::Driver notification interface **
|
||||||
|
****************************************/
|
||||||
|
|
||||||
|
bool link_state();
|
||||||
|
|
||||||
|
void link_state_sigh(Genode::Signal_context_capability sigh) {
|
||||||
|
_link_state_sigh = sigh; }
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
** Packet_handler interface **
|
** Packet_handler interface **
|
||||||
******************************/
|
******************************/
|
||||||
|
@ -134,4 +134,5 @@ Net::Nic::Nic()
|
|||||||
_nic.rx_channel()->sigh_packet_avail(_sink_submit);
|
_nic.rx_channel()->sigh_packet_avail(_sink_submit);
|
||||||
_nic.tx_channel()->sigh_ack_avail(_source_ack);
|
_nic.tx_channel()->sigh_ack_avail(_source_ack);
|
||||||
_nic.tx_channel()->sigh_ready_to_submit(_source_submit);
|
_nic.tx_channel()->sigh_ready_to_submit(_source_submit);
|
||||||
|
_nic.link_state_sigh(_client_link_state);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ class Net::Nic : public Net::Packet_handler
|
|||||||
::Nic::Connection *nic() { return &_nic; }
|
::Nic::Connection *nic() { return &_nic; }
|
||||||
Ethernet_frame::Mac_address mac() { return _mac; }
|
Ethernet_frame::Mac_address mac() { return _mac; }
|
||||||
|
|
||||||
|
bool link_state() { return _nic.link_state(); }
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
** Packet_handler interface **
|
** Packet_handler interface **
|
||||||
|
@ -54,6 +54,16 @@ void Packet_handler::_ready_to_ack(unsigned)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Packet_handler::_link_state(unsigned)
|
||||||
|
{
|
||||||
|
Mac_address_node *node = Env::vlan()->mac_list()->first();
|
||||||
|
while (node) {
|
||||||
|
node->component()->link_state_changed();
|
||||||
|
node = node->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Packet_handler::broadcast_to_clients(Ethernet_frame *eth, Genode::size_t size)
|
void Packet_handler::broadcast_to_clients(Ethernet_frame *eth, Genode::size_t size)
|
||||||
{
|
{
|
||||||
/* check whether it's really a broadcast packet */
|
/* check whether it's really a broadcast packet */
|
||||||
@ -121,5 +131,6 @@ Packet_handler::Packet_handler()
|
|||||||
: _sink_ack(*Net::Env::receiver(), *this, &Packet_handler::_ack_avail),
|
: _sink_ack(*Net::Env::receiver(), *this, &Packet_handler::_ack_avail),
|
||||||
_sink_submit(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_submit),
|
_sink_submit(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_submit),
|
||||||
_source_ack(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_ack),
|
_source_ack(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_ack),
|
||||||
_source_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail)
|
_source_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail),
|
||||||
|
_client_link_state(*Net::Env::receiver(), *this, &Packet_handler::_link_state)
|
||||||
{ }
|
{ }
|
||||||
|
@ -65,12 +65,18 @@ class Net::Packet_handler
|
|||||||
*/
|
*/
|
||||||
void _packet_avail(unsigned) { }
|
void _packet_avail(unsigned) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the link-state of changed
|
||||||
|
*/
|
||||||
|
void _link_state(unsigned);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Genode::Signal_dispatcher<Packet_handler> _sink_ack;
|
Genode::Signal_dispatcher<Packet_handler> _sink_ack;
|
||||||
Genode::Signal_dispatcher<Packet_handler> _sink_submit;
|
Genode::Signal_dispatcher<Packet_handler> _sink_submit;
|
||||||
Genode::Signal_dispatcher<Packet_handler> _source_ack;
|
Genode::Signal_dispatcher<Packet_handler> _source_ack;
|
||||||
Genode::Signal_dispatcher<Packet_handler> _source_submit;
|
Genode::Signal_dispatcher<Packet_handler> _source_submit;
|
||||||
|
Genode::Signal_dispatcher<Packet_handler> _client_link_state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -142,6 +142,14 @@ namespace Nic {
|
|||||||
Mac_address result = {{1,2,3,4,5,6}};
|
Mac_address result = {{1,2,3,4,5,6}};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool link_state()
|
||||||
|
{
|
||||||
|
/* XXX always return true, for now */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void link_state_sigh(Genode::Signal_context_capability sigh) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Root : public Genode::Root_component<Session_component>
|
class Root : public Genode::Root_component<Session_component>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Genode Labs GmbH
|
* Copyright (C) 2014-2015 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -87,8 +87,9 @@ class Nic_driver : public Tuntap_device,
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Nic::Mac_address _mac_addr {{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 }};
|
Nic::Mac_address _mac_addr {{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 }};
|
||||||
Nic::Rx_buffer_alloc &_alloc;
|
Nic::Rx_buffer_alloc &_alloc;
|
||||||
|
Nic::Driver_notification &_notify;
|
||||||
|
|
||||||
char const *_packet;
|
char const *_packet;
|
||||||
|
|
||||||
@ -101,10 +102,9 @@ class Nic_driver : public Tuntap_device,
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Nic_driver(Nic::Rx_buffer_alloc &alloc)
|
Nic_driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify)
|
||||||
:
|
:
|
||||||
_alloc(alloc),
|
_alloc(alloc), _notify(notify), _packet(0)
|
||||||
_packet(0)
|
|
||||||
{
|
{
|
||||||
if (pipe(_pipefd)) {
|
if (pipe(_pipefd)) {
|
||||||
PERR("could not create pipe");
|
PERR("could not create pipe");
|
||||||
@ -114,6 +114,7 @@ class Nic_driver : public Tuntap_device,
|
|||||||
|
|
||||||
~Nic_driver() { PDBG("should probably be implemented"); }
|
~Nic_driver() { PDBG("should probably be implemented"); }
|
||||||
|
|
||||||
|
void link_state_changed() { _notify.link_state_changed(); }
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Nic::Driver interface **
|
** Nic::Driver interface **
|
||||||
@ -121,6 +122,12 @@ class Nic_driver : public Tuntap_device,
|
|||||||
|
|
||||||
Nic::Mac_address mac_address() { return _mac_addr; }
|
Nic::Mac_address mac_address() { return _mac_addr; }
|
||||||
|
|
||||||
|
bool link_state()
|
||||||
|
{
|
||||||
|
/* XXX always return true for now */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void tx(char const *packet, Genode::size_t size)
|
void tx(char const *packet, Genode::size_t size)
|
||||||
{
|
{
|
||||||
PDBGV("packet:0x%p size:%zu", packet, size);
|
PDBGV("packet:0x%p size:%zu", packet, size);
|
||||||
@ -185,11 +192,12 @@ struct Main
|
|||||||
Nic_driver *drv { 0 };
|
Nic_driver *drv { 0 };
|
||||||
Openvpn_thread *openvpn { 0 };
|
Openvpn_thread *openvpn { 0 };
|
||||||
|
|
||||||
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
|
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
|
||||||
|
Nic::Driver_notification ¬ify)
|
||||||
{
|
{
|
||||||
/* there can be only one */
|
/* there can be only one */
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
drv = new (Genode::env()->heap()) Nic_driver(alloc);
|
drv = new (Genode::env()->heap()) Nic_driver(alloc, notify);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting the pointer in this manner is quite hackish but it has
|
* Setting the pointer in this manner is quite hackish but it has
|
||||||
|
Loading…
x
Reference in New Issue
Block a user