mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
6c6375aa83
commit
2d469cb35c
@ -47,6 +47,13 @@ int lwip_nic_init(genode_int32_t ip_addr,
|
||||
__SIZE_TYPE__ tx_buf_size,
|
||||
__SIZE_TYPE__ rx_buf_size);
|
||||
|
||||
/**
|
||||
* Pass on link-state changes to lwIP
|
||||
*
|
||||
* \param state current link-state
|
||||
*/
|
||||
void lwip_nic_link_state_changed(int state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -42,7 +42,8 @@
|
||||
#define TCP_RCV_SCALE 2 /* receive scale factor IETF RFC 1323 */
|
||||
|
||||
#if LWIP_DHCP
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used by DHCP init */
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used for interface changes */
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1 /* callback function used for link-state changes */
|
||||
#endif
|
||||
|
||||
/***********************************
|
||||
|
@ -32,6 +32,13 @@ extern "C" {
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/connection.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void genode_netif_input(struct netif *netif);
|
||||
|
||||
void lwip_nic_link_state_changed(int state);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Thread, that receives packets by the nic-session interface.
|
||||
@ -46,6 +53,28 @@ class Nic_receiver_thread : public Genode::Thread<8192>
|
||||
Packet_descriptor _rx_packet; /* actual packet received */
|
||||
struct netif *_netif; /* LwIP network interface structure */
|
||||
|
||||
Genode::Signal_receiver _sig_rec;
|
||||
|
||||
Genode::Signal_dispatcher<Nic_receiver_thread> _link_state_dispatcher;
|
||||
Genode::Signal_dispatcher<Nic_receiver_thread> _rx_packet_avail_dispatcher;
|
||||
Genode::Signal_dispatcher<Nic_receiver_thread> _rx_ready_to_ack_dispatcher;
|
||||
|
||||
void _handle_rx_packet_avail(unsigned)
|
||||
{
|
||||
while (_nic->rx()->packet_avail() && _nic->rx()->ready_to_ack()) {
|
||||
_rx_packet = _nic->rx()->get_packet();
|
||||
genode_netif_input(_netif);
|
||||
_nic->rx()->acknowledge_packet(_rx_packet);
|
||||
}
|
||||
}
|
||||
|
||||
void _handle_rx_read_to_ack(unsigned) { _handle_rx_packet_avail(0); }
|
||||
|
||||
void _handle_link_state(unsigned)
|
||||
{
|
||||
lwip_nic_link_state_changed(_nic->link_state());
|
||||
}
|
||||
|
||||
void _tx_ack(bool block = false)
|
||||
{
|
||||
/* check for acknowledgements */
|
||||
@ -59,7 +88,16 @@ class Nic_receiver_thread : public Genode::Thread<8192>
|
||||
public:
|
||||
|
||||
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
|
||||
: Genode::Thread<8192>("nic-recv"), _nic(nic), _netif(netif) {}
|
||||
:
|
||||
Genode::Thread<8192>("nic-recv"), _nic(nic), _netif(netif),
|
||||
_link_state_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_link_state),
|
||||
_rx_packet_avail_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_packet_avail),
|
||||
_rx_ready_to_ack_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_read_to_ack)
|
||||
{
|
||||
_nic->link_state_sigh(_link_state_dispatcher);
|
||||
_nic->rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher);
|
||||
_nic->rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher);
|
||||
}
|
||||
|
||||
void entry();
|
||||
Nic::Connection *nic() { return _nic; };
|
||||
@ -95,9 +133,6 @@ class Nic_receiver_thread : public Genode::Thread<8192>
|
||||
*/
|
||||
extern "C" {
|
||||
|
||||
static void genode_netif_input(struct netif *netif);
|
||||
|
||||
|
||||
/**
|
||||
* This function should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
@ -192,8 +227,6 @@ extern "C" {
|
||||
LINK_STATS_INC(link.drop);
|
||||
}
|
||||
|
||||
/* Acknowledge the packet */
|
||||
nic->rx()->acknowledge_packet(rx_packet);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -295,11 +328,11 @@ void Nic_receiver_thread::entry()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
/*
|
||||
* Block until we receive a packet,
|
||||
* then call input function.
|
||||
*/
|
||||
_rx_packet = _nic->rx()->get_packet();
|
||||
genode_netif_input(_netif);
|
||||
Genode::Signal sig = _sig_rec.wait_for_signal();
|
||||
int num = sig.num();
|
||||
|
||||
Genode::Signal_dispatcher_base *dispatcher;
|
||||
dispatcher = dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context());
|
||||
dispatcher->dispatch(num);
|
||||
}
|
||||
}
|
||||
|
@ -64,16 +64,6 @@ static Lwip::Mutex *global_mutex()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a timed semaphore used to wait for DHCP to come up.
|
||||
*/
|
||||
static Genode::Timed_semaphore *dhcp_semaphore()
|
||||
{
|
||||
static Genode::Timed_semaphore _sem;
|
||||
return &_sem;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used for startup synchronization by the tcpip thread.
|
||||
*/
|
||||
@ -83,15 +73,6 @@ static void startup_done(void *arg)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function used when doing dhcp requests,
|
||||
* to check availability of an IP address.
|
||||
*/
|
||||
static void dhcp_callback(struct netif *netif)
|
||||
{
|
||||
dhcp_semaphore()->up();
|
||||
}
|
||||
|
||||
using namespace Lwip;
|
||||
|
||||
extern "C" {
|
||||
@ -115,6 +96,42 @@ extern "C" {
|
||||
#error "You cannot use the Genode LwIP backend with NO_SYS!"
|
||||
#endif //NO_SYS
|
||||
|
||||
#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
|
||||
#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
|
||||
|
||||
static struct netif netif;
|
||||
|
||||
/*
|
||||
* Callback function used when changing the interface state.
|
||||
*/
|
||||
static void status_callback(struct netif *netif)
|
||||
{
|
||||
static ip_addr_t ip_addr = { 0 };
|
||||
|
||||
if (ip_addr.addr != netif->ip_addr.addr) {
|
||||
PINF("got IP address %d.%d.%d.%d",
|
||||
ip4_addr1(&(netif->ip_addr)),
|
||||
ip4_addr2(&(netif->ip_addr)),
|
||||
ip4_addr3(&(netif->ip_addr)),
|
||||
ip4_addr4(&(netif->ip_addr)));
|
||||
ip_addr.addr = netif->ip_addr.addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback function used when doing a link-state change.
|
||||
*/
|
||||
static void link_callback(struct netif *netif)
|
||||
{
|
||||
/*
|
||||
* We call the status callback at this point to print
|
||||
* the IP address because we may have got a new one,
|
||||
* e.h., we joined another wireless network.
|
||||
*/
|
||||
status_callback(netif);
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** Initialization **
|
||||
@ -141,7 +158,6 @@ extern "C" {
|
||||
Genode::size_t tx_buf_size,
|
||||
Genode::size_t rx_buf_size)
|
||||
{
|
||||
static struct netif netif;
|
||||
struct ip_addr ip, nm, gw;
|
||||
static struct netif_buf_sizes nbs;
|
||||
nbs.tx_buf_size = tx_buf_size;
|
||||
@ -174,25 +190,11 @@ extern "C" {
|
||||
/* If no static ip was set, we do dhcp */
|
||||
if (!ip_addr) {
|
||||
#if LWIP_DHCP
|
||||
/* Register callback function triggered, when DHCP succeeded. */
|
||||
netif.status_callback = dhcp_callback;
|
||||
/* Register callback functions. */
|
||||
netif.status_callback = status_callback;
|
||||
netif.link_callback = link_callback;
|
||||
|
||||
/* Start DHCP requests */
|
||||
netifapi_dhcp_start(&netif);
|
||||
|
||||
/* Block until DHCP succeeded or a timeout was triggered */
|
||||
try {
|
||||
dhcp_semaphore()->down(20000);
|
||||
} catch (Genode::Timeout_exception) {
|
||||
PWRN("DHCP timed out!");
|
||||
netifapi_dhcp_stop(&netif);
|
||||
return 1;
|
||||
}
|
||||
PINF("got IP address %d.%d.%d.%d",
|
||||
ip4_addr1(&(netif.ip_addr)),
|
||||
ip4_addr2(&(netif.ip_addr)),
|
||||
ip4_addr3(&(netif.ip_addr)),
|
||||
ip4_addr4(&(netif.ip_addr)));
|
||||
#else
|
||||
/* no IP address - no networking */
|
||||
return 1;
|
||||
@ -208,6 +210,15 @@ extern "C" {
|
||||
}
|
||||
|
||||
|
||||
void lwip_nic_link_state_changed(int state)
|
||||
{
|
||||
if (state)
|
||||
netifapi_netif_set_link_up(&netif);
|
||||
else
|
||||
netifapi_netif_set_link_down(&netif);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Semaphore **
|
||||
***************/
|
||||
|
Loading…
Reference in New Issue
Block a user