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

Commit 5b086414 authored by Golan Ben-Ami's avatar Golan Ben-Ami Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: support dumping UMAC internal txfifos



In case of FW error, support dumping the UMAC internal txfifos.
To do so, support version 2 of shared memory cfg command, which
contains the sizes of the internal txfifos, and move the command
to the system group.

Signed-off-by: default avatarGolan Ben-Ami <golan.ben.ami@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent cd47a3d3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ enum iwl_fw_error_dump_type {
	IWL_FW_ERROR_DUMP_RB = 11,
	IWL_FW_ERROR_DUMP_PAGING = 12,
	IWL_FW_ERROR_DUMP_RADIO_REG = 13,
	IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14,

	IWL_FW_ERROR_DUMP_MAX,
};
+3 −0
Original line number Diff line number Diff line
@@ -324,6 +324,8 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
 * @IWL_UCODE_TLV_CAPA_CTDP_SUPPORT: supports cTDP command
 * @IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED: supports usniffer enabled in
 *	regular image.
 * @IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG: support getting more shared
 *	memory addresses from the firmware.
 *
 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
 */
@@ -361,6 +363,7 @@ enum iwl_ucode_tlv_capa {
	IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT	= (__force iwl_ucode_tlv_capa_t)75,
	IWL_UCODE_TLV_CAPA_CTDP_SUPPORT			= (__force iwl_ucode_tlv_capa_t)76,
	IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED		= (__force iwl_ucode_tlv_capa_t)77,
	IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG	= (__force iwl_ucode_tlv_capa_t)80,

	NUM_IWL_UCODE_TLV_CAPA
#ifdef __CHECKER__
+12 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 *
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
 *
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -345,6 +347,16 @@ enum secure_load_status_reg {
#define TXF_READ_MODIFY_DATA		(0xa00448)
#define TXF_READ_MODIFY_ADDR		(0xa0044c)

/* UMAC Internal Tx Fifo */
#define TXF_CPU2_FIFO_ITEM_CNT		(0xA00538)
#define TXF_CPU2_WR_PTR		(0xA00514)
#define TXF_CPU2_RD_PTR		(0xA00510)
#define TXF_CPU2_FENCE_PTR		(0xA00518)
#define TXF_CPU2_LOCK_FENCE		(0xA00524)
#define TXF_CPU2_NUM			(0xA0053C)
#define TXF_CPU2_READ_MODIFY_DATA	(0xA00548)
#define TXF_CPU2_READ_MODIFY_ADDR	(0xA0054C)

/* Radio registers access */
#define RSP_RADIO_CMD			(0xa02804)
#define RSP_RADIO_RDDAT			(0xa02814)
+16 −1
Original line number Diff line number Diff line
@@ -287,6 +287,10 @@ enum iwl_phy_ops_subcmd_ids {
	DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
};

enum iwl_system_subcmd_ids {
	SHARED_MEM_CFG_CMD = 0x0,
};

enum iwl_data_path_subcmd_ids {
	UPDATE_MU_GROUPS_CMD = 0x1,
	TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
@@ -302,6 +306,7 @@ enum iwl_prot_offload_subcmd_ids {
enum {
	LEGACY_GROUP = 0x0,
	LONG_GROUP = 0x1,
	SYSTEM_GROUP = 0x2,
	PHY_OPS_GROUP = 0x4,
	DATA_PATH_GROUP = 0x5,
	PROT_OFFLOAD_GROUP = 0xb,
@@ -1923,6 +1928,7 @@ struct iwl_tdls_config_res {

#define TX_FIFO_MAX_NUM		8
#define RX_FIFO_MAX_NUM		2
#define TX_FIFO_INTERNAL_MAX_NUM	6

/**
 * Shared memory configuration information from the FW
@@ -1940,6 +1946,12 @@ struct iwl_tdls_config_res {
 * @page_buff_addr: used by UMAC and performance debug (page miss analysis),
 *	when paging is not supported this should be 0
 * @page_buff_size: size of %page_buff_addr
 * @rxfifo_addr: Start address of rxFifo
 * @internal_txfifo_addr: start address of internalFifo
 * @internal_txfifo_size: internal fifos' size
 *
 * NOTE: on firmware that don't have IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG
 *	 set, the last 3 members don't exist.
 */
struct iwl_shared_mem_cfg {
	__le32 shared_mem_addr;
@@ -1951,7 +1963,10 @@ struct iwl_shared_mem_cfg {
	__le32 rxfifo_size[RX_FIFO_MAX_NUM];
	__le32 page_buff_addr;
	__le32 page_buff_size;
} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
	__le32 rxfifo_addr;
	__le32 internal_txfifo_addr;
	__le32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
} __packed; /* SHARED_MEM_ALLOC_API_S_VER_2 */

/**
 * VHT MU-MIMO group configuration
+77 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2015        Intel Deutschland GmbH
 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
 *
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2015        Intel Deutschland GmbH
 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -265,6 +265,65 @@ static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
		*dump_data = iwl_fw_error_next_data(*dump_data);
	}

	if (fw_has_capa(&mvm->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
		/* Pull UMAC internal TXF data from all TXFs */
		for (i = 0;
		     i < ARRAY_SIZE(mvm->shared_mem_cfg.internal_txfifo_size);
		     i++) {
			/* Mark the number of TXF we're pulling now */
			iwl_trans_write_prph(mvm->trans, TXF_CPU2_NUM, i);

			fifo_hdr = (void *)(*dump_data)->data;
			fifo_data = (void *)fifo_hdr->data;
			fifo_len = mvm->shared_mem_cfg.internal_txfifo_size[i];

			/* No need to try to read the data if the length is 0 */
			if (fifo_len == 0)
				continue;

			/* Add a TLV for the internal FIFOs */
			(*dump_data)->type =
				cpu_to_le32(IWL_FW_ERROR_DUMP_INTERNAL_TXF);
			(*dump_data)->len =
				cpu_to_le32(fifo_len + sizeof(*fifo_hdr));

			fifo_hdr->fifo_num = cpu_to_le32(i);
			fifo_hdr->available_bytes =
				cpu_to_le32(iwl_trans_read_prph(mvm->trans,
								TXF_CPU2_FIFO_ITEM_CNT));
			fifo_hdr->wr_ptr =
				cpu_to_le32(iwl_trans_read_prph(mvm->trans,
								TXF_CPU2_WR_PTR));
			fifo_hdr->rd_ptr =
				cpu_to_le32(iwl_trans_read_prph(mvm->trans,
								TXF_CPU2_RD_PTR));
			fifo_hdr->fence_ptr =
				cpu_to_le32(iwl_trans_read_prph(mvm->trans,
								TXF_CPU2_FENCE_PTR));
			fifo_hdr->fence_mode =
				cpu_to_le32(iwl_trans_read_prph(mvm->trans,
								TXF_CPU2_LOCK_FENCE));

			/* Set TXF_CPU2_READ_MODIFY_ADDR to TXF_CPU2_WR_PTR */
			iwl_trans_write_prph(mvm->trans,
					     TXF_CPU2_READ_MODIFY_ADDR,
					     TXF_CPU2_WR_PTR);

			/* Dummy-read to advance the read pointer to head */
			iwl_trans_read_prph(mvm->trans,
					    TXF_CPU2_READ_MODIFY_DATA);

			/* Read FIFO */
			fifo_len /= sizeof(u32); /* Size in DWORDS */
			for (j = 0; j < fifo_len; j++)
				fifo_data[j] =
					iwl_trans_read_prph(mvm->trans,
							    TXF_CPU2_READ_MODIFY_DATA);
			*dump_data = iwl_fw_error_next_data(*dump_data);
		}
	}

	iwl_trans_release_nic_access(mvm->trans, &flags);
}

@@ -494,6 +553,22 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
					 sizeof(struct iwl_fw_error_dump_fifo);
		}

		if (fw_has_capa(&mvm->fw->ucode_capa,
				IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
			for (i = 0;
			     i < ARRAY_SIZE(mem_cfg->internal_txfifo_size);
			     i++) {
				if (!mem_cfg->internal_txfifo_size[i])
					continue;

				/* Add header info */
				fifo_data_len +=
					mem_cfg->internal_txfifo_size[i] +
					sizeof(*dump_data) +
					sizeof(struct iwl_fw_error_dump_fifo);
			}
		}

		/* Make room for PRPH registers */
		for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
			/* The range includes both boundaries */
Loading