diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index bec3c7ec3f4c528562fa2d010b721dd1d4e9269b..f99328cc6b01a2712776453bbe8f4cc3b5bb2143 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -38,6 +38,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
 	u16 mac_type = 0, rf_id = 0;
 	struct iwl_pnvm_image pnvm_data = {};
 	bool hw_match = false;
+	int ret;
 
 	IWL_DEBUG_FW(trans, "Handling PNVM section\n");
 
@@ -152,9 +153,14 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
 		return -ENOENT;
 	}
 
+	ret = iwl_trans_load_pnvm(trans, &pnvm_data);
+	if (ret)
+		return ret;
+
 	IWL_INFO(trans, "loaded PNVM version %08x\n", sha1);
 
-	return iwl_trans_set_pnvm(trans, &pnvm_data);
+	iwl_trans_set_pnvm(trans);
+	return 0;
 }
 
 static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
@@ -262,9 +268,7 @@ int iwl_pnvm_load(struct iwl_trans *trans,
 	 * need to set it again.
 	 */
 	if (trans->pnvm_loaded) {
-		ret = iwl_trans_set_pnvm(trans, NULL);
-		if (ret)
-			return ret;
+		iwl_trans_set_pnvm(trans);
 		goto skip_parse;
 	}
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
index 9d2dcb64523cea390f8eac0c87c88066b1353291..9f718e43dd81a2634a437319ab5525843470234f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
@@ -279,8 +279,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
 				 const struct fw_img *fw);
 void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive);
 
-int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
-					  const struct iwl_pnvm_image *pnvm_payloads);
+int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans,
+					   const struct iwl_pnvm_image *pnvm_payloads);
+void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans);
 int iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
 						  const void *data, u32 len);
 int iwl_trans_pcie_ctx_info_gen3_set_step(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index b7f43cfc35fbeed77428927e505f55eb46ce032e..35782cba5b8165d422a6ad82c05bd5c7e3e64702 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -557,6 +557,7 @@ struct iwl_pnvm_image {
  *	Note that the transport must fill in the proper file headers.
  * @debugfs_cleanup: used in the driver unload flow to make a proper cleanup
  *	of the trans debugfs
+ * @load_pnvm: save the pnvm data in DRAM
  * @set_pnvm: set the pnvm data in the prph scratch buffer, inside the
  *	context info.
  * @interrupts: disable/enable interrupts to transport
@@ -630,8 +631,9 @@ struct iwl_trans_ops {
 						 void *sanitize_ctx);
 	void (*debugfs_cleanup)(struct iwl_trans *trans);
 	void (*sync_nmi)(struct iwl_trans *trans);
-	int (*set_pnvm)(struct iwl_trans *trans,
-			const struct iwl_pnvm_image *pnvm_data);
+	int (*load_pnvm)(struct iwl_trans *trans,
+			 const struct iwl_pnvm_image *pnvm_payloads);
+	void (*set_pnvm)(struct iwl_trans *trans);
 	int (*set_reduce_power)(struct iwl_trans *trans,
 				const void *data, u32 len);
 	void (*interrupts)(struct iwl_trans *trans, bool enable);
@@ -1532,19 +1534,16 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
 void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
 				  u32 sw_err_bit);
 
-static inline int iwl_trans_set_pnvm(struct iwl_trans *trans,
-				     const struct iwl_pnvm_image *pnvm_data)
+static inline int iwl_trans_load_pnvm(struct iwl_trans *trans,
+				      const struct iwl_pnvm_image *pnvm_data)
 {
-	if (trans->ops->set_pnvm) {
-		int ret = trans->ops->set_pnvm(trans, pnvm_data);
-
-		if (ret)
-			return ret;
-	}
-
-	trans->pnvm_loaded = true;
+	return trans->ops->load_pnvm(trans, pnvm_data);
+}
 
-	return 0;
+static inline void iwl_trans_set_pnvm(struct iwl_trans *trans)
+{
+	if (trans->ops->set_pnvm)
+		trans->ops->set_pnvm(trans);
 }
 
 static inline int iwl_trans_set_reduce_power(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index 800857e61d6559023f5c23c82be53f0cb4c38bf2..e9f3799d4593c574e454f5f496ea342a9bc4e541 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -281,55 +281,68 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive)
 	trans_pcie->prph_info = NULL;
 }
 
