aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c34
1 files changed, 26 insertions, 8 deletions
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 cb60ba40fe97..800857e61d65 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -282,28 +282,46 @@ 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 void *data, u32 len)
+ 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;
- int ret;
+ struct iwl_dram_data *dram = &trans_pcie->pnvm_dram;
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 (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
return -EBUSY;
- ret = iwl_pcie_ctxt_info_alloc_dma(trans, data, len,
- &trans_pcie->pnvm_dram);
- if (ret < 0) {
- IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA %d.\n",
- ret);
- return ret;
+ 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");
+ 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);
}
prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =