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

Commit 5f659c79 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'iwlwifi-next-for-kalle-2019-04-03' of...

Merge tag 'iwlwifi-next-for-kalle-2019-04-03' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Second batch of patches intended for v5.2

* Work on the new debugging infra continues;
* Fixes for the 22000 series;
* Support for some new FW API changes;
* Work on new hardware continues;
* Some debugfs cleanups by Greg-KH;
* General bugfixes;
* Other cleanups;
parents 95336d4c ef8a9137
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -180,7 +180,11 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
	.dbgc_supported = true,						\
	.min_umac_error_event_table = 0x400000,				\
	.d3_debug_data_base_addr = 0x401000,				\
	.d3_debug_data_length = 60 * 1024
	.d3_debug_data_length = 60 * 1024,				\
	.fw_mon_smem_write_ptr_addr = 0xa0c16c,				\
	.fw_mon_smem_write_ptr_msk = 0xfffff,				\
	.fw_mon_smem_cycle_cnt_ptr_addr = 0xa0c174,			\
	.fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff

#define IWL_DEVICE_AX200_COMMON						\
	IWL_DEVICE_22000_COMMON,					\
@@ -190,7 +194,8 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
	IWL_DEVICE_22000_COMMON,					\
	.device_family = IWL_DEVICE_FAMILY_22000,			\
	.base_params = &iwl_22000_base_params,				\
	.csr = &iwl_csr_v1
	.csr = &iwl_csr_v1,						\
	.gp2_reg_addr = 0xa02c68

#define IWL_DEVICE_22560						\
	IWL_DEVICE_22000_COMMON,					\
@@ -203,7 +208,9 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
	.device_family = IWL_DEVICE_FAMILY_AX210,			\
	.base_params = &iwl_22000_base_params,				\
	.csr = &iwl_csr_v1,						\
	.min_txq_size = 128
	.min_txq_size = 128,						\
	.gp2_reg_addr = 0xd02c68,					\
	.min_256_ba_txq_size = 512

