wifi: get firmware from tar archive

This commit changes the firmware handling from requesting each
firmware file as a ROM module that is checked against a list of
known images (including their size) to requesting each file via
the local VFS of the 'wifi_drv'. This allows for using the original
probing mechanism that tries to select a matching firmware version.

The 'repos/dde_linux/src/drivers/wifi/README' file contains more
detailed information on how to configure the driver.

Issue #4861.
This commit is contained in:
Josef Söntgen 2023-05-03 17:34:22 +02:00 committed by Christian Helmuth
parent 3ba070e5e4
commit ea0a692879
22 changed files with 553 additions and 197 deletions

View File

@ -0,0 +1,58 @@
/*
* \brief Firmware access interface
* \author Josef Soentgen
* \date 2023-05-05
*/
/*
* Copyright (C) 2023 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _WIFI__FIRMWARE_H_
#define _WIFI__FIRMWARE_H_
#include <util/interface.h>
namespace Wifi {
struct Firmware_request : Genode::Interface
{
enum State { INVALID, PROBING, PROBING_COMPLETE,
REQUESTING, REQUESTING_COMPLETE };
State state { INVALID };
bool success { false };
/* name of the firmware image requested by the driver */
char const *name { nullptr };
/*
* Length of the firmware image in bytes used for
* arranging the memory buffer for the loaded firmware.
*/
unsigned long fw_len { 0 };
/*
* Pointer to and length of the memory location where
* the firmware image should be copied into to. It is
* allocated by the driver.
*/
char *dst { nullptr };
unsigned long dst_len { 0 };
virtual void submit_response() = 0;
};
struct Firmware_request_handler : Genode::Interface
{
virtual void submit_request() = 0;
};
void firmware_establish_handler(Firmware_request_handler &);
Firmware_request *firmware_get_request();
} /* namespace Wifi */
#endif /* _WIFI__FIRMWARE_H_ */

View File

@ -19,3 +19,5 @@ jiffies_64 D 0
socket_call B 1
wifi_ifindex T
wifi_ifname T
_ZN4Wifi20firmware_get_requestEv T
_ZN4Wifi26firmware_establish_handlerERNS_24Firmware_request_handlerE T

View File

@ -1 +1 @@
a04c8eb7c80e3d17836c7c8065c5c4358af8258b
dc55c3afb4c9498364834030d33e3922addb1387

View File

@ -2,7 +2,7 @@ LICENSE := mixed
VERSION := 1
DOWNLOADS := fw.archive
FW_REV := a3216b6e5f31996f791577ba019a58419122ace6
FW_REV := b7b5865b749f5a321259d95e0959929789a94959
URL(fw) := https://github.com/cnuke/dde_linux_firmware/archive/$(FW_REV).tar.gz
SHA(fw) := 310be6f8fd5ba65caa92187a4c1c9c6c8ab05ba4ef4df869e8a486594286fdc7
SHA(fw) := 0fd10961cae2582a9a3e9efca7a8d761427f215562626a221062abd001e36772
DIR(fw) := firmware

View File

