mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 07:38:28 +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:
committed by
Christian Helmuth
parent
e4f6fca355
commit
dd47129bef
@ -80,6 +80,11 @@ namespace Nic {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -130,6 +135,8 @@ namespace Nic {
|
||||
bool _tx_alloc; /* get next packet from client or use _tx_packet */
|
||||
Packet_descriptor _tx_packet; /* saved packet in case of driver errors */
|
||||
|
||||
Signal_context_capability _link_state_sigh;
|
||||
|
||||
void _send_packet_avail_signal() {
|
||||
Signal_transmitter(_tx.sigh_packet_avail()).submit(); }
|
||||
|
||||
@ -256,8 +263,23 @@ namespace Nic {
|
||||
_tx_alloc(true)
|
||||
{ _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(); }
|
||||
|
||||
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)
|
||||
*/
|
||||
|
@ -144,6 +144,7 @@ class Nic_device : public Nic::Device
|
||||
struct net_device *_ndev; /* Linux-net device */
|
||||
fixup_t _tx_fixup;
|
||||
bool const _burst;
|
||||
bool _has_link { false };
|
||||
|
||||
public:
|
||||
|
||||
@ -177,11 +178,29 @@ class Nic_device : public Nic::Device
|
||||
static Nic_device *add(struct net_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 **
|
||||
**********************/
|
||||
|
||||
bool link_state() override { return _has_link; }
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
dev->state &= ~(1 << __LINK_STATE_NOCARRIER);
|
||||
if (_nic)
|
||||
_nic->link_state(true);
|
||||
}
|
||||
|
||||
|
||||
void netif_carrier_off(struct net_device *dev)
|
||||
{
|
||||
dev->state |= 1 << __LINK_STATE_NOCARRIER;
|
||||
if (_nic)
|
||||
_nic->link_state(false);
|
||||
}
|
||||
|
||||
#ifdef GENODE_NET_STAT
|
||||
|
Reference in New Issue
Block a user