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
This commit is contained in:
Zong-Zhe Yang 2022-12-02 14:05:21 +08:00 committed by Kalle Valo
parent 3ddfe3bdd3
commit 13eb07e0be
3 changed files with 32 additions and 9 deletions

View File

@ -3420,6 +3420,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;
@ -3427,7 +3428,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)
@ -3454,6 +3455,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");
@ -3462,6 +3464,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);
@ -3469,6 +3472,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);

View File

@ -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

View File

@ -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);