const struct iwl_cfg iwl22000_2ac_cfg_hr = {
	.name = "Intel(R) Dual Band Wireless AC 22000",
+7 −3
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2015-2017 Intel Deutschland GmbH
 * Copyright (C) 2018 Intel Corporation
 * Copyright (C) 2018 - 2019 Intel Corporation
 *
 * 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
@@ -20,7 +20,7 @@
 * BSD LICENSE
 *
 * Copyright(c) 2015-2017 Intel Deutschland GmbH
 * Copyright (C) 2018 Intel Corporation
 * Copyright (C) 2018 - 2019 Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -148,7 +148,11 @@ static const struct iwl_tt_params iwl9000_tt_params = {
	.d3_debug_data_length = 92 * 1024,				\
	.ht_params = &iwl9000_ht_params,				\
	.nvm_ver = IWL9000_NVM_VERSION,					\
	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,		\
	.fw_mon_smem_write_ptr_addr = 0xa0476c,				\
	.fw_mon_smem_write_ptr_msk = 0xfffff,				\
	.fw_mon_smem_cycle_cnt_ptr_addr = 0xa04774,			\
	.fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff


const struct iwl_cfg iwl9160_2ac_cfg = {
+76 −1
Original line number Diff line number Diff line
@@ -541,6 +541,66 @@ enum iwl_he_htc_flags {
#define IWL_HE_HTC_LINK_ADAP_UNSOLICITED	(2 << IWL_HE_HTC_LINK_ADAP_POS)
#define IWL_HE_HTC_LINK_ADAP_BOTH		(3 << IWL_HE_HTC_LINK_ADAP_POS)

/**
 * struct iwl_he_sta_context_cmd_v1 - configure FW to work with HE AP
 * @sta_id: STA id
 * @tid_limit: max num of TIDs in TX HE-SU multi-TID agg
 *	0 - bad value, 1 - multi-tid not supported, 2..8 - tid limit
 * @reserved1: reserved byte for future use
 * @reserved2: reserved byte for future use
 * @flags: see %iwl_11ax_sta_ctxt_flags
 * @ref_bssid_addr: reference BSSID used by the AP
 * @reserved0: reserved 2 bytes for aligning the ref_bssid_addr field to 8 bytes
 * @htc_flags: which features are supported in HTC
 * @frag_flags: frag support in A-MSDU
 * @frag_level: frag support level
 * @frag_max_num: max num of "open" MSDUs in the receiver (in power of 2)
 * @frag_min_size: min frag size (except last frag)
 * @pkt_ext: optional, exists according to PPE-present bit in the HE-PHY capa
 * @bss_color: 11ax AP ID that is used in the HE SIG-A to mark inter BSS frame
 * @htc_trig_based_pkt_ext: default PE in 4us units
 * @frame_time_rts_th: HE duration RTS threshold, in units of 32us
 * @rand_alloc_ecwmin: random CWmin = 2**ECWmin-1
 * @rand_alloc_ecwmax: random CWmax = 2**ECWmax-1
 * @reserved3: reserved byte for future use
 * @trig_based_txf: MU EDCA Parameter set for the trigger based traffic queues
 */
struct iwl_he_sta_context_cmd_v1 {
	u8 sta_id;
	u8 tid_limit;
	u8 reserved1;
	u8 reserved2;
	__le32 flags;

	/* The below fields are set via Multiple BSSID IE */
	u8 ref_bssid_addr[6];
	__le16 reserved0;

	/* The below fields are set via HE-capabilities IE */
	__le32 htc_flags;

	u8 frag_flags;
	u8 frag_level;
	u8 frag_max_num;
	u8 frag_min_size;

	/* The below fields are set via PPE thresholds element */
	struct iwl_he_pkt_ext pkt_ext;

	/* The below fields are set via HE-Operation IE */
	u8 bss_color;
	u8 htc_trig_based_pkt_ext;
	__le16 frame_time_rts_th;

	/* Random access parameter set (i.e. RAPS) */
	u8 rand_alloc_ecwmin;
	u8 rand_alloc_ecwmax;
	__le16 reserved3;

	/* The below fields are set via MU EDCA parameter set element */
	struct iwl_he_backoff_conf trig_based_txf[AC_NUM];
} __packed; /* STA_CONTEXT_DOT11AX_API_S_VER_1 */

/**
 * struct iwl_he_sta_context_cmd - configure FW to work with HE AP
 * @sta_id: STA id
@@ -564,6 +624,14 @@ enum iwl_he_htc_flags {
 * @rand_alloc_ecwmax: random CWmax = 2**ECWmax-1
 * @reserved3: reserved byte for future use
 * @trig_based_txf: MU EDCA Parameter set for the trigger based traffic queues
 * @max_bssid_indicator: indicator of the max bssid supported on the associated
 *	bss
 * @bssid_index: index of the associated VAP
 * @ema_ap: AP supports enhanced Multi BSSID advertisement
 * @profile_periodicity: number of Beacon periods that are needed to receive the
 *	complete VAPs info
 * @bssid_count: actual number of VAPs in the MultiBSS Set
 * @reserved4: alignment
 */
struct iwl_he_sta_context_cmd {
	u8 sta_id;
@@ -599,7 +667,14 @@ struct iwl_he_sta_context_cmd {

	/* The below fields are set via MU EDCA parameter set element */
	struct iwl_he_backoff_conf trig_based_txf[AC_NUM];
} __packed; /* STA_CONTEXT_DOT11AX_API_S */

	u8 max_bssid_indicator;
	u8 bssid_index;
	u8 ema_ap;
	u8 profile_periodicity;
	u8 bssid_count;
	u8 reserved4[3];
} __packed; /* STA_CONTEXT_DOT11AX_API_S_VER_2 */

/**
 * struct iwl_he_monitor_cmd - configure air sniffer for HE
+167 −70
Original line number Diff line number Diff line
@@ -967,9 +967,10 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
	if (fifo_len) {
		iwl_fw_dump_rxf(fwrt, &dump_data);
		iwl_fw_dump_txf(fwrt, &dump_data);
	}

	if (radio_len)
		iwl_read_radio_regs(fwrt, &dump_data);
	}

	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_ERROR_INFO) &&
	    fwrt->dump.desc) {
@@ -1049,14 +1050,14 @@ static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_error_dump_range *range = range_ptr;
	__le32 *val = range->data;
	u32 addr, prph_val, offset = le32_to_cpu(reg->offset);
	u32 prph_val;
	u32 addr = le32_to_cpu(reg->start_addr[idx]) + le32_to_cpu(reg->offset);
	int i;

	range->start_addr = reg->start_addr[idx];
	range->start_addr = cpu_to_le64(addr);
	range->range_data_size = reg->internal.range_data_size;
	for (i = 0; i < le32_to_cpu(reg->internal.range_data_size); i += 4) {
		addr = le32_to_cpu(range->start_addr) + i;
		prph_val = iwl_read_prph(fwrt->trans, addr + offset);
		prph_val = iwl_read_prph(fwrt->trans, addr + i);
		if (prph_val == 0x5a5a5a5a)
			return -EBUSY;
		*val++ = cpu_to_le32(prph_val);
@@ -1071,16 +1072,13 @@ static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_error_dump_range *range = range_ptr;
	__le32 *val = range->data;
	u32 addr, offset = le32_to_cpu(reg->offset);
	u32 addr = le32_to_cpu(reg->start_addr[idx]) + le32_to_cpu(reg->offset);
	int i;

	range->start_addr = reg->start_addr[idx];
	range->start_addr = cpu_to_le64(addr);
	range->range_data_size = reg->internal.range_data_size;
	for (i = 0; i < le32_to_cpu(reg->internal.range_data_size); i += 4) {
		addr = le32_to_cpu(range->start_addr) + i;
		*val++ = cpu_to_le32(iwl_trans_read32(fwrt->trans,
						      addr + offset));
	}
	for (i = 0; i < le32_to_cpu(reg->internal.range_data_size); i += 4)
		*val++ = cpu_to_le32(iwl_trans_read32(fwrt->trans, addr + i));

	return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
@@ -1090,12 +1088,11 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
				     void *range_ptr, int idx)
{
	struct iwl_fw_ini_error_dump_range *range = range_ptr;
	u32 addr = le32_to_cpu(range->start_addr);
	u32 offset = le32_to_cpu(reg->offset);
	u32 addr = le32_to_cpu(reg->start_addr[idx]) + le32_to_cpu(reg->offset);

	range->start_addr = reg->start_addr[idx];
	range->start_addr = cpu_to_le64(addr);
	range->range_data_size = reg->internal.range_data_size;
	iwl_trans_read_mem_bytes(fwrt->trans, addr + offset, range->data,
	iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
				 le32_to_cpu(reg->internal.range_data_size));

	return sizeof(*range) + le32_to_cpu(range->range_data_size);
@@ -1109,7 +1106,7 @@ iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt,
	struct iwl_fw_ini_error_dump_range *range = range_ptr;
	u32 page_size = fwrt->trans->init_dram.paging[idx].size;

	range->start_addr = cpu_to_le32(idx);
	range->start_addr = cpu_to_le64(idx);
	range->range_data_size = cpu_to_le32(page_size);
	memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
	       page_size);
@@ -1129,7 +1126,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
	dma_addr_t addr = fwrt->fw_paging_db[idx].fw_paging_phys;
	u32 page_size = fwrt->fw_paging_db[idx].fw_paging_size;

	range->start_addr = cpu_to_le32(idx);
	range->start_addr = cpu_to_le64(idx);
	range->range_data_size = cpu_to_le32(page_size);
	dma_sync_single_for_cpu(fwrt->trans->dev, addr,	page_size,
				DMA_BIDIRECTIONAL);
@@ -1152,7 +1149,7 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
	if (start_addr == 0x5a5a5a5a)
		return -EBUSY;

	range->start_addr = cpu_to_le32(start_addr);
	range->start_addr = cpu_to_le64(start_addr);
	range->range_data_size = cpu_to_le32(fwrt->trans->fw_mon[idx].size);

	memcpy(range->data, fwrt->trans->fw_mon[idx].block,
@@ -1228,10 +1225,11 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
	struct iwl_ini_txf_iter_data *iter;
	struct iwl_fw_ini_error_dump_register *reg_dump = (void *)range->data;
	u32 offs = le32_to_cpu(reg->offset), addr;
	u32 registers_size =
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
	__le32 *val = range->data;
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(*reg_dump);
	__le32 *data;
	unsigned long flags;
	int i;

@@ -1249,11 +1247,18 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,

	iwl_write_prph_no_grab(fwrt->trans, TXF_LARC_NUM + offs, iter->fifo);

	/* read txf registers */
	/*
	 * read txf registers. for each register, write to the dump the
	 * register address and its value
	 */
	for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
		addr = le32_to_cpu(reg->start_addr[i]) + offs;

		*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
		reg_dump->addr = cpu_to_le32(addr);
		reg_dump->data = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans,
								   addr));

		reg_dump++;
	}

	if (reg->fifos.header_only) {
@@ -1270,8 +1275,9 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,

	/* Read FIFO */
	addr = TXF_READ_MODIFY_DATA + offs;
	for (i = 0; i < iter->fifo_size; i += sizeof(__le32))
		*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
	data = (void *)reg_dump;
	for (i = 0; i < iter->fifo_size; i += sizeof(*data))
		*data++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));

