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:
parent
3ddfe3bdd3
commit
13eb07e0be
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue