Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f130bb75 authored by Mordechay Goodstein's avatar Mordechay Goodstein Committed by Luca Coelho
Browse files

iwlwifi: add FW recovery flow



Add new API and TLV for the ability to send commands in the beginning
and end of reset flow.

The full flow of recovery is:

1. While loading FW, get address (from the TLV) of target buffer
   to read in case of reset
2. If an error/assert happens read the address data from step 1.
3. Reset the HW and load the FW.
4. Send the data read in step 2.
5. Add station keys
6. Send notification to FW that reset flow is done.

The main use of the recovery flow is for support in PN/SN recovery
when offloaded

Signed-off-by: default avatarMordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent ff911dca
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -197,4 +197,24 @@ struct iwl_card_state_notif {
	__le32 flags;
} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */

/**
 * enum iwl_error_recovery_flags - flags for error recovery cmd
 * @ERROR_RECOVERY_UPDATE_DB: update db from blob sent
 * @ERROR_RECOVERY_END_OF_RECOVERY: end of recovery
 */
enum iwl_error_recovery_flags {
	ERROR_RECOVERY_UPDATE_DB = BIT(0),
	ERROR_RECOVERY_END_OF_RECOVERY = BIT(1),
};

/**
 * struct iwl_fw_error_recovery_cmd - recovery cmd sent upon assert
 * @flags: &enum iwl_error_recovery_flags
 * @buf_size: db buffer size in bytes
 */
struct iwl_fw_error_recovery_cmd {
	__le32 flags;
	__le32 buf_size;
} __packed; /* ERROR_RECOVERY_CMD_HDR_API_S_VER_1 */

#endif /* __iwl_fw_api_alive_h__ */
+5 −0
Original line number Diff line number Diff line
@@ -643,6 +643,11 @@ enum iwl_system_subcmd_ids {
	 * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd
	 */
	INIT_EXTENDED_CFG_CMD = 0x03,

	/**
	 * @FW_ERROR_RECOVERY_CMD: &struct iwl_fw_error_recovery_cmd
	 */
	FW_ERROR_RECOVERY_CMD = 0x7,
};

#endif /* __iwl_fw_api_commands_h__ */
+1 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ enum iwl_ucode_tlv_type {
	IWL_UCODE_TLV_IML		= 52,
	IWL_UCODE_TLV_UMAC_DEBUG_ADDRS	= 54,
	IWL_UCODE_TLV_LMAC_DEBUG_ADDRS	= 55,
	IWL_UCODE_TLV_FW_RECOVERY_INFO	= 57,
	IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION	= IWL_UCODE_INI_TLV_GROUP | 0x1,
	IWL_UCODE_TLV_TYPE_HCMD			= IWL_UCODE_INI_TLV_GROUP | 0x2,
	IWL_UCODE_TLV_TYPE_REGIONS		= IWL_UCODE_INI_TLV_GROUP | 0x3,
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ struct iwl_ucode_capabilities {
	u32 n_scan_channels;
	u32 standard_phy_calibration_size;
	u32 flags;
	u32 error_log_addr;
	u32 error_log_size;
	unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
	unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
};
+14 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,20 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
				return -ENOMEM;
			break;
			}
		case IWL_UCODE_TLV_FW_RECOVERY_INFO: {
			struct {
				__le32 buf_addr;
				__le32 buf_size;
			} *recov_info = (void *)tlv_data;

			if (tlv_len != sizeof(*recov_info))
				goto invalid_tlv_len;
			capa->error_log_addr =
				le32_to_cpu(recov_info->buf_addr);
			capa->error_log_size =
				le32_to_cpu(recov_info->buf_size);
			}
			break;
		case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: {
			struct iwl_umac_debug_addrs *dbg_ptrs =
				(void *)tlv_data;
Loading