mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 16:35:28 +00:00
pc: update wifi driver
The driver falls in line with the previous 'legacy_wifi_drv' component where the ported wireless LAN stack and device driver is encapsulated in a library. This library in return is used by the 'Libc::Component' providing the necessary environment for the 'wpa_supplicant'. In constrast to the old driver a 'wifi' VFS plugin is in charge of initalizing the 'Lx_kit::Env' prior to executing any static constructors. Fixes #4455.
This commit is contained in:
parent
8056811b4f
commit
e7e7893f22
17
repos/dde_linux/recipes/raw/wifi_firmware/content.mk
Normal file
17
repos/dde_linux/recipes/raw/wifi_firmware/content.mk
Normal file
@ -0,0 +1,17 @@
|
||||
PORT_DIR := $(call port_dir,$(REP_DIR)/ports/linux-firmware)
|
||||
|
||||
content: ucode_files LICENSE.wifi_drv
|
||||
|
||||
|
||||
.PHONY: ucode_files
|
||||
ucode_files:
|
||||
cp $(PORT_DIR)/firmware/*.ucode .
|
||||
cp $(PORT_DIR)/firmware/regulatory.db .
|
||||
cp $(PORT_DIR)/firmware/regulatory.db.p7s .
|
||||
|
||||
LICENSE.wifi_drv:
|
||||
for i in $(PORT_DIR)/firmware/LICEN*E.*; do \
|
||||
echo "$${i##*/}:" >> $@; \
|
||||
cat $$i >> $@; \
|
||||
echo >> $@; \
|
||||
done
|
1
repos/dde_linux/recipes/raw/wifi_firmware/hash
Normal file
1
repos/dde_linux/recipes/raw/wifi_firmware/hash
Normal file
@ -0,0 +1 @@
|
||||
2019-11-25 ff24f3bafaeeb47c053670264b5096dbc4b9a36d
|
5
repos/pc/lib/mk/spec/x86_32/wifi.mk
Normal file
5
repos/pc/lib/mk/spec/x86_32/wifi.mk
Normal file
@ -0,0 +1,5 @@
|
||||
include $(REP_DIR)/lib/mk/wifi.inc
|
||||
|
||||
REQUIRES += 32bit
|
||||
|
||||
SRC_C += lx_emul/spec/x86_32/atomic64_32.c
|
3
repos/pc/lib/mk/spec/x86_64/wifi.mk
Normal file
3
repos/pc/lib/mk/spec/x86_64/wifi.mk
Normal file
@ -0,0 +1,3 @@
|
||||
include $(REP_DIR)/lib/mk/wifi.inc
|
||||
|
||||
REQUIRES += 64bit
|
11
repos/pc/lib/mk/vfs_wifi.mk
Normal file
11
repos/pc/lib/mk/vfs_wifi.mk
Normal file
@ -0,0 +1,11 @@
|
||||
SRC_CC = vfs.cc
|
||||
|
||||
DDE_LINUX_DIR := $(subst /src/include/lx_kit,,$(call select_from_repositories,src/include/lx_kit))
|
||||
|
||||
INC_DIR += $(DDE_LINUX_DIR)/src/include
|
||||
|
||||
LIBS := wifi
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/vfs/wifi
|
||||
|
||||
SHARED_LIB := yes
|
48
repos/pc/lib/mk/wifi.inc
Normal file
48
repos/pc/lib/mk/wifi.inc
Normal file
@ -0,0 +1,48 @@
|
||||
REQUIRES := x86
|
||||
|
||||
TARGET_LIB_DIR := $(REP_DIR)/src/lib/wifi
|
||||
|
||||
SHARED_LIB := yes
|
||||
|
||||
LD_OPT += --version-script=$(TARGET_LIB_DIR)/symbol.map
|
||||
|
||||
LIBS += base pc_linux_generated pc_lx_emul
|
||||
INC_DIR := $(TARGET_LIB_DIR)
|
||||
SRC_CC += wlan.cc
|
||||
SRC_CC += misc.cc
|
||||
SRC_CC += time.cc
|
||||
SRC_CC += firmware.cc
|
||||
SRC_CC += socket_call.cc
|
||||
SRC_CC += random.cc
|
||||
|
||||
SRC_C += dummies.c
|
||||
SRC_C += lx_emul.c
|
||||
SRC_C += uplink.c
|
||||
|
||||
CC_OPT_lx_socket_call += -DKBUILD_MODNAME='"lx_socket_call"'
|
||||
SRC_C += lx_socket_call.c
|
||||
|
||||
SRC_C += $(notdir $(wildcard $(TARGET_LIB_DIR)/generated_dummies.c))
|
||||
SRC_C += pc/lx_emul/common_dummies.c
|
||||
SRC_C += lx_emul/spec/x86/pci.c
|
||||
|
||||
CC_C_OPT += -I$(LX_SRC_DIR)/drivers/net/wireless/intel/iwlwifi
|
||||
CC_C_OPT += -I$(LX_SRC_DIR)/include/linux
|
||||
|
||||
CC_C_OPT += -Wno-address-of-packed-member
|
||||
|
||||
#CC_OPT += -DCONFIG_IWLWIFI_DEBUG
|
||||
|
||||
vpath %.c $(TARGET_LIB_DIR)
|
||||
vpath %.cc $(TARGET_LIB_DIR)
|
||||
vpath pc/lx_emul/common_dummies.c $(REP_DIR)/src/lib
|
||||
|
||||
CUSTOM_TARGET_DEPS += $(TARGET_LIB_DIR)/symbol.map
|
||||
|
||||
#
|
||||
# Genode C-API backends
|
||||
#
|
||||
|
||||
SRC_CC += genode_c_api/uplink.cc
|
||||
|
||||
vpath genode_c_api/uplink.cc $(subst /genode_c_api,,$(call select_from_repositories,src/lib/genode_c_api))
|
24
repos/pc/lib/mk/wifi_firmware.mk
Normal file
24
repos/pc/lib/mk/wifi_firmware.mk
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Pseudo library to copy wireless LAN firmware to build directory
|
||||
#
|
||||
|
||||
FW_CONTRIB_DIR := $(call select_from_ports,linux-firmware)
|
||||
|
||||
IMAGES := $(notdir $(wildcard $(FW_CONTRIB_DIR)/firmware/*.ucode))
|
||||
IMAGES += $(notdir $(wildcard $(FW_CONTRIB_DIR)/firmware/*.db))
|
||||
IMAGES += $(notdir $(wildcard $(FW_CONTRIB_DIR)/firmware/*.p7s))
|
||||
BIN_DIR := $(BUILD_BASE_DIR)/bin
|
||||
FW_DIR := $(FW_CONTRIB_DIR)/firmware
|
||||
|
||||
CUSTOM_TARGET_DEPS += $(addprefix $(BIN_DIR)/,$(IMAGES))
|
||||
|
||||
$(BIN_DIR)/%.ucode: $(FW_DIR)/%.ucode
|
||||
$(VERBOSE)cp $^ $@
|
||||
|
||||
$(BIN_DIR)/%.db: $(FW_DIR)/%.db
|
||||
$(VERBOSE)cp $^ $@
|
||||
|
||||
$(BIN_DIR)/%.p7s: $(FW_DIR)/%.p7s
|
||||
$(VERBOSE)cp $^ $@
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
2
repos/pc/recipes/pkg/wifi/README
Normal file
2
repos/pc/recipes/pkg/wifi/README
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
Package for bundling pc_wifi_drv and wifi_firmware
|
6
repos/pc/recipes/pkg/wifi/archives
Normal file
6
repos/pc/recipes/pkg/wifi/archives
Normal file
@ -0,0 +1,6 @@
|
||||
_/src/pc_wifi_drv
|
||||
_/src/openssl
|
||||
_/src/vfs
|
||||
_/src/vfs_jitterentropy
|
||||
_/src/libc
|
||||
_/raw/wifi_firmware
|
1
repos/pc/recipes/pkg/wifi/hash
Normal file
1
repos/pc/recipes/pkg/wifi/hash
Normal file
@ -0,0 +1 @@
|
||||
2022-03-28-c 2f0c23734634d4c90d6c4ed2d08a5873bd3daed1
|
43
repos/pc/recipes/pkg/wifi/runtime
Normal file
43
repos/pc/recipes/pkg/wifi/runtime
Normal file
@ -0,0 +1,43 @@
|
||||
<runtime ram="32M" caps="300" binary="pc_wifi_drv">
|
||||
|
||||
<requires> <rom label="wifi_config"/> </requires>
|
||||
|
||||
<config ld_verbose="yes" verbose="no">
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <rtc/> <null/>
|
||||
<jitterentropy name="random"/>
|
||||
<jitterentropy name="urandom"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
|
||||
</config>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="pc_wifi_drv"/>
|
||||
<rom label="libcrypto.lib.so"/>
|
||||
<rom label="libc.lib.so"/>
|
||||
<rom label="libm.lib.so"/>
|
||||
<rom label="vfs_jitterentropy.lib.so"/>
|
||||
<rom label="libssl.lib.so"/>
|
||||
<rom label="wifi.lib.so"/>
|
||||
<rom label="wpa_driver_nl80211.lib.so"/>
|
||||
<rom label="wpa_supplicant.lib.so"/>
|
||||
<rom label="vfs.lib.so"/>
|
||||
<rom label="iwlwifi-1000-5.ucode"/>
|
||||
<rom label="iwlwifi-3160-17.ucode"/>
|
||||
<rom label="iwlwifi-3168-29.ucode"/>
|
||||
<rom label="iwlwifi-5000-5.ucode"/>
|
||||
<rom label="iwlwifi-6000-4.ucode"/>
|
||||
<rom label="iwlwifi-6000g2a-6.ucode"/>
|
||||
<rom label="iwlwifi-6000g2b-6.ucode"/>
|
||||
<rom label="iwlwifi-7260-17.ucode"/>
|
||||
<rom label="iwlwifi-7265-17.ucode"/>
|
||||
<rom label="iwlwifi-7265D-29.ucode"/>
|
||||
<rom label="iwlwifi-8000C-36.ucode"/>
|
||||
<rom label="iwlwifi-8265-36.ucode"/>
|
||||
<rom label="iwlwifi-9000-pu-b0-jf-b0-34.ucode"/>
|
||||
<rom label="iwlwifi-9000-pu-b0-jf-b0-46.ucode"/>
|
||||
<rom label="iwlwifi-QuZ-a0-hr-b0-63.ucode"/>
|
||||
</content>
|
||||
</runtime>
|
72
repos/pc/recipes/src/pc_wifi_drv/content.mk
Normal file
72
repos/pc/recipes/src/pc_wifi_drv/content.mk
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# Driver portions
|
||||
#
|
||||
|
||||
LIB_MK := $(addprefix lib/mk/,wifi_firmware.mk wifi.inc vfs_wifi.mk) \
|
||||
$(foreach SPEC,x86_32 x86_64,lib/mk/spec/$(SPEC)/wifi.mk) \
|
||||
|
||||
MIRROR_FROM_REP_DIR := src/drivers/wifi/pc \
|
||||
src/lib/pc/lx_emul \
|
||||
$(LIB_MK) \
|
||||
$(shell cd $(REP_DIR); find src/drivers/wifi -type f) \
|
||||
$(shell cd $(REP_DIR); find src/lib/wifi -type f) \
|
||||
$(shell cd $(REP_DIR); find src/lib/vfs/wifi -type f)
|
||||
|
||||
MIRROR_FROM_OS_DIR := src/lib/genode_c_api/uplink.cc
|
||||
|
||||
#
|
||||
# DDE Linux portions (wpa_supplicant, libnl)
|
||||
#
|
||||
|
||||
DDE_LINUX_REP_DIR := $(GENODE_DIR)/repos/dde_linux
|
||||
DDE_LINUX_PORT_DIR := $(call port_dir,$(DDE_LINUX_REP_DIR)/ports/dde_linux)
|
||||
|
||||
DDE_LINUX_LIB_MK := \
|
||||
$(addprefix lib/mk/,libnl.inc libnl_include.mk) \
|
||||
$(foreach SPEC,x86_32 x86_64,lib/mk/spec/$(SPEC)/libnl.mk) \
|
||||
$(addprefix lib/mk/spec/x86/,wpa_driver_nl80211.mk wpa_supplicant.mk)
|
||||
|
||||
MIRROR_FROM_DDE_LINUX_DIR := $(DDE_LINUX_LIB_MK) \
|
||||
lib/import/import-libnl_include.mk \
|
||||
lib/import/import-libnl.mk \
|
||||
include/wifi \
|
||||
$(shell cd $(DDE_LINUX_REP_DIR); find src/lib/libnl -type f) \
|
||||
$(shell cd $(DDE_LINUX_REP_DIR); find src/lib/wpa_driver_nl80211 -type f) \
|
||||
$(shell cd $(DDE_LINUX_REP_DIR); find src/lib/wpa_supplicant -type f)
|
||||
|
||||
MIRROR_FROM_DDE_LINUX_PORT_DIR := $(shell cd $(DDE_LINUX_PORT_DIR); find src/lib/libnl -type f) \
|
||||
$(shell cd $(DDE_LINUX_PORT_DIR); find src/app/wpa_supplicant -type f)
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_OS_DIR) $(MIRROR_FROM_DDE_LINUX_DIR) \
|
||||
$(MIRROR_FROM_DDE_LINUX_PORT_DIR) cleanup-wpa
|
||||
|
||||
$(MIRROR_FROM_REP_DIR):
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
$(MIRROR_FROM_OS_DIR):
|
||||
mkdir -p $(dir $@)
|
||||
cp -r $(GENODE_DIR)/repos/os/$@ $@
|
||||
|
||||
$(MIRROR_FROM_DDE_LINUX_DIR):
|
||||
mkdir -p $(dir $@)
|
||||
cp -r $(GENODE_DIR)/repos/dde_linux/$@ $@
|
||||
|
||||
$(MIRROR_FROM_DDE_LINUX_PORT_DIR):
|
||||
mkdir -p $(dir $@)
|
||||
cp -r $(DDE_LINUX_PORT_DIR)/$@ $@
|
||||
|
||||
cleanup-wpa: $(MIRROR_FROM_DDE_LINUX_PORT_DIR)
|
||||
@for dir in .git doc eap_example hs20 mac80211_hwsim radius_example \
|
||||
hostapd tests wlantest wpadebug wpaspy; do \
|
||||
rm -rf src/app/wpa_supplicant/$$dir; done
|
||||
|
||||
content: LICENSE
|
||||
LICENSE:
|
||||
( echo "Linux is subject to GNU General Public License version 2, see:"; \
|
||||
echo "https://www.kernel.org/pub/linux/kernel/COPYING"; \
|
||||
echo; \
|
||||
echo "Libnl is subject to GNU LESSER GENERAL PUBLIC LICENSE Verson 2.1, see:"; \
|
||||
echo " src/lib/libnl/COPYING"; \
|
||||
echo; \
|
||||
echo "Wpa_supplicant is subject to 3-clause BSD license, see:"; \
|
||||
echo " src/app/wpa_supplicant/COPYING"; ) > $@
|
1
repos/pc/recipes/src/pc_wifi_drv/hash
Normal file
1
repos/pc/recipes/src/pc_wifi_drv/hash
Normal file
@ -0,0 +1 @@
|
||||
2022-03-25-d 6b387b53c6390a75e1fdd55586aac54d3812271c
|
12
repos/pc/recipes/src/pc_wifi_drv/used_apis
Normal file
12
repos/pc/recipes/src/pc_wifi_drv/used_apis
Normal file
@ -0,0 +1,12 @@
|
||||
base
|
||||
genode_c_api
|
||||
libc
|
||||
openssl
|
||||
os
|
||||
pc_linux
|
||||
nic_session
|
||||
platform_session
|
||||
report_session
|
||||
timer_session
|
||||
uplink_session
|
||||
vfs
|
283
repos/pc/run/wifi.run
Normal file
283
repos/pc/run/wifi.run
Normal file
@ -0,0 +1,283 @@
|
||||
#
|
||||
# Configure wireless lan
|
||||
#
|
||||
|
||||
proc wifi_ssid { } {
|
||||
return $::env(GENODE_WIFI_SSID)
|
||||
}
|
||||
|
||||
proc wifi_psk { } {
|
||||
return $::env(GENODE_WIFI_PSK)
|
||||
}
|
||||
|
||||
#
|
||||
# widi_drv config generator (supporting a network list)
|
||||
#
|
||||
# You may script your tests with this function in the dynamic_rom config below.
|
||||
# The syntax for the networks parameter is
|
||||
#
|
||||
# { ssid protection passphrase explicit_scan }
|
||||
#
|
||||
# Example dynamic_rom config:
|
||||
#
|
||||
# {<inline description="auto-connect both networks">
|
||||
# } [wifi_config 30 5 no [list "net1 WPA2 net1_psk no" "net2 WPA2 net2_psk no"]] {
|
||||
# </inline>
|
||||
# <inline description="aquto-connect both, but net2 explicitly">
|
||||
# } [wifi_config 30 5 no [list "net1 WPA2 net1_psk no" "net2 WPA2 net2_psk yes"]] {
|
||||
# </inline>}
|
||||
|
||||
set wifi_verbose false
|
||||
set wifi_verbose_state false
|
||||
|
||||
proc wifi_config { connected_scan_interval scan_interval rfkill networks } {
|
||||
global wifi_verbose
|
||||
global wifi_verbose_state
|
||||
|
||||
set config "<wifi_config"
|
||||
append config " verbose=\"$wifi_verbose\""
|
||||
append config " verbose_state=\"$wifi_verbose_state\""
|
||||
append config " connected_scan_interval=\"$connected_scan_interval\""
|
||||
append config " scan_interval=\"$scan_interval\""
|
||||
append config " rfkill=\"$rfkill\""
|
||||
append config ">\n"
|
||||
foreach n $networks {
|
||||
append config " <network"
|
||||
append config " ssid=\"[lindex $n 0]\""
|
||||
append config " protection=\"[lindex $n 1]\""
|
||||
append config " passphrase=\"[lindex $n 2]\""
|
||||
append config " explicit_scan=\"[lindex $n 3]\""
|
||||
append config "/>\n"
|
||||
}
|
||||
append config "</wifi_config>\n"
|
||||
|
||||
return $config
|
||||
}
|
||||
|
||||
#
|
||||
# Restrict platforms
|
||||
#
|
||||
assert_spec x86
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/rtc
|
||||
drivers/wifi/pc
|
||||
server/report_rom
|
||||
server/dynamic_rom
|
||||
server/nic_router
|
||||
test/lwip/http_srv
|
||||
lib/vfs/wifi
|
||||
lib/vfs/jitterentropy
|
||||
lib/vfs/lwip
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config verbose="yes" prio_levels="2">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="rtc_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Rtc"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="test-lwip_httpsrv">
|
||||
<resource name="RAM" quantum="128M"/>
|
||||
<config>
|
||||
<libc stdout="/dev/null" stderr="/dev/log" socket="/socket"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <null/> </dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="state_report_rom">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="no"/>
|
||||
</start>
|
||||
|
||||
<start name="accesspoints_report_rom">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="no"/>
|
||||
</start>
|
||||
|
||||
<start name="config_rom">
|
||||
<binary name="dynamic_rom"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="ROM"/></provides>
|
||||
<config verbose="yes">
|
||||
<rom name="wifi_config">
|
||||
<inline description="disconnect">
|
||||
} [wifi_config 30 5 no {}] {
|
||||
</inline>
|
||||
<sleep milliseconds="15000"/>
|
||||
<inline description="connect">
|
||||
} [wifi_config 30 5 no [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] {
|
||||
</inline>
|
||||
<sleep milliseconds="6000000"/>
|
||||
<inline description="rfkill block">
|
||||
} [wifi_config 30 5 yes [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] {
|
||||
</inline>
|
||||
<sleep milliseconds="30000"/>
|
||||
<inline description="rfkill unblock">
|
||||
} [wifi_config 30 5 no [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] {
|
||||
</inline>
|
||||
<sleep milliseconds="30000"/>
|
||||
</rom>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="nic_router" caps="150">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no" verbose_domain_state="yes" dhcp_discover_timeout_sec="10" dhcp_request_timeout_sec="6">
|
||||
|
||||
<policy label_prefix="test-lwip_httpsrv" domain="downlink"/>
|
||||
<policy label_prefix="wifi_drv" domain="uplink"/>
|
||||
|
||||
<domain name="uplink" verbose_packets="no" verbose_packet_drop="no" icmp_echo_server="yes">
|
||||
|
||||
<nat domain="downlink" tcp-ports="16384"/>
|
||||
<tcp-forward port="443" domain="downlink" to="10.0.3.2"/>
|
||||
<tcp-forward port="80" domain="downlink" to="10.0.3.2"/>
|
||||
|
||||
</domain>
|
||||
|
||||
<domain name="downlink" verbose_packets="no" verbose_packet_drop="no" interface="10.0.3.1/24">
|
||||
|
||||
<dhcp-server ip_first="10.0.3.2" ip_last="10.0.3.2"/>
|
||||
|
||||
</domain>
|
||||
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="devices_report_rom">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="1200K"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="yes"/>
|
||||
</start>
|
||||
|
||||
<start name="wifi_drv" caps="250" priority="-1">
|
||||
<binary name="pc_wifi_drv"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<config ld_verbose="yes">
|
||||
<report mac_address="true"/>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <null/> <rtc/>
|
||||
<jitterentropy name="random"/>
|
||||
<jitterentropy name="urandom"/>
|
||||
<wifi/>
|
||||
</dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Uplink"> <child name="nic_router"/> </service>
|
||||
<service name="Rtc"> <any-child/> </service>
|
||||
<service name="Report" label="accesspoints"> <child name="accesspoints_report_rom"/> </service>
|
||||
<service name="Report" label="state"> <child name="state_report_rom"/> </service>
|
||||
<service name="Report" label="devices"> <child name="devices_report_rom"/> </service>
|
||||
<service name="ROM" label="wifi_config"> <child name="config_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
set firmware_modules {
|
||||
iwlwifi-1000-5.ucode
|
||||
iwlwifi-3160-17.ucode
|
||||
iwlwifi-3168-29.ucode
|
||||
iwlwifi-5000-5.ucode
|
||||
iwlwifi-6000-4.ucode
|
||||
iwlwifi-7260-17.ucode
|
||||
iwlwifi-7265-17.ucode
|
||||
iwlwifi-7265D-29.ucode
|
||||
iwlwifi-8000C-36.ucode
|
||||
iwlwifi-8265-36.ucode
|
||||
iwlwifi-9000-pu-b0-jf-b0-34.ucode
|
||||
iwlwifi-9000-pu-b0-jf-b0-46.ucode
|
||||
iwlwifi-QuZ-a0-hr-b0-63.ucode
|
||||
regulatory.db
|
||||
regulatory.db.p7s
|
||||
}
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer rtc_drv report_rom dynamic_rom
|
||||
vfs_jitterentropy.lib.so
|
||||
libc.lib.so vfs.lib.so libcrypto.lib.so libssl.lib.so
|
||||
wpa_driver_nl80211.lib.so wpa_supplicant.lib.so
|
||||
pc_wifi_drv wifi.lib.so vfs_wifi.lib.so
|
||||
nic_router
|
||||
|
||||
test-lwip_httpsrv
|
||||
vfs_lwip.lib.so
|
||||
}
|
||||
|
||||
append boot_modules $firmware_modules
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
# vi: set ft=tcl :
|
108
repos/pc/src/drivers/wifi/pc/README
Normal file
108
repos/pc/src/drivers/wifi/pc/README
Normal file
@ -0,0 +1,108 @@
|
||||
The pc_wifi_drv component is a port of the Linux mac802.11 stack, including
|
||||
the iwlwifi driver as well as libnl and wpa_supplicant, to Genode.
|
||||
|
||||
To start the component the following configuration snippet can be used:
|
||||
|
||||
!<start name="pc_wifi_drv" caps="250">
|
||||
! <resource name="RAM" quantum="32M"/>
|
||||
! <provides><service name="Nic"/></provides>
|
||||
! <config>
|
||||
! <libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
|
||||
! <vfs>
|
||||
! <dir name="dev"> <log/> <null/> <rtc/> <wifi/>
|
||||
! <jitterentropy name="random"/>
|
||||
! <jitterentropy name="urandom"/>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! </config>
|
||||
! <route>
|
||||
! <service name="Rtc"> <any-child /> </service>
|
||||
! <any-service> <parent/> <any-child /> </any-service>
|
||||
! </route>
|
||||
!</start
|
||||
|
||||
The driver will request access to the ROM module 'wifi_config' to
|
||||
connect to a network:
|
||||
|
||||
!<wifi_config connected_scan_interval="30" scan_interval="10" rfkill="no">
|
||||
! <network ssid="Foobar" protection="WPA2" passphrase="allyourbase"/>
|
||||
!</wifi_config>
|
||||
|
||||
To temporarily prevent any radio activity, the 'rfkill' attribute
|
||||
can be set to 'true'.
|
||||
|
||||
If the network is protected by, e.g., WPA/WPA2, the protection type, either
|
||||
'WPA' or 'WPA2' as well as the the passphrase have to be specified.
|
||||
The 'bssid' attribute can be used to select a specifc accesspoint within a
|
||||
network. Of all attributes only the 'ssid' attribute is mandatory, all others
|
||||
are optional and should only be used when needed.
|
||||
|
||||
The configuration may contain more than one network. In This case the driver
|
||||
will try to select the best one it gets a response from. To prevent it
|
||||
from automatically joining the network the 'auto_connect' attribute must be
|
||||
set to 'false'; the default value is 'true'. If the 'explicit_scan' attribute
|
||||
is set, the driver will pro-actively scan for a hidden network with the given
|
||||
SSID:
|
||||
|
||||
!<wifi_config connected_scan_interval="30" scan_interval="10">
|
||||
! <network ssid="Zero" protection="WPA2" passphrase="allyourbase"/>
|
||||
! <network ssid="Skynet" protection="WPA" passphrase="12345678"
|
||||
! explicit_scan="true" auto_connect="false"/>
|
||||
!</wifi_config>
|
||||
|
||||
By default, the driver scans for available networks only when not
|
||||
connected. This can be changed with the 'connected_scan_interval'
|
||||
attribute, which specifies the interval for connected scans in
|
||||
seconds and directly influences any roaming decision, i.e., select
|
||||
a better fit accesspoint for the configured network.
|
||||
|
||||
Also, the driver can be switched to verbose logging during runtime
|
||||
by setting the 'verbose' or 'verbose_state' attribute to 'true'.
|
||||
|
||||
The wifi_drv creates two distinct reports to communicate its state and
|
||||
information about the wireless infrastructure to other components. The
|
||||
first one is a list of all available accesspoints. The following examplary
|
||||
report shows its general structure:
|
||||
|
||||
!<accesspoints>
|
||||
! <accesspoint ssid="skynet" bssid="00:01:02:03:04:05" quality="40"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" protection="WPA2"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:07" quality="10" protection="WPA2"/>
|
||||
!</accesspoints>
|
||||
|
||||
Each accesspoint node has attributes that contain the SSID and the BSSID
|
||||
of the accesspoint as well as the link quality (signal strength). These
|
||||
attributes are mandatory. If the network is protected, the node will also
|
||||
have an attribute describing the type of protection in addition.
|
||||
|
||||
The second report provides information about the state of the connection
|
||||
to the currently connected accesspoint:
|
||||
|
||||
!<state>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" freq="2418" state="connected"/>
|
||||
!</state>
|
||||
|
||||
Valid state values are 'connected', 'disconnected', 'connecting'. Depending
|
||||
on the state, there are additional attributes that can be checked. In case
|
||||
of an authentication error, e.g. the passphrase is wrong, the 'auth_failure'
|
||||
attribute will be set to 'true'. The 'rfkilled' attribute is set to 'true'
|
||||
if a disconnect was triggered by disabling the radio activity via setting
|
||||
the 'rfkill' attribute.
|
||||
|
||||
By subscribing to both reports and providing the required 'wifi_config' ROM
|
||||
module, a component is able control the wireless driver.
|
||||
|
||||
Currently only WPA/WPA2 protection using a passphrase is supported and the the
|
||||
SSID is copied verbatim. At the moment, there is no way to express or escape
|
||||
non alphanumeric characters.
|
||||
|
||||
On certain cards, e.g. Intel Wireless 6200 ABG, it may be necessary to disable
|
||||
the 11n mode. This can be achieved by setting the 'use_11n' attribute in
|
||||
the 'wifi_config' node to 'no'.
|
||||
|
||||
The driver optionally reports the following information under the
|
||||
label "devices" if requested in the config as depicted.
|
||||
|
||||
! <config> <report mac_address="true"/> </config>
|
||||
|
||||
! <devices> <nic mac_address="02:00:00:00:00:01"/> </devices>
|
1658
repos/pc/src/drivers/wifi/pc/frontend.h
Normal file
1658
repos/pc/src/drivers/wifi/pc/frontend.h
Normal file
File diff suppressed because it is too large
Load Diff
147
repos/pc/src/drivers/wifi/pc/main.cc
Normal file
147
repos/pc/src/drivers/wifi/pc/main.cc
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* \brief Startup Wifi driver
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-03-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <libc/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
/* local includes */
|
||||
#include <util.h>
|
||||
#include <wpa.h>
|
||||
#include <frontend.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static Wifi::Frontend *_wifi_frontend = nullptr;
|
||||
|
||||
|
||||
/**
|
||||
* Notify front end about command processing
|
||||
*
|
||||
* Called by the CTRL interface after wpa_supplicant has processed
|
||||
* the command.
|
||||
*/
|
||||
void wifi_block_for_processing(void)
|
||||
{
|
||||
if (!_wifi_frontend) {
|
||||
warning("frontend not available, dropping notification");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next time we block as long as the front end has not finished
|
||||
* handling our previous request
|
||||
*/
|
||||
_wifi_frontend->block_for_processing();
|
||||
|
||||
/* XXX hack to trick poll() into returning faster */
|
||||
wpa_ctrl_set_fd();
|
||||
}
|
||||
|
||||
|
||||
void wifi_notify_cmd_result(void)
|
||||
{
|
||||
if (!_wifi_frontend) {
|
||||
warning("frontend not available, dropping notification");
|
||||
return;
|
||||
}
|
||||
|
||||
Signal_transmitter(_wifi_frontend->result_sigh()).submit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify front end about triggered event
|
||||
*
|
||||
* Called by the CTRL interface whenever wpa_supplicant has triggered
|
||||
* a event.
|
||||
*/
|
||||
void wifi_notify_event(void)
|
||||
{
|
||||
if (!_wifi_frontend) {
|
||||
Genode::warning("frontend not available, dropping notification");
|
||||
return;
|
||||
}
|
||||
|
||||
Signal_transmitter(_wifi_frontend->event_sigh()).submit();
|
||||
}
|
||||
|
||||
|
||||
/* exported by wifi.lib.so */
|
||||
extern void wifi_init(Genode::Env&,
|
||||
Genode::Blockade&,
|
||||
bool,
|
||||
Genode::Signal_context_capability);
|
||||
|
||||
struct Main
|
||||
{
|
||||
Env &env;
|
||||
|
||||
Constructible<Wpa_thread> _wpa;
|
||||
Constructible<Wifi::Frontend> _frontend;
|
||||
|
||||
Blockade _wpa_startup_blockade { };
|
||||
|
||||
Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
_wpa.construct(env, _wpa_startup_blockade);
|
||||
|
||||
wifi_init(env, _wpa_startup_blockade, false,
|
||||
Genode::Signal_context_capability());
|
||||
}
|
||||
};
|
||||
|
||||
static Main *_main;
|
||||
|
||||
|
||||
/**
|
||||
* Return shared-memory message buffer
|
||||
*
|
||||
* It is used by the wpa_supplicant CTRL interface.
|
||||
*/
|
||||
void *wifi_get_buffer(void)
|
||||
{
|
||||
/*
|
||||
* XXX creating the front end at this point is merely a hack
|
||||
* to post-pone its creation
|
||||
*/
|
||||
if (_wifi_frontend)
|
||||
return &_wifi_frontend->msg_buffer();
|
||||
|
||||
Libc::with_libc([&] () {
|
||||
|
||||
if (_main->_frontend.constructed())
|
||||
return;
|
||||
|
||||
_main->_frontend.construct(_main->env);
|
||||
_wifi_frontend = &*_main->_frontend;
|
||||
});
|
||||
|
||||
return &_wifi_frontend->msg_buffer();
|
||||
}
|
||||
|
||||
|
||||
void Libc::Component::construct(Libc::Env &env)
|
||||
{
|
||||
Libc::with_libc([&] () {
|
||||
static Main server(env);
|
||||
_main = &server;
|
||||
});
|
||||
}
|
10
repos/pc/src/drivers/wifi/pc/target.mk
Normal file
10
repos/pc/src/drivers/wifi/pc/target.mk
Normal file
@ -0,0 +1,10 @@
|
||||
TARGET := pc_wifi_drv
|
||||
SRC_CC := main.cc wpa.cc
|
||||
LIBS := base wifi wifi_firmware
|
||||
LIBS += libc
|
||||
LIBS += wpa_supplicant
|
||||
LIBS += libcrypto libssl wpa_driver_nl80211
|
||||
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
CC_CXX_WARN_STRICT :=
|
90
repos/pc/src/drivers/wifi/pc/util.h
Normal file
90
repos/pc/src/drivers/wifi/pc/util.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* \brief Wifi front end utilities
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WIFI__UTIL_H_
|
||||
#define _WIFI__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
|
||||
typedef unsigned long size_t;
|
||||
typedef long long ssize_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
|
||||
namespace Util {
|
||||
|
||||
using size_t = Genode::size_t;
|
||||
using uint8_t = Genode::uint8_t;
|
||||
|
||||
size_t next_char(char const *s, size_t start, char const c)
|
||||
{
|
||||
size_t v = start;
|
||||
while (s[v]) {
|
||||
if (s[v] == c) { break; }
|
||||
v++;
|
||||
}
|
||||
return v - start;
|
||||
}
|
||||
|
||||
bool string_contains(char const *str, char const *pattern)
|
||||
{
|
||||
char const *p = pattern;
|
||||
while (*str && *p) {
|
||||
p = *str == *p ? p + 1 : pattern;
|
||||
str++;
|
||||
}
|
||||
return !*p;
|
||||
}
|
||||
|
||||
void byte2hex(char *dest, uint8_t b)
|
||||
{
|
||||
int i = 1;
|
||||
if (b < 16) { dest[i--] = '0'; }
|
||||
|
||||
for (; b > 0; b /= 16) {
|
||||
uint8_t const v = b % 16;
|
||||
uint8_t const c = (v > 9) ? v + 'a' - 10 : v + '0';
|
||||
dest[i--] = (char)c;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************
|
||||
** Front end specific utilities **
|
||||
**********************************/
|
||||
|
||||
inline unsigned approximate_quality(char const *str)
|
||||
{
|
||||
long level = 0;
|
||||
Genode::ascii_to(str, level);
|
||||
|
||||
/*
|
||||
* We provide an quality value by transforming the actual
|
||||
* signal level [-50,-100] (dBm) to [100,0] (%).
|
||||
*/
|
||||
if (level <= -100) { return 0; }
|
||||
else if (level >= -50) { return 100; }
|
||||
|
||||
return 2 * (unsigned)(level + 100);
|
||||
}
|
||||
|
||||
inline Genode::uint64_t check_time(Genode::uint64_t value, Genode::uint64_t min, Genode::uint64_t max)
|
||||
{
|
||||
if (value < min) { return min; }
|
||||
else if (value > max) { return max; }
|
||||
return value;
|
||||
}
|
||||
|
||||
} /* namespace Util */
|
||||
|
||||
#endif /* _WIFI__UTIL_H_ */
|
57
repos/pc/src/drivers/wifi/pc/wpa.cc
Normal file
57
repos/pc/src/drivers/wifi/pc/wpa.cc
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* \brief Wpa_supplicant thread of the wifi driver
|
||||
* \author Josef Soentgen
|
||||
* \author Christian Helmuth
|
||||
* \date 2019-12-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/blockade.h>
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wpa.h"
|
||||
|
||||
|
||||
/* entry function */
|
||||
extern "C" int wpa_main(void);
|
||||
|
||||
|
||||
void * Wpa_thread::_entry_trampoline(void *arg)
|
||||
{
|
||||
Wpa_thread *t = (Wpa_thread *)arg;
|
||||
t->_entry();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void Wpa_thread::_entry()
|
||||
{
|
||||
/* wait until the wifi driver is up and running */
|
||||
_blockade.block();
|
||||
_exit = wpa_main();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
Wpa_thread::Wpa_thread(Genode::Env &env, Genode::Blockade &blockade)
|
||||
: _blockade(blockade), _exit(-1)
|
||||
{
|
||||
pthread_t tid = 0;
|
||||
if (pthread_create(&tid, 0, _entry_trampoline, this) != 0) {
|
||||
printf("Error: pthread_create() failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
39
repos/pc/src/drivers/wifi/pc/wpa.h
Normal file
39
repos/pc/src/drivers/wifi/pc/wpa.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* \brief Wpa_supplicant thread of the wifi driver
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-03-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WIFI__WPA_H_
|
||||
#define _WIFI__WPA_H_
|
||||
|
||||
|
||||
namespace Genode {
|
||||
struct Env;
|
||||
struct Blockade;
|
||||
}
|
||||
|
||||
class Wpa_thread
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Blockade &_blockade;
|
||||
int _exit;
|
||||
|
||||
static void * _entry_trampoline(void *arg);
|
||||
|
||||
void _entry();
|
||||
|
||||
public:
|
||||
|
||||
Wpa_thread(Genode::Env &, Genode::Blockade &);
|
||||
};
|
||||
|
||||
#endif /* _WIFI__WPA_H_ */
|
1
repos/pc/src/lib/vfs/wifi/target.mk
Normal file
1
repos/pc/src/lib/vfs/wifi/target.mk
Normal file
@ -0,0 +1 @@
|
||||
LIBS := vfs_wifi
|
87
repos/pc/src/lib/vfs/wifi/vfs.cc
Normal file
87
repos/pc/src/lib/vfs/wifi/vfs.cc
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* \brief Minimal VFS plugin for bringing up WLAN driver
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-20
|
||||
*
|
||||
* The sole purpose of this VFS plugin is to call 'Lx_kit::initialize_env'
|
||||
* at the right time before 'env.exec_static_constructors' is executed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/vfs.h>
|
||||
#include <vfs/single_file_system.h>
|
||||
|
||||
/* DDE Linux includes */
|
||||
#include <lx_kit/init.h>
|
||||
|
||||
|
||||
namespace Vfs_wlan
|
||||
{
|
||||
using namespace Vfs;
|
||||
using namespace Genode;
|
||||
|
||||
struct File_system;
|
||||
}
|
||||
|
||||
struct Vfs_wlan::File_system : Single_file_system
|
||||
{
|
||||
|
||||
File_system(Vfs::Env &env, Xml_node config)
|
||||
:
|
||||
Single_file_system { Vfs::Node_type::CONTINUOUS_FILE, name(),
|
||||
Vfs::Node_rwx::ro(), config }
|
||||
{
|
||||
/*
|
||||
* Various ports of a DDE Linux based library rely on the
|
||||
* 'env' being set before any static constructor is executed.
|
||||
* So we set it here and wait for the user of the library to
|
||||
* execute the constructors at the proper time.
|
||||
*/
|
||||
|
||||
Lx_kit::initialize(env.env());
|
||||
}
|
||||
|
||||
Open_result open(char const *, unsigned,
|
||||
Vfs::Vfs_handle **,
|
||||
Allocator &) override
|
||||
{
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
}
|
||||
|
||||
Stat_result stat(char const *, Stat &) override
|
||||
{
|
||||
return STAT_ERR_NO_ENTRY;
|
||||
}
|
||||
|
||||
static char const *name() { return "wlan"; }
|
||||
char const *type() override { return name(); }
|
||||
};
|
||||
|
||||
|
||||
/**************************
|
||||
** VFS plugin interface **
|
||||
**************************/
|
||||
|
||||
extern "C" Vfs::File_system_factory *vfs_file_system_factory(void)
|
||||
{
|
||||
struct Factory : Vfs::File_system_factory
|
||||
{
|
||||
Vfs::File_system *create(Vfs::Env &vfs_env,
|
||||
Genode::Xml_node node) override
|
||||
{
|
||||
static Vfs::File_system *fs =
|
||||
new (vfs_env.alloc()) Vfs_wlan::File_system(vfs_env, node);
|
||||
return fs;
|
||||
}
|
||||
};
|
||||
|
||||
static Factory factory;
|
||||
return &factory;
|
||||
}
|
798
repos/pc/src/lib/wifi/dummies.c
Normal file
798
repos/pc/src/lib/wifi/dummies.c
Normal file
@ -0,0 +1,798 @@
|
||||
/*
|
||||
* \brief Dummy definitions of Linux Kernel functions - handled manually
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <linux/cpuhotplug.h>
|
||||
|
||||
int __cpuhp_setup_state(enum cpuhp_state state,const char * name,bool invoke,int (* startup)(unsigned int cpu),int (* teardown)(unsigned int cpu),bool multi_instance)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/timekeeper_internal.h>
|
||||
|
||||
void update_vsyscall(struct timekeeper * tk)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
void clocksource_arch_init(struct clocksource * cs)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
void ignore_signals(struct task_struct * t)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched/loadavg.h>
|
||||
|
||||
void calc_global_load(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kernel_stat.h>
|
||||
|
||||
void account_process_tick(struct task_struct * p,int user_tick)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
void rcu_sched_clock_irq(int user)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_bin_file(struct kobject * kobj,const struct bin_attribute * attr)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_file_ns(struct kobject * kobj,const struct attribute * attr,const void * ns)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_groups(struct kobject * kobj,const struct attribute_group ** groups)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_group(struct kobject * kobj,const struct attribute_group * grp)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_link(struct kobject * kobj,struct kobject * target,const char * name)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
void sysfs_remove_link(struct kobject * kobj,const char * name)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
void sysfs_remove_file_ns(struct kobject * kobj,const struct attribute * attr,const void * ns)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
void sysfs_remove_groups(struct kobject * kobj,const struct attribute_group ** groups)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
void sysfs_remove_dir(struct kobject * kobj)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
void sysfs_remove_bin_file(struct kobject * kobj,const struct bin_attribute * attr)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kernfs.h>
|
||||
|
||||
void kernfs_get(struct kernfs_node * kn)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kernfs.h>
|
||||
|
||||
void kernfs_put(struct kernfs_node * kn)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_uevent(struct kobject * kobj,enum kobject_action action)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
int add_random_ready_callback(struct random_ready_callback * rdy)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
void add_device_randomness(const void * buf,unsigned int size)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
void add_interrupt_randomness(int irq,int irq_flags)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern bool irq_wait_for_poll(struct irq_desc * desc);
|
||||
bool irq_wait_for_poll(struct irq_desc * desc)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/irq.h>
|
||||
|
||||
void note_interrupt(struct irq_desc * desc,irqreturn_t action_ret)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
int __register_chrdev(unsigned int major,unsigned int baseminor,unsigned int count,const char * name,const struct file_operations * fops)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
int register_chrdev_region(dev_t from,unsigned count,const char * name)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern void register_handler_proc(unsigned int irq,struct irqaction * action);
|
||||
void register_handler_proc(unsigned int irq,struct irqaction * action)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void register_irq_proc(unsigned int irq,struct irq_desc * desc);
|
||||
void register_irq_proc(unsigned int irq,struct irq_desc * desc)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cdev.h>
|
||||
|
||||
void cdev_init(struct cdev * cdev,const struct file_operations * fops)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cdev.h>
|
||||
|
||||
int cdev_add(struct cdev * p,dev_t dev,unsigned count)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cdev.h>
|
||||
|
||||
void cdev_del(struct cdev * p)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
void register_syscore_ops(struct syscore_ops * ops)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
struct proc_dir_entry { int dummy; };
|
||||
|
||||
struct proc_dir_entry * proc_create_seq_private(const char * name,umode_t mode,struct proc_dir_entry * parent,const struct seq_operations * ops,unsigned int state_size,void * data)
|
||||
{
|
||||
static struct proc_dir_entry ret;
|
||||
lx_emul_trace(__func__);
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/property.h>
|
||||
|
||||
int software_node_notify(struct device * dev,unsigned long action)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/user_namespace.h>
|
||||
|
||||
struct user_namespace init_user_ns;
|
||||
|
||||
struct uts_namespace init_uts_ns;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* linux/seq_file.h depends on user_namespace being defined, add
|
||||
* all dummies pulling in this header below here
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
void seq_vprintf(struct seq_file * m,const char * f,va_list args)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vt_kern.h>
|
||||
|
||||
void unblank_screen(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void pci_allocate_vc_save_buffers(struct pci_dev * dev);
|
||||
void pci_allocate_vc_save_buffers(struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void pci_vpd_init(struct pci_dev * dev);
|
||||
void pci_vpd_init(struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int pci_proc_attach_device(struct pci_dev * dev);
|
||||
int pci_proc_attach_device(struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
bool parse_option_str(const char * str,const char * option)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
extern bool pat_enabled(void);
|
||||
bool pat_enabled(void)
|
||||
{
|
||||
// XXX pat_enabled necessary?
|
||||
lx_emul_trace(__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
bool is_vmalloc_addr(const void * x)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)];
|
||||
|
||||
|
||||
extern int pci_dev_specific_acs_enabled(struct pci_dev * dev,u16 acs_flags);
|
||||
int pci_dev_specific_acs_enabled(struct pci_dev * dev,u16 acs_flags)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int pci_dev_specific_disable_acs_redir(struct pci_dev * dev);
|
||||
int pci_dev_specific_disable_acs_redir(struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int pci_dev_specific_enable_acs(struct pci_dev * dev);
|
||||
int pci_dev_specific_enable_acs(struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int pci_dev_specific_reset(struct pci_dev * dev,int probe);
|
||||
int pci_dev_specific_reset(struct pci_dev * dev,int probe)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
void pci_fixup_device(enum pci_fixup_pass pass,struct pci_dev * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
int pci_disable_link_state(struct pci_dev * pdev,int state)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const unsigned long module_cert_size = 0;
|
||||
const u8 system_certificate_list[] = { };
|
||||
const unsigned long system_certificate_list_size = sizeof (system_certificate_list);
|
||||
|
||||
const u8 shipped_regdb_certs[] = { };
|
||||
unsigned int shipped_regdb_certs_len = sizeof (shipped_regdb_certs);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Generate_dummies.c will otherwise pull in <linux/rcutree.h>
|
||||
* that clashes with rcutiny.h.
|
||||
*/
|
||||
void rcu_barrier(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
#include <linux/jump_label.h> /* for DEFINE_STATIC_KEY_FALSE */
|
||||
|
||||
void bpf_prog_change_xdp(struct bpf_prog *prev_prog, struct bpf_prog *prog)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
|
||||
|
||||
|
||||
asmlinkage __wsum csum_partial(const void * buff,int len,__wsum sum)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
struct static_key_false init_on_alloc;
|
||||
|
||||
|
||||
#include <linux/proc_ns.h>
|
||||
|
||||
int proc_alloc_inum(unsigned int * inum)
|
||||
{
|
||||
*inum = 1; /* according to linux/proc_ns.h without CONFIG_PROC_FS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
__init int net_sysctl_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
struct proc_dir_entry * proc_create_net_data(const char * name,umode_t mode,struct proc_dir_entry * parent,const struct seq_operations * ops,unsigned int state_size,void * data)
|
||||
{
|
||||
static struct proc_dir_entry _proc_dir_entry;
|
||||
lx_emul_trace(__func__);
|
||||
return &_proc_dir_entry;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
unsigned int get_next_ino(void)
|
||||
{
|
||||
static unsigned int count = 0;
|
||||
return ++count;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
int __init dev_proc_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/stringhash.h>
|
||||
|
||||
unsigned int full_name_hash(const void * salt,const char * name,unsigned int len)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/key.h>
|
||||
|
||||
static struct key _key;
|
||||
|
||||
struct key * keyring_alloc(const char * description,kuid_t uid,kgid_t gid,const struct cred * cred,key_perm_t perm,unsigned long flags,struct key_restriction * restrict_link,struct key * dest)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return &_key;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * envp_ext[])
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
void sched_set_fifo(struct task_struct * p)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
void kernel_param_lock(struct module * mod)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
void kernel_param_unlock(struct module * mod)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
unsigned long lpj_fine = 0;
|
||||
|
||||
|
||||
#include <linux/pid.h>
|
||||
|
||||
void put_pid(struct pid * pid)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
int sk_filter_trim_cap(struct sock * sk,struct sk_buff * skb,unsigned int cap)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/capability.h>
|
||||
|
||||
bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
void synchronize_rcu(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
void __skb_get_hash(struct sk_buff * skb)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
bool __skb_flow_dissect(const struct net * net,const struct sk_buff * skb,struct flow_dissector * flow_dissector,void * target_container,const void * data,__be16 proto,int nhoff,int hlen,unsigned int flags)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pid.h>
|
||||
|
||||
pid_t pid_vnr(struct pid * pid)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/verification.h>
|
||||
|
||||
int verify_pkcs7_signature(const void *data, size_t len,
|
||||
const void *raw_pkcs7, size_t pkcs7_len,
|
||||
struct key *trusted_keys,
|
||||
enum key_being_used_for usage,
|
||||
int (*view_content)(void *ctx,
|
||||
const void *data, size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpixf.h>
|
||||
|
||||
int acpi_device_modalias(struct device *d, char * s, int i)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
int acpi_device_uevent_modalias(struct device *d, struct kobj_uevent_env *k)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
int acpi_dma_configure_id(struct device *dev,
|
||||
enum dev_dma_attr attr,
|
||||
const u32 *input_id)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
bool acpi_driver_match_device(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid,
|
||||
u64 rev, u64 func, union acpi_object *argv4)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
acpi_status acpi_evaluate_object(acpi_handle handle,
|
||||
acpi_string pathname,
|
||||
struct acpi_object_list *external_params,
|
||||
struct acpi_buffer *return_buffer)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
acpi_status acpi_get_handle(acpi_handle parent,acpi_string pathname,acpi_handle * ret_handle)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
int acpi_platform_notify(struct device *dev, enum kobject_action action)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool is_acpi_device_node(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
const struct attribute_group pci_dev_acpi_attr_group;
|
||||
|
||||
int pci_acpi_program_hp_params(struct pci_dev *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool pciehp_is_native(struct pci_dev *bridge)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/thermal.h>
|
||||
|
||||
struct thermal_cooling_device *thermal_cooling_device_register(const char *s,
|
||||
void *p, const struct thermal_cooling_device_ops *op)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
|
||||
void thermal_cooling_device_unregister(struct thermal_cooling_device *tcd)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
int thermal_zone_device_enable(struct thermal_zone_device *tz)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *s, int i, int j,
|
||||
void *p, struct thermal_zone_device_ops *ops,
|
||||
struct thermal_zone_params *params, int x, int y)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
|
||||
void thermal_zone_device_unregister(struct thermal_zone_device *tzd)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
void thermal_zone_device_update(struct thermal_zone_device *tzd,
|
||||
enum thermal_notify_event e)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/net.h>
|
||||
|
||||
int net_ratelimit(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
/* suppress */
|
||||
return 0;
|
||||
}
|
106
repos/pc/src/lib/wifi/firmware.cc
Normal file
106
repos/pc/src/lib/wifi/firmware.cc
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* \brief Linux wireless stack
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-06-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <lx_kit/env.h>
|
||||
#include <firmware_list.h>
|
||||
|
||||
|
||||
Firmware_list fw_list[] = {
|
||||
{ "regulatory.db", 4144, nullptr },
|
||||
{ "regulatory.db.p7s", 1182, nullptr },
|
||||
|
||||
{ "iwlwifi-1000-5.ucode", 337520, nullptr },
|
||||
{ "iwlwifi-3160-17.ucode", 918268, nullptr },
|
||||
{ "iwlwifi-5000-5.ucode", 340696, nullptr },
|
||||
{ "iwlwifi-6000-4.ucode", 454608, nullptr },
|
||||
{ "iwlwifi-6000-6.ucode", 454608, "iwlwifi-6000-4.ucode" },
|
||||
{ "iwlwifi-6000g2a-6.ucode", 677296, nullptr },
|
||||
{ "iwlwifi-6000g2b-6.ucode", 679436, nullptr },
|
||||
{ "iwlwifi-7260-17.ucode", 1049340, nullptr },
|
||||
{ "iwlwifi-7265-16.ucode", 1180412, nullptr },
|
||||
{ "iwlwifi-7265D-29.ucode", 1036772, nullptr },
|
||||
{ "iwlwifi-8000C-22.ucode", 2120860, nullptr },
|
||||
{ "iwlwifi-8000C-36.ucode", 2428004, nullptr },
|
||||
{ "iwlwifi-8265-22.ucode", 1811984, nullptr },
|
||||
{ "iwlwifi-8265-36.ucode", 2436632, nullptr },
|
||||
|
||||
{ "iwlwifi-9000-pu-b0-jf-b0-34.ucode", 2678284, nullptr },
|
||||
{ "iwlwifi-9000-pu-b0-jf-b0-36.ucode", 2678284, "iwlwifi-9000-pu-b0-jf-b0-34.ucode" },
|
||||
{ "iwlwifi-9000-pu-b0-jf-b0-46.ucode", 1514876, nullptr },
|
||||
|
||||
{ "iwlwifi-QuZ-a0-hr-b0-63.ucode", 1334804, nullptr },
|
||||
{ "iwlwifi-QuZ-a0-hr-b0-64.ucode", 1334804, "iwlwifi-QuZ-a0-hr-b0-63.ucode" },
|
||||
};
|
||||
|
||||
|
||||
size_t fw_list_len = sizeof(fw_list) / sizeof(fw_list[0]);
|
||||
|
||||
|
||||
/**********************
|
||||
** linux/firmware.h **
|
||||
**********************/
|
||||
|
||||
extern "C" int lx_emul_request_firmware_nowait(const char *name, void **dest, size_t *result)
|
||||
{
|
||||
if (!dest || !result)
|
||||
return -1;
|
||||
|
||||
/* only try to load known firmware images */
|
||||
Firmware_list *fwl = 0;
|
||||
for (size_t i = 0; i < fw_list_len; i++) {
|
||||
if (Genode::strcmp(name, fw_list[i].requested_name) == 0) {
|
||||
fwl = &fw_list[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fwl) {
|
||||
Genode::error("firmware '", name, "' is not in the firmware white list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char const *fw_name = fwl->available_name
|
||||
? fwl->available_name : fwl->requested_name;
|
||||
Genode::Rom_connection rom(Lx_kit::env().env, fw_name);
|
||||
Genode::Dataspace_capability ds_cap = rom.dataspace();
|
||||
|
||||
if (!ds_cap.valid()) {
|
||||
Genode::error("could not get firmware ROM dataspace");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* use allocator because fw is too big for slab */
|
||||
void *data = Lx_kit::env().heap.alloc(fwl->size);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
void const *image = Lx_kit::env().env.rm().attach(ds_cap);
|
||||
Genode::memcpy(data, image, fwl->size);
|
||||
Lx_kit::env().env.rm().detach(image);
|
||||
|
||||
*dest = data;
|
||||
*result = fwl->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void lx_emul_release_firmware(void const *data, size_t size)
|
||||
{
|
||||
Lx_kit::env().heap.free(const_cast<void *>(data), size);
|
||||
}
|
26
repos/pc/src/lib/wifi/firmware_list.h
Normal file
26
repos/pc/src/lib/wifi/firmware_list.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief List for firmware images and their sizes
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-03-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _FIRMWARE_LIST_H_
|
||||
#define _FIRMWARE_LIST_H_
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
struct Firmware_list
|
||||
{
|
||||
char const *requested_name;
|
||||
size_t size;
|
||||
char const *available_name;
|
||||
};
|
||||
|
||||
#endif /* _FIRMWARE_LIST_H_ */
|
1346
repos/pc/src/lib/wifi/generated_dummies.c
Normal file
1346
repos/pc/src/lib/wifi/generated_dummies.c
Normal file
File diff suppressed because it is too large
Load Diff
109
repos/pc/src/lib/wifi/libc_errno.h
Normal file
109
repos/pc/src/lib/wifi/libc_errno.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* \brief Libc errno values
|
||||
* \date 2022-03-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WLAN__LIBC_ERRNO_H_
|
||||
#define _WLAN__LIBC_ERRNO_H_
|
||||
|
||||
/* Linux errno values */
|
||||
#include <uapi/asm-generic/errno.h>
|
||||
|
||||
namespace Libc {
|
||||
|
||||
enum class Errno : int {
|
||||
/*
|
||||
* The following numbers correspond to the FreeBSD errno values
|
||||
*/
|
||||
BSD_EPERM = 1,
|
||||
BSD_ENOENT = 2,
|
||||
BSD_ESRCH = 3,
|
||||
BSD_EINTR = 4,
|
||||
BSD_EIO = 5,
|
||||
BSD_ENXIO = 6,
|
||||
BSD_E2BIG = 7,
|
||||
BSD_ENOEXEC = 8,
|
||||
BSD_EBADF = 9,
|
||||
BSD_EDEADLK = 11,
|
||||
BSD_ENOMEM = 12,
|
||||
BSD_EACCES = 13,
|
||||
BSD_EFAULT = 14,
|
||||
BSD_EBUSY = 16,
|
||||
BSD_EEXIST = 17,
|
||||
BSD_EXDEV = 18,
|
||||
BSD_ENODEV = 19,
|
||||
BSD_EINVAL = 22,
|
||||
BSD_ENFILE = 23,
|
||||
BSD_ENOTTY = 25,
|
||||
BSD_EFBIG = 27,
|
||||
BSD_ENOSPC = 28,
|
||||
BSD_ESPIPE = 29,
|
||||
BSD_EPIPE = 32,
|
||||
BSD_EDOM = 33,
|
||||
BSD_ERANGE = 34,
|
||||
BSD_EAGAIN = 35,
|
||||
BSD_EINPROGRESS = 36,
|
||||
BSD_EALREADY = 37,
|
||||
BSD_ENOTSOCK = 38,
|
||||
BSD_EDESTADDRREQ = 39,
|
||||
BSD_EMSGSIZE = 40,
|
||||
BSD_ENOPROTOOPT = 42,
|
||||
BSD_EPROTONOSUPPORT = 43,
|
||||
BSD_ESOCKTNOSUPPORT = 44,
|
||||
BSD_EOPNOTSUPP = 45,
|
||||
BSD_EPFNOSUPPORT = 46,
|
||||
BSD_EAFNOSUPPORT = 47,
|
||||
BSD_EADDRINUSE = 48,
|
||||
BSD_EADDRNOTAVAIL = 49,
|
||||
BSD_ENETDOWN = 50,
|
||||
BSD_ENETUNREACH = 51,
|
||||
BSD_ECONNABORTED = 53,
|
||||
BSD_ECONNRESET = 54,
|
||||
BSD_ENOBUFS = 55,
|
||||
BSD_EISCONN = 56,
|
||||
BSD_ENOTCONN = 57,
|
||||
BSD_ETIMEDOUT = 60,
|
||||
BSD_ECONNREFUSED = 61,
|
||||
BSD_ENAMETOOLONG = 63,
|
||||
BSD_EHOSTDOWN = 64,
|
||||
BSD_EHOSTUNREACH = 65,
|
||||
BSD_ENOSYS = 78,
|
||||
BSD_ENOMSG = 83,
|
||||
BSD_EOVERFLOW = 84,
|
||||
BSD_ECANCELED = 85,
|
||||
BSD_EILSEQ = 86,
|
||||
BSD_EBADMSG = 89,
|
||||
BSD_ENOLINK = 91,
|
||||
BSD_EPROTO = 92,
|
||||
|
||||
/*
|
||||
* The following numbers correspond to nothing
|
||||
*/
|
||||
BSD_EREMOTEIO = 200,
|
||||
BSD_ERESTARTSYS = 201,
|
||||
BSD_ENODATA = 202,
|
||||
BSD_ETOOSMALL = 203,
|
||||
BSD_ENOIOCTLCMD = 204,
|
||||
BSD_ENONET = 205,
|
||||
BSD_ENOTSUPP = 206,
|
||||
BSD_ENOTUNIQ = 207,
|
||||
BSD_ERFKILL = 208,
|
||||
BSD_ETIME = 209,
|
||||
BSD_EPROBE_DEFER = 210,
|
||||
|
||||
BSD_EL3RST = 211,
|
||||
BSD_ENOKEY = 212,
|
||||
BSD_ECHRNG = 213,
|
||||
|
||||
MAX_ERRNO = 4095,
|
||||
};
|
||||
} /* namespace Libc */
|
||||
|
||||
#endif /* _WLAN__LIBC_ERRNO_H_ */
|
765
repos/pc/src/lib/wifi/lx_emul.c
Normal file
765
repos/pc/src/lib/wifi/lx_emul.c
Normal file
@ -0,0 +1,765 @@
|
||||
/*
|
||||
* \brief Linux emulation environment specific to this driver
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <lx_emul/alloc.h>
|
||||
#include <lx_emul/io_mem.h>
|
||||
|
||||
|
||||
#include <asm-generic/delay.h>
|
||||
|
||||
void __const_udelay(unsigned long xloops)
|
||||
{
|
||||
lx_emul_time_udelay(xloops / 0x10C7UL);
|
||||
}
|
||||
|
||||
|
||||
void __udelay(unsigned long usecs)
|
||||
{
|
||||
lx_emul_time_udelay(usecs);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
atomic_t __num_online_cpus = ATOMIC_INIT(1);
|
||||
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
dma_addr_t dma_map_page_attrs(struct device * dev,
|
||||
struct page * page,
|
||||
size_t offset,
|
||||
size_t size,
|
||||
enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
{
|
||||
dma_addr_t const dma_addr = page_to_phys(page);
|
||||
unsigned long const virt_addr = (unsigned long)page_to_virt(page);
|
||||
|
||||
lx_emul_mem_cache_clean_invalidate((void *)(virt_addr + offset), size);
|
||||
return dma_addr + offset;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dmapool.h>
|
||||
|
||||
struct dma_pool {
|
||||
size_t size;
|
||||
size_t align;
|
||||
};
|
||||
|
||||
void * dma_pool_alloc(struct dma_pool * pool, gfp_t mem_flags, dma_addr_t * handle)
|
||||
{
|
||||
void * ret =
|
||||
lx_emul_mem_alloc_aligned_uncached(pool->size, pool->align);
|
||||
*handle = lx_emul_mem_dma_addr(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct dma_pool * dma_pool_create(const char * name,
|
||||
struct device * dev,
|
||||
size_t size,
|
||||
size_t align,
|
||||
size_t boundary)
|
||||
{
|
||||
struct dma_pool * pool = kmalloc(sizeof(struct dma_pool), GFP_KERNEL);
|
||||
pool->size = size;
|
||||
pool->align = align;
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
void dma_pool_free(struct dma_pool * pool,void * vaddr,dma_addr_t dma)
|
||||
{
|
||||
lx_emul_mem_free(vaddr);
|
||||
}
|
||||
|
||||
|
||||
struct dma_pool *dmam_pool_create(const char *name,
|
||||
struct device *dev,
|
||||
size_t size,
|
||||
size_t align,
|
||||
size_t allocation)
|
||||
{
|
||||
/*
|
||||
* Only take care of allocating the pool because
|
||||
* we do not detach the driver anyway.
|
||||
*/
|
||||
return dma_pool_create(name, dev, size, align, 0);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
int dma_supported(struct device * dev,u64 mask)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
void dma_unmap_page_attrs(struct device * dev,
|
||||
dma_addr_t addr,
|
||||
size_t size,
|
||||
enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
{
|
||||
unsigned long const virt_addr = lx_emul_mem_virt_addr((void*)addr);
|
||||
|
||||
if (!virt_addr)
|
||||
return;
|
||||
|
||||
if (dir == DMA_FROM_DEVICE)
|
||||
lx_emul_mem_cache_invalidate((void *)virt_addr, size);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
unsigned long const virt_addr = lx_emul_mem_virt_addr((void*)addr);
|
||||
|
||||
if (!virt_addr)
|
||||
return;
|
||||
|
||||
lx_emul_mem_cache_invalidate((void *)virt_addr, size);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
void dma_sync_single_for_device(struct device *dev, dma_addr_t addr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
unsigned long const virt_addr = lx_emul_mem_virt_addr((void*)addr);
|
||||
|
||||
if (!virt_addr)
|
||||
return;
|
||||
|
||||
lx_emul_mem_cache_clean_invalidate((void *)virt_addr, size);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void * kmalloc_order(size_t size, gfp_t flags, unsigned int order)
|
||||
{
|
||||
return kmalloc(size, flags);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
int simple_pin_fs(struct file_system_type * type, struct vfsmount ** mount, int * count)
|
||||
{
|
||||
*mount = kmalloc(sizeof(struct vfsmount), GFP_KERNEL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
void simple_release_fs(struct vfsmount ** mount,int * count)
|
||||
{
|
||||
kfree(*mount);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
struct inode * alloc_anon_inode(struct super_block * s)
|
||||
{
|
||||
return kmalloc(sizeof(struct inode), GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
// softirq.c
|
||||
void tasklet_setup(struct tasklet_struct * t,
|
||||
void (* callback)(struct tasklet_struct *))
|
||||
{
|
||||
t->next = NULL;
|
||||
t->state = 0;
|
||||
atomic_set(&t->count, 0);
|
||||
t->callback = callback;
|
||||
t->use_callback = true;
|
||||
t->data = 0;
|
||||
}
|
||||
|
||||
|
||||
void __tasklet_schedule(struct tasklet_struct * t)
|
||||
{
|
||||
if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
|
||||
t->callback(t);
|
||||
}
|
||||
|
||||
|
||||
void __tasklet_hi_schedule(struct tasklet_struct * t)
|
||||
{
|
||||
if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
|
||||
t->callback(t);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
void call_rcu(struct rcu_head * head,rcu_callback_t func)
|
||||
{
|
||||
enum { KVFREE_RCU_OFFSET = 4096, };
|
||||
if (func < (rcu_callback_t)KVFREE_RCU_OFFSET) {
|
||||
kvfree((void*)head - (unsigned long)func);
|
||||
return;
|
||||
}
|
||||
|
||||
func(head);
|
||||
}
|
||||
|
||||
|
||||
#include <asm-generic/logic_io.h>
|
||||
|
||||
void __iomem * ioremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return lx_emul_io_mem_map(phys_addr, size);
|
||||
}
|
||||
|
||||
|
||||
#include <asm-generic/logic_io.h>
|
||||
|
||||
void iounmap(volatile void __iomem * addr)
|
||||
{
|
||||
(void)addr;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
struct kmem_cache * kmem_cache_create_usercopy(const char * name,
|
||||
unsigned int size,
|
||||
unsigned int align,
|
||||
slab_flags_t flags,
|
||||
unsigned int useroffset,
|
||||
unsigned int usersize,
|
||||
void (* ctor)(void *))
|
||||
{
|
||||
return kmem_cache_create(name, size, align, flags, ctor);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
int register_filesystem(struct file_system_type * fs)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs_context.h>
|
||||
#include <linux/pseudo_fs.h>
|
||||
|
||||
struct pseudo_fs_context * init_pseudo(struct fs_context *fc,
|
||||
unsigned long magic)
|
||||
{
|
||||
struct pseudo_fs_context *pfs_ctx;
|
||||
|
||||
pfs_ctx = kzalloc(sizeof (struct pseudo_fs_context), GFP_KERNEL);
|
||||
if (pfs_ctx) {
|
||||
pfs_ctx->magic = magic;
|
||||
fc->fs_private = pfs_ctx;
|
||||
}
|
||||
return pfs_ctx;
|
||||
}
|
||||
|
||||
|
||||
struct vfsmount * kern_mount(struct file_system_type * type)
|
||||
{
|
||||
struct vfsmount *m;
|
||||
|
||||
/*
|
||||
* This sets everything up so that 'new_inode_pseudo()'
|
||||
* called from 'sock_alloc()' properly allocates the inode.
|
||||
*/
|
||||
|
||||
m = kzalloc(sizeof (struct vfsmount), 0);
|
||||
if (m) {
|
||||
|
||||
struct fs_context fs_ctx;
|
||||
|
||||
if (type->init_fs_context) {
|
||||
type->init_fs_context(&fs_ctx);
|
||||
|
||||
m->mnt_sb = kzalloc(sizeof (struct super_block), GFP_KERNEL);
|
||||
m->mnt_sb->s_type = type;
|
||||
m->mnt_sb->s_op =
|
||||
((struct pseudo_fs_context*)fs_ctx.fs_private)->ops;
|
||||
} else {
|
||||
kfree(m);
|
||||
m = (struct vfsmount*)ERR_PTR(-ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
struct inode * new_inode_pseudo(struct super_block * sb)
|
||||
{
|
||||
const struct super_operations *ops = sb->s_op;
|
||||
struct inode *inode;
|
||||
|
||||
if (ops->alloc_inode) {
|
||||
inode = ops->alloc_inode(sb);
|
||||
}
|
||||
|
||||
if (!inode)
|
||||
return (struct inode*)ERR_PTR(-ENOMEM);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
int sysfs_create_dir_ns(struct kobject * kobj,const void * ns)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
kobj->sd = kzalloc(sizeof(*kobj->sd), GFP_KERNEL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#if 0
|
||||
struct firmware_work {
|
||||
struct work_struct work;
|
||||
struct firmware const *firmware;
|
||||
void *context;
|
||||
void (*cont)(struct firmware const *, void *);
|
||||
};
|
||||
|
||||
|
||||
static void request_firmware_work_func(struct work_struct *work)
|
||||
{
|
||||
struct firmware_work *fw_work =
|
||||
container_of(work, struct firmware_work, work);
|
||||
|
||||
fw_work->cont(fw_work->firmware, fw_work->context);
|
||||
|
||||
kfree(fw_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern int lx_emul_request_firmware_nowait(const char *name, void *dest, size_t *result);
|
||||
extern void lx_emul_release_firmware(void const *data, size_t size);
|
||||
|
||||
extern void rtnl_lock(void);
|
||||
extern void rtnl_unlock(void);
|
||||
|
||||
int request_firmware_nowait(struct module * module,
|
||||
bool uevent, const char * name,
|
||||
struct device * device, gfp_t gfp,
|
||||
void * context,
|
||||
void (* cont)(const struct firmware * fw,
|
||||
void * context))
|
||||
{
|
||||
struct firmware *fw = kzalloc(sizeof (struct firmware), GFP_KERNEL);
|
||||
#if 0
|
||||
struct firmware_work *fw_work;
|
||||
#endif
|
||||
bool reg_db;
|
||||
|
||||
if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size)) {
|
||||
kfree(fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normally we would schedule fw_work but for reasons not
|
||||
* yet understood doing so will lead to a page-fault. So
|
||||
* for the time being we will execute the callback directly
|
||||
* and we have to make sure to manage the RTNL lock as the
|
||||
* callback will grab it while we already hold it.
|
||||
*/
|
||||
reg_db = strcmp(name, "regulatory.db") == 0;
|
||||
|
||||
if (reg_db)
|
||||
rtnl_unlock();
|
||||
|
||||
cont(fw, context);
|
||||
|
||||
if (reg_db)
|
||||
rtnl_lock();
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
fw_work = kzalloc(sizeof (struct firmware_work), GFP_KERNEL);
|
||||
if (!fw_work) {
|
||||
kfree(fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fw_work->firmware = fw;
|
||||
fw_work->context = context;
|
||||
fw_work->cont = cont;
|
||||
|
||||
INIT_WORK(&fw_work->work, request_firmware_work_func);
|
||||
schedule_work(&fw_work->work);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int request_firmware(const struct firmware ** firmware_p,
|
||||
const char * name, struct device * device)
|
||||
{
|
||||
struct firmware *fw;
|
||||
|
||||
if (!*firmware_p)
|
||||
return -1;
|
||||
|
||||
fw = kzalloc(sizeof (struct firmware), GFP_KERNEL);
|
||||
|
||||
if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size)) {
|
||||
kfree(fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*firmware_p = fw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void release_firmware(const struct firmware * fw)
|
||||
{
|
||||
lx_emul_release_firmware(fw->data, fw->size);
|
||||
kfree(fw);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is only called when using newer WIFI6 devices to
|
||||
* load 'iwl-debug-yoyo.bin'. We simply deny the request.
|
||||
*/
|
||||
int firmware_request_nowarn(const struct firmware ** firmware,const char * name,struct device * device)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
int pcim_iomap_regions_request_all(struct pci_dev * pdev,int mask,const char * name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
static unsigned long *_pci_iomap_table;
|
||||
|
||||
void __iomem * const * pcim_iomap_table(struct pci_dev * pdev)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (!_pci_iomap_table)
|
||||
_pci_iomap_table = kzalloc(sizeof (unsigned long*) * 6, GFP_KERNEL);
|
||||
|
||||
if (!_pci_iomap_table)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
struct resource *r = &pdev->resource[i];
|
||||
unsigned long phys_addr = r->start;
|
||||
unsigned long size = r->end - r->start;
|
||||
|
||||
if (!phys_addr || !size)
|
||||
continue;
|
||||
|
||||
_pci_iomap_table[i] =
|
||||
(unsigned long)lx_emul_io_mem_map(phys_addr, size);
|
||||
}
|
||||
|
||||
return (void const *)_pci_iomap_table;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/task_work.h>
|
||||
|
||||
int task_work_add(struct task_struct * task,struct callback_head * work,enum task_work_notify_mode notify)
|
||||
{
|
||||
printk("%s: task: %p work: %p notify: %u\n", __func__, task, work, notify);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void vfree(const void * addr)
|
||||
{
|
||||
kfree(addr);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void * vmalloc(unsigned long size)
|
||||
{
|
||||
return kmalloc(size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void * vzalloc(unsigned long size)
|
||||
{
|
||||
return kzalloc(size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
void __raise_softirq_irqoff(unsigned int nr)
|
||||
{
|
||||
raise_softirq(nr);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void kfree_sensitive(const void *p)
|
||||
{
|
||||
size_t ks;
|
||||
void *mem = (void *)p;
|
||||
|
||||
ks = ksize(mem);
|
||||
if (ks)
|
||||
memset(mem, 0, ks);
|
||||
|
||||
kfree(mem);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
void free_pages(unsigned long addr,unsigned int order)
|
||||
{
|
||||
__free_pages(virt_to_page((void *)addr), order);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
unsigned long get_zeroed_page(gfp_t gfp_mask)
|
||||
{
|
||||
return (unsigned long)kzalloc(PAGE_SIZE, gfp_mask | __GFP_ZERO);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
pid_t __task_pid_nr_ns(struct task_struct * task,
|
||||
enum pid_type type,
|
||||
struct pid_namespace * ns)
|
||||
{
|
||||
(void)type;
|
||||
(void)ns;
|
||||
|
||||
return lx_emul_task_pid(task);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
unsigned long _copy_from_user(void * to, const void __user * from,
|
||||
unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uio.h>
|
||||
|
||||
size_t _copy_from_iter(void * addr, size_t bytes, struct iov_iter * i)
|
||||
{
|
||||
char *kdata;
|
||||
struct iovec const *iov;
|
||||
size_t len;
|
||||
|
||||
if (bytes > i->count)
|
||||
bytes = i->count;
|
||||
|
||||
if (bytes == 0)
|
||||
return 0;
|
||||
|
||||
kdata = (char*)(addr);
|
||||
iov = i->iov;
|
||||
|
||||
len = bytes;
|
||||
while (len > 0) {
|
||||
if (iov->iov_len) {
|
||||
size_t copy_len = (size_t)len < iov->iov_len ? len
|
||||
: iov->iov_len;
|
||||
memcpy(kdata, iov->iov_base, copy_len);
|
||||
|
||||
len -= copy_len;
|
||||
kdata += copy_len;
|
||||
}
|
||||
iov++;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uio.h>
|
||||
|
||||
size_t _copy_to_iter(const void * addr, size_t bytes, struct iov_iter * i)
|
||||
{
|
||||
char *kdata;
|
||||
struct iovec const *iov;
|
||||
size_t len;
|
||||
|
||||
if (bytes > i->count)
|
||||
bytes = i->count;
|
||||
|
||||
if (bytes == 0)
|
||||
return 0;
|
||||
|
||||
kdata = (char*)(addr);
|
||||
iov = i->iov;
|
||||
|
||||
len = bytes;
|
||||
while (len > 0) {
|
||||
if (iov->iov_len) {
|
||||
size_t copy_len = (size_t)len < iov->iov_len ? len
|
||||
: iov->iov_len;
|
||||
memcpy(iov->iov_base, kdata, copy_len);
|
||||
|
||||
len -= copy_len;
|
||||
kdata += copy_len;
|
||||
}
|
||||
iov++;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
asmlinkage __visible void dump_stack(void)
|
||||
{
|
||||
lx_backtrace();
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
void __put_page(struct page * page)
|
||||
{
|
||||
__free_pages(page, 0);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
u32 get_random_u32(void)
|
||||
{
|
||||
return lx_emul_get_random_u32();
|
||||
}
|
||||
|
||||
|
||||
int __must_check get_random_bytes_arch(void *buf, int nbytes)
|
||||
{
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
|
||||
lx_emul_get_random_bytes(buf, (unsigned long)nbytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void get_random_bytes(void *buf, int nbytes)
|
||||
{
|
||||
get_random_bytes_arch(buf, nbytes);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/prandom.h>
|
||||
|
||||
void prandom_bytes(void *buf, size_t bytes)
|
||||
{
|
||||
lx_emul_get_random_bytes(buf, bytes);
|
||||
}
|
||||
|
||||
|
||||
u32 prandom_u32(void)
|
||||
{
|
||||
return lx_emul_get_random_u32();
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
void *page_frag_alloc_align(struct page_frag_cache *nc,
|
||||
unsigned int fragsz, gfp_t gfp_mask,
|
||||
unsigned int align_mask)
|
||||
{
|
||||
(void)nc;
|
||||
unsigned int const order = fragsz / PAGE_SIZE;
|
||||
struct page *page = __alloc_pages(gfp_mask, order, 0, NULL);
|
||||
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
/* see page_frag_free */
|
||||
if (order > 0)
|
||||
printk("%s: alloc might leak memory: fragsz: %u PAGE_SIZE: %u "
|
||||
"order: %u page: %p addr: %p\n", __func__, fragsz, PAGE_SIZE, order, page, page->virtual);
|
||||
|
||||
return page->virtual;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
void page_frag_free(void * addr)
|
||||
{
|
||||
struct page *page = lx_emul_virt_to_pages(addr, 1ul);
|
||||
if (!page) {
|
||||
printk("BUG %s: page for addr: %p not found\n", __func__, addr);
|
||||
lx_backtrace();
|
||||
}
|
||||
|
||||
__free_pages(page, 0ul);
|
||||
}
|
37
repos/pc/src/lib/wifi/lx_emul.h
Normal file
37
repos/pc/src/lib/wifi/lx_emul.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* \brief Dummy definitions of Linux Kernel functions
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-03-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Needed to trace and stop */
|
||||
#include <lx_emul/debug.h>
|
||||
|
||||
/* fix for wait_for_completion_timeout where the __sched include is missing */
|
||||
#include <linux/sched/debug.h>
|
||||
|
||||
/* fix for missing include in linux/dynamic_debug.h */
|
||||
#include <linux/compiler_attributes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lx_backtrace(void);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
208
repos/pc/src/lib/wifi/lx_emul/initcall_order.h
Normal file
208
repos/pc/src/lib/wifi/lx_emul/initcall_order.h
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* \brief Array defining order of Linux Kernel initcalls
|
||||
* \author Automatically generated file - do no edit
|
||||
* \date 2022-02-28
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
static const char * lx_emul_initcall_order[] = {
|
||||
"__initcall_init_hw_perf_eventsearly",
|
||||
"__initcall_start",
|
||||
"__initcall_init_real_modeearly",
|
||||
"__initcall_validate_x2apicearly",
|
||||
"__initcall_register_nmi_cpu_backtrace_handlerearly",
|
||||
"__initcall_spawn_ksoftirqdearly",
|
||||
"__initcall_static_call_initearly",
|
||||
"__initcall_init_zero_pfnearly",
|
||||
"__initcall_initialize_ptr_randomearly",
|
||||
"__initcall_init_mmap_min_addr0",
|
||||
"__initcall_pci_realloc_setup_params0",
|
||||
"__initcall_net_ns_init0",
|
||||
"__initcall_reboot_init1",
|
||||
"__initcall_wq_sysfs_init1",
|
||||
"__initcall_ksysfs_init1",
|
||||
"__initcall_rcu_set_runtime_mode1",
|
||||
"__initcall_init_jiffies_clocksource1",
|
||||
"__initcall_init_script_binfmt1",
|
||||
"__initcall_init_elf_binfmt1",
|
||||
"__initcall_prandom_init_early1",
|
||||
"__initcall_sock_init1",
|
||||
"__initcall_net_inuse_init1",
|
||||
"__initcall_net_defaults_init1",
|
||||
"__initcall_init_default_flow_dissectors1",
|
||||
"__initcall_netlink_proto_init1",
|
||||
"__initcall_genl_init1",
|
||||
"__initcall_irq_sysfs_init2",
|
||||
"__initcall_bdi_class_init2",
|
||||
"__initcall_mm_sysfs_init2",
|
||||
"__initcall_init_per_zone_wmark_min2",
|
||||
"__initcall_mpi_init2",
|
||||
"__initcall_pcibus_class_init2",
|
||||
"__initcall_pci_driver_init2",
|
||||
"__initcall_tty_class_init2",
|
||||
"__initcall_vtconsole_class_init2",
|
||||
"__initcall_devlink_class_init2",
|
||||
"__initcall_software_node_init2",
|
||||
"__initcall_amd_postcore_init2",
|
||||
"__initcall_kobject_uevent_init2",
|
||||
"__initcall_bts_init3",
|
||||
"__initcall_pt_init3",
|
||||
"__initcall_boot_params_ksysfs_init3",
|
||||
"__initcall_sbf_init3",
|
||||
"__initcall_arch_kdebugfs_init3",
|
||||
"__initcall_intel_pconfig_init3",
|
||||
"__initcall_cryptomgr_init3",
|
||||
"__initcall_pci_arch_init3",
|
||||
"__initcall_init_vdso4",
|
||||
"__initcall_fixup_ht_bug4",
|
||||
"__initcall_topology_init4",
|
||||
"__initcall_uid_cache_init4",
|
||||
"__initcall_param_sysfs_init4",
|
||||
"__initcall_user_namespace_sysctl_init4",
|
||||
"__initcall_oom_init4",
|
||||
"__initcall_default_bdi_init4",
|
||||
"__initcall_percpu_enable_async4",
|
||||
"__initcall_init_user_reserve4",
|
||||
"__initcall_init_admin_reserve4",
|
||||
"__initcall_init_reserve_notifier4",
|
||||
"__initcall_rsa_init4",
|
||||
"__initcall_crypto_cmac_module_init4",
|
||||
"__initcall_crypto_null_mod_init4",
|
||||
"__initcall_sha256_generic_mod_init4",
|
||||
"__initcall_crypto_ctr_module_init4",
|
||||
"__initcall_crypto_gcm_module_init4",
|
||||
"__initcall_crypto_ccm_module_init4",
|
||||
"__initcall_aes_init4",
|
||||
"__initcall_ghash_mod_init4",
|
||||
"__initcall_pci_slot_init4",
|
||||
"__initcall_misc_init4",
|
||||
"__initcall_usb_common_init4",
|
||||
"__initcall_usb_init4",
|
||||
"__initcall_serio_init4",
|
||||
"__initcall_input_init4",
|
||||
"__initcall_proto_init4",
|
||||
"__initcall_net_dev_init4",
|
||||
"__initcall_neigh_init4",
|
||||
"__initcall_fib_notifier_init4",
|
||||
"__initcall_ethnl_init4",
|
||||
"__initcall_ieee80211_init4",
|
||||
"__initcall_pci_subsys_init4",
|
||||
"__initcall_nmi_warning_debugfs5",
|
||||
"__initcall_hpet_late_init5",
|
||||
"__initcall_init_amd_nbs5",
|
||||
"__initcall_iomem_init_inode5",
|
||||
"__initcall_clocksource_done_booting5",
|
||||
"__initcall_init_pipe_fs5",
|
||||
"__initcall_anon_inode_init5",
|
||||
"__initcall_proc_cmdline_init5",
|
||||
"__initcall_proc_consoles_init5",
|
||||
"__initcall_proc_cpuinfo_init5",
|
||||
"__initcall_proc_devices_init5",
|
||||
"__initcall_proc_interrupts_init5",
|
||||
"__initcall_proc_loadavg_init5",
|
||||
"__initcall_proc_meminfo_init5",
|
||||
"__initcall_proc_stat_init5",
|
||||
"__initcall_proc_uptime_init5",
|
||||
"__initcall_proc_version_init5",
|
||||
"__initcall_proc_softirqs_init5",
|
||||
"__initcall_proc_kmsg_init5",
|
||||
"__initcall_proc_page_init5",
|
||||
"__initcall_init_ramfs_fs5",
|
||||
"__initcall_chr_dev_init5",
|
||||
"__initcall_firmware_class_init5",
|
||||
"__initcall_sysctl_core_init5",
|
||||
"__initcall_eth_offload_init5",
|
||||
"__initcall_cfg80211_init5",
|
||||
"__initcall_pcibios_assign_resources5",
|
||||
"__initcall_pci_apply_final_quirks5s",
|
||||
"__initcall_populate_rootfsrootfs",
|
||||
"__initcall_pci_iommu_initrootfs",
|
||||
"__initcall_rapl_pmu_init6",
|
||||
"__initcall_packet_init6",
|
||||
"__initcall_amd_uncore_init6",
|
||||
"__initcall_amd_ibs_init6",
|
||||
"__initcall_msr_init6",
|
||||
"__initcall_intel_uncore_init6",
|
||||
"__initcall_cstate_pmu_init6",
|
||||
"__initcall_register_kernel_offset_dumper6",
|
||||
"__initcall_i8259A_init_ops6",
|
||||
"__initcall_init_tsc_clocksource6",
|
||||
"__initcall_add_rtc_cmos6",
|
||||
"__initcall_umwait_init6",
|
||||
"__initcall_ioapic_init_ops6",
|
||||
"__initcall_sysfb_init6",
|
||||
"__initcall_proc_execdomains_init6",
|
||||
"__initcall_ioresources_init6",
|
||||
"__initcall_timekeeping_init_ops6",
|
||||
"__initcall_init_clocksource_sysfs6",
|
||||
"__initcall_init_timer_list_procfs6",
|
||||
"__initcall_alarmtimer_init6",
|
||||
"__initcall_clockevents_init_sysfs6",
|
||||
"__initcall_utsname_sysctl_init6",
|
||||
"__initcall_perf_event_sysfs_init6",
|
||||
"__initcall_system_trusted_keyring_init6",
|
||||
"__initcall_kswapd_init6",
|
||||
"__initcall_workingset_init6",
|
||||
"__initcall_proc_vmalloc_init6",
|
||||
"__initcall_fcntl_init6",
|
||||
"__initcall_proc_filesystems_init6",
|
||||
"__initcall_start_dirtytime_writeback6",
|
||||
"__initcall_init_devpts_fs6",
|
||||
"__initcall_key_proc_init6",
|
||||
"__initcall_crypto_algapi_init6",
|
||||
"__initcall_asymmetric_key_init6",
|
||||
"__initcall_x509_key_init6",
|
||||
"__initcall_pci_proc_init6",
|
||||
"__initcall_gpio_clk_driver_init6",
|
||||
"__initcall_plt_clk_driver_init6",
|
||||
"__initcall_n_null_init6",
|
||||
"__initcall_pty_init6",
|
||||
"__initcall_serial8250_init6",
|
||||
"__initcall_serial_pci_driver_init6",
|
||||
"__initcall_exar_pci_driver_init6",
|
||||
"__initcall_lpss8250_pci_driver_init6",
|
||||
"__initcall_mid8250_pci_driver_init6",
|
||||
"__initcall_topology_sysfs_init6",
|
||||
"__initcall_cacheinfo_sysfs_init6",
|
||||
"__initcall_net_olddevs_init6",
|
||||
"__initcall_blackhole_netdev_init6",
|
||||
"__initcall_iwl_drv_init6",
|
||||
"__initcall_iwl_init6",
|
||||
"__initcall_iwl_mvm_init6",
|
||||
"__initcall_ehci_hcd_init6",
|
||||
"__initcall_ehci_pci_init6",
|
||||
"__initcall_ohci_hcd_mod_init6",
|
||||
"__initcall_ohci_pci_init6",
|
||||
"__initcall_xhci_hcd_init6",
|
||||
"__initcall_xhci_pci_init6",
|
||||
"__initcall_i8042_init6",
|
||||
"__initcall_serport_init6",
|
||||
"__initcall_atkbd_init6",
|
||||
"__initcall_psmouse_init6",
|
||||
"__initcall_pmc_atom_init6",
|
||||
"__initcall_sock_diag_init6",
|
||||
"__initcall_update_mp_table7",
|
||||
"__initcall_lapic_insert_resource7",
|
||||
"__initcall_print_ICs7",
|
||||
"__initcall_create_tlb_single_page_flush_ceiling7",
|
||||
"__initcall_init_oops_id7",
|
||||
"__initcall_reboot_ksysfs_init7",
|
||||
"__initcall_sched_clock_init_late7",
|
||||
"__initcall_sched_init_debug7",
|
||||
"__initcall_printk_late_init7",
|
||||
"__initcall_load_system_certificate_list7",
|
||||
"__initcall_check_early_ioremap_leak7",
|
||||
"__initcall_init_root_keyring7",
|
||||
"__initcall_prandom_init_late7",
|
||||
"__initcall_pci_resource_alignment_sysfs_init7",
|
||||
"__initcall_pci_sysfs_init7",
|
||||
"__initcall_sync_state_resume_initcall7",
|
||||
"__initcall_deferred_probe_initcall7",
|
||||
"__initcall_regulatory_init_db7",
|
||||
"__initcall_clk_disable_unused7s",
|
||||
"__initcall_con_initcon",
|
||||
"__initcall_end",
|
||||
"__initcall_univ8250_console_initcon",
|
||||
"END_OF_INITCALL_ORDER_ARRAY_DUMMY_ENTRY"
|
||||
};
|
5
repos/pc/src/lib/wifi/lx_emul/pci_fixups.h
Normal file
5
repos/pc/src/lib/wifi/lx_emul/pci_fixups.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
static const char * lx_emul_pci_final_fixups[] = {
|
||||
"END_OF_PCI_FIXUPS"
|
||||
};
|
279
repos/pc/src/lib/wifi/lx_socket_call.c
Normal file
279
repos/pc/src/lib/wifi/lx_socket_call.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* \brief Linux socket call interface back end
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* DDE Linux includes */
|
||||
#include "lx_socket_call.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <linux/socket.h>
|
||||
#include <linux/net.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
|
||||
struct task_struct *lx_socket_call_task;
|
||||
void *lx_socket_call_task_args;
|
||||
extern int run_lx_socket_call_task(void *p);
|
||||
|
||||
|
||||
extern struct net init_net;
|
||||
|
||||
void lx_user_init(void)
|
||||
{
|
||||
int pid = kernel_thread(run_lx_socket_call_task,
|
||||
lx_socket_call_task_args,
|
||||
CLONE_FS | CLONE_FILES);
|
||||
lx_socket_call_task = find_task_by_pid_ns(pid, NULL);
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_create_kern(int domain, int type, int protocol,
|
||||
struct socket **res)
|
||||
{
|
||||
int const err = __sock_create(&init_net, domain, type, protocol, res, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
init_waitqueue_head(&(*res)->wq.wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_release(struct socket *sock)
|
||||
{
|
||||
return sock->ops->release(sock);
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_bind(struct socket *sock, void *sockaddr, int sockaddr_len)
|
||||
{
|
||||
return sock->ops->bind(sock, sockaddr, sockaddr_len);
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_getname(struct socket *sock, void *sockaddr, int peer)
|
||||
{
|
||||
return sock->ops->getname(sock, sockaddr, peer);
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_recvmsg(struct socket *sock, struct lx_msghdr *lx_msg,
|
||||
int flags, int dontwait)
|
||||
{
|
||||
struct msghdr *msg;
|
||||
struct iovec *iov;
|
||||
size_t iovlen;
|
||||
unsigned iov_count;
|
||||
unsigned i;
|
||||
|
||||
int err = -1;
|
||||
|
||||
iov_count = lx_msg->msg_iovcount;
|
||||
|
||||
msg = kzalloc(sizeof (struct msghdr), GFP_KERNEL);
|
||||
if (!msg)
|
||||
goto err_msg;
|
||||
iov = kzalloc(sizeof (struct iovec) * iov_count, GFP_KERNEL);
|
||||
if (!iov)
|
||||
goto err_iov;
|
||||
|
||||
iovlen = 0;
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
iov[i].iov_base = lx_msg->msg_iov[i].iov_base;
|
||||
iov[i].iov_len = lx_msg->msg_iov[i].iov_len;
|
||||
|
||||
iovlen += lx_msg->msg_iov[i].iov_len;
|
||||
}
|
||||
|
||||
msg->msg_name = lx_msg->msg_name;
|
||||
msg->msg_namelen = lx_msg->msg_namelen;
|
||||
msg->msg_iter.iov = iov;
|
||||
msg->msg_iter.nr_segs = iov_count;
|
||||
msg->msg_iter.count = iovlen;
|
||||
|
||||
msg->msg_flags = flags;
|
||||
if (dontwait) {
|
||||
msg->msg_flags |= MSG_DONTWAIT;
|
||||
flags |= MSG_DONTWAIT;
|
||||
}
|
||||
|
||||
err = sock->ops->recvmsg(sock, msg, iovlen, flags);
|
||||
|
||||
kfree(iov);
|
||||
err_iov:
|
||||
kfree(msg);
|
||||
err_msg:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_sendmsg(struct socket *sock, struct lx_msghdr* lx_msg,
|
||||
int flags, int dontwait)
|
||||
{
|
||||
struct msghdr *msg;
|
||||
struct iovec *iov;
|
||||
size_t iovlen;
|
||||
unsigned iov_count;
|
||||
unsigned i;
|
||||
|
||||
int err = -1;
|
||||
|
||||
iov_count = lx_msg->msg_iovcount;
|
||||
|
||||
msg = kzalloc(sizeof (struct msghdr), GFP_KERNEL);
|
||||
if (!msg)
|
||||
goto err_msg;
|
||||
iov = kzalloc(sizeof (struct iovec) * iov_count, GFP_KERNEL);
|
||||
if (!iov)
|
||||
goto err_iov;
|
||||
|
||||
iovlen = 0;
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
iov[i].iov_base = lx_msg->msg_iov[i].iov_base;
|
||||
iov[i].iov_len = lx_msg->msg_iov[i].iov_len;
|
||||
|
||||
iovlen += lx_msg->msg_iov[i].iov_len;
|
||||
}
|
||||
|
||||
msg->msg_name = lx_msg->msg_name;
|
||||
msg->msg_namelen = lx_msg->msg_namelen;
|
||||
msg->msg_iter.iov = iov;
|
||||
msg->msg_iter.nr_segs = iov_count;
|
||||
msg->msg_iter.count = iovlen;
|
||||
|
||||
msg->msg_flags = flags;
|
||||
if (dontwait)
|
||||
msg->msg_flags |= MSG_DONTWAIT;
|
||||
|
||||
err = sock->ops->sendmsg(sock, msg, iovlen);
|
||||
|
||||
kfree(iov);
|
||||
err_iov:
|
||||
kfree(msg);
|
||||
err_msg:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
void const *optval, unsigned optlen)
|
||||
{
|
||||
sockptr_t soptval = (sockptr_t) { .user = optval };
|
||||
|
||||
if (level == SOL_SOCKET)
|
||||
return sock_setsockopt(sock, level, optname,
|
||||
soptval, optlen);
|
||||
|
||||
return sock->ops->setsockopt(sock, level, optname,
|
||||
soptval, optlen);
|
||||
}
|
||||
|
||||
|
||||
unsigned char const* lx_get_mac_addr()
|
||||
{
|
||||
static char mac_addr_buffer[16];
|
||||
|
||||
struct sockaddr addr;
|
||||
int err;
|
||||
size_t length;
|
||||
|
||||
memset(mac_addr_buffer, 0, sizeof (mac_addr_buffer));
|
||||
memset(addr.sa_data, 0, sizeof (addr.sa_data));
|
||||
|
||||
err = dev_get_mac_address(&addr, &init_net, "wlan0");
|
||||
if (err)
|
||||
return NULL;
|
||||
|
||||
length = sizeof (mac_addr_buffer) < sizeof (addr.sa_data)
|
||||
? sizeof (mac_addr_buffer)
|
||||
: sizeof (addr.sa_data);
|
||||
memcpy(mac_addr_buffer, addr.sa_data, length);
|
||||
|
||||
return mac_addr_buffer;
|
||||
}
|
||||
|
||||
|
||||
struct lx_poll_result lx_sock_poll(struct socket *sock)
|
||||
{
|
||||
enum {
|
||||
POLLIN_SET = (EPOLLRDHUP | EPOLLIN | EPOLLRDNORM),
|
||||
POLLOUT_SET = (EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND),
|
||||
POLLEX_SET = (EPOLLERR | EPOLLPRI)
|
||||
};
|
||||
|
||||
// enum {
|
||||
// POLLIN_SET = (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR)
|
||||
// POLLOUT_SET = (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR)
|
||||
// POLLEX_SET = (EPOLLPRI)
|
||||
// };
|
||||
|
||||
int const mask = sock->ops->poll(0, sock, 0);
|
||||
|
||||
struct lx_poll_result result = { false, false, false };
|
||||
|
||||
if (mask & POLLIN_SET)
|
||||
result.in = true;
|
||||
if (mask & POLLOUT_SET)
|
||||
result.out = true;
|
||||
if (mask & POLLEX_SET)
|
||||
result.ex = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int lx_sock_poll_wait(struct socket *socks[], unsigned num, int timeout)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned long j;
|
||||
signed long ex;
|
||||
unsigned int to;
|
||||
|
||||
enum { NUM_WQE = 8u, };
|
||||
struct wait_queue_entry sock_wqe[NUM_WQE];
|
||||
|
||||
/* should not happen as the number of sockets is capped by libnl */
|
||||
if ((unsigned)NUM_WQE < num)
|
||||
printk("%s: more num: %d sockets than available"
|
||||
"wait queue entries: %d\n", __func__, num, (unsigned)NUM_WQE);
|
||||
|
||||
/*
|
||||
* Add the appropriate wait queue entries and sleep afterwards
|
||||
* for the requested timeout duration. Either a 'wake_up' call
|
||||
* or the timeout will get us going again.
|
||||
*/
|
||||
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct socket *sock = socks[i];
|
||||
if (!sock)
|
||||
continue;
|
||||
|
||||
init_waitqueue_entry(&sock_wqe[i], current);
|
||||
add_wait_queue(&(sock->sk->sk_wq->wait), &sock_wqe[i]);
|
||||
}
|
||||
|
||||
j = msecs_to_jiffies(timeout);
|
||||
ex = schedule_timeout(j);
|
||||
to = jiffies_to_msecs(ex);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct socket *sock = socks[i];
|
||||
if (!sock)
|
||||
continue;
|
||||
|
||||
remove_wait_queue(&(sock->sk->sk_wq->wait), &sock_wqe[i]);
|
||||
}
|
||||
|
||||
return (int)to;
|
||||
}
|
75
repos/pc/src/lib/wifi/lx_socket_call.h
Normal file
75
repos/pc/src/lib/wifi/lx_socket_call.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* \brief Linux socket call interface back end
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LX_SOCKET_CALL_H_
|
||||
#define _LX_SOCKET_CALL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lx_iov
|
||||
{
|
||||
void *iov_base;
|
||||
unsigned long iov_len;
|
||||
};
|
||||
|
||||
enum { MAX_IOV_LEN = 8 };
|
||||
|
||||
|
||||
struct lx_msghdr
|
||||
{
|
||||
void *msg_name;
|
||||
unsigned msg_namelen;
|
||||
struct lx_iov msg_iov[MAX_IOV_LEN];
|
||||
unsigned msg_iovcount;
|
||||
/*
|
||||
* Omit total length covered by vector as it is
|
||||
* calculated where needed.
|
||||
*/
|
||||
|
||||
void *msg_control;
|
||||
unsigned msg_controllen;
|
||||
};
|
||||
|
||||
struct socket;
|
||||
|
||||
int lx_sock_create_kern(int domain, int type, int protocol,
|
||||
struct socket **res);
|
||||
int lx_sock_release(struct socket *sock);
|
||||
int lx_sock_bind(struct socket *sock, void *sockaddr, int sockaddr_len);
|
||||
int lx_sock_getname(struct socket *sock, void *sockaddr, int peer);
|
||||
int lx_sock_recvmsg(struct socket *sock, struct lx_msghdr *lx_msg,
|
||||
int flags, int dontwait);
|
||||
int lx_sock_sendmsg(struct socket *socket, struct lx_msghdr* lx_msg,
|
||||
int flags, int dontwait);
|
||||
int lx_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
void const *optval, unsigned optlen);
|
||||
unsigned char const* lx_get_mac_addr(void);
|
||||
|
||||
struct lx_poll_result
|
||||
{
|
||||
int in;
|
||||
int out;
|
||||
int ex;
|
||||
};
|
||||
|
||||
struct lx_poll_result lx_sock_poll(struct socket *sock);
|
||||
|
||||
int lx_sock_poll_wait(struct socket *sock[], unsigned num, int timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _LX_SOCKET_CALL_H_ */
|
20
repos/pc/src/lib/wifi/misc.cc
Normal file
20
repos/pc/src/lib/wifi/misc.cc
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* \brief Misc
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-01-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/backtrace.h>
|
||||
|
||||
extern "C" void lx_backtrace(void)
|
||||
{
|
||||
Genode::backtrace();
|
||||
}
|
111
repos/pc/src/lib/wifi/random.cc
Normal file
111
repos/pc/src/lib/wifi/random.cc
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* \brief Linux random emulation code
|
||||
* \author Josef Soentgen
|
||||
* \date 2016-10-19
|
||||
*
|
||||
* For all intents and purposes this random back end should be treated
|
||||
* as a gloryfied counter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/fixed_stdint.h>
|
||||
#include <util/string.h>
|
||||
|
||||
|
||||
using Genode::uint64_t;
|
||||
|
||||
/*
|
||||
* Xoroshiro128+ written in 2014-2016 by Sebastiano Vigna (vigna@acm.org)
|
||||
*
|
||||
* (see http://xoroshiro.di.unimi.it/xorshift128plus.c and
|
||||
* http://xoroshiro.di.unimi.it/splitmix64.c)
|
||||
*/
|
||||
|
||||
struct Xoroshiro
|
||||
{
|
||||
uint64_t seed;
|
||||
|
||||
uint64_t splitmix64()
|
||||
{
|
||||
uint64_t z = (seed += __UINT64_C(0x9E3779B97F4A7C15));
|
||||
z = (z ^ (z >> 30)) * __UINT64_C(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * __UINT64_C(0x94D049BB133111EB);
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
Xoroshiro(uint64_t seed) : seed(seed)
|
||||
{
|
||||
s[0] = splitmix64();
|
||||
s[1] = splitmix64();
|
||||
}
|
||||
|
||||
uint64_t s[2];
|
||||
|
||||
static uint64_t rotl(uint64_t const x, int k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
uint64_t get()
|
||||
{
|
||||
uint64_t const s0 = s[0];
|
||||
uint64_t s1 = s[1];
|
||||
uint64_t const result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
|
||||
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14);
|
||||
s[1] = rotl(s1, 36);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Xoroshiro &xoroshiro()
|
||||
{
|
||||
static Xoroshiro inst(0x636864324d766931);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/random.h **
|
||||
********************/
|
||||
|
||||
extern "C" void lx_emul_get_random_bytes(void *buf, unsigned long nbytes)
|
||||
{
|
||||
if (!buf || !nbytes)
|
||||
return;
|
||||
|
||||
char *p = reinterpret_cast<char*>(buf);
|
||||
|
||||
unsigned long const rounds = nbytes / 8;
|
||||
for (unsigned long i = 0; i < rounds; i++) {
|
||||
uint64_t const v = xoroshiro().get();
|
||||
|
||||
Genode::memcpy(p, &v, 8);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
unsigned long const remain = nbytes - rounds * 8;
|
||||
if (!remain) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t const v = xoroshiro().get();
|
||||
Genode::memcpy(p, &v, remain);
|
||||
}
|
||||
|
||||
|
||||
extern "C" unsigned int lx_emul_get_random_u32(void)
|
||||
{
|
||||
return (unsigned int)xoroshiro().get();
|
||||
}
|
724
repos/pc/src/lib/wifi/socket_call.cc
Normal file
724
repos/pc/src/lib/wifi/socket_call.cc
Normal file
@ -0,0 +1,724 @@
|
||||
/*
|
||||
* \brief Linux socket call interface front end
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* DDE Linux includes */
|
||||
#include <wifi/socket_call.h>
|
||||
#include <lx_emul/task.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
/* local includes */
|
||||
#include "lx_socket_call.h"
|
||||
#include "libc_errno.h"
|
||||
|
||||
/*
|
||||
* The values were taken from 'uapi/asm-generic/socket.h',
|
||||
* 'uapi/linux/netlink.h' and 'linux/socket.h' and must be
|
||||
* kept in sync.
|
||||
*/
|
||||
enum : int {
|
||||
SOL_SOCKET = 1,
|
||||
SOL_NETLINK = 270,
|
||||
|
||||
SO_SNDBUF = 7,
|
||||
SO_RCVBUF = 8,
|
||||
SO_PASSCRED = 16,
|
||||
SO_WIFI_STATUS = 41,
|
||||
|
||||
NETLINK_ADD_MEMBERSHIP = 1,
|
||||
NETLINK_DROP_MEMBERSHIP = 2,
|
||||
NETLINK_PKTINFO = 3,
|
||||
|
||||
MSG_DONTWAIT = 0x40,
|
||||
MSG_ERRQUEUE = 0x2000,
|
||||
};
|
||||
|
||||
|
||||
static int convert_errno_from_linux(int linux_errno)
|
||||
{
|
||||
if (linux_errno >= 0)
|
||||
return linux_errno;
|
||||
|
||||
linux_errno *= -1;
|
||||
|
||||
switch (linux_errno) {
|
||||
case 0: return 0;
|
||||
case E2BIG: return -(int)Libc::Errno::BSD_E2BIG;
|
||||
case EACCES: return -(int)Libc::Errno::BSD_EACCES;
|
||||
case EADDRINUSE: return -(int)Libc::Errno::BSD_EADDRINUSE;
|
||||
case EADDRNOTAVAIL: return -(int)Libc::Errno::BSD_EADDRNOTAVAIL;
|
||||
case EAFNOSUPPORT: return -(int)Libc::Errno::BSD_EAFNOSUPPORT;
|
||||
case EAGAIN: return -(int)Libc::Errno::BSD_EAGAIN;
|
||||
case EALREADY: return -(int)Libc::Errno::BSD_EALREADY;
|
||||
case EBADF: return -(int)Libc::Errno::BSD_EBADF;
|
||||
case EBADMSG: return -(int)Libc::Errno::BSD_EBADMSG;
|
||||
case EBUSY: return -(int)Libc::Errno::BSD_EBUSY;
|
||||
case ECANCELED: return -(int)Libc::Errno::BSD_ECANCELED;
|
||||
case ECONNABORTED: return -(int)Libc::Errno::BSD_ECONNABORTED;
|
||||
case ECONNREFUSED: return -(int)Libc::Errno::BSD_ECONNREFUSED;
|
||||
case ECONNRESET: return -(int)Libc::Errno::BSD_ECONNRESET;
|
||||
case EDEADLK: return -(int)Libc::Errno::BSD_EDEADLK;
|
||||
case EDESTADDRREQ: return -(int)Libc::Errno::BSD_EDESTADDRREQ;
|
||||
case EDOM: return -(int)Libc::Errno::BSD_EDOM;
|
||||
case EEXIST: return -(int)Libc::Errno::BSD_EEXIST;
|
||||
case EFAULT: return -(int)Libc::Errno::BSD_EFAULT;
|
||||
case EFBIG: return -(int)Libc::Errno::BSD_EFBIG;
|
||||
case EHOSTDOWN: return -(int)Libc::Errno::BSD_EHOSTDOWN;
|
||||
case EHOSTUNREACH: return -(int)Libc::Errno::BSD_EHOSTUNREACH;
|
||||
case EILSEQ: return -(int)Libc::Errno::BSD_EILSEQ;
|
||||
case EINPROGRESS: return -(int)Libc::Errno::BSD_EINPROGRESS;
|
||||
case EINTR: return -(int)Libc::Errno::BSD_EINTR;
|
||||
case EINVAL: return -(int)Libc::Errno::BSD_EINVAL;
|
||||
case EIO: return -(int)Libc::Errno::BSD_EIO;
|
||||
case EISCONN: return -(int)Libc::Errno::BSD_EISCONN;
|
||||
case EMSGSIZE: return -(int)Libc::Errno::BSD_EMSGSIZE;
|
||||
case ENAMETOOLONG: return -(int)Libc::Errno::BSD_ENAMETOOLONG;
|
||||
case ENETDOWN: return -(int)Libc::Errno::BSD_ENETDOWN;
|
||||
case ENETUNREACH: return -(int)Libc::Errno::BSD_ENETUNREACH;
|
||||
case ENFILE: return -(int)Libc::Errno::BSD_ENFILE;
|
||||
case ENOBUFS: return -(int)Libc::Errno::BSD_ENOBUFS;
|
||||
case ENODEV: return -(int)Libc::Errno::BSD_ENODEV;
|
||||
case ENOENT: return -(int)Libc::Errno::BSD_ENOENT;
|
||||
case ENOEXEC: return -(int)Libc::Errno::BSD_ENOEXEC;
|
||||
case ENOLINK:
|
||||
Genode::error("ENOLINK (", (int) ENOLINK, ") -> ", (int)Libc::Errno::BSD_ENOLINK);
|
||||
return -(int)Libc::Errno::BSD_ENOLINK;
|
||||
case ENOMEM: return -(int)Libc::Errno::BSD_ENOMEM;
|
||||
case ENOMSG: return -(int)Libc::Errno::BSD_ENOMSG;
|
||||
case ENOPROTOOPT: return -(int)Libc::Errno::BSD_ENOPROTOOPT;
|
||||
case ENOSPC: return -(int)Libc::Errno::BSD_ENOSPC;
|
||||
case ENOSYS: return -(int)Libc::Errno::BSD_ENOSYS;
|
||||
case ENOTCONN: return -(int)Libc::Errno::BSD_ENOTCONN;
|
||||
case ENOTSOCK: return -(int)Libc::Errno::BSD_ENOTSOCK;
|
||||
case ENOTTY: return -(int)Libc::Errno::BSD_ENOTTY;
|
||||
case ENXIO: return -(int)Libc::Errno::BSD_ENXIO;
|
||||
case EOPNOTSUPP: return -(int)Libc::Errno::BSD_EOPNOTSUPP;
|
||||
case EOVERFLOW: return -(int)Libc::Errno::BSD_EOVERFLOW;
|
||||
case EPERM: return -(int)Libc::Errno::BSD_EPERM;
|
||||
case EPFNOSUPPORT: return -(int)Libc::Errno::BSD_EPFNOSUPPORT;
|
||||
case EPIPE: return -(int)Libc::Errno::BSD_EPIPE;
|
||||
case EPROTO: return -(int)Libc::Errno::BSD_EPROTO;
|
||||
case EPROTONOSUPPORT: return -(int)Libc::Errno::BSD_EPROTONOSUPPORT;
|
||||
case ERANGE: return -(int)Libc::Errno::BSD_ERANGE;
|
||||
case ESOCKTNOSUPPORT: return -(int)Libc::Errno::BSD_ESOCKTNOSUPPORT;
|
||||
case ESPIPE: return -(int)Libc::Errno::BSD_ESPIPE;
|
||||
case ESRCH: return -(int)Libc::Errno::BSD_ESRCH;
|
||||
case ETIMEDOUT: return -(int)Libc::Errno::BSD_ETIMEDOUT;
|
||||
case EXDEV: return -(int)Libc::Errno::BSD_EXDEV;
|
||||
default:
|
||||
Genode::error(__func__, ": unhandled errno ", linux_errno);
|
||||
return linux_errno;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static_assert((unsigned)Wifi::Msghdr::MAX_IOV_LEN == (unsigned)MAX_IOV_LEN);
|
||||
|
||||
|
||||
extern "C" struct task_struct *lx_socket_call_task;
|
||||
extern "C" void *lx_socket_call_task_args;
|
||||
|
||||
|
||||
|
||||
/* XXX move Wifi::Socket definition to better location */
|
||||
struct Wifi::Socket
|
||||
{
|
||||
void *socket = nullptr;
|
||||
bool non_block = false;
|
||||
|
||||
Socket() { }
|
||||
|
||||
explicit Socket(void *s) : socket(s) { }
|
||||
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
Genode::print(out, "this: ", this, " socket: ", socket, " non_block: ", non_block);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Call
|
||||
{
|
||||
enum Opcode {
|
||||
NONE, SOCKET, CLOSE,
|
||||
BIND, GETSOCKNAME, RECVMSG, SENDMSG, SENDTO, SETSOCKOPT,
|
||||
GET_MAC_ADDRESS, POLL_ALL, NON_BLOCK,
|
||||
};
|
||||
|
||||
Opcode opcode = NONE;
|
||||
Wifi::Socket *handle = nullptr;
|
||||
|
||||
union {
|
||||
struct
|
||||
{
|
||||
int domain;
|
||||
int type;
|
||||
int protocol;
|
||||
void *result;
|
||||
} socket;
|
||||
struct { /* no args */ } close;
|
||||
struct
|
||||
{
|
||||
void const *addr;
|
||||
int addrlen;
|
||||
} bind;
|
||||
struct
|
||||
{
|
||||
void *addr;
|
||||
int *addrlen;
|
||||
} getsockname;
|
||||
struct
|
||||
{
|
||||
lx_msghdr msg;
|
||||
int flags;
|
||||
} recvmsg;
|
||||
struct
|
||||
{
|
||||
lx_msghdr msg;
|
||||
int flags;
|
||||
} sendmsg;
|
||||
struct {
|
||||
int level;
|
||||
int optname;
|
||||
void const *optval;
|
||||
unsigned optlen;
|
||||
} setsockopt;
|
||||
struct
|
||||
{
|
||||
unsigned char *addr;
|
||||
unsigned int addr_len;
|
||||
} get_mac_address;
|
||||
struct
|
||||
{
|
||||
Wifi::Poll_socket_fd *sockets;
|
||||
unsigned num;
|
||||
int timeout;
|
||||
} poll_all;
|
||||
struct
|
||||
{
|
||||
bool value;
|
||||
} non_block;
|
||||
};
|
||||
|
||||
int err = 0;
|
||||
};
|
||||
|
||||
static Call _call;
|
||||
static Genode::Semaphore _block;
|
||||
|
||||
|
||||
namespace Lx {
|
||||
class Socket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Context for socket calls
|
||||
*/
|
||||
class Lx::Socket
|
||||
{
|
||||
private:
|
||||
|
||||
Socket(const Socket&) = delete;
|
||||
Socket& operator=(const Socket&) = delete;
|
||||
|
||||
Genode::Signal_transmitter _sender { };
|
||||
Genode::Signal_handler<Lx::Socket> _dispatcher;
|
||||
|
||||
struct socket *_sock_poll_table[Wifi::MAX_POLL_SOCKETS] { };
|
||||
|
||||
struct socket *_call_socket()
|
||||
{
|
||||
struct socket *sock = static_cast<struct socket*>(_call.handle->socket);
|
||||
if (!sock)
|
||||
Genode::error("BUG: sock is zero");
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
void _do_socket()
|
||||
{
|
||||
struct socket *s;
|
||||
int res = lx_sock_create_kern(_call.socket.domain, _call.socket.type,
|
||||
_call.socket.protocol, &s);
|
||||
if (!res) {
|
||||
_call.socket.result = s;
|
||||
_call.err = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_call.socket.result = nullptr;
|
||||
_call.err = res;
|
||||
}
|
||||
|
||||
void _do_close()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
|
||||
_call.err = lx_sock_release(sock);
|
||||
}
|
||||
|
||||
void _do_bind()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
|
||||
_call.err = lx_sock_bind(sock,
|
||||
const_cast<void*>(_call.bind.addr),
|
||||
_call.bind.addrlen);
|
||||
}
|
||||
|
||||
void _do_getsockname()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
int addrlen = *_call.getsockname.addrlen;
|
||||
|
||||
_call.err = lx_sock_getname(sock, _call.getsockname.addr, 0);
|
||||
|
||||
*_call.getsockname.addrlen = addrlen;
|
||||
}
|
||||
|
||||
void _do_recvmsg()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
|
||||
_call.err = lx_sock_recvmsg(sock, &_call.recvmsg.msg,
|
||||
_call.recvmsg.flags,
|
||||
_call.handle->non_block);
|
||||
}
|
||||
|
||||
void _do_sendmsg()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
|
||||
_call.err = lx_sock_sendmsg(sock, &_call.sendmsg.msg,
|
||||
_call.sendmsg.flags,
|
||||
_call.handle->non_block);
|
||||
}
|
||||
|
||||
void _do_setsockopt()
|
||||
{
|
||||
struct socket *sock = _call_socket();
|
||||
|
||||
_call.err = lx_sock_setsockopt(sock,
|
||||
_call.setsockopt.level,
|
||||
_call.setsockopt.optname,
|
||||
_call.setsockopt.optval,
|
||||
_call.setsockopt.optlen);
|
||||
}
|
||||
|
||||
void _do_get_mac_address()
|
||||
{
|
||||
unsigned const char *addr = lx_get_mac_addr();
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
Genode::size_t const copy = 6 > _call.get_mac_address.addr_len
|
||||
? _call.get_mac_address.addr_len
|
||||
: 6;
|
||||
|
||||
Genode::memcpy(_call.get_mac_address.addr, addr, copy);
|
||||
}
|
||||
|
||||
void _do_poll_all()
|
||||
{
|
||||
Wifi::Poll_socket_fd *sockets = _call.poll_all.sockets;
|
||||
unsigned num = _call.poll_all.num;
|
||||
int timeout = _call.poll_all.timeout;
|
||||
|
||||
int nready = 0;
|
||||
bool timeout_triggered = false;
|
||||
bool woken_up = false;
|
||||
do {
|
||||
/**
|
||||
* Timeout was triggered, exit early.
|
||||
*/
|
||||
if (timeout_triggered) {
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll each socket and check if there is something of interest.
|
||||
*/
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
struct socket *sock = static_cast<struct socket*>(sockets[i].s->socket);
|
||||
|
||||
struct lx_poll_result result = lx_sock_poll(sock);
|
||||
|
||||
sockets[i].revents = 0;
|
||||
if (result.in)
|
||||
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLIN ? Wifi::WIFI_POLLIN : 0;
|
||||
if (result.out)
|
||||
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLOUT ? Wifi::WIFI_POLLOUT : 0;
|
||||
if (result.ex)
|
||||
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLEX ? Wifi::WIFI_POLLEX : 0;
|
||||
|
||||
if (sockets[i].revents)
|
||||
nready++;
|
||||
}
|
||||
|
||||
/**
|
||||
* We were woken up but there is still nothing of interest.
|
||||
*/
|
||||
if (woken_up) {
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit the loop if either a socket is ready or there is
|
||||
* no timeout given.
|
||||
*/
|
||||
if (nready || !timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of a timeout add all sockets to an artificial wait list
|
||||
* so at least one is woken up an sk_data_ready() call.
|
||||
*/
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
struct socket *sock = static_cast<struct socket*>(sockets[i].s->socket);
|
||||
_sock_poll_table[i] = sock;
|
||||
}
|
||||
|
||||
timeout_triggered = !lx_sock_poll_wait(_sock_poll_table, num, timeout);
|
||||
|
||||
woken_up = true;
|
||||
} while (1);
|
||||
|
||||
_call.err = nready;
|
||||
}
|
||||
|
||||
void _do_non_block()
|
||||
{
|
||||
_call.handle->non_block = _call.non_block.value;
|
||||
}
|
||||
|
||||
void _handle()
|
||||
{
|
||||
lx_emul_task_unblock(lx_socket_call_task);
|
||||
Lx_kit::env().scheduler.schedule();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Socket(Genode::Entrypoint &ep)
|
||||
:
|
||||
_dispatcher(ep, *this, &Lx::Socket::_handle)
|
||||
{
|
||||
_sender.context(_dispatcher);
|
||||
}
|
||||
|
||||
void exec_call()
|
||||
{
|
||||
switch (_call.opcode) {
|
||||
case Call::BIND: _do_bind(); break;
|
||||
case Call::CLOSE: _do_close(); break;
|
||||
case Call::GETSOCKNAME: _do_getsockname(); break;
|
||||
case Call::POLL_ALL: _do_poll_all(); break;
|
||||
case Call::RECVMSG: _do_recvmsg(); break;
|
||||
case Call::SENDMSG: _do_sendmsg(); break;
|
||||
case Call::SETSOCKOPT: _do_setsockopt(); break;
|
||||
case Call::SOCKET: _do_socket(); break;
|
||||
case Call::GET_MAC_ADDRESS: _do_get_mac_address(); break;
|
||||
case Call::NON_BLOCK: _do_non_block(); break;
|
||||
|
||||
case Call::NONE: [[fallthrough]];/* ignore silently */
|
||||
default:
|
||||
_call.err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save old call opcode as we may only release the blocker
|
||||
* when actually did something useful, i.e., were called by
|
||||
* some socket operation and not by kicking the socket.
|
||||
*/
|
||||
Call::Opcode old = _call.opcode;
|
||||
|
||||
_call.opcode = Call::NONE;
|
||||
|
||||
if (old != Call::NONE) { _block.up(); }
|
||||
}
|
||||
|
||||
void submit_and_block()
|
||||
{
|
||||
_sender.submit();
|
||||
_block.down();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Lx::Socket *_socket;
|
||||
|
||||
|
||||
extern Genode::Blockade *wpa_blockade;
|
||||
extern "C" void uplink_init(void);
|
||||
|
||||
extern "C" int run_lx_socket_call_task(void *)
|
||||
{
|
||||
static Lx::Socket inst(Lx_kit::env().env.ep());
|
||||
_socket = &inst;
|
||||
|
||||
uplink_init();
|
||||
wpa_blockade->wakeup();
|
||||
|
||||
while (true) {
|
||||
|
||||
_socket->exec_call();
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wifi_kick_socketcall()
|
||||
{
|
||||
/* ignore silently, the function might be called to before init */
|
||||
if (!_socket) { return; }
|
||||
|
||||
lx_emul_task_unblock(lx_socket_call_task);
|
||||
Lx_kit::env().scheduler.schedule();
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** Socket_call instance **
|
||||
**************************/
|
||||
|
||||
Wifi::Socket_call socket_call;
|
||||
|
||||
|
||||
/***************************
|
||||
** Socket_call interface **
|
||||
***************************/
|
||||
|
||||
using namespace Wifi;
|
||||
|
||||
|
||||
Wifi::Socket *Socket_call::socket(int domain, int type, int protocol)
|
||||
{
|
||||
/* FIXME domain, type, protocol values */
|
||||
_call.opcode = Call::SOCKET;
|
||||
_call.socket.domain = domain;
|
||||
_call.socket.type = type & 0xff;
|
||||
_call.socket.protocol = protocol;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
if (_call.socket.result == 0)
|
||||
return 0;
|
||||
|
||||
Wifi::Socket *s = new (Lx_kit::env().heap) Wifi::Socket(_call.socket.result);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int Socket_call::close(Socket *s)
|
||||
{
|
||||
_call.opcode = Call::CLOSE;
|
||||
_call.handle = s;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
if (_call.err)
|
||||
Genode::warning("closing socket failed: ", _call.err);
|
||||
|
||||
destroy(Lx_kit::env().heap, s);
|
||||
return _call.err;
|
||||
}
|
||||
|
||||
|
||||
int Socket_call::bind(Socket *s, Wifi::Sockaddr const *addr, unsigned addrlen)
|
||||
{
|
||||
/* FIXME convert to/from Sockaddr */
|
||||
_call.opcode = Call::BIND;
|
||||
_call.handle = s;
|
||||
_call.bind.addr = (void const *)addr;
|
||||
_call.bind.addrlen = addrlen;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
int Socket_call::getsockname(Socket *s, Wifi::Sockaddr *addr, unsigned *addrlen)
|
||||
{
|
||||
/* FIXME convert to/from Sockaddr */
|
||||
/* FIXME unsigned * -> int * */
|
||||
_call.opcode = Call::GETSOCKNAME;
|
||||
_call.handle = s;
|
||||
_call.getsockname.addr = (void *)addr;
|
||||
_call.getsockname.addrlen = (int *)addrlen;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
int Socket_call::poll_all(Poll_socket_fd *s, unsigned num, int timeout)
|
||||
{
|
||||
_call.opcode = Call::POLL_ALL;
|
||||
_call.handle = 0;
|
||||
_call.poll_all.sockets = s;
|
||||
_call.poll_all.num = num;
|
||||
_call.poll_all.timeout = timeout;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
static inline int msg_flags(Wifi::Flags in)
|
||||
{
|
||||
int out = Wifi::WIFI_F_NONE;
|
||||
if (in & Wifi::WIFI_F_MSG_ERRQUEUE)
|
||||
out |= MSG_ERRQUEUE;
|
||||
if (in & Wifi::WIFI_F_MSG_DONTWAIT) {
|
||||
out |= MSG_DONTWAIT;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
|
||||
Wifi::ssize_t Socket_call::recvmsg(Socket *s, Wifi::Msghdr *msg, Wifi::Flags flags)
|
||||
{
|
||||
_call.opcode = Call::RECVMSG;
|
||||
_call.handle = s;
|
||||
_call.recvmsg.msg.msg_name = msg->msg_name;
|
||||
_call.recvmsg.msg.msg_namelen = msg->msg_namelen;
|
||||
_call.recvmsg.msg.msg_iovcount = msg->msg_iovlen;
|
||||
|
||||
_call.recvmsg.msg.msg_control = msg->msg_control;
|
||||
_call.recvmsg.msg.msg_controllen = msg->msg_controllen;
|
||||
_call.recvmsg.flags = msg_flags(flags);
|
||||
|
||||
for (unsigned i = 0; i < msg->msg_iovlen; ++i) {
|
||||
_call.recvmsg.msg.msg_iov[i].iov_base = msg->msg_iov[i].iov_base;
|
||||
_call.recvmsg.msg.msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
|
||||
}
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
msg->msg_namelen = _call.recvmsg.msg.msg_namelen;
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
Wifi::ssize_t Socket_call::sendmsg(Socket *s, Wifi::Msghdr const *msg, Wifi::Flags flags)
|
||||
{
|
||||
_call.opcode = Call::SENDMSG;
|
||||
_call.handle = s;
|
||||
_call.sendmsg.msg.msg_name = msg->msg_name;
|
||||
_call.sendmsg.msg.msg_namelen = msg->msg_namelen;
|
||||
_call.sendmsg.msg.msg_iovcount = msg->msg_iovlen;
|
||||
|
||||
_call.sendmsg.msg.msg_control = 0;
|
||||
_call.sendmsg.msg.msg_controllen = 0;
|
||||
_call.sendmsg.flags = msg_flags(flags);
|
||||
|
||||
for (unsigned i = 0; i < msg->msg_iovlen; ++i) {
|
||||
_call.sendmsg.msg.msg_iov[i].iov_base = msg->msg_iov[i].iov_base;
|
||||
_call.sendmsg.msg.msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
|
||||
}
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
static int sockopt_level(Sockopt_level const in)
|
||||
{
|
||||
switch (in) {
|
||||
case Wifi::WIFI_SOL_SOCKET: return SOL_SOCKET;
|
||||
case Wifi::WIFI_SOL_NETLINK: return SOL_NETLINK;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int sockopt_name(Sockopt_level const level, Sockopt_name const in)
|
||||
{
|
||||
switch (level) {
|
||||
case Wifi::WIFI_SOL_SOCKET:
|
||||
switch (in) {
|
||||
case Wifi::WIFI_SO_SNDBUF: return SO_SNDBUF;
|
||||
case Wifi::WIFI_SO_RCVBUF: return SO_RCVBUF;
|
||||
case Wifi::WIFI_SO_PASSCRED: return SO_PASSCRED;
|
||||
case Wifi::WIFI_SO_WIFI_STATUS: return SO_WIFI_STATUS;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
case Wifi::WIFI_SOL_NETLINK:
|
||||
switch (in) {
|
||||
case Wifi::WIFI_NETLINK_ADD_MEMBERSHIP: return NETLINK_ADD_MEMBERSHIP;
|
||||
case Wifi::WIFI_NETLINK_DROP_MEMBERSHIP: return NETLINK_DROP_MEMBERSHIP;
|
||||
case Wifi::WIFI_NETLINK_PKTINFO: return NETLINK_PKTINFO;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Socket_call::setsockopt(Socket *s,
|
||||
Wifi::Sockopt_level level, Wifi::Sockopt_name optname,
|
||||
const void *optval, unsigned optlen)
|
||||
{
|
||||
/* FIXME optval values */
|
||||
_call.opcode = Call::SETSOCKOPT;
|
||||
_call.handle = s;
|
||||
_call.setsockopt.level = sockopt_level(level);
|
||||
_call.setsockopt.optname = sockopt_name(level, optname);
|
||||
_call.setsockopt.optval = optval;
|
||||
_call.setsockopt.optlen = optlen;
|
||||
|
||||
_socket->submit_and_block();
|
||||
|
||||
return convert_errno_from_linux(_call.err);
|
||||
}
|
||||
|
||||
|
||||
void Socket_call::non_block(Socket *s, bool value)
|
||||
{
|
||||
_call.opcode = Call::NON_BLOCK;
|
||||
_call.handle = s;
|
||||
_call.non_block.value = value;
|
||||
|
||||
_socket->submit_and_block();
|
||||
}
|
||||
|
||||
|
||||
void Socket_call::get_mac_address(unsigned char *addr)
|
||||
{
|
||||
_call.opcode = Call::GET_MAC_ADDRESS;
|
||||
_call.handle = 0;
|
||||
_call.get_mac_address.addr = addr;
|
||||
_call.get_mac_address.addr_len = 6; // XXX enforce and set from caller
|
||||
|
||||
_socket->submit_and_block();
|
||||
}
|
273
repos/pc/src/lib/wifi/spec/x86_32/source.list
Normal file
273
repos/pc/src/lib/wifi/spec/x86_32/source.list
Normal file
@ -0,0 +1,273 @@
|
||||
arch/x86/pci/legacy.c
|
||||
drivers/base/bus.c
|
||||
drivers/base/class.c
|
||||
drivers/base/component.c
|
||||
drivers/base/core.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/platform.c
|
||||
drivers/base/property.c
|
||||
drivers/clk/clk-devres.c
|
||||
drivers/pci/access.c
|
||||
drivers/pci/bus.c
|
||||
drivers/pci/host-bridge.c
|
||||
drivers/pci/msi.c
|
||||
drivers/pci/pci.c
|
||||
drivers/pci/pci-driver.c
|
||||
drivers/pci/pci-sysfs.c
|
||||
drivers/pci/probe.c
|
||||
drivers/pci/rom.c
|
||||
drivers/pci/search.c
|
||||
drivers/pci/setup-res.c
|
||||
drivers/pci/slot.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/irq/chip.c
|
||||
kernel/irq/devres.c
|
||||
kernel/irq/handle.c
|
||||
kernel/irq/irqdesc.c
|
||||
kernel/irq/irqdomain.c
|
||||
kernel/irq/manage.c
|
||||
kernel/irq/resend.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/panic.c
|
||||
kernel/resource.c
|
||||
kernel/sched/clock.c
|
||||
kernel/sched/completion.c
|
||||
kernel/sched/swait.c
|
||||
kernel/sched/wait.c
|
||||
kernel/smpboot.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/debug_locks.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/idr.c
|
||||
lib/irq_regs.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/list_sort.c
|
||||
lib/iomap.c
|
||||
lib/math/div64.c
|
||||
lib/pci_iomap.c
|
||||
lib/radix-tree.c
|
||||
lib/rbtree.c
|
||||
lib/refcount.c
|
||||
lib/scatterlist.c
|
||||
lib/siphash.c
|
||||
lib/sort.c
|
||||
lib/string.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
lib/xarray.c
|
||||
mm/mempool.c
|
||||
mm/util.c
|
||||
|
||||
certs/common.c
|
||||
crypto/acompress.c
|
||||
crypto/aead.c
|
||||
crypto/aes_generic.c
|
||||
crypto/ahash.c
|
||||
crypto/akcipher.c
|
||||
crypto/algapi.c
|
||||
crypto/algboss.c
|
||||
crypto/api.c
|
||||
crypto/ccm.c
|
||||
crypto/cipher.c
|
||||
crypto/cmac.c
|
||||
crypto/compress.c
|
||||
crypto/crypto_null.c
|
||||
crypto/ctr.c
|
||||
crypto/gcm.c
|
||||
crypto/geniv.c
|
||||
crypto/gf128mul.c
|
||||
crypto/ghash-generic.c
|
||||
crypto/hash_info.c
|
||||
crypto/kpp.c
|
||||
crypto/memneq.c
|
||||
crypto/proc.c
|
||||
crypto/rng.c
|
||||
crypto/scatterwalk.c
|
||||
crypto/scompress.c
|
||||
crypto/sha256_generic.c
|
||||
crypto/shash.c
|
||||
crypto/skcipher.c
|
||||
crypto/testmgr.c
|
||||
drivers/net/Space.c
|
||||
drivers/net/loopback.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/1000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/2000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/5000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/6000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/7000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/8000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/calib.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/devices.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/lib.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/main.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/power.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rs.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/scan.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/sta.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/tt.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/dump.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/img.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/init.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/paging.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/smem.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-debug.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-io.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-trans.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/binding.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/power.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/quota.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rfi.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/sf.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/queue/tx.c
|
||||
lib/asn1_decoder.c
|
||||
lib/bsearch.c
|
||||
lib/crypto/aes.c
|
||||
lib/dynamic_queue_limits.c
|
||||
lib/hweight.c
|
||||
lib/nlattr.c
|
||||
lib/rhashtable.c
|
||||
net/core/datagram.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/net-sysfs.c
|
||||
net/core/net_namespace.c
|
||||
net/core/rtnetlink.c
|
||||
net/core/skbuff.c
|
||||
net/core/sock.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/socket.c
|
||||
net/sched/sch_generic.c
|
||||
net/sched/sch_mq.c
|
||||
net/mac80211/aead_api.c
|
||||
net/mac80211/aes_cmac.c
|
||||
net/mac80211/aes_gmac.c
|
||||
net/mac80211/agg-rx.c
|
||||
net/mac80211/agg-tx.c
|
||||
net/mac80211/airtime.c
|
||||
net/mac80211/cfg.c
|
||||
net/mac80211/chan.c
|
||||
net/mac80211/driver-ops.c
|
||||
net/mac80211/ethtool.c
|
||||
net/mac80211/fils_aead.c
|
||||
net/mac80211/he.c
|
||||
net/mac80211/ht.c
|
||||
net/mac80211/ibss.c
|
||||
net/mac80211/iface.c
|
||||
net/mac80211/key.c
|
||||
net/mac80211/main.c
|
||||
net/mac80211/michael.c
|
||||
net/mac80211/mlme.c
|
||||
net/mac80211/ocb.c
|
||||
net/mac80211/offchannel.c
|
||||
net/mac80211/rate.c
|
||||
net/mac80211/rc80211_minstrel_ht.c
|
||||
net/mac80211/rx.c
|
||||
net/mac80211/s1g.c
|
||||
net/mac80211/scan.c
|
||||
net/mac80211/spectmgmt.c
|
||||
net/mac80211/sta_info.c
|
||||
net/mac80211/status.c
|
||||
net/mac80211/tdls.c
|
||||
net/mac80211/tkip.c
|
||||
net/mac80211/trace.c
|
||||
net/mac80211/tx.c
|
||||
net/mac80211/util.c
|
||||
net/mac80211/vht.c
|
||||
net/mac80211/wep.c
|
||||
net/mac80211/wme.c
|
||||
net/mac80211/wpa.c
|
||||
net/netlink/af_netlink.c
|
||||
net/netlink/genetlink.c
|
||||
net/netlink/policy.c
|
||||
net/packet/af_packet.c
|
||||
net/wireless/ap.c
|
||||
net/wireless/chan.c
|
||||
net/wireless/core.c
|
||||
net/wireless/ethtool.c
|
||||
net/wireless/ibss.c
|
||||
net/wireless/mesh.c
|
||||
net/wireless/mlme.c
|
||||
net/wireless/nl80211.c
|
||||
net/wireless/ocb.c
|
||||
net/wireless/pmsr.c
|
||||
net/wireless/radiotap.c
|
||||
net/wireless/reg.c
|
||||
net/wireless/scan.c
|
||||
net/wireless/sme.c
|
||||
net/wireless/sysfs.c
|
||||
net/wireless/trace.c
|
||||
net/wireless/util.c
|
1290
repos/pc/src/lib/wifi/spec/x86_64/dep.list
Normal file
1290
repos/pc/src/lib/wifi/spec/x86_64/dep.list
Normal file
File diff suppressed because it is too large
Load Diff
273
repos/pc/src/lib/wifi/spec/x86_64/source.list
Normal file
273
repos/pc/src/lib/wifi/spec/x86_64/source.list
Normal file
@ -0,0 +1,273 @@
|
||||
arch/x86/pci/legacy.c
|
||||
drivers/base/bus.c
|
||||
drivers/base/class.c
|
||||
drivers/base/component.c
|
||||
drivers/base/core.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/platform.c
|
||||
drivers/base/property.c
|
||||
drivers/clk/clk-devres.c
|
||||
drivers/pci/access.c
|
||||
drivers/pci/bus.c
|
||||
drivers/pci/host-bridge.c
|
||||
drivers/pci/msi.c
|
||||
drivers/pci/pci.c
|
||||
drivers/pci/pci-driver.c
|
||||
drivers/pci/pci-sysfs.c
|
||||
drivers/pci/probe.c
|
||||
drivers/pci/rom.c
|
||||
drivers/pci/search.c
|
||||
drivers/pci/setup-res.c
|
||||
drivers/pci/slot.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/irq/chip.c
|
||||
kernel/irq/devres.c
|
||||
kernel/irq/handle.c
|
||||
kernel/irq/irqdesc.c
|
||||
kernel/irq/irqdomain.c
|
||||
kernel/irq/manage.c
|
||||
kernel/irq/resend.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/panic.c
|
||||
kernel/resource.c
|
||||
kernel/sched/clock.c
|
||||
kernel/sched/completion.c
|
||||
kernel/sched/swait.c
|
||||
kernel/sched/wait.c
|
||||
kernel/smpboot.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-broadcast.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/debug_locks.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/idr.c
|
||||
lib/irq_regs.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/list_sort.c
|
||||
lib/iomap.c
|
||||
lib/pci_iomap.c
|
||||
lib/radix-tree.c
|
||||
lib/rbtree.c
|
||||
lib/refcount.c
|
||||
lib/scatterlist.c
|
||||
lib/siphash.c
|
||||
lib/sort.c
|
||||
lib/string.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
lib/xarray.c
|
||||
mm/mempool.c
|
||||
mm/util.c
|
||||
|
||||
certs/common.c
|
||||
crypto/acompress.c
|
||||
crypto/aead.c
|
||||
crypto/aes_generic.c
|
||||
crypto/ahash.c
|
||||
crypto/akcipher.c
|
||||
crypto/algapi.c
|
||||
crypto/algboss.c
|
||||
crypto/api.c
|
||||
crypto/ccm.c
|
||||
crypto/cipher.c
|
||||
crypto/cmac.c
|
||||
crypto/compress.c
|
||||
crypto/crypto_null.c
|
||||
crypto/ctr.c
|
||||
crypto/gcm.c
|
||||
crypto/geniv.c
|
||||
crypto/gf128mul.c
|
||||
crypto/ghash-generic.c
|
||||
crypto/hash_info.c
|
||||
crypto/kpp.c
|
||||
crypto/memneq.c
|
||||
crypto/proc.c
|
||||
crypto/rng.c
|
||||
crypto/scatterwalk.c
|
||||
crypto/scompress.c
|
||||
crypto/sha256_generic.c
|
||||
crypto/shash.c
|
||||
crypto/skcipher.c
|
||||
crypto/testmgr.c
|
||||
drivers/net/Space.c
|
||||
drivers/net/loopback.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/1000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/2000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/5000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/6000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/7000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/8000.c
|
||||
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/calib.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/devices.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/lib.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/main.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/power.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rs.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/scan.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/sta.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/tt.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/dump.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/img.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/init.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/paging.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
|
||||
drivers/net/wireless/intel/iwlwifi/fw/smem.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-debug.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-io.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c
|
||||
drivers/net/wireless/intel/iwlwifi/iwl-trans.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/binding.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/power.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/quota.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rfi.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/sf.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
|
||||
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
|
||||
drivers/net/wireless/intel/iwlwifi/queue/tx.c
|
||||
lib/asn1_decoder.c
|
||||
lib/bsearch.c
|
||||
lib/crypto/aes.c
|
||||
lib/dynamic_queue_limits.c
|
||||
lib/hweight.c
|
||||
lib/nlattr.c
|
||||
lib/rhashtable.c
|
||||
net/core/datagram.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/net-sysfs.c
|
||||
net/core/net_namespace.c
|
||||
net/core/rtnetlink.c
|
||||
net/core/skbuff.c
|
||||
net/core/sock.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/socket.c
|
||||
net/sched/sch_generic.c
|
||||
net/sched/sch_mq.c
|
||||
net/mac80211/aead_api.c
|
||||
net/mac80211/aes_cmac.c
|
||||
net/mac80211/aes_gmac.c
|
||||
net/mac80211/agg-rx.c
|
||||
net/mac80211/agg-tx.c
|
||||
net/mac80211/airtime.c
|
||||
net/mac80211/cfg.c
|
||||
net/mac80211/chan.c
|
||||
net/mac80211/driver-ops.c
|
||||
net/mac80211/ethtool.c
|
||||
net/mac80211/fils_aead.c
|
||||
net/mac80211/he.c
|
||||
net/mac80211/ht.c
|
||||
net/mac80211/ibss.c
|
||||
net/mac80211/iface.c
|
||||
net/mac80211/key.c
|
||||
net/mac80211/main.c
|
||||
net/mac80211/michael.c
|
||||
net/mac80211/mlme.c
|
||||
net/mac80211/ocb.c
|
||||
net/mac80211/offchannel.c
|
||||
net/mac80211/rate.c
|
||||
net/mac80211/rc80211_minstrel_ht.c
|
||||
net/mac80211/rx.c
|
||||
net/mac80211/s1g.c
|
||||
net/mac80211/scan.c
|
||||
net/mac80211/spectmgmt.c
|
||||
net/mac80211/sta_info.c
|
||||
net/mac80211/status.c
|
||||
net/mac80211/tdls.c
|
||||
net/mac80211/tkip.c
|
||||
net/mac80211/trace.c
|
||||
net/mac80211/tx.c
|
||||
net/mac80211/util.c
|
||||
net/mac80211/vht.c
|
||||
net/mac80211/wep.c
|
||||
net/mac80211/wme.c
|
||||
net/mac80211/wpa.c
|
||||
net/netlink/af_netlink.c
|
||||
net/netlink/genetlink.c
|
||||
net/netlink/policy.c
|
||||
net/packet/af_packet.c
|
||||
net/wireless/ap.c
|
||||
net/wireless/chan.c
|
||||
net/wireless/core.c
|
||||
net/wireless/ethtool.c
|
||||
net/wireless/ibss.c
|
||||
net/wireless/mesh.c
|
||||
net/wireless/mlme.c
|
||||
net/wireless/nl80211.c
|
||||
net/wireless/ocb.c
|
||||
net/wireless/pmsr.c
|
||||
net/wireless/radiotap.c
|
||||
net/wireless/reg.c
|
||||
net/wireless/scan.c
|
||||
net/wireless/sme.c
|
||||
net/wireless/sysfs.c
|
||||
net/wireless/trace.c
|
||||
net/wireless/util.c
|
29
repos/pc/src/lib/wifi/symbol.map
Normal file
29
repos/pc/src/lib/wifi/symbol.map
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
global:
|
||||
|
||||
/* needed by vfs_wlan */
|
||||
*Lx_kit*initialize*;
|
||||
|
||||
/* initialize function */
|
||||
_*wifi_init*;
|
||||
/* Wifi::Socket_call interface */
|
||||
*Socket_call*;
|
||||
/* Wifi::Socket_call instance */
|
||||
socket_call;
|
||||
/* rfkill interface */
|
||||
_*wifi_*_rfkill*;
|
||||
_*wifi_kick_*;
|
||||
|
||||
/* interface for libnl/wpa_driver_nl82011 */
|
||||
wifi_if*;
|
||||
|
||||
/* used by libnl's time() */
|
||||
jiffies;
|
||||
|
||||
/* for general debugging purposes */
|
||||
lx_backtrace;
|
||||
|
||||
local:
|
||||
|
||||
*;
|
||||
};
|
25
repos/pc/src/lib/wifi/time.cc
Normal file
25
repos/pc/src/lib/wifi/time.cc
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* \brief Lx_emul udelay function for very short delays
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-07-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec);
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec)
|
||||
{
|
||||
if (usec > 100)
|
||||
Genode::error("Cannot delay that long ", usec, " microseconds");
|
||||
|
||||
unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value;
|
||||
while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; }
|
||||
}
|
285
repos/pc/src/lib/wifi/uplink.c
Normal file
285
repos/pc/src/lib/wifi/uplink.c
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* \brief Wireless LAN driver uplink back end
|
||||
* \author Norman Feske
|
||||
* \author Josef Soentgen
|
||||
* \date 2021-06-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <lx_user/init.h>
|
||||
#include <genode_c_api/uplink.h>
|
||||
|
||||
|
||||
static struct genode_uplink *dev_genode_uplink(struct net_device *dev)
|
||||
{
|
||||
return (struct genode_uplink *)dev->ifalias;
|
||||
}
|
||||
|
||||
|
||||
struct genode_uplink_rx_context
|
||||
{
|
||||
struct net_device *dev;
|
||||
};
|
||||
|
||||
|
||||
struct genode_uplink_tx_packet_context
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
|
||||
static unsigned long uplink_tx_packet_content(struct genode_uplink_tx_packet_context *ctx,
|
||||
char *dst, unsigned long dst_len)
|
||||
{
|
||||
struct sk_buff * const skb = ctx->skb;
|
||||
unsigned long total = 0;
|
||||
unsigned long result = 0;
|
||||
unsigned long linear = 0;
|
||||
|
||||
/*
|
||||
* We always get the ethernet header from the headroom. In case
|
||||
* the payload is stored in frags we have to copy them as well.
|
||||
*/
|
||||
|
||||
/* get ethernet header from head before calling skb_headlen */
|
||||
skb_push(skb, ETH_HLEN);
|
||||
total = skb->len;
|
||||
|
||||
if (dst_len < total) {
|
||||
printk("uplink_tx_packet_content: packet exceeds uplink packet size\n");
|
||||
memset(dst, 0, dst_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
linear = min_t(int, skb_headlen(skb), total);
|
||||
skb_copy_from_linear_data(skb, dst, linear);
|
||||
|
||||
total -= linear;
|
||||
result += linear;
|
||||
|
||||
if (total && skb_shinfo(skb)->nr_frags) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = skb_shinfo(skb)->nr_frags - 1; (int)i >= 0; i--) {
|
||||
unsigned int size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
|
||||
void const * frag = skb_frag_address_safe(&skb_shinfo(skb)->frags[i]);
|
||||
|
||||
memcpy(dst + result, frag, size);
|
||||
result += size;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static rx_handler_result_t handle_rx(struct sk_buff **pskb)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct net_device *dev = skb->dev;
|
||||
struct genode_uplink_tx_packet_context ctx = { .skb = skb };
|
||||
|
||||
/*
|
||||
* Pass on EAPOL related frames to send them to the
|
||||
* wpa_supplicant.
|
||||
*/
|
||||
if (ntohs(skb->protocol) == ETH_P_PAE)
|
||||
return RX_HANDLER_PASS;
|
||||
|
||||
{
|
||||
bool uplink_available = !!dev_genode_uplink(dev);
|
||||
bool progress = uplink_available &&
|
||||
genode_uplink_tx_packet(dev_genode_uplink(dev),
|
||||
uplink_tx_packet_content,
|
||||
&ctx);
|
||||
if (!progress && uplink_available)
|
||||
printk("handle_rx: uplink saturated, dropping packet\n");
|
||||
|
||||
if (progress)
|
||||
genode_uplink_notify_peers();
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
return RX_HANDLER_CONSUMED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create Genode uplink for given net device
|
||||
*
|
||||
* The uplink is registered at the dev->ifalias pointer.
|
||||
*/
|
||||
static void handle_create_uplink(struct net_device *dev)
|
||||
{
|
||||
struct genode_uplink_args args;
|
||||
|
||||
if (dev_genode_uplink(dev))
|
||||
return;
|
||||
|
||||
if (!netif_carrier_ok(dev))
|
||||
return;
|
||||
|
||||
printk("create uplink for net device %s\n", &dev->name[0]);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
if (dev->addr_len != sizeof(args.mac_address)) {
|
||||
printk("error: net device has unexpected addr_len %u\n", dev->addr_len);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < dev->addr_len; i++)
|
||||
args.mac_address[i] = dev->dev_addr[i];
|
||||
}
|
||||
|
||||
args.label = &dev->name[0];
|
||||
|
||||
dev->ifalias = (struct dev_ifalias *)genode_uplink_create(&args);
|
||||
}
|
||||
|
||||
|
||||
static void handle_destroy_uplink(struct net_device *dev)
|
||||
{
|
||||
struct genode_uplink *uplink = dev_genode_uplink(dev);
|
||||
|
||||
if (!uplink)
|
||||
return;
|
||||
|
||||
if (netif_carrier_ok(dev))
|
||||
return;
|
||||
|
||||
genode_uplink_destroy(uplink);
|
||||
|
||||
dev->ifalias = NULL;
|
||||
}
|
||||
|
||||
|
||||
static genode_uplink_rx_result_t uplink_rx_one_packet(struct genode_uplink_rx_context *ctx,
|
||||
char const *ptr, unsigned long len)
|
||||
{
|
||||
struct sk_buff *skb = alloc_skb(len + 128, GFP_KERNEL);
|
||||
skb_reserve(skb, 128);
|
||||
|
||||
if (!skb) {
|
||||
printk("alloc_skb failed\n");
|
||||
return GENODE_UPLINK_RX_RETRY;
|
||||
}
|
||||
|
||||
skb_copy_to_linear_data(skb, ptr, len);
|
||||
skb_put(skb, len);
|
||||
skb->dev = ctx->dev;
|
||||
|
||||
if (dev_queue_xmit(skb) < 0) {
|
||||
printk("lx_user: failed to xmit packet\n");
|
||||
return GENODE_UPLINK_RX_REJECTED;
|
||||
}
|
||||
|
||||
return GENODE_UPLINK_RX_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct task_struct *uplink_task_struct_ptr; /* used by 'Main' for lx_emul_task_unblock */
|
||||
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
struct netdev_event_notification
|
||||
{
|
||||
struct notifier_block nb;
|
||||
struct netdev_net_notifier nn;
|
||||
|
||||
bool registered;
|
||||
};
|
||||
|
||||
|
||||
static int uplink_netdev_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
/*
|
||||
* For now we ignore what kind of event occurred and simply
|
||||
* unblock the uplink task.
|
||||
*/
|
||||
if (uplink_task_struct_ptr)
|
||||
lx_emul_task_unblock(uplink_task_struct_ptr);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
||||
static int user_task_function(void *arg)
|
||||
{
|
||||
struct netdev_event_notification events;
|
||||
memset(&events, 0, sizeof (struct netdev_event_notification));
|
||||
|
||||
events.nb.notifier_call = uplink_netdev_event;
|
||||
events.registered = false;
|
||||
|
||||
for (;;) {
|
||||
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev(&init_net, dev) {
|
||||
|
||||
/* there might be more devices, e.g. 'lo', in the netnamespace */
|
||||
if (strcmp(&dev->name[0], "wlan0") != 0)
|
||||
continue;
|
||||
|
||||
/* enable link sensing, repeated calls are handled by testing IFF_UP */
|
||||
dev_open(dev, 0);
|
||||
|
||||
/* install rx handler once */
|
||||
if (!netdev_is_rx_handler_busy(dev))
|
||||
netdev_rx_handler_register(dev, handle_rx, NULL);
|
||||
|
||||
/* register notifier once */
|
||||
if (!events.registered) {
|
||||
events.registered =
|
||||
!register_netdevice_notifier_dev_net(dev,
|
||||
&events.nb,
|
||||
&events.nn);
|
||||
}
|
||||
|
||||
/* respond to cable plug/unplug */
|
||||
handle_create_uplink(dev);
|
||||
handle_destroy_uplink(dev);
|
||||
|
||||
/* transmit packets received from the uplink session */
|
||||
if (netif_carrier_ok(dev)) {
|
||||
|
||||
struct genode_uplink_rx_context ctx = { .dev = dev };
|
||||
|
||||
while (genode_uplink_rx(dev_genode_uplink(dev),
|
||||
uplink_rx_one_packet,
|
||||
&ctx));
|
||||
}
|
||||
};
|
||||
|
||||
/* block until lx_emul_task_unblock */
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uplink_init(void)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
skb_init();
|
||||
|
||||
pid = kernel_thread(user_task_function, NULL, CLONE_FS | CLONE_FILES);
|
||||
|
||||
uplink_task_struct_ptr = find_task_by_pid_ns(pid, NULL);
|
||||
}
|
104
repos/pc/src/lib/wifi/wlan.cc
Normal file
104
repos/pc/src/lib/wifi/wlan.cc
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* \brief Wireless network driver Linux port
|
||||
* \author Josef Soentgen
|
||||
* \date 2022-02-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
#include <genode_c_api/uplink.h>
|
||||
|
||||
/* DDE Linux includes */
|
||||
#include <lx_emul/init.h>
|
||||
#include <lx_emul/page_virt.h>
|
||||
#include <lx_emul/task.h>
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/init.h>
|
||||
#include <lx_user/io.h>
|
||||
|
||||
|
||||
extern "C" void lx_user_handle_io(void) { }
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
bool wifi_get_rfkill(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void wifi_set_rfkill(bool blocked)
|
||||
{
|
||||
(void)blocked;
|
||||
}
|
||||
|
||||
|
||||
extern "C" unsigned int wifi_ifindex(void)
|
||||
{
|
||||
/* TODO replace with actual qyery */
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
extern "C" char const *wifi_ifname(void)
|
||||
{
|
||||
/* TODO replace with actual qyery */
|
||||
return "wlan0";
|
||||
}
|
||||
|
||||
|
||||
extern "C" struct task_struct *uplink_task_struct_ptr;
|
||||
|
||||
struct Wlan
|
||||
{
|
||||
Env &_env;
|
||||
Io_signal_handler<Wlan> _signal_handler { _env.ep(), *this,
|
||||
&Wlan::_handle_signal };
|
||||
|
||||
void _handle_signal()
|
||||
{
|
||||
if (uplink_task_struct_ptr) {
|
||||
lx_emul_task_unblock(uplink_task_struct_ptr);
|
||||
Lx_kit::env().scheduler.schedule();
|
||||
}
|
||||
|
||||
genode_uplink_notify_peers();
|
||||
}
|
||||
|
||||
Wlan(Env &env) : _env { env }
|
||||
{
|
||||
genode_uplink_init(genode_env_ptr(_env),
|
||||
genode_allocator_ptr(Lx_kit::env().heap),
|
||||
genode_signal_handler_ptr(_signal_handler));
|
||||
|
||||
lx_emul_start_kernel(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Genode::Blockade *wpa_blockade;
|
||||
|
||||
|
||||
void wifi_init(Genode::Env &env,
|
||||
Genode::Blockade &blockade,
|
||||
bool disable_11n,
|
||||
Genode::Signal_context_capability rfkill)
|
||||
{
|
||||
(void)disable_11n;
|
||||
(void)rfkill;
|
||||
|
||||
wpa_blockade = &blockade;
|
||||
|
||||
static Wlan wlan(env);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user