wifi: add RFKILL notification interface

Add somewhat cosmetic changes to the RFKILL interface used between
the management layer and the driver library to make the intent clear.

Issue #4861.
This commit is contained in:
Josef Söntgen 2023-05-19 10:03:51 +00:00 committed by Christian Helmuth
parent 6b406469f6
commit 22c9157231
7 changed files with 62 additions and 21 deletions

View File

@ -14,12 +14,34 @@
#ifndef _WIFI__RFKILL_H_ #ifndef _WIFI__RFKILL_H_
#define _WIFI__RFKILL_H_ #define _WIFI__RFKILL_H_
#include <util/interface.h>
namespace Wifi { namespace Wifi {
/*
* FD used to poll RFKILL state from the supplicant.
*/
enum { RFKILL_FD = 42, }; enum { RFKILL_FD = 42, };
}
bool wifi_get_rfkill(void); struct Rfkill_notification_handler : Genode::Interface
{
virtual void rfkill_notify() = 0;
};
void rfkill_establish_handler(Rfkill_notification_handler &);
/**
* Query current RFKILL state
*/
bool rfkill_blocked();
/**
* Set RFKILL state from the frontend
*
* May be only called from an EP context.
*/
void set_rfkill(bool);
} /* namespace Wifi */
#endif /* _WIFI__RFKILL_H_ */ #endif /* _WIFI__RFKILL_H_ */

View File

@ -21,3 +21,6 @@ wifi_ifindex T
wifi_ifname T wifi_ifname T
_ZN4Wifi20firmware_get_requestEv T _ZN4Wifi20firmware_get_requestEv T
_ZN4Wifi26firmware_establish_handlerERNS_24Firmware_request_handlerE T _ZN4Wifi26firmware_establish_handlerERNS_24Firmware_request_handlerE T
_ZN4Wifi10set_rfkillEb T
_ZN4Wifi14rfkill_blockedEv T
_ZN4Wifi24rfkill_establish_handlerERNS_27Rfkill_notification_handlerE T

View File

