summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
diff options
context:
space:
mode:
authorLuca Coelho <luciano.coelho@intel.com>2020-10-08 18:09:40 +0300
committerKalle Valo <kvalo@codeaurora.org>2020-10-08 20:09:28 +0300
commit70d3ca86b0255e4c5739e8d44c88502875395fb5 (patch)
tree731ed0c100d270acaf5be0dae9836ced4d64f6c0 /drivers/net/wireless/intel/iwlwifi/mvm/fw.c
parent7ef3e2246638e4c4ca9d343f5e3a041d7921e142 (diff)
downloadlinux-70d3ca86b0255e4c5739e8d44c88502875395fb5.tar.xz
iwlwifi: mvm: ring the doorbell and wait for PNVM load completion
When we receive a non-zero SKU_ID in the alive notification, we need to ring the doorbell and wait for the FW to send us a PNVM load complete notification before we continue the init phase. Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/iwlwifi.20201008180656.a10e8b6bbcf9.Ib5d10b3d508a4d2d4e6b7b629af89d76f4f03d81@changeid
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/fw.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index fda86c582049..a8a10f84f45d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -79,6 +79,7 @@
#define MVM_UCODE_ALIVE_TIMEOUT HZ
#define MVM_UCODE_CALIB_TIMEOUT (2*HZ)
+#define MVM_UCODE_PNVM_TIMEOUT (HZ / 10)
#define UCODE_VALID_OK cpu_to_le32(0x1)
@@ -305,6 +306,20 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
return true;
}
+static bool iwl_pnvm_complete_fn(struct iwl_notif_wait_data *notif_wait,
+ struct iwl_rx_packet *pkt, void *data)
+{
+ struct iwl_mvm *mvm =
+ container_of(notif_wait, struct iwl_mvm, notif_wait);
+ struct iwl_pnvm_init_complete_ntfy *pnvm_ntf = (void *)pkt->data;
+
+ IWL_DEBUG_FW(mvm,
+ "PNVM complete notification received with status %d\n",
+ le32_to_cpu(pnvm_ntf->status));
+
+ return true;
+}
+
static bool iwl_wait_init_complete(struct iwl_notif_wait_data *notif_wait,
struct iwl_rx_packet *pkt, void *data)
{
@@ -328,6 +343,35 @@ static bool iwl_wait_phy_db_entry(struct iwl_notif_wait_data *notif_wait,
return false;
}
+static int iwl_mvm_load_pnvm(struct iwl_mvm *mvm)
+{
+ struct iwl_notification_wait pnvm_wait;
+ static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
+ PNVM_INIT_COMPLETE_NTFY) };
+
+ /* if the SKU_ID is empty, there's nothing to do */
+ if (!mvm->trans->sku_id[0] &&
+ !mvm->trans->sku_id[1] &&
+ !mvm->trans->sku_id[2])
+ return 0;
+
+ /*
+ * TODO: phase 2: load the pnvm file, find the right section,
+ * load it and set the right DMA pointer.
+ */
+
+ iwl_init_notification_wait(&mvm->notif_wait, &pnvm_wait,
+ ntf_cmds, ARRAY_SIZE(ntf_cmds),
+ iwl_pnvm_complete_fn, NULL);
+
+ /* kick the doorbell */
+ iwl_write_umac_prph(mvm->trans, UREG_DOORBELL_TO_ISR6,
+ UREG_DOORBELL_TO_ISR6_PNVM);
+
+ return iwl_wait_notification(&mvm->notif_wait, &pnvm_wait,
+ MVM_UCODE_PNVM_TIMEOUT);
+}
+
static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
enum iwl_ucode_type ucode_type)
{
@@ -416,6 +460,13 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
return -EIO;
}
+ ret = iwl_mvm_load_pnvm(mvm);
+ if (ret) {
+ IWL_ERR(mvm, "Timeout waiting for PNVM load!\n");
+ iwl_fw_set_current_image(&mvm->fwrt, old_type);
+ return ret;
+ }
+
iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr);
/*