out:
	iwl_trans_release_nic_access(fwrt->trans, &flags);
@@ -1327,10 +1333,11 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
	struct iwl_ini_rxf_data rxf_data;
	struct iwl_fw_ini_error_dump_register *reg_dump = (void *)range->data;
	u32 offs = le32_to_cpu(reg->offset), addr;
	u32 registers_size =
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
	__le32 *val = range->data;
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(*reg_dump);
	__le32 *data;
	unsigned long flags;
	int i;

@@ -1341,17 +1348,22 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
	if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
		return -EBUSY;

	offs += rxf_data.offset;

	range->fifo_num = cpu_to_le32(rxf_data.fifo_num);
	range->num_of_registers = reg->fifos.num_of_registers;
	range->range_data_size = cpu_to_le32(rxf_data.size + registers_size);

	/* read rxf registers */
	/*
	 * read rxf registers. for each register, write to the dump the
	 * register address and its value
	 */
	for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
		addr = le32_to_cpu(reg->start_addr[i]) + offs;

		*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
		reg_dump->addr = cpu_to_le32(addr);
		reg_dump->data = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans,
								   addr));

		reg_dump++;
	}

	if (reg->fifos.header_only) {
@@ -1359,6 +1371,12 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
		goto out;
	}

	/*
	 * region register have absolute value so apply rxf offset after
	 * reading the registers
	 */
	offs += rxf_data.offset;

	/* Lock fence */
	iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1);
	/* Set fence pointer to the same place like WR pointer */
