You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.4 KiB
182 lines
6.4 KiB
From 77ea9f18933b7c4dac76e658206be0153796566c Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
|
Date: Wed, 24 May 2023 15:00:31 +0200
|
|
Subject: [PATCH 073/142] wifi: rtw89: request full firmware only once if it's
|
|
early requested
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Bugzilla: https://bugzilla.redhat.com/2207499
|
|
|
|
commit 13eb07e0be1b95f1e1fab721fb0f38117edfe80b
|
|
Author: Zong-Zhe Yang <kevin_yang@realtek.com>
|
|
Date: Fri Dec 2 14:05:21 2022 +0800
|
|
|
|
wifi: rtw89: request full firmware only once if it's early requested
|
|
|
|
Under some condition, we now have to do early request full firmware when
|
|
rtw89_early_fw_feature_recognize(). In this case, we can avoid requesting
|
|
full firmware twice during probing driver. So, we pass out full firmware
|
|
from rtw89_early_fw_feature_recognize() if it's requested successfully.
|
|
And then, if firmware is settled, we have no need to request full firmware
|
|
again during normal initizating flow.
|
|
|
|
Setting firmware flow is updated to be as the following.
|
|
|
|
platform | early recognizing | normally initizating
|
|
-----------------------------------------------------------------------
|
|
deny reading | request full FW | (no more FW requesting)
|
|
partial file | | (obtain FW from early pahse)
|
|
-----------------------------------------------------------------------
|
|
able to read | request partial FW | async request full FW
|
|
partial file | (quite small chunk) |
|
|
|
|
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
|
|
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
Link: https://lore.kernel.org/r/20221202060521.501512-3-pkshih@realtek.com
|
|
|
|
Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
|
|
---
|
|
drivers/net/wireless/realtek/rtw89/core.c | 6 +++++-
|
|
drivers/net/wireless/realtek/rtw89/fw.c | 28 +++++++++++++++++++++++-----
|
|
drivers/net/wireless/realtek/rtw89/fw.h | 7 ++++---
|
|
3 files changed, 32 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
|
|
index 18b4361505229..e99eccf11c762 100644
|
|
--- a/drivers/net/wireless/realtek/rtw89/core.c
|
|
+++ b/drivers/net/wireless/realtek/rtw89/core.c
|
|
@@ -3423,6 +3423,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
|
|
u32 bus_data_size,
|
|
const struct rtw89_chip_info *chip)
|
|
{
|
|
+ const struct firmware *firmware;
|
|
struct ieee80211_hw *hw;
|
|
struct rtw89_dev *rtwdev;
|
|
struct ieee80211_ops *ops;
|
|
@@ -3430,7 +3431,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
|
|
u32 early_feat_map = 0;
|
|
bool no_chanctx;
|
|
|
|
- rtw89_early_fw_feature_recognize(device, chip, &early_feat_map);
|
|
+ firmware = rtw89_early_fw_feature_recognize(device, chip, &early_feat_map);
|
|
|
|
ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL);
|
|
if (!ops)
|
|
@@ -3457,6 +3458,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
|
|
rtwdev->dev = device;
|
|
rtwdev->ops = ops;
|
|
rtwdev->chip = chip;
|
|
+ rtwdev->fw.firmware = firmware;
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n",
|
|
no_chanctx ? "without" : "with");
|
|
@@ -3465,6 +3467,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
|
|
|
|
err:
|
|
kfree(ops);
|
|
+ release_firmware(firmware);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw);
|
|
@@ -3472,6 +3475,7 @@ EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw);
|
|
void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev)
|
|
{
|
|
kfree(rtwdev->ops);
|
|
+ release_firmware(rtwdev->fw.firmware);
|
|
ieee80211_free_hw(rtwdev->hw);
|
|
}
|
|
EXPORT_SYMBOL(rtw89_free_ieee80211_hw);
|
|
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
|
|
index e81aac935721a..3b7af8faca505 100644
|
|
--- a/drivers/net/wireless/realtek/rtw89/fw.c
|
|
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
|
|
@@ -273,9 +273,10 @@ static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
|
|
}
|
|
}
|
|
|
|
-void rtw89_early_fw_feature_recognize(struct device *device,
|
|
- const struct rtw89_chip_info *chip,
|
|
- u32 *early_feat_map)
|
|
+const struct firmware *
|
|
+rtw89_early_fw_feature_recognize(struct device *device,
|
|
+ const struct rtw89_chip_info *chip,
|
|
+ u32 *early_feat_map)
|
|
{
|
|
union rtw89_compat_fw_hdr buf = {};
|
|
const struct firmware *firmware;
|
|
@@ -300,7 +301,7 @@ void rtw89_early_fw_feature_recognize(struct device *device,
|
|
|
|
if (ret) {
|
|
dev_err(device, "failed to early request firmware: %d\n", ret);
|
|
- return;
|
|
+ return NULL;
|
|
}
|
|
|
|
if (full_req)
|
|
@@ -322,7 +323,11 @@ void rtw89_early_fw_feature_recognize(struct device *device,
|
|
}
|
|
|
|
out:
|
|
+ if (full_req)
|
|
+ return firmware;
|
|
+
|
|
release_firmware(firmware);
|
|
+ return NULL;
|
|
}
|
|
|
|
int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
|
|
@@ -629,6 +634,13 @@ int rtw89_load_firmware(struct rtw89_dev *rtwdev)
|
|
fw->rtwdev = rtwdev;
|
|
init_completion(&fw->completion);
|
|
|
|
+ if (fw->firmware) {
|
|
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
|
|
+ "full firmware has been early requested\n");
|
|
+ complete_all(&fw->completion);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev,
|
|
GFP_KERNEL, fw, rtw89_load_firmware_cb);
|
|
if (ret) {
|
|
@@ -645,8 +657,14 @@ void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
|
|
|
|
rtw89_wait_firmware_completion(rtwdev);
|
|
|
|
- if (fw->firmware)
|
|
+ if (fw->firmware) {
|
|
release_firmware(fw->firmware);
|
|
+
|
|
+ /* assign NULL back in case rtw89_free_ieee80211_hw()
|
|
+ * try to release the same one again.
|
|
+ */
|
|
+ fw->firmware = NULL;
|
|
+ }
|
|
}
|
|
|
|
#define H2C_CAM_LEN 60
|
|
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
|
|
index 5c4c7de1b4f5d..4d2f9ea9e0022 100644
|
|
--- a/drivers/net/wireless/realtek/rtw89/fw.h
|
|
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
|
|
@@ -3444,9 +3444,10 @@ struct rtw89_fw_h2c_rf_get_mccch {
|
|
|
|
int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev);
|
|
int rtw89_fw_recognize(struct rtw89_dev *rtwdev);
|
|
-void rtw89_early_fw_feature_recognize(struct device *device,
|
|
- const struct rtw89_chip_info *chip,
|
|
- u32 *early_feat_map);
|
|
+const struct firmware *
|
|
+rtw89_early_fw_feature_recognize(struct device *device,
|
|
+ const struct rtw89_chip_info *chip,
|
|
+ u32 *early_feat_map);
|
|
int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type);
|
|
int rtw89_load_firmware(struct rtw89_dev *rtwdev);
|
|
void rtw89_unload_firmware(struct rtw89_dev *rtwdev);
|
|
--
|
|
2.13.6
|
|
|