Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bda7faf authored by Pontus Fuchs's avatar Pontus Fuchs Committed by John W. Linville
Browse files

wcn36xx: Cache nv to avoid request_firmware on resume path



If wowlan if off mac80211 will stop / start the driver on suspend /
resume. This causes problems on resume since request_firmware is called
from start. Fix this by caching the nv.

Signed-off-by: default avatarPontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 546c505b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include "wcn36xx.h"

@@ -992,6 +993,7 @@ static int wcn36xx_remove(struct platform_device *pdev)
	struct wcn36xx *wcn = hw->priv;
	wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");

	release_firmware(wcn->nv);
	mutex_destroy(&wcn->hal_mutex);

	ieee80211_unregister_hw(hw);
+10 −12
Original line number Diff line number Diff line
@@ -251,21 +251,22 @@ static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)

int wcn36xx_smd_load_nv(struct wcn36xx *wcn)
{
	const struct firmware *nv;
	struct nv_data *nv_d;
	struct wcn36xx_hal_nv_img_download_req_msg msg_body;
	int fw_bytes_left;
	int ret;
	u16 fm_offset = 0;

	ret = request_firmware(&nv, WLAN_NV_FILE, wcn->dev);
	if (!wcn->nv) {
		ret = request_firmware(&wcn->nv, WLAN_NV_FILE, wcn->dev);
		if (ret) {
			wcn36xx_err("Failed to load nv file %s: %d\n",
				      WLAN_NV_FILE, ret);
		goto out_free_nv;
			goto out;
		}
	}

	nv_d = (struct nv_data *)nv->data;
	nv_d = (struct nv_data *)wcn->nv->data;
	INIT_HAL_MSG(msg_body, WCN36XX_HAL_DOWNLOAD_NV_REQ);

	msg_body.header.len += WCN36XX_NV_FRAGMENT_SIZE;
@@ -275,7 +276,7 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn)
	mutex_lock(&wcn->hal_mutex);

	do {
		fw_bytes_left = nv->size - fm_offset - 4;
		fw_bytes_left = wcn->nv->size - fm_offset - 4;
		if (fw_bytes_left > WCN36XX_NV_FRAGMENT_SIZE) {
			msg_body.last_fragment = 0;
			msg_body.nv_img_buffer_size = WCN36XX_NV_FRAGMENT_SIZE;
@@ -313,10 +314,7 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn)

out_unlock:
	mutex_unlock(&wcn->hal_mutex);
out_free_nv:
	release_firmware(nv);

	return ret;
out:	return ret;
}

static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
+2 −0
Original line number Diff line number Diff line
@@ -171,6 +171,8 @@ struct wcn36xx {
	struct device		*dev;
	struct list_head	vif_list;

	const struct firmware	*nv;

	u8			fw_revision;
	u8			fw_version;
	u8			fw_minor;