diff --git a/repos/dde_linux/src/lib/lxip/dummies.c b/repos/dde_linux/src/lib/lxip/dummies.c index 7185f55fa4..6826fbf874 100644 --- a/repos/dde_linux/src/lib/lxip/dummies.c +++ b/repos/dde_linux/src/lib/lxip/dummies.c @@ -365,6 +365,12 @@ int netdev_register_kobject(struct net_device * ndev) } +void netdev_unregister_kobject(struct net_device * ndev) +{ + lx_emul_trace(__func__); +} + + #include int send_sig(int sig,struct task_struct * p,int priv) diff --git a/repos/dde_linux/src/lib/lxip/init.cc b/repos/dde_linux/src/lib/lxip/init.cc index 12a3ccceee..717cfb6454 100644 --- a/repos/dde_linux/src/lib/lxip/init.cc +++ b/repos/dde_linux/src/lib/lxip/init.cc @@ -42,12 +42,16 @@ struct Main : env(env), io_progress(io_progress) { } + void _io_progress() + { + if (io_progress && io_progress->callback) + io_progress->callback(io_progress->data); + } + void handle_schedule() { Lx_kit::env().scheduler.execute(); - - if (io_progress && io_progress->callback) - io_progress->callback(io_progress->data); + _io_progress(); } void handle_nic_client() @@ -62,13 +66,13 @@ struct Main lx_emul_task_unblock(lx_nic_client_rx_task()); Lx_kit::env().scheduler.execute(); - if (io_progress && io_progress->callback) - io_progress->callback(io_progress->data); + _io_progress(); } void handle_link_state() { - Genode::error("handle_link_state: not implemented"); + socket_update_link_state(); + _io_progress(); } void init() diff --git a/repos/dde_linux/src/lib/lxip/net_driver.c b/repos/dde_linux/src/lib/lxip/net_driver.c index e43f2d1ad3..59a7cc4928 100644 --- a/repos/dde_linux/src/lib/lxip/net_driver.c +++ b/repos/dde_linux/src/lib/lxip/net_driver.c @@ -25,12 +25,38 @@ static struct genode_nic_client *dev_nic_client(struct net_device *dev) } +static struct net_device *dev_net_device(void) +{ + return dev_get_by_name(&init_net, "eth0"); +} + + static int net_open(struct net_device *dev) { return 0; } +bool lx_nic_client_link_state(void) +{ + return netif_carrier_ok(dev_net_device()); +} + + +bool lx_nic_client_update_link_state(void) +{ + struct net_device *dev = dev_net_device(); + bool state = genode_nic_client_link_state(dev_nic_client(dev)); + + if (state == false && netif_carrier_ok(dev)) + netif_carrier_off(dev); + if (state == true && !netif_carrier_ok(dev)) + netif_carrier_on(dev); + + return state; +} + + struct genode_nic_client_tx_packet_context { struct sk_buff *skb; @@ -82,7 +108,7 @@ static int driver_net_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_packets++; stats->tx_bytes += skb->len; - lx_nic_client_schedule_peer(); + socket_schedule_peer(); return NETDEV_TX_OK; } @@ -155,7 +181,7 @@ static int rx_task_function(void *arg) &ctx)) { progress = true; } - if (progress) lx_nic_client_schedule_peer(); + if (progress) socket_schedule_peer(); } return 0; @@ -192,6 +218,14 @@ static int __init virtio_net_driver_init(void) goto out_nic; } + if (dev_net_device() != dev) { + printk("error: net device name is \"%s\", but must be \"eth0\"\n", + dev->name); + BUG(); + } + + lx_nic_client_update_link_state(); + /* create RX task */ pid = kernel_thread(rx_task_function, dev, "rx_task", CLONE_FS | CLONE_FILES); diff --git a/repos/dde_linux/src/lib/lxip/net_driver.h b/repos/dde_linux/src/lib/lxip/net_driver.h index a4d575c0c7..9f6824b2ff 100644 --- a/repos/dde_linux/src/lib/lxip/net_driver.h +++ b/repos/dde_linux/src/lib/lxip/net_driver.h @@ -18,9 +18,17 @@ #ifdef __cplusplus extern "C" { #endif + /* net_driver.c */ struct task_struct; struct task_struct *lx_nic_client_rx_task(void); - void lx_nic_client_schedule_peer(void); + bool lx_nic_client_link_state(void); + bool lx_nic_client_update_link_state(void); + + /* socket.cc */ + void socket_schedule_peer(void); + void socket_config_address(void); + void socket_unconfigure_address(void); + void socket_update_link_state(void); #ifdef __cplusplus } #endif diff --git a/repos/dde_linux/src/lib/lxip/socket.cc b/repos/dde_linux/src/lib/lxip/socket.cc index 4aacf17432..fad5d5a916 100644 --- a/repos/dde_linux/src/lib/lxip/socket.cc +++ b/repos/dde_linux/src/lib/lxip/socket.cc @@ -37,7 +37,10 @@ using Socket_queue = Fifo; struct Statics { - genode_socket_wakeup *wakeup_remote; + genode_socket_wakeup *wakeup_remote { nullptr }; + genode_socket_config config{ }; + bool address_configured { false }; + bool address_valid { false }; }; @@ -433,6 +436,39 @@ struct Lx_sock_release : Lx_call }; +struct Lx_nic_link_state : Lx_call +{ + bool state { false }; + + Lx_nic_link_state(genode_socket_handle &handle) : Lx_call(handle) + { + schedule(); + } + + void execute() override + { + state = lx_nic_client_link_state(); + finished = true; + } +}; + + +struct Lx_nic_update_link_state : Lx_call +{ + bool state { false }; + + Lx_nic_update_link_state(genode_socket_handle &handle) : Lx_call(handle) + { + schedule(); + } + + void execute() override + { + state = lx_nic_client_update_link_state(); + finished = true; + } +}; + /* * Dispatch socket calls in Linux task */ @@ -485,18 +521,38 @@ static void _destroy_handle(genode_socket_handle *handle) } +static genode_socket_handle _disposable_handle() +{ + return { + .sock = nullptr, + .task = lx_socket_dispatch_root(), + .queue = static_cast(lx_socket_dispatch_queue()), + }; +} + /* * Genode socket C-API */ void genode_socket_config_address(struct genode_socket_config *config) { - genode_socket_handle handle = { - .task = lx_socket_dispatch_root(), - .queue = static_cast(lx_socket_dispatch_queue()), - }; - Lx_address addr { handle, config }; + statics().config = *config; + statics().address_valid = true; + + genode_socket_handle handle { _disposable_handle() }; + Lx_nic_link_state link { handle }; + if (link.state) { + /* local implementation here */ + statics().address_configured = false; + socket_config_address(); + } + + /* wait for link state change to trigger ip configuration */ + while (!statics().address_configured) { + genode_socket_wakeup_remote(); + genode_socket_wait_for_progress(); + } } @@ -505,9 +561,6 @@ extern "C" unsigned int ic_netmask; extern "C" unsigned int ic_gateway; extern "C" unsigned int ic_nameservers[1]; -//XXX: implement link state -bool ic_link_state = true; - void genode_socket_config_info(struct genode_socket_info *info) { if (!info) return; @@ -515,16 +568,16 @@ void genode_socket_config_info(struct genode_socket_info *info) info->netmask = ic_netmask; info->gateway = ic_gateway; info->nameserver = ic_nameservers[0]; - info->link_state = ic_link_state; + + genode_socket_handle handle { _disposable_handle() }; + Lx_nic_link_state link { handle }; + info->link_state = link.state; } + void genode_socket_configure_mtu(unsigned mtu) { - genode_socket_handle handle = { - .task = lx_socket_dispatch_root(), - .queue = static_cast(lx_socket_dispatch_queue()), - }; - + genode_socket_handle handle { _disposable_handle() }; Lx_mtu addr { handle, mtu }; } @@ -708,11 +761,43 @@ void genode_socket_register_wakeup(struct genode_socket_wakeup *remote) /* - * Called by net_driver.c + * local C-interface */ -void lx_nic_client_schedule_peer(void) + +void socket_schedule_peer(void) { if (statics().wakeup_remote && statics().wakeup_remote->callback) { statics().wakeup_remote->callback(statics().wakeup_remote->data); } } + + +void socket_config_address(void) +{ + if (statics().address_configured || statics().address_valid == false) + return; + + genode_socket_handle handle { _disposable_handle() }; + + Lx_address addr { handle, &statics().config }; + + statics().address_configured = true; +} + + +void socket_unconfigure_address(void) +{ + statics().address_configured = false; +} + + +void socket_update_link_state(void) +{ + genode_socket_handle handle { _disposable_handle() }; + Lx_nic_update_link_state link { handle }; + + if (link.state) + socket_config_address(); + else + statics().address_configured = false; +} diff --git a/repos/dde_linux/src/lib/lxip/spec/arm_v6/generated_dummies.c b/repos/dde_linux/src/lib/lxip/spec/arm_v6/generated_dummies.c index 223fa59ec1..8890e317ae 100644 --- a/repos/dde_linux/src/lib/lxip/spec/arm_v6/generated_dummies.c +++ b/repos/dde_linux/src/lib/lxip/spec/arm_v6/generated_dummies.c @@ -580,13 +580,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index) } -extern void netdev_unregister_kobject(struct net_device * ndev); -void netdev_unregister_kobject(struct net_device * ndev) -{ - lx_emul_trace_and_stop(__func__); -} - - #include const struct pipe_buf_operations nosteal_pipe_buf_ops; diff --git a/repos/dde_linux/src/lib/lxip/spec/arm_v7/generated_dummies.c b/repos/dde_linux/src/lib/lxip/spec/arm_v7/generated_dummies.c index 3d46652039..ef9dc5cf00 100644 --- a/repos/dde_linux/src/lib/lxip/spec/arm_v7/generated_dummies.c +++ b/repos/dde_linux/src/lib/lxip/spec/arm_v7/generated_dummies.c @@ -471,13 +471,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index) } -extern void netdev_unregister_kobject(struct net_device * ndev); -void netdev_unregister_kobject(struct net_device * ndev) -{ - lx_emul_trace_and_stop(__func__); -} - - #include const struct pipe_buf_operations nosteal_pipe_buf_ops; diff --git a/repos/dde_linux/src/lib/lxip/spec/arm_v8/generated_dummies.c b/repos/dde_linux/src/lib/lxip/spec/arm_v8/generated_dummies.c index 65033c6d25..17510d5a96 100644 --- a/repos/dde_linux/src/lib/lxip/spec/arm_v8/generated_dummies.c +++ b/repos/dde_linux/src/lib/lxip/spec/arm_v8/generated_dummies.c @@ -588,13 +588,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index) } -extern void netdev_unregister_kobject(struct net_device * ndev); -void netdev_unregister_kobject(struct net_device * ndev) -{ - lx_emul_trace_and_stop(__func__); -} - - #include const struct pipe_buf_operations nosteal_pipe_buf_ops; diff --git a/repos/dde_linux/src/lib/lxip/spec/x86_32/generated_dummies.c b/repos/dde_linux/src/lib/lxip/spec/x86_32/generated_dummies.c index f5408a3066..cb9be8988d 100644 --- a/repos/dde_linux/src/lib/lxip/spec/x86_32/generated_dummies.c +++ b/repos/dde_linux/src/lib/lxip/spec/x86_32/generated_dummies.c @@ -543,13 +543,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index) } -extern void netdev_unregister_kobject(struct net_device * ndev); -void netdev_unregister_kobject(struct net_device * ndev) -{ - lx_emul_trace_and_stop(__func__); -} - - #include const struct pipe_buf_operations nosteal_pipe_buf_ops; diff --git a/repos/dde_linux/src/lib/lxip/spec/x86_64/generated_dummies.c b/repos/dde_linux/src/lib/lxip/spec/x86_64/generated_dummies.c index fec5eee0be..4ea3c24f9a 100644 --- a/repos/dde_linux/src/lib/lxip/spec/x86_64/generated_dummies.c +++ b/repos/dde_linux/src/lib/lxip/spec/x86_64/generated_dummies.c @@ -548,13 +548,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index) } -extern void netdev_unregister_kobject(struct net_device * ndev); -void netdev_unregister_kobject(struct net_device * ndev) -{ - lx_emul_trace_and_stop(__func__); -} - - #include const struct pipe_buf_operations nosteal_pipe_buf_ops;