pc_wifi_drv: add RFKILL support

This commits hooks up a RFKILL management to the driver. The
'README' contains instructions on how to use it.

Fixes #4506.
This commit is contained in:
Josef Söntgen 2022-04-04 17:15:59 +02:00 committed by Christian Helmuth
parent 913aec1667
commit d92b84fbc3
13 changed files with 137 additions and 19 deletions

View File

@ -32,6 +32,11 @@ CC_C_OPT += -I$(LX_SRC_DIR)/include/linux
CC_C_OPT += -Wno-address-of-packed-member
# need net/rfkill/rfkill.h
CC_OPT_lx_emul += -I$(LX_SRC_DIR)
CC_C_OPT += -DCONFIG_RFKILL_INPUT
#CC_OPT += -DCONFIG_IWLWIFI_DEBUG

View File

@ -155,7 +155,7 @@ append config {
<inline description="connect">
} [wifi_config 30 5 no [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] {
</inline>
<sleep milliseconds="6000000"/>
<sleep milliseconds="60000"/>
<inline description="rfkill block">
} [wifi_config 30 5 yes [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] {
</inline>

View File

@ -85,10 +85,9 @@ void wifi_notify_event(void)
/* exported by wifi.lib.so */
extern void wifi_init(Genode::Env&,
Genode::Blockade&,
bool,
Genode::Signal_context_capability);
extern void wifi_init(Genode::Env&, Genode::Blockade&, bool);
extern void wifi_set_rfkill_sigh(Genode::Signal_context_capability);
struct Main
{
@ -103,8 +102,7 @@ struct Main
{
_wpa.construct(env, _wpa_startup_blockade);
wifi_init(env, _wpa_startup_blockade, false,
Genode::Signal_context_capability());
wifi_init(env, _wpa_startup_blockade, false);
}
};
@ -132,6 +130,7 @@ void *wifi_get_buffer(void)
_main->_frontend.construct(_main->env);
_wifi_frontend = &*_main->_frontend;
wifi_set_rfkill_sigh(_wifi_frontend->rfkill_sigh());
});
return &_wifi_frontend->msg_buffer();

View File

@ -1,7 +1,7 @@
/*
* \brief Array defining order of Linux Kernel initcalls
* \author Automatically generated file - do no edit
* \date 2022-05-03
* \date 2022-05-13
*/
#pragma once
@ -103,6 +103,7 @@ static const char * lx_emul_initcall_order[] = {
"__initcall_fib_notifier_init4",
"__initcall_ethnl_init4",
"__initcall_ieee80211_init4",
"__initcall_rfkill_init4",
"__initcall_pci_subsys_init4",
"__initcall_nmi_warning_debugfs5",
"__initcall_hpet_late_init5",

View File

@ -154,6 +154,7 @@ include/linux/ip.h
include/linux/ipv6_route.h
include/linux/kcov.h
include/linux/leds.h
include/linux/miscdevice.h
include/linux/mpls.h
include/linux/netfilter.h
include/linux/netfilter_ingress.h
@ -309,6 +310,7 @@ net/mac80211/wme.h
net/mac80211/wpa.h
net/netlink/af_netlink.h
net/packet/internal.h
net/rfkill/rfkill.h
net/wireless/core.h
net/wireless/debugfs.h
net/wireless/nl80211.h

View File

@ -510,3 +510,77 @@ void page_frag_free(void * addr)
__free_pages(page, 0ul);
}
#include <linux/miscdevice.h>
int misc_register(struct miscdevice *misc)
{
return 0;
}
void misc_deregister(struct miscdevice *misc)
{
}
/* rfkill support */
#include <linux/rfkill.h>
#include <net/rfkill/rfkill.h>
int __init rfkill_handler_init(void)
{
return 0;
}
static struct
{
int rfkilled;
int blocked;
} _rfkill_state;
struct task_struct *rfkill_task_struct_ptr;
int lx_emul_rfkill_get_any(void)
{
return _rfkill_state.rfkilled;
}
void lx_emul_rfkill_switch_all(int blocked)
{
_rfkill_state.blocked = blocked;
}
static int rfkill_task_function(void *arg)
{
(void)arg;
for (;;) {
bool rfkilled = !!rfkill_get_global_sw_state(RFKILL_TYPE_WLAN);
if (rfkilled != _rfkill_state.blocked)
rfkill_switch_all(RFKILL_TYPE_WLAN, !!_rfkill_state.blocked);
_rfkill_state.rfkilled = rfkilled;
lx_emul_task_schedule(true);
}
return 0;
}
void rfkill_init(void)
{
pid_t pid;
pid = kernel_thread(rfkill_task_function, NULL, CLONE_FS | CLONE_FILES);
rfkill_task_struct_ptr = find_task_by_pid_ns(pid, NULL);
}

View File

@ -31,6 +31,8 @@ void lx_emul_time_udelay(unsigned long usec);
void lx_emul_get_random_bytes(void *buf, unsigned long nbytes);
unsigned int lx_emul_get_random_u32(void);
int lx_emul_rfkill_get_any(void);
void lx_emul_rfkill_switch_all(int blocked);
#ifdef __cplusplus
}