@ -1,19 +0,0 @@
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/*.bin .
cp $(PORT_DIR)/firmware/*.ucode .
cp $(PORT_DIR)/firmware/*.pnvm .
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

View File

@ -119,6 +119,9 @@ install_config {
<jitterentropy name="urandom"/>
</dir>
<dir name="config"> <ram/> </dir>
<dir name="firmware">
<tar name="wifi_firmware.tar"/>
</dir>
</vfs>
<libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
</config>
@ -128,6 +131,7 @@ install_config {
<service name="Report"> <child name="report_rom"/> </service>
<service name="ROM" label="wifi_config"> <child name="config_rom"/> </service>
<service name="ROM" label="wifi.lib.so"> <parent label="pc_wifi.lib.so"/> </service>
<service name="ROM" label="wifi_firmware.tar"> <parent label="pc_wifi_firmware.tar"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>

View File

@ -20,15 +20,19 @@ can be used:
! <libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
! <vfs>
! <dir name="dev"> <log/> <null/> <rtc/> <wifi/>
! <jitterentropy name="random"/>
! <jitterentropy name="urandom"/>
! <jitterentropy name="random"/>
! <jitterentropy name="urandom"/>
! </dir>
! <dir name="firmware"> <tar name="wifi_firmware.tar"/> </dir>
! </vfs>
! </config>
! <route>
! <service name="ROM" label="wifi.lib.so">
! <parent label="pc_wifi.lib.so"/>
! </service>
! <service name="ROM" label="wifi_firmware.tar">
! <parent label="pc_wifi_firmware.tar"/>
! </service>
! <service name="Rtc"> <any-child /> </service>
! <any-service> <parent/> <any-child /> </any-service>
! </route>
@ -44,15 +48,19 @@ snippet illustrates the use of the driver on the PinePhone:
! <libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
! <vfs>
! <dir name="dev"> <log/> <null/> <rtc/> <wifi/>
! <jitterentropy name="random"/>
! <jitterentropy name="urandom"/>
! <jitterentropy name="random"/>
! <jitterentropy name="urandom"/>
! </dir>
! <dir name="firmware"> <tar name="wifi_firmware.tar"/> </dir>
! </vfs>
! </config>
! <route>
! <service name="ROM" label="wifi.lib.so">
! <parent label="a64_wifi.lib.so"/>
! </service>
! <service name="ROM" label="wifi_firmware.tar">
! <parent label="a64_wifi_firmware.tar"/>
! </service>
! <service name="ROM" label="dtb">
! <parent label="wifi-pinephone.dtb"/>
! </service>
@ -65,6 +73,12 @@ Note the ROM route for the device-tree binary that is essential on
ARM-based platforms. The name of the request DTB can by changed
by setting the 'dtb' attribute in the config node.
Depending on the used device additional firmware images might be
required. The driver will request them by accessing the '/firmware'
directory in the driver's local VFS. It is up to the configuration
how those files are made available. In these examples they are
contained in an '.tar' archive that is request as a ROM module.
The driver will request access to the ROM module 'wifi_config' to
connect to a network:

View File

@ -0,0 +1,77 @@
/*
* \brief Firmware I/O functions
* \author Josef Soentgen
* \date 2023-05-05
*/
/*
* Copyright (C) 2023 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <libc/component.h>
/* libc includes */
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/* local includes */
#include "access_firmware.h"
Stat_firmware_result access_firmware(char const *path)
{
Stat_firmware_result result { false, 0 };
Libc::with_libc([&] {
struct stat stat_buf { };
int const err = ::stat(path, &stat_buf);
if (!err) {
result.success = true;
result.length = stat_buf.st_size;
}
});
return result;
}
Read_firmware_result read_firmware(char const *path, char *dst, size_t dst_len)
{
Read_firmware_result result { false };
Libc::with_libc([&] {
int const fd = ::open(path, O_RDONLY);
if (fd < 0)
return;
size_t total = 0;
size_t remain = dst_len;
do {
ssize_t const cur = ::read(fd, dst, remain);
if (cur < ssize_t(0) && errno != EINTR)
break;
if (cur == ssize_t(0))
break;
total += cur;
dst += cur;
remain -= (size_t)cur;
} while (total < dst_len);
(void)close(fd);
if (total > 0 && (size_t)total != dst_len)
return;
result.success = true;
});
return result;
}

View File

@ -0,0 +1,33 @@
/*
* \brief Firmware I/O functions
* \author Josef Soentgen
* \date 2023-05-05
*/
/*
* Copyright (C) 2023 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _ACCESS_FIRMWARE_H_
#define _ACCESS_FIRMWARE_H_
struct Stat_firmware_result
{
size_t length;
bool success;
};
Stat_firmware_result access_firmware(char const *path);
struct Read_firmware_result
{
bool success;
};
Read_firmware_result read_firmware(char const *path, char *dst, size_t dst_len);
#endif /* _ACCESS_FIRMWARE_H_ */

View File