-int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
-					  const struct iwl_pnvm_image *pnvm_payloads)
+int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans,
+					   const struct iwl_pnvm_image *pnvm_payloads)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
 		&trans_pcie->prph_scratch->ctrl_cfg;
 	struct iwl_dram_data *dram = &trans_pcie->pnvm_dram;
+	u32 len, len0, len1;
 
 	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
 		return 0;
 
 	/* only allocate the DRAM if not allocated yet */
-	if (!trans->pnvm_loaded) {
-		u32 len, len0, len1;
+	if (trans->pnvm_loaded)
+		return 0;
 
-		if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
-			return -EBUSY;
+	if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
+		return -EBUSY;
 
-		if (pnvm_payloads->n_chunks !=
-			UNFRAGMENTED_PNVM_PAYLOADS_NUMBER) {
-			IWL_DEBUG_FW(trans, "expected 2 payloads, got %d.\n",
-				     pnvm_payloads->n_chunks);
-			return -EINVAL;
-		}
-		len0 = pnvm_payloads->chunks[0].len;
-		len1 = pnvm_payloads->chunks[1].len;
-		if (len1 > 0xFFFFFFFF - len0) {
-			IWL_DEBUG_FW(trans, "sizes of payloads overflow.\n");
+	if (pnvm_payloads->n_chunks != UNFRAGMENTED_PNVM_PAYLOADS_NUMBER) {
+		IWL_DEBUG_FW(trans, "expected 2 payloads, got %d.\n",
+			     pnvm_payloads->n_chunks);
 			return -EINVAL;
-		}
-		len = len0 + len1;
+	}
 
-		dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent(trans, len, &dram->physical);
-		if (!dram->block) {
-			IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA.\n");
-			return -ENOMEM;
-		}
-		dram->size = len;
-		memcpy(dram->block, pnvm_payloads->chunks[0].data, len0);
-		memcpy((u8 *)dram->block + len0, pnvm_payloads->chunks[1].data,
-		       len1);
+	len0 = pnvm_payloads->chunks[0].len;
+	len1 = pnvm_payloads->chunks[1].len;
+	if (len1 > 0xFFFFFFFF - len0) {
+		IWL_DEBUG_FW(trans, "sizes of payloads overflow.\n");
+		return -EINVAL;
+	}
+	len = len0 + len1;
+
+	dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent(trans, len,
+							    &dram->physical);
+	if (!dram->block) {
+		IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA.\n");
+		return -ENOMEM;
 	}
 
+	dram->size = len;
+	memcpy(dram->block, pnvm_payloads->chunks[0].data, len0);
+	memcpy((u8 *)dram->block + len0, pnvm_payloads->chunks[1].data, len1);
+
+	trans->pnvm_loaded = true;
+	return 0;
+}
+
+void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans)
+{
+	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+	struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
+		&trans_pcie->prph_scratch->ctrl_cfg;
+
+	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
+		return;
+
 	prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =
 		cpu_to_le64(trans_pcie->pnvm_dram.physical);
 	prph_sc_ctrl->pnvm_cfg.pnvm_size =
 		cpu_to_le32(trans_pcie->pnvm_dram.size);
 
-	return 0;
 }
 
 int iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index db10bd3c105824e1793acdfbf9672728320f93f1..666dda554f3054cb3039f598ac027eb485163396 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3536,6 +3536,7 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
 	.txq_free = iwl_txq_dyn_free,
 	.wait_txq_empty = iwl_trans_pcie_wait_txq_empty,
 	.rxq_dma_data = iwl_trans_pcie_rxq_dma_data,
+	.load_pnvm = iwl_trans_pcie_ctx_info_gen3_load_pnvm,
 	.set_pnvm = iwl_trans_pcie_ctx_info_gen3_set_pnvm,
 	.set_reduce_power = iwl_trans_pcie_ctx_info_gen3_set_reduce_power,
 #ifdef CONFIG_IWLWIFI_DEBUGFS