OSDN Git Service

iwlwifi: parse debug exclude data from firmware file
authorJohannes Berg <johannes.berg@intel.com>
Sun, 17 Oct 2021 09:40:12 +0000 (12:40 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 22 Oct 2021 07:49:00 +0000 (10:49 +0300)
Parse the memory dump exclusion TLVs from the firmware file
and save the data to be able to apply them later upon dump.

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.20211017123741.ec280bcb32cb.Iac0da0e22d7c3c0e237867c9113a06ddd95c7a51@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/fw/img.h
drivers/net/wireless/intel/iwlwifi/iwl-drv.c

index 6c8e9f3..3a03107 100644 (file)
@@ -100,6 +100,9 @@ enum iwl_ucode_tlv_type {
        IWL_UCODE_TLV_PNVM_SKU                  = 64,
        IWL_UCODE_TLV_TCM_DEBUG_ADDRS           = 65,
 
+       IWL_UCODE_TLV_SEC_TABLE_ADDR            = 66,
+       IWL_UCODE_TLV_D3_KEK_KCK_ADDR           = 67,
+
        IWL_UCODE_TLV_FW_NUM_STATIONS           = IWL_UCODE_TLV_CONST_BASE + 0,
 
        IWL_UCODE_TLV_TYPE_DEBUG_INFO           = IWL_UCODE_TLV_DEBUG_BASE + 0,
@@ -956,6 +959,10 @@ struct iwl_fw_tcm_error_addr {
        __le32 addr;
 }; /* FW_TLV_TCM_ERROR_INFO_ADDRS_S */
 
+struct iwl_fw_dump_exclude {
+       __le32 addr, size;
+};
+
 static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,
                                        size_t fixed_size, size_t var_size)
 {
index 6099d1e..993bda1 100644 (file)
@@ -176,6 +176,10 @@ struct iwl_fw_dbg {
        u32 dump_mask;
 };
 
+struct iwl_dump_exclude {
+       u32 addr, size;
+};
+
 /**
  * struct iwl_fw - variables associated with the firmware
  *
@@ -198,6 +202,8 @@ struct iwl_fw_dbg {
  *     we get the ALIVE from the uCode
  * @phy_integration_ver: PHY integration version string
  * @phy_integration_ver_len: length of @phy_integration_ver
+ * @dump_excl: image dump exclusion areas for RT image
+ * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image
  */
 struct iwl_fw {
        u32 ucode_ver;
@@ -229,6 +235,8 @@ struct iwl_fw {
 
        u8 *phy_integration_ver;
        u32 phy_integration_ver_len;
+
+       struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2];
 };
 
 static inline const char *get_fw_dbg_mode_string(int mode)
index 6712ff6..8296b71 100644 (file)
@@ -549,6 +549,43 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
        return 0;
 }
 
+static void iwl_drv_set_dump_exclude(struct iwl_drv *drv,
+                                    enum iwl_ucode_tlv_type tlv_type,
+                                    const void *tlv_data, u32 tlv_len)
+{
+       const struct iwl_fw_dump_exclude *fw = tlv_data;
+       struct iwl_dump_exclude *excl;
+
+       if (tlv_len < sizeof(*fw))
+               return;
+
+       if (tlv_type == IWL_UCODE_TLV_SEC_TABLE_ADDR) {
+               excl = &drv->fw.dump_excl[0];
+
+               /* second time we find this, it's for WoWLAN */
+               if (excl->addr)
+                       excl = &drv->fw.dump_excl_wowlan[0];
+       } else if (fw_has_capa(&drv->fw.ucode_capa,
+                              IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG)) {
+               /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is regular image */
+               excl = &drv->fw.dump_excl[0];
+       } else {
+               /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is WoWLAN image */
+               excl = &drv->fw.dump_excl_wowlan[0];
+       }
+
+       if (excl->addr)
+               excl++;
+
+       if (excl->addr) {
+               IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n");
+               return;
+       }
+
+       excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL;
+       excl->size = le32_to_cpu(fw->size);
+}
+
 static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
                                const struct firmware *ucode_raw,
                                struct iwl_firmware_pieces *pieces,
@@ -1165,6 +1202,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
                                return -ENOMEM;
                        drv->fw.phy_integration_ver_len = tlv_len;
                        break;
+               case IWL_UCODE_TLV_SEC_TABLE_ADDR:
+               case IWL_UCODE_TLV_D3_KEK_KCK_ADDR:
+                       iwl_drv_set_dump_exclude(drv, tlv_type,
+                                                tlv_data, tlv_len);
+                       break;
                default:
                        IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
                        break;