wifi/pc: implement firmware requests without warning

Until now, requesting optional blobs such as 'iwl-debug-yoyo.bin' has
just failed silently. To support desired blobs such as PNVM firmware,
implement the loading of optional firmware while preserving the nowarn
characteristics of the function.

Issue #4663
This commit is contained in:
Benjamin Lamowski 2022-11-10 13:41:12 +01:00 committed by Christian Helmuth
parent 0a8d6ddba9
commit bcea2a958e
2 changed files with 21 additions and 14 deletions

View File

@ -56,7 +56,8 @@ size_t fw_list_len = sizeof(fw_list) / sizeof(fw_list[0]);
** linux/firmware.h ** ** linux/firmware.h **
**********************/ **********************/
extern "C" int lx_emul_request_firmware_nowait(const char *name, void **dest, size_t *result) extern "C" int lx_emul_request_firmware_nowait(const char *name, void **dest,
size_t *result, bool warn)
{ {
if (!dest || !result) if (!dest || !result)
return -1; return -1;
@ -70,8 +71,10 @@ extern "C" int lx_emul_request_firmware_nowait(const char *name, void **dest, si
} }
} }
if (!fwl) { if (!fwl ) {
Genode::error("firmware '", name, "' is not in the firmware white list"); if (warn)
Genode::error("firmware '", name, "' is not in the firmware white list");
return -1; return -1;
} }

View File

@ -157,7 +157,8 @@ static void request_firmware_work_func(struct work_struct *work)
#endif #endif
extern int lx_emul_request_firmware_nowait(const char *name, void *dest, size_t *result); 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 lx_emul_release_firmware(void const *data, size_t size);
extern void rtnl_lock(void); extern void rtnl_lock(void);
@ -176,7 +177,7 @@ int request_firmware_nowait(struct module * module,
#endif #endif
bool reg_db; bool reg_db;
if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size)) { if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size, true)) {
kfree(fw); kfree(fw);
return -1; return -1;
} }
@ -218,17 +219,17 @@ int request_firmware_nowait(struct module * module,
} }
int request_firmware(const struct firmware ** firmware_p, int request_firmware_common(const struct firmware **firmware_p,
const char * name, struct device * device) const char *name, struct device *device, bool warn)
{ {
struct firmware *fw; struct firmware *fw;
if (!*firmware_p) if (!*firmware_p)
return -1; return -1;
fw = kzalloc(sizeof (struct firmware), GFP_KERNEL); fw = kzalloc(sizeof(struct firmware), GFP_KERNEL);
if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size)) { if (lx_emul_request_firmware_nowait(name, &fw->data, &fw->size, warn)) {
kfree(fw); kfree(fw);
return -1; return -1;
} }
@ -238,6 +239,13 @@ int request_firmware(const struct firmware ** firmware_p,
} }
int request_firmware(const struct firmware ** firmware_p,
const char * name, struct device * device)
{
return request_firmware_common(firmware_p, name, device, true);
}
void release_firmware(const struct firmware * fw) void release_firmware(const struct firmware * fw)
{ {
lx_emul_release_firmware(fw->data, fw->size); lx_emul_release_firmware(fw->data, fw->size);
@ -245,13 +253,9 @@ void release_firmware(const struct firmware * 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) int firmware_request_nowarn(const struct firmware ** firmware,const char * name,struct device * device)
{ {
return -1; return request_firmware_common(firmware, name, device, false);
} }