View File

@ -21,6 +21,7 @@
void lx_user_init(void)
{
uplink_init();
rfkill_init();
socketcall_init();
}

View File

@ -23,6 +23,9 @@ void uplink_init(void);
extern struct task_struct *socketcall_task_struct_ptr;
void socketcall_init(void);
extern struct task_struct *rfkill_task_struct_ptr;
void rfkill_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -250,6 +250,7 @@ net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/packet/af_packet.c
net/rfkill/core.c
net/sched/sch_generic.c
net/sched/sch_mq.c
net/socket.c

View File

@ -250,6 +250,7 @@ net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/packet/af_packet.c
net/rfkill/core.c
net/sched/sch_generic.c
net/sched/sch_mq.c
net/socket.c

View File

@ -28,19 +28,46 @@
/* local includes */
#include "lx_user.h"
using namespace Genode;
extern "C" int lx_emul_rfkill_get_any(void);
extern "C" void lx_emul_rfkill_switch_all(int blocked);
static Genode::Signal_context_capability _rfkill_sigh_cap;
bool wifi_get_rfkill(void)
{
return false;
if (!rfkill_task_struct_ptr)
return false;
lx_emul_task_unblock(rfkill_task_struct_ptr);
Lx_kit::env().scheduler.schedule();
return lx_emul_rfkill_get_any();
}
void wifi_set_rfkill(bool blocked)
{
(void)blocked;
if (!rfkill_task_struct_ptr)
return;
lx_emul_rfkill_switch_all(blocked);
lx_emul_task_unblock(rfkill_task_struct_ptr);
Lx_kit::env().scheduler.schedule();
/*
* We have to open the device again after unblocking
* as otherwise we will get ENETDOWN. So unblock the uplink
* task _afterwards_ because there we call * 'dev_open()'
* unconditionally and that will bring the netdevice UP again.
*/
lx_emul_task_unblock(uplink_task_struct_ptr);
Lx_kit::env().scheduler.schedule();
Genode::Signal_transmitter(_rfkill_sigh_cap).submit();
}
@ -57,9 +84,6 @@ extern "C" char const *wifi_ifname(void)
return "wlan0";
}
extern "C" struct task_struct *uplink_task_struct_ptr;
struct Wlan
{
Env &_env;
@ -90,15 +114,19 @@ struct Wlan
Genode::Blockade *wpa_blockade;
void wifi_init(Genode::Env &env,
Genode::Blockade &blockade,
bool disable_11n,
Genode::Signal_context_capability rfkill)
void wifi_init(Genode::Env &env,
Genode::Blockade &blockade,
bool disable_11n)
{
(void)disable_11n;
(void)rfkill;
wpa_blockade = &blockade;
static Wlan wlan(env);
}
void wifi_set_rfkill_sigh(Genode::Signal_context_capability cap)
{
_rfkill_sigh_cap = cap;
}

View File

@ -20,6 +20,7 @@ LX_ENABLE += ACPI
# general network and WLAN support
LX_ENABLE += NET NETDEVICES PACKET
LX_ENABLE += WLAN CFG80211 MAC80211
LX_ENABLE += RFKILL
# iwlwifi
LX_ENABLE += WLAN_VENDOR_INTEL IWLWIFI IWLDVM IWLMVM