iwlwifi: pcie: free some DMA memory earlier
authorJohannes Berg <johannes.berg@intel.com>
Fri, 18 Jun 2021 08:01:19 +0000 (11:01 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 22 Jun 2021 13:57:56 +0000 (16:57 +0300)
In gen3, after firmware is alive, we no longer need the
firmware and image loader images, only the context info
itself and PRPH info/scratch need to remain.

Call iwl_pcie_ctxt_info_gen3_free() appropriately in the
alive callback (iwl_trans_pcie_gen2_fw_alive()) with a new
argument indicating whether it can free everything or only
partially.

The context info and PRPH scratch are also not needed after
PNVM load, but we don't have a good hook for freeing after
that, so keep them for now.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210618105614.8230d91a46c1.Ia7db71e5e6265ca87363f1481eac1bc3bbebb15c@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c

index 2be605c..518a1bc 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2018, 2020 Intel Corporation
+ * Copyright (C) 2018, 2020-2021 Intel Corporation
  */
 #ifndef __iwl_context_info_file_gen3_h__
 #define __iwl_context_info_file_gen3_h__
@@ -245,7 +245,7 @@ struct iwl_context_info_gen3 {
 
 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);
+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);
index c7b9ca2..c69a154 100644 (file)
@@ -231,32 +231,39 @@ err_free_prph_scratch:
 
 }
 
-void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
+void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
+       if (trans_pcie->iml) {
+               dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
+                                 trans_pcie->iml_dma_addr);
+               trans_pcie->iml_dma_addr = 0;
+               trans_pcie->iml = NULL;
+       }
+
+       iwl_pcie_ctxt_info_free_fw_img(trans);
+
+       if (alive)
+               return;
+
        if (!trans_pcie->ctxt_info_gen3)
                return;
 
+       /* ctxt_info_gen3 and prph_scratch are still needed for PNVM load */
        dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3),
                          trans_pcie->ctxt_info_gen3,
                          trans_pcie->ctxt_info_dma_addr);
        trans_pcie->ctxt_info_dma_addr = 0;
        trans_pcie->ctxt_info_gen3 = NULL;
 
-       dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
-                         trans_pcie->iml_dma_addr);
-       trans_pcie->iml_dma_addr = 0;
-       trans_pcie->iml = NULL;
-
-       iwl_pcie_ctxt_info_free_fw_img(trans);
-
        dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch),
                          trans_pcie->prph_scratch,
                          trans_pcie->prph_scratch_dma_addr);
        trans_pcie->prph_scratch_dma_addr = 0;
        trans_pcie->prph_scratch = NULL;
 
+       /* this is needed for the entire lifetime */
        dma_free_coherent(trans->dev, PAGE_SIZE, trans_pcie->prph_info,
                          trans_pcie->prph_info_dma_addr);
        trans_pcie->prph_info_dma_addr = 0;
index 93b9578..a340093 100644 (file)
@@ -149,7 +149,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
 
        iwl_pcie_ctxt_info_free_paging(trans);
        if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
-               iwl_pcie_ctxt_info_gen3_free(trans);
+               iwl_pcie_ctxt_info_gen3_free(trans, false);
        else
                iwl_pcie_ctxt_info_free(trans);
 
@@ -323,7 +323,9 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
        /* now that we got alive we can free the fw image & the context info.
         * paging memory cannot be freed included since FW will still use it
         */
-       if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
+               iwl_pcie_ctxt_info_gen3_free(trans, true);
+       else
                iwl_pcie_ctxt_info_free(trans);
 
        /*