diff options
author | Luca Coelho <luciano.coelho@intel.com> | 2021-02-10 18:23:53 +0300 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2021-02-11 02:57:40 +0300 |
commit | cdda18fbbefafc6f3b8e6fe03482c1a7de4772e6 (patch) | |
tree | 0965d5a09afd00f0ea1f76e07f30fa5dd0e066b9 | |
parent | ff11a8ee2d2d0f78514ac9b42fb50c525ca695c7 (diff) | |
download | linux-cdda18fbbefafc6f3b8e6fe03482c1a7de4772e6.tar.xz |
iwlwifi: pnvm: move file loading code to a separate function
In preparation to support loading the PNVM from UEFI, move the
function that loads the PNVM from the filesystem to a separate
function. This will make it easier to try to load from both places
later on.
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210210172142.072aa2e8bbc5.Ib351ee5da47a4cee60d44e66d32d2f6bba6f3150@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 37ce4fe136c5..d515af8c1686 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -1,9 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/****************************************************************************** - * - * Copyright(c) 2020 Intel Corporation - * - *****************************************************************************/ +/* + * Copyright(c) 2020-2021 Intel Corporation + */ #include "iwl-drv.h" #include "pnvm.h" @@ -221,9 +219,44 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, return -ENOENT; } +static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len) +{ + const struct firmware *pnvm; + char pnvm_name[64]; + int ret; + + /* + * The prefix unfortunately includes a hyphen at the end, so + * don't add the dot here... + */ + snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm", + trans->cfg->fw_name_pre); + + /* ...but replace the hyphen with the dot here. */ + if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name)) + pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.'; + + ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev); + if (ret) { + IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n", + pnvm_name, ret); + return ret; + } + + *data = kmemdup(pnvm->data, pnvm->size, GFP_KERNEL); + if (!*data) + return -ENOMEM; + + *len = pnvm->size; + + return 0; +} + int iwl_pnvm_load(struct iwl_trans *trans, struct iwl_notif_wait_data *notif_wait) { + u8 *data; + size_t len; struct iwl_notification_wait pnvm_wait; static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP, PNVM_INIT_COMPLETE_NTFY) }; @@ -233,44 +266,35 @@ int iwl_pnvm_load(struct iwl_trans *trans, if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2]) return 0; - /* load from disk only if we haven't done it (or tried) before */ - if (!trans->pnvm_loaded) { - const struct firmware *pnvm; - char pnvm_name[64]; + /* + * If we already loaded (or tried to load) it before, we just + * need to set it again. + */ + if (trans->pnvm_loaded) { + ret = iwl_trans_set_pnvm(trans, NULL, 0); + if (ret) + return ret; + goto skip_parse; + } + /* Try to load the PNVM from the filesystem */ + ret = iwl_pnvm_get_from_fs(trans, &data, &len); + if (ret) { /* - * The prefix unfortunately includes a hyphen at the end, so - * don't add the dot here... + * Pretend we've loaded it - at least we've tried and + * couldn't load it at all, so there's no point in + * trying again over and over. */ - snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm", - trans->cfg->fw_name_pre); - - /* ...but replace the hyphen with the dot here. */ - if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name)) - pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.'; - - ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev); - if (ret) { - IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n", - pnvm_name, ret); - /* - * Pretend we've loaded it - at least we've tried and - * couldn't load it at all, so there's no point in - * trying again over and over. - */ - trans->pnvm_loaded = true; - } else { - iwl_pnvm_parse(trans, pnvm->data, pnvm->size); + trans->pnvm_loaded = true; - release_firmware(pnvm); - } - } else { - /* if we already loaded, we need to set it again */ - ret = iwl_trans_set_pnvm(trans, NULL, 0); - if (ret) - return ret; + goto skip_parse; } + iwl_pnvm_parse(trans, data, len); + + kfree(data); + +skip_parse: iwl_init_notification_wait(notif_wait, &pnvm_wait, ntf_cmds, ARRAY_SIZE(ntf_cmds), iwl_pnvm_complete_fn, trans); |