@ -20,11 +20,14 @@
#include <timer_session/connection.h>
#include <util/xml_node.h>
/* local includes */
#include <util.h>
#include <wpa.h>
#include <frontend.h>
/* wifi library includes */
#include <wifi/firmware.h>
/* local includes */
#include "util.h"
#include "wpa.h"
#include "frontend.h"
#include "access_firmware.h"
using namespace Genode;
@ -98,12 +101,78 @@ struct Main
Blockade _wpa_startup_blockade { };
struct Request_handler : Wifi::Firmware_request_handler
{
Signal_handler<Request_handler> _handler;
void _handle_request()
{
using Fw_path = Genode::String<128>;
using namespace Wifi;
Firmware_request *request_ptr = firmware_get_request();
if (!request_ptr)
return;
Firmware_request &request = *request_ptr;
request.success = false;
switch (request.state) {
case Firmware_request::State::PROBING:
{
Fw_path const path { "/firmware/", request.name };
Stat_firmware_result const result = access_firmware(path.string());
request.fw_len = result.success ? result.length : 0;
request.success = result.success;
request.submit_response();
break;
}
case Firmware_request::State::REQUESTING:
{
Fw_path const path { "/firmware/", request.name };
Read_firmware_result const result =
read_firmware(path.string(), request.dst, request.dst_len);
request.success = result.success;
request.submit_response();
break;
}
case Firmware_request::State::INVALID:
break;
case Firmware_request::State::PROBING_COMPLETE:
break;
case Firmware_request::State::REQUESTING_COMPLETE:
break;
}
}
Request_handler(Genode::Entrypoint &ep)
:
_handler { ep, *this, &Request_handler::_handle_request }
{ }
void submit_request() override
{
_handler.local_submit();
}
};
Request_handler _request_handler { env.ep() };
Main(Genode::Env &env) : env(env)
{
_frontend.construct(env, _wifi_msg_buffer);
_wifi_frontend = &*_frontend;
wifi_set_rfkill_sigh(_wifi_frontend->rfkill_sigh());
Wifi::firmware_establish_handler(_request_handler);
_wpa.construct(env, _wpa_startup_blockade);
wifi_init(env, _wpa_startup_blockade);

View File

@ -1,5 +1,5 @@
TARGET := wifi_drv
SRC_CC := main.cc wpa.cc
SRC_CC := main.cc wpa.cc access_firmware.cc
LIBS := base wifi
LIBS += libc
LIBS += wpa_supplicant

View File

@ -17,103 +17,41 @@
/* local includes */
#include <lx_kit/env.h>
#include <firmware_list.h>
using namespace Genode;
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-36.ucode", 2428004, nullptr },
{ "iwlwifi-8265-36.ucode", 2436632, nullptr },
{ "iwlwifi-9000-pu-b0-jf-b0-46.ucode", 1514876, nullptr },
{ "iwlwifi-9260-th-b0-jf-b0-46.ucode", 1490376, nullptr },
{ "iwlwifi-QuZ-a0-hr-b0-68.ucode", 1355800, nullptr },
{ "iwlwifi-QuZ-a0-hr-b0-72.ucode", 1355800, "iwlwifi-QuZ-a0-hr-b0-68.ucode" },
{ "iwlwifi-so-a0-hr-b0-68.ucode", 1429192, nullptr },
{ "iwlwifi-so-a0-hr-b0-72.ucode", 1429192, "iwlwifi-so-a0-hr-b0-68.ucode" },
{ "iwlwifi-so-a0-gf-a0-68.ucode", 1533812, nullptr },
{ "iwlwifi-so-a0-gf-a0-72.ucode", 1533812, "iwlwifi-so-a0-gf-a0-68.ucode" },
{ "iwlwifi-so-a0-gf-a0.pnvm", 41808, nullptr },
{ "iwlwifi-ty-a0-gf-a0-68.ucode", 1494304, nullptr },
{ "iwlwifi-ty-a0-gf-a0-72.ucode", 1494304, "iwlwifi-ty-a0-gf-a0-68.ucode" },
{ "iwlwifi-ty-a0-gf-a0.pnvm", 41588, nullptr },
{ "rtl8192eu_nic.bin", 31818, nullptr },
{ "rtlwifi/rtl8192eefw.bin", 31818, "rtl8192eu_nic.bin" },
{ "rtl8188efw.bin", 11216, nullptr },
{ "rtlwifi/rtl8188efw.bin", 11216, "rtl8188efw.bin" }, /* FW Power Save off */
};
size_t fw_list_len = sizeof(fw_list) / sizeof(fw_list[0]);
/**********************
** linux/firmware.h **
**********************/
extern size_t _wifi_probe_firmware(char const *name);
extern int _wifi_request_firmware(char const *name, char *dst, size_t dst_len);
extern "C" int lx_emul_request_firmware_nowait(const char *name, void **dest,
size_t *result, bool warn)
size_t *result, bool /* warn */)
{
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 (strcmp(name, fw_list[i].requested_name) == 0) {
fwl = &fw_list[i];
break;
}
}
if (!fwl ) {
if (warn)
error("firmware '", name, "' is not in the firmware white list");
size_t const fw_size = _wifi_probe_firmware(name);
if (!fw_size)
return -1;
}
char const *fw_name = fwl->available_name
? fwl->available_name : fwl->requested_name;
Rom_connection rom(Lx_kit::env().env, fw_name);
Dataspace_capability ds_cap = rom.dataspace();
if (!ds_cap.valid()) {
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);
char *data = (char*)Lx_kit::env().heap.alloc(fw_size);
if (!data)
return -1;
void const *image = Lx_kit::env().env.rm().attach(ds_cap);
memcpy(data, image, fwl->size);
Lx_kit::env().env.rm().detach(image);
if (_wifi_request_firmware(name, data, fw_size)) {
error("could not request firmware ", name);
Lx_kit::env().heap.free(data, fw_size);
return -1;
}
*dest = data;
*result = fwl->size;
*result = fw_size;
return 0;
}

View File

@ -1,26 +0,0 @@
/*
* \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_ */

View File

@ -136,34 +136,41 @@ void iput(struct inode * inode)
#include <linux/firmware.h>
#if 0
struct firmware_work {
struct work_struct work;
struct firmware const *firmware;
struct firmware *firmware;
char const *name;
void *context;
void (*cont)(struct firmware const *, void *);
};
extern int lx_emul_request_firmware_nowait(const char *name, void *dest,
size_t *result, bool warn);
static void request_firmware_work_func(struct work_struct *work)
{
struct firmware_work *fw_work =
container_of(work, struct firmware_work, work);
struct firmware *fw = fw_work->firmware;
fw_work->cont(fw_work->firmware, fw_work->context);
if (lx_emul_request_firmware_nowait(fw_work->name,
&fw->data, &fw->size, true)) {
/*
* Free and set to NULL here as passing NULL to
* 'cont()' triggers requesting next possible ucode
* version.
*/
kfree(fw);
fw = NULL;
}
fw_work->cont(fw, fw_work->context);
kfree(fw_work);
kfree(fw);
}
#endif
extern int lx_emul_request_firmware_nowait(const char *name, void *dest,
size_t *result, bool warn);
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,
@ -172,41 +179,15 @@ int request_firmware_nowait(struct module * module,
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, true)) {
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->name = name;
fw_work->firmware = fw;
fw_work->context = context;
fw_work->cont = cont;
@ -215,7 +196,6 @@ int request_firmware_nowait(struct module * module,
schedule_work(&fw_work->work);
return 0;
#endif
}
@ -246,8 +226,14 @@ int request_firmware(const struct firmware ** firmware_p,
}
extern void lx_emul_release_firmware(void const *data, size_t size);
void release_firmware(const struct firmware * fw)
{
if (!fw)
return;
lx_emul_release_firmware(fw->data, fw->size);
kfree(fw);
}

View File

@ -14,6 +14,8 @@
_*wifi_*_rfkill*;
_*wifi_kick_*;
_*Wifi*firmware*;
/* interface for libnl/wpa_driver_nl82011 */
wifi_if*;

View File

@ -27,6 +27,9 @@
#include <lx_kit/init.h>
#include <lx_user/io.h>
/* wifi includes */
#include <wifi/firmware.h>
/* local includes */
#include "lx_user.h"
#include "dtb_helper.h"
@ -79,6 +82,168 @@ bool wifi_get_rfkill(void)
}
/* Firmware access, move to object later */
struct task_struct;
struct Firmware_helper
{
Firmware_helper(Firmware_helper const&) = delete;
Firmware_helper & operator = (Firmware_helper const&) = delete;
void *_waiting_task { nullptr };
void *_calling_task { nullptr };
Genode::Signal_handler<Firmware_helper> _response_handler;
void _handle_response()
{
if (_calling_task)
lx_emul_task_unblock((struct task_struct*)_calling_task);
Lx_kit::env().scheduler.schedule();
}
Wifi::Firmware_request_handler &_request_handler;
struct Request : Wifi::Firmware_request
{
Genode::Signal_context &_response_handler;
Request(Genode::Signal_context &sig_ctx)
:
_response_handler { sig_ctx }
{ }
void submit_response() override
{
switch (state) {
case Firmware_request::State::PROBING:
state = Firmware_request::State::PROBING_COMPLETE;
break;
case Firmware_request::State::REQUESTING:
state = Firmware_request::State::REQUESTING_COMPLETE;
break;
default:
return;
}
_response_handler.local_submit();
}
};
using S = Wifi::Firmware_request::State;
Request _request { _response_handler };
void _update_waiting_task()
{
if (_waiting_task)
if (_waiting_task != lx_emul_task_get_current())
warning("Firmware_request: already waiting task is not current task");
_waiting_task = lx_emul_task_get_current();
}
void _submit_request_and_wait_for(Wifi::Firmware_request::State state)
{
_calling_task = lx_emul_task_get_current();
_request_handler.submit_request();
do {
lx_emul_task_schedule(true);
} while (_request.state != state);
}
void _wait_until_pending_request_finished()
{
while (_request.state != S::INVALID) {
_update_waiting_task();
lx_emul_task_schedule(true);
}
}
void _wakeup_any_waiting_request()
{
_request.state = S::INVALID;
if (_waiting_task) {
lx_emul_task_unblock((struct task_struct*)_waiting_task);
_waiting_task = nullptr;
}
_calling_task = nullptr;
}
Firmware_helper(Genode::Entrypoint &ep,
Wifi::Firmware_request_handler &request_handler)
:
_response_handler { ep, *this, &Firmware_helper::_handle_response },
_request_handler { request_handler }
{ }
size_t perform_probing(char const *name)
{
_wait_until_pending_request_finished();
_request.name = name;
_request.state = S::PROBING;
_request.dst = nullptr;
_request.dst_len = 0;
_submit_request_and_wait_for(S::PROBING_COMPLETE);
size_t const fw_length = _request.success ? _request.fw_len : 0;
_wakeup_any_waiting_request();
return fw_length;
}
int perform_requesting(char const *name, char *dst, size_t dst_len)
{
_wait_until_pending_request_finished();
_request.name = name;
_request.state = S::REQUESTING;
_request.dst = dst;
_request.dst_len = dst_len;
_submit_request_and_wait_for(S::REQUESTING_COMPLETE);
bool const success = _request.success;
_wakeup_any_waiting_request();
return success ? 0 : -1;
}
Wifi::Firmware_request *request()
{
return &_request;
}
};
Constructible<Firmware_helper> firmware_helper { };
size_t _wifi_probe_firmware(char const *name)
{
if (firmware_helper.constructed())
return firmware_helper->perform_probing(name);
return 0;
}
int _wifi_request_firmware(char const *name, char *dst, size_t dst_len)
{
if (firmware_helper.constructed())
return firmware_helper->perform_requesting(name, dst, dst_len);
return -1;
}
extern "C" unsigned int wifi_ifindex(void)
{
/* TODO replace with actual qyery */
@ -209,3 +374,18 @@ void wifi_set_rfkill_sigh(Signal_context_capability cap)
{
_rfkill_sigh_cap = cap;
}
void Wifi::firmware_establish_handler(Wifi::Firmware_request_handler &request_handler)
{
firmware_helper.construct(Lx_kit::env().env.ep(), request_handler);
}
Wifi::Firmware_request *Wifi::firmware_get_request()
{
if (firmware_helper.constructed())
return firmware_helper->request();
return nullptr;
}

View File

@ -158,6 +158,7 @@ proc nic_driver_routes { } {
set result(pc) {
<service name="ROM" label="nic_drv"> <parent label="ipxe_nic_drv"/> </service>
<service name="ROM" label="wifi.lib.so"> <parent label="pc_wifi.lib.so"/> </service>
<service name="ROM" label="wifi_firmware.tar"> <parent label="pc_wifi_firmware.tar"/> </service>
}
set result(mnt_reform2) {
@ -173,6 +174,7 @@ proc nic_driver_routes { } {
set result(pinephone) {
<service name="ROM" label="wifi.lib.so"> <parent label="a64_wifi.lib.so"/> </service>
<service name="ROM" label="wifi_drv.dtb"> <parent label="wifi-pinephone.dtb"/> </service>
<service name="ROM" label="wifi_firmware.tar"> <parent label="a64_wifi_firmware.tar"/> </service>
}
if {[info exists result([board])]} {

View File

@ -35,6 +35,11 @@ void Sculpt::gen_wifi_drv_start_content(Xml_generator &xml)
gen_named_node(xml, "inline", "rtc", [&] () {
xml.append("2018-01-01 00:01");
});
gen_named_node(xml, "dir", "firmware", [&] () {
xml.node("tar", [&] () {
xml.attribute("name", "wifi_firmware.tar");
});
});
});
xml.node("libc", [&] () {
@ -69,32 +74,9 @@ void Sculpt::gen_wifi_drv_start_content(Xml_generator &xml)
gen_parent_rom_route(xml, "vfs_wifi.lib.so");
gen_parent_rom_route(xml, "libssl.lib.so");
gen_parent_rom_route(xml, "wifi.lib.so");
gen_parent_rom_route(xml, "wifi_firmware.tar");
gen_parent_rom_route(xml, "wpa_driver_nl80211.lib.so");
gen_parent_rom_route(xml, "wpa_supplicant.lib.so");
gen_parent_rom_route(xml, "iwlwifi-1000-5.ucode");
gen_parent_rom_route(xml, "iwlwifi-3160-17.ucode");
gen_parent_rom_route(xml, "iwlwifi-3168-17.ucode");
gen_parent_rom_route(xml, "iwlwifi-5000-5.ucode");
gen_parent_rom_route(xml, "iwlwifi-6000-4.ucode");
gen_parent_rom_route(xml, "iwlwifi-6000g2a-6.ucode");
gen_parent_rom_route(xml, "iwlwifi-6000g2b-6.ucode");
gen_parent_rom_route(xml, "iwlwifi-7260-17.ucode");
gen_parent_rom_route(xml, "iwlwifi-7265-17.ucode");
gen_parent_rom_route(xml, "iwlwifi-7265D-29.ucode");
gen_parent_rom_route(xml, "iwlwifi-8000C-36.ucode");
gen_parent_rom_route(xml, "iwlwifi-8265-36.ucode");
gen_parent_rom_route(xml, "iwlwifi-9000-pu-b0-jf-b0-46.ucode");
gen_parent_rom_route(xml, "iwlwifi-9260-th-b0-jf-b0-46.ucode");
gen_parent_rom_route(xml, "iwlwifi-QuZ-a0-hr-b0-68.ucode");
gen_parent_rom_route(xml, "iwlwifi-so-a0-hr-b0-68.ucode");
gen_parent_rom_route(xml, "iwlwifi-so-a0-gf-a0-68.ucode");
gen_parent_rom_route(xml, "iwlwifi-so-a0-gf-a0.pnvm");
gen_parent_rom_route(xml, "iwlwifi-ty-a0-gf-a0-68.ucode");
gen_parent_rom_route(xml, "iwlwifi-ty-a0-gf-a0.pnvm");
gen_parent_rom_route(xml, "rtl8192eu_nic.bin");
gen_parent_rom_route(xml, "rtl8188efw.bin");
gen_parent_rom_route(xml, "regulatory.db");
gen_parent_rom_route(xml, "regulatory.db.p7s");
gen_parent_route<Cpu_session> (xml);
gen_parent_route<Pd_session> (xml);
gen_parent_route<Rm_session> (xml);

View File

@ -0,0 +1,24 @@
PORT_DIR := $(call port_dir,$(GENODE_DIR)/repos/dde_linux/ports/linux-firmware)
content: ucode_files LICENSE.wifi_drv pc_wifi_firmware.tar
.PHONY: ucode_files
ucode_files:
cp -R $(PORT_DIR)/firmware/rtlwifi .
cp $(PORT_DIR)/firmware/*.ucode .
cp $(PORT_DIR)/firmware/*.pnvm .
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
pc_wifi_firmware.tar: ucode_files LICENSE.wifi_drv
tar --mtime='2023-05-03 00:00Z' --remove-files \
-cf $@ -C . *.* rtlwifi/*.* && \
rmdir rtlwifi

View File

@ -1,3 +1,10 @@
#
# Set to true in case the driver needs to be debugged to
# pull in the locally build binaries rather than the ones
# from the depot.
#
set debug_driver false
#
# Configure wireless lan
#
@ -80,6 +87,11 @@ set build_components {
lib/vfs_lwip
}
append_if $debug_driver build_components {
drivers/wifi
lib/pc_wifi
}
build $build_components
#
@ -270,7 +282,7 @@ append config {
<config verbose="yes"/>
</start>
<start name="wifi_drv" caps="250" priority="-1">
<start name="wifi_drv" caps="260" priority="-1">
<resource name="RAM" quantum="32M"/>
<config ld_verbose="yes">
<report mac_address="true"/>
@ -281,6 +293,9 @@ append config {
<jitterentropy name="urandom"/>
<wifi/>
</dir>
<dir name="firmware">
<tar name="wifi_firmware.tar"/>
</dir>
</vfs>
</config>
<route>
@ -291,6 +306,7 @@ append config {
<service name="Report" label="devices"> <child name="devices_report_rom"/> </service>
<service name="ROM" label="wifi_config"> <child name="config_rom"/> </service>
<service name="ROM" label="wifi.lib.so"> <parent label="pc_wifi.lib.so"/> </service>
<service name="ROM" label="wifi_firmware.tar"> <parent label="pc_wifi_firmware.tar"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
@ -299,6 +315,16 @@ append config {
install_config $config
#
# Provide dummy 'wifi.lib.so' shared-object for
# boot-module assembly
#
if {$debug_driver} {
exec rm bin/wifi.lib.so
exec echo dummy > bin/wifi.lib.so
}
#
# Boot modules
#

View File

@ -261,7 +261,7 @@ append config { </wifi_config>
</start>
<start name="nic_drv" caps="300">
<binary name="pc_wifi_drv"/>
<binary name="wifi_drv"/>
<resource name="RAM" quantum="32M"/>
<config>
<libc stdout="/dev/null" stderr="/dev/log" rtc="/dev/rtc"/>
@ -272,6 +272,9 @@ append config { </wifi_config>
<jitterentropy name="urandom"/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="firmware">
<tar name="wifi_firmware.tar"/>
</dir>
</vfs>
</config>
<route>
@ -279,6 +282,7 @@ append config { </wifi_config>
<service name="File_system"> <child name="config_fs"/> </service>
<service name="ROM" label="wifi_config"> <child name="config_rom" /> </service>
<service name="ROM" label="wifi.lib.so"> <parent label="pc_wifi.lib.so"/> </service>
<service name="ROM" label="wifi_firmware.tar"> <parent label="pc_wifi_firmware.tar"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Uplink"> <child name="nic_router"/> </service>
<any-service> <parent/> <any-child /> </any-service>