@ -62,9 +62,6 @@
/* declare manually as it is a internal hack^Winterface */ /* declare manually as it is a internal hack^Winterface */
extern void wifi_kick_socketcall(); extern void wifi_kick_socketcall();
extern bool _wifi_get_rfkill(void);
extern bool _wifi_set_rfkill(bool);
namespace Wifi { namespace Wifi {
struct Frontend; struct Frontend;
@ -252,7 +249,7 @@ static void for_each_result_line(char const *msg, FUNC const &func)
/* /*
* Wifi driver front end * Wifi driver front end
*/ */
struct Wifi::Frontend struct Wifi::Frontend : Wifi::Rfkill_notification_handler
{ {
Frontend(const Frontend&) = delete; Frontend(const Frontend&) = delete;
Frontend& operator=(const Frontend&) = delete; Frontend& operator=(const Frontend&) = delete;
@ -346,7 +343,7 @@ struct Wifi::Frontend
void _handle_rfkill() void _handle_rfkill()
{ {
_rfkilled = _wifi_get_rfkill(); _rfkilled = Wifi::rfkill_blocked();
/* re-enable scan timer */ /* re-enable scan timer */
if (!_rfkilled) { if (!_rfkilled) {
@ -410,7 +407,7 @@ struct Wifi::Frontend
*/ */
if (config.has_attribute("rfkill")) { if (config.has_attribute("rfkill")) {
bool const blocked = config.attribute_value("rfkill", false); bool const blocked = config.attribute_value("rfkill", false);
_wifi_set_rfkill(blocked); Wifi::set_rfkill(blocked);
/* /*
* In case we get blocked set rfkilled immediately to prevent * In case we get blocked set rfkilled immediately to prevent
@ -1589,13 +1586,13 @@ struct Wifi::Frontend
} }
/** /**
* Get RFKILL signal capability * Trigger RFKILL notification
* *
* Used by the wifi_drv to notify front end. * Used by the wifi_drv to notify front end.
*/ */
Genode::Signal_context_capability rfkill_sigh() void rfkill_notify() override
{ {
return _rfkill_handler; _rfkill_handler.local_submit();
} }
/** /**

View File

@ -169,8 +169,8 @@ struct Main
{ {
_frontend.construct(env, _wifi_msg_buffer); _frontend.construct(env, _wifi_msg_buffer);
_wifi_frontend = &*_frontend; _wifi_frontend = &*_frontend;
wifi_set_rfkill_sigh(_wifi_frontend->rfkill_sigh());
Wifi::rfkill_establish_handler(*_wifi_frontend);
Wifi::firmware_establish_handler(_request_handler); Wifi::firmware_establish_handler(_request_handler);
_wpa.construct(env, _wpa_startup_blockade); _wpa.construct(env, _wpa_startup_blockade);

View File

@ -11,7 +11,7 @@
/* Wifi::Socket_call instance */ /* Wifi::Socket_call instance */
socket_call; socket_call;
/* rfkill interface */ /* rfkill interface */
_*wifi_*_rfkill*; _*Wifi*rfkill*;
_*wifi_kick_*; _*wifi_kick_*;
_*Wifi*firmware*; _*Wifi*firmware*;

View File

@ -29,6 +29,7 @@
/* wifi includes */ /* wifi includes */
#include <wifi/firmware.h> #include <wifi/firmware.h>
#include <wifi/rfkill.h>
/* local includes */ /* local includes */
#include "lx_user.h" #include "lx_user.h"
@ -36,12 +37,11 @@
using namespace Genode; using namespace Genode;
/* RFKILL handling */
extern "C" int lx_emul_rfkill_get_any(void); extern "C" int lx_emul_rfkill_get_any(void);
extern "C" void lx_emul_rfkill_switch_all(int blocked); extern "C" void lx_emul_rfkill_switch_all(int blocked);
static Signal_context_capability _rfkill_sigh_cap;
bool _wifi_get_rfkill(void) bool _wifi_get_rfkill(void)
{ {
@ -53,7 +53,25 @@ bool _wifi_get_rfkill(void)
} }
void _wifi_set_rfkill(bool blocked) struct Rfkill_helper
{
Wifi::Rfkill_notification_handler &_handler;
Rfkill_helper(Wifi::Rfkill_notification_handler &handler)
:
_handler { handler }
{ }
void submit_notification()
{
_handler.rfkill_notify();
}
};
Constructible<Rfkill_helper> rfkill_helper { };
void Wifi::set_rfkill(bool blocked)
{ {
if (!rfkill_task_struct_ptr) if (!rfkill_task_struct_ptr)
return; return;
@ -72,11 +90,12 @@ void _wifi_set_rfkill(bool blocked)
lx_emul_task_unblock(uplink_task_struct_ptr); lx_emul_task_unblock(uplink_task_struct_ptr);
Lx_kit::env().scheduler.schedule(); Lx_kit::env().scheduler.schedule();
Signal_transmitter(_rfkill_sigh_cap).submit(); if (rfkill_helper.constructed())
rfkill_helper->submit_notification();
} }
bool wifi_get_rfkill(void) bool Wifi::rfkill_blocked(void)
{ {
return _wifi_get_rfkill(); return _wifi_get_rfkill();
} }
@ -370,9 +389,9 @@ void wifi_init(Env &env, Blockade &blockade)
} }
void wifi_set_rfkill_sigh(Signal_context_capability cap) void Wifi::rfkill_establish_handler(Wifi::Rfkill_notification_handler &handler)
{ {
_rfkill_sigh_cap = cap; rfkill_helper.construct(handler);
} }

View File

@ -44,7 +44,7 @@ struct rfkill_data {
static void rfkill_receive(int sock, void *eloop_ctx, void *sock_ctx) static void rfkill_receive(int sock, void *eloop_ctx, void *sock_ctx)
{ {
struct rfkill_data * const rfkill = (rfkill_data*)eloop_ctx; struct rfkill_data * const rfkill = (rfkill_data*)eloop_ctx;
bool const new_blocked = wifi_get_rfkill(); bool const new_blocked = Wifi::rfkill_blocked();
if (new_blocked != rfkill->blocked) { if (new_blocked != rfkill->blocked) {
rfkill->blocked = new_blocked; rfkill->blocked = new_blocked;