@@ -1369,8 +1387,9 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,

	/* Read FIFO */
	addr =  RXF_FIFO_RD_FENCE_INC + offs;
	for (i = 0; i < rxf_data.size; i += sizeof(__le32))
		*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
	data = (void *)reg_dump;
	for (i = 0; i < rxf_data.size; i += sizeof(*data))
		*data++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));

out:
	iwl_trans_release_nic_access(fwrt->trans, &flags);
@@ -1384,32 +1403,86 @@ static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_error_dump *dump = data;

	dump->header.version = cpu_to_le32(IWL_INI_DUMP_MEM_VER);

	return dump->ranges;
}

static void
*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
*iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt,
			      struct iwl_fw_ini_region_cfg *reg,
				   void *data)
			      struct iwl_fw_ini_monitor_dump *data,
			      u32 write_ptr_addr, u32 write_ptr_msk,
			      u32 cycle_cnt_addr, u32 cycle_cnt_msk)
{
	struct iwl_fw_ini_monitor_dram_dump *mon_dump = (void *)data;
	u32 write_ptr, cycle_cnt;
	unsigned long flags;

	if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) {
		IWL_ERR(fwrt, "Failed to get DRAM monitor header\n");
		IWL_ERR(fwrt, "Failed to get monitor header\n");
		return NULL;
	}
	write_ptr = iwl_read_umac_prph_no_grab(fwrt->trans,
					       MON_BUFF_WRPTR_VER2);
	cycle_cnt = iwl_read_umac_prph_no_grab(fwrt->trans,
					       MON_BUFF_CYCLE_CNT_VER2);

	write_ptr = iwl_read_prph_no_grab(fwrt->trans, write_ptr_addr);
	cycle_cnt = iwl_read_prph_no_grab(fwrt->trans, cycle_cnt_addr);

	iwl_trans_release_nic_access(fwrt->trans, &flags);

	mon_dump->write_ptr = cpu_to_le32(write_ptr);
	mon_dump->cycle_cnt = cpu_to_le32(cycle_cnt);
	data->header.version = cpu_to_le32(IWL_INI_DUMP_MONITOR_VER);
	data->write_ptr = cpu_to_le32(write_ptr & write_ptr_msk);
	data->cycle_cnt = cpu_to_le32(cycle_cnt & cycle_cnt_msk);

	return data->ranges;
}

static void
*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
				   struct iwl_fw_ini_region_cfg *reg,
				   void *data)
{
	struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
	u32 write_ptr_addr, write_ptr_msk, cycle_cnt_addr, cycle_cnt_msk;

	switch (fwrt->trans->cfg->device_family) {
	case IWL_DEVICE_FAMILY_9000:
	case IWL_DEVICE_FAMILY_22000:
		write_ptr_addr = MON_BUFF_WRPTR_VER2;
		write_ptr_msk = -1;
		cycle_cnt_addr = MON_BUFF_CYCLE_CNT_VER2;
		cycle_cnt_msk = -1;
		break;
	default:
		IWL_ERR(fwrt, "Unsupported device family %d\n",
			fwrt->trans->cfg->device_family);
		return NULL;
	}

	return iwl_dump_ini_mon_fill_header(fwrt, reg, mon_dump, write_ptr_addr,
					    write_ptr_msk, cycle_cnt_addr,
					    cycle_cnt_msk);
}

static void
*iwl_dump_ini_mon_smem_fill_header(struct iwl_fw_runtime *fwrt,
				   struct iwl_fw_ini_region_cfg *reg,
				   void *data)
{
	struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
	const struct iwl_cfg *cfg = fwrt->trans->cfg;

	if (fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_9000 &&
	    fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_22000) {
		IWL_ERR(fwrt, "Unsupported device family %d\n",
			fwrt->trans->cfg->device_family);
		return NULL;
	}

	return iwl_dump_ini_mon_fill_header(fwrt, reg, mon_dump,
					    cfg->fw_mon_smem_write_ptr_addr,
					    cfg->fw_mon_smem_write_ptr_msk,
					    cfg->fw_mon_smem_cycle_cnt_ptr_addr,
					    cfg->fw_mon_smem_cycle_cnt_ptr_msk);

	return mon_dump->ranges;
}

static void *iwl_dump_ini_fifo_fill_header(struct iwl_fw_runtime *fwrt,
@@ -1418,6 +1491,8 @@ static void *iwl_dump_ini_fifo_fill_header(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_ini_fifo_error_dump *dump = data;

	dump->header.version = cpu_to_le32(IWL_INI_DUMP_FIFO_VER);

	return dump->ranges;
}

@@ -1509,7 +1584,8 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt,
					  struct iwl_fw_ini_region_cfg *reg)
{
	u32 size = sizeof(struct iwl_fw_ini_monitor_dram_dump);
	u32 size = sizeof(struct iwl_fw_ini_monitor_dump) +
		sizeof(struct iwl_fw_ini_error_dump_range);

	if (fwrt->trans->num_blocks)
		size += fwrt->trans->fw_mon[0].size;
@@ -1517,6 +1593,15 @@ static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt,
	return size;
}

static u32 iwl_dump_ini_mon_smem_get_size(struct iwl_fw_runtime *fwrt,
					  struct iwl_fw_ini_region_cfg *reg)
{
	return sizeof(struct iwl_fw_ini_monitor_dump) +
		iwl_dump_ini_mem_ranges(fwrt, reg) *
		(sizeof(struct iwl_fw_ini_error_dump_range) +
		 le32_to_cpu(reg->internal.range_data_size));
}

static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
				     struct iwl_fw_ini_region_cfg *reg)
{
@@ -1524,7 +1609,7 @@ static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
	void *fifo_iter = fwrt->dump.fifo_iter;
	u32 size = 0;
	u32 fifo_hdr = sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32) * 2;

	fwrt->dump.fifo_iter = &iter;
	while (iwl_ini_txf_iter(fwrt, reg)) {
@@ -1547,7 +1632,7 @@ static u32 iwl_dump_ini_rxf_get_size(struct iwl_fw_runtime *fwrt,
	struct iwl_ini_rxf_data rx_data;
	u32 size = sizeof(struct iwl_fw_ini_fifo_error_dump) +
		sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
		le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32) * 2;

	if (reg->fifos.header_only)
		return size;
@@ -1584,17 +1669,17 @@ struct iwl_dump_ini_mem_ops {
 * @fwrt: fw runtime struct.
 * @data: dump memory data.
 * @reg: region to copy to the dump.
 * @ops: memory dump operations.
 */
static void
iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
		 enum iwl_fw_ini_region_type type,
		 struct iwl_fw_error_dump_data **data,
		 struct iwl_fw_ini_region_cfg *reg,
		 struct iwl_dump_ini_mem_ops *ops)
{
	struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data;
	u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type);
	void *range;
	u32 num_of_ranges, i;

	if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
		    !ops->fill_mem_hdr || !ops->fill_range))
@@ -1605,6 +1690,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
	(*data)->type = cpu_to_le32(type | INI_DUMP_BIT);
	(*data)->len = cpu_to_le32(ops->get_size(fwrt, reg));

	header->region_id = reg->region_id;
	header->num_of_ranges = cpu_to_le32(num_of_ranges);
	header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME,
					     le32_to_cpu(reg->name_len)));
@@ -1641,7 +1727,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
	for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) {
		u32 reg_id = le32_to_cpu(trigger->data[i]);
		struct iwl_fw_ini_region_cfg *reg;
		enum iwl_fw_ini_region_type type;

		if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
			continue;
@@ -1650,13 +1735,11 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
		if (WARN(!reg, "Unassigned region %d\n", reg_id))
			continue;

		type = le32_to_cpu(reg->region_type);
		switch (type) {
		switch (le32_to_cpu(reg->region_type)) {
		case IWL_FW_INI_REGION_DEVICE_MEMORY:
		case IWL_FW_INI_REGION_PERIPHERY_MAC:
		case IWL_FW_INI_REGION_PERIPHERY_PHY:
		case IWL_FW_INI_REGION_PERIPHERY_AUX:
		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
		case IWL_FW_INI_REGION_CSR:
			size += hdr_len + iwl_dump_ini_mem_get_size(fwrt, reg);
			break;
@@ -1666,7 +1749,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
		case IWL_FW_INI_REGION_RXF:
			size += hdr_len + iwl_dump_ini_rxf_get_size(fwrt, reg);
			break;
		case IWL_FW_INI_REGION_PAGING: {
		case IWL_FW_INI_REGION_PAGING:
			size += hdr_len;
			if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
				size += iwl_dump_ini_paging_get_size(fwrt, reg);
@@ -1675,13 +1758,16 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
									  reg);
			}
			break;
		}
		case IWL_FW_INI_REGION_DRAM_BUFFER:
			if (!fwrt->trans->num_blocks)
				break;
			size += hdr_len +
				iwl_dump_ini_mon_dram_get_size(fwrt, reg);
			break;
		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
			size += hdr_len +
				iwl_dump_ini_mon_smem_get_size(fwrt, reg);
			break;
		case IWL_FW_INI_REGION_DRAM_IMR:
			/* Undefined yet */
		default:
@@ -1699,7 +1785,6 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,

	for (i = 0; i < num; i++) {
		u32 reg_id = le32_to_cpu(trigger->data[i]);
		enum iwl_fw_ini_region_type type;
		struct iwl_fw_ini_region_cfg *reg;
		struct iwl_dump_ini_mem_ops ops;

@@ -1711,15 +1796,17 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
		if (!reg)
			continue;

		type = le32_to_cpu(reg->region_type);
		switch (type) {
		/* currently the driver supports always on domain only */
		if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
			continue;

		switch (le32_to_cpu(reg->region_type)) {
		case IWL_FW_INI_REGION_DEVICE_MEMORY:
		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
			ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
			ops.get_size = iwl_dump_ini_mem_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
			ops.fill_range = iwl_dump_ini_dev_mem_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_PERIPHERY_MAC:
		case IWL_FW_INI_REGION_PERIPHERY_PHY:
@@ -1728,16 +1815,23 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
			ops.get_size = iwl_dump_ini_mem_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
			ops.fill_range = iwl_dump_ini_prph_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_DRAM_BUFFER:
			ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges;
			ops.get_size = iwl_dump_ini_mon_dram_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header;
			ops.fill_range = iwl_dump_ini_mon_dram_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_PAGING: {
		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
			ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
			ops.get_size = iwl_dump_ini_mon_smem_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header;
			ops.fill_range = iwl_dump_ini_dev_mem_iter;
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_PAGING:
			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
			if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
				ops.get_num_of_ranges =
@@ -1752,9 +1846,8 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
				ops.fill_range = iwl_dump_ini_paging_gen2_iter;
			}

			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		}
		case IWL_FW_INI_REGION_TXF: {
			struct iwl_ini_txf_iter_data iter = { .init = true };
			void *fifo_iter = fwrt->dump.fifo_iter;
@@ -1764,7 +1857,7 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
			ops.get_size = iwl_dump_ini_txf_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header;
			ops.fill_range = iwl_dump_ini_txf_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			fwrt->dump.fifo_iter = fifo_iter;
			break;
		}
@@ -1773,14 +1866,14 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
			ops.get_size = iwl_dump_ini_rxf_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header;
			ops.fill_range = iwl_dump_ini_rxf_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_CSR:
			ops.get_num_of_ranges =	iwl_dump_ini_mem_ranges;
			ops.get_size = iwl_dump_ini_mem_get_size;
			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
			ops.fill_range = iwl_dump_ini_csr_iter;
			iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
			iwl_dump_ini_mem(fwrt, data, reg, &ops);
			break;
		case IWL_FW_INI_REGION_DRAM_IMR:
			/* This is undefined yet */
@@ -2320,6 +2413,10 @@ static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
		.data = { data->data, },
	};

	/* currently the driver supports always on domain only */
	if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
		return;

	iwl_trans_send_cmd(fwrt->trans, &hcmd);
}

+10 −0
Original line number Diff line number Diff line
@@ -458,4 +458,14 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
/* This bit is used to differentiate the legacy dump from the ini dump */
#define INI_DUMP_BIT BIT(31)

static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
{
	if (fwrt->trans->ini_valid && fwrt->trans->hw_error) {
		_iwl_fw_dbg_ini_collect(fwrt, IWL_FW_TRIGGER_ID_FW_HW_ERROR);
		fwrt->trans->hw_error = false;
	} else {
		iwl_fw_dbg_collect_desc(fwrt, &iwl_dump_desc_assert, false, 0);
	}
}

#endif  /* __iwl_fw_dbg_h__